diff --git a/PKHeX.Core/Legality/Encounters/EncounterEgg.cs b/PKHeX.Core/Legality/Encounters/EncounterEgg.cs
index 5bad6b694..be2a294ad 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterEgg.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterEgg.cs
@@ -17,7 +17,9 @@ public class EncounterEgg : IEncounterable, IVersion
public GameVersion Version { get; set; }
- public PKM ConvertToPKM(ITrainerInfo SAV)
+ public PKM ConvertToPKM(ITrainerInfo SAV) => ConvertToPKM(SAV, EncounterCriteria.Unrestricted);
+
+ public PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria)
{
int gen = Version.GetGeneration();
if (gen < 2)
@@ -26,12 +28,14 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
Version = GameVersion.C;
}
var pk = PKMConverter.GetBlank(gen, Version);
+
SAV.ApplyToPKM(pk);
pk.Species = Species;
pk.Nickname = PKX.GetSpeciesNameGeneration(Species, SAV.Language, gen);
pk.CurrentLevel = Level;
pk.Version = (int)Version;
+ pk.Ball = 4;
int[] moves = GetCurrentEggMoves(pk);
pk.Moves = moves;
pk.SetMaximumPPCurrent(moves);
@@ -42,16 +46,48 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
if (pk.Format <= 2 && Version != GameVersion.C)
return pk;
- pk.Met_Level = EncounterSuggestion.GetSuggestedEncounterEggMetLevel(pk);
- pk.Met_Location = Math.Max(0, EncounterSuggestion.GetSuggestedEggMetLocation(pk));
+ SetMetData(pk);
if (pk.Format < 3)
return pk;
- pk.Ball = 4;
+ SetNatureGenderAbility(pk, criteria);
- int gender = pk.PersonalInfo.RandomGender;
- int nature = Util.Rand.Next(25);
+ if (pk.GenNumber >= 4)
+ pk.SetEggMetData(Version, (GameVersion)SAV.Game);
+
+ if (pk.Format < 6)
+ return pk;
+ if (pk.Gen6)
+ pk.SetHatchMemory6();
+
+ SetAltForm(pk, SAV);
+
+ pk.SetRandomEC();
+ pk.RelearnMoves = moves;
+
+ return pk;
+ }
+
+ private void SetAltForm(PKM pk, ITrainerInfo SAV)
+ {
+ switch (Species)
+ {
+ case 774: // Minior
+ pk.AltForm = Util.Rand.Next(7, 14);
+ break;
+ case 664: // Scatterbug
+ case 665:
+ case 666:
+ pk.AltForm = Legal.GetVivillonPattern(SAV.Country, SAV.SubRegion);
+ break;
+ }
+ }
+
+ private static void SetNatureGenderAbility(PKM pk, EncounterCriteria criteria)
+ {
+ int gender = criteria.GetGender(-1, pk.PersonalInfo);
+ int nature = (int)criteria.GetNature(Nature.Random);
if (pk.Format <= 5)
{
@@ -68,34 +104,12 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
pk.Gender = gender;
pk.RefreshAbility(Util.Rand.Next(2));
}
+ }
- bool traded = (int)Version == SAV.Game;
- var today = pk.MetDate = DateTime.Today;
- if (pk.GenNumber >= 4)
- {
- pk.Egg_Location = EncounterSuggestion.GetSuggestedEncounterEggLocationEgg(pk, traded);
- pk.EggMetDate = today;
- }
-
- if (pk.Format < 6)
- return pk;
- if (pk.Gen6)
- pk.SetHatchMemory6();
-
- switch (Species)
- {
- case 774: // Minior
- pk.AltForm = Util.Rand.Next(7, 14);
- break;
- case 664: // Scatterbug
- pk.AltForm = Legal.GetVivillonPattern(SAV.Country, SAV.SubRegion);
- break;
- }
-
- pk.SetRandomEC();
- pk.RelearnMoves = moves;
-
- return pk;
+ private static void SetMetData(PKM pk)
+ {
+ pk.Met_Level = EncounterSuggestion.GetSuggestedEncounterEggMetLevel(pk);
+ pk.Met_Location = Math.Max(0, EncounterSuggestion.GetSuggestedEggMetLocation(pk));
}
private int[] GetCurrentEggMoves(PKM pk)
@@ -112,7 +126,7 @@ private int[] GetCurrentEggMoves(PKM pk)
}
}
- public class EncounterEggSplit : EncounterEgg
+ public sealed class EncounterEggSplit : EncounterEgg
{
public int OtherSpecies;
}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterInvalid.cs b/PKHeX.Core/Legality/Encounters/EncounterInvalid.cs
index e65e3cd89..c30737fff 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterInvalid.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterInvalid.cs
@@ -5,7 +5,7 @@ namespace PKHeX.Core
///
/// Invalid Encounter Data
///
- public class EncounterInvalid : IEncounterable
+ public sealed class EncounterInvalid : IEncounterable
{
public int Species { get; }
public int LevelMin { get; }
@@ -22,6 +22,7 @@ public EncounterInvalid(PKM pkm)
EggEncounter = pkm.WasEgg;
}
- public PKM ConvertToPKM(ITrainerInfo SAV) => throw new ArgumentException($"Cannot convert an {nameof(EncounterInvalid)} to PKM.");
+ public PKM ConvertToPKM(ITrainerInfo SAV) => ConvertToPKM(SAV, EncounterCriteria.Unrestricted);
+ public PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria) => throw new ArgumentException($"Cannot convert an {nameof(EncounterInvalid)} to PKM.");
}
}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterLink.cs b/PKHeX.Core/Legality/Encounters/EncounterLink.cs
index 432b7188f..9720fb89d 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterLink.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterLink.cs
@@ -5,7 +5,7 @@ namespace PKHeX.Core
///
/// Pokémon Link Encounter Data
///
- public class EncounterLink : IEncounterable, IRibbonSetEvent4, IMoveset, ILocation, IVersion
+ public sealed class EncounterLink : IEncounterable, IRibbonSetEvent4, IMoveset, ILocation, IVersion
{
public int Species { get; set; }
public int Level { get; set; }
@@ -37,7 +37,9 @@ public class EncounterLink : IEncounterable, IRibbonSetEvent4, IMoveset, ILocati
public bool RibbonChampionWorld { get; set; }
public bool RibbonSouvenir { get; set; }
- public PKM ConvertToPKM(ITrainerInfo SAV)
+ public PKM ConvertToPKM(ITrainerInfo SAV) => ConvertToPKM(SAV, EncounterCriteria.Unrestricted);
+
+ public PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria)
{
const int gen = 6;
var version = this.GetCompatibleVersion((GameVersion)SAV.Game);
@@ -52,21 +54,21 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
PID = Util.Rand32(),
Nickname = PKX.GetSpeciesNameGeneration(Species, lang, gen),
Ball = Ball,
- Met_Level = Level,
- Met_Location = Location,
- MetDate = DateTime.Today
};
SAV.ApplyToPKM(pk);
+ SetMetData(pk);
+ SetNatureGender(pk, criteria);
+ pk.RefreshAbility(Ability >> 1);
+ pk.SetRandomIVs(flawless: 3);
+
pk.Version = (int)version;
- pk.Gender = pk.PersonalInfo.RandomGender;
pk.Language = lang;
pk.Moves = Moves;
pk.SetMaximumPPCurrent(Moves);
pk.OT_Friendship = pk.PersonalInfo.BaseFriendship;
- pk.SetRandomIVs(flawless: 3);
- pk.RefreshAbility(Ability >> 1);
+
if (RelearnMoves.Length > 0)
pk.RelearnMoves = RelearnMoves;
if (RibbonClassic)
@@ -78,5 +80,18 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
return pk;
}
+
+ private static void SetNatureGender(PKM pk, EncounterCriteria criteria)
+ {
+ pk.Nature = (int)criteria.GetNature(Nature.Random);
+ pk.Gender = criteria.GetGender(-1, pk.PersonalInfo);
+ }
+
+ private void SetMetData(PKM pk)
+ {
+ pk.MetDate = DateTime.Today;
+ pk.Met_Level = Level;
+ pk.Met_Location = Location;
+ }
}
}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterRejected.cs b/PKHeX.Core/Legality/Encounters/EncounterRejected.cs
index 70cd1bf3b..c90e6e32a 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterRejected.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterRejected.cs
@@ -5,7 +5,7 @@ namespace PKHeX.Core
///
/// Rejected Encounter Data containing a reason why the encounter was rejected (not compatible).
///
- public class EncounterRejected : IEncounterable
+ public sealed class EncounterRejected : IEncounterable
{
public readonly IEncounterable Encounter;
public readonly CheckResult Check;
@@ -23,6 +23,7 @@ public EncounterRejected(IEncounterable encounter, CheckResult check)
Check = check;
}
- public PKM ConvertToPKM(ITrainerInfo SAV) => throw new ArgumentException($"Cannot convert an {nameof(EncounterRejected)} to PKM.");
+ public PKM ConvertToPKM(ITrainerInfo SAV) => ConvertToPKM(SAV, EncounterCriteria.Unrestricted);
+ public PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria) => throw new ArgumentException($"Cannot convert an {nameof(EncounterRejected)} to PKM.");
}
}
\ No newline at end of file
diff --git a/PKHeX.Core/Legality/Encounters/EncounterSlot.cs b/PKHeX.Core/Legality/Encounters/EncounterSlot.cs
index 9fb53c3ac..7577b9ad5 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterSlot.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterSlot.cs
@@ -2,23 +2,6 @@
namespace PKHeX.Core
{
- public class EncounterSlotPermissions
- {
- public int StaticIndex { get; set; } = -1;
- public int MagnetPullIndex { get; set; } = -1;
- public int StaticCount { get; set; }
- public int MagnetPullCount { get; set; }
-
- public bool AllowDexNav { get; set; }
- public bool Pressure { get; set; }
- public bool DexNav { get; set; }
- public bool WhiteFlute { get; set; }
- public bool BlackFlute { get; set; }
- public bool IsNormalLead => !(WhiteFlute || BlackFlute || DexNav);
- public bool IsDexNav => AllowDexNav && DexNav;
- public EncounterSlotPermissions Clone() => (EncounterSlotPermissions)MemberwiseClone();
- }
-
///
/// Wild Encounter Slot data
///
@@ -65,80 +48,35 @@ public string Name
}
}
- public PKM ConvertToPKM(ITrainerInfo SAV)
+ public PKM ConvertToPKM(ITrainerInfo SAV) => ConvertToPKM(SAV, EncounterCriteria.Unrestricted);
+
+ public PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria)
{
var version = this.GetCompatibleVersion((GameVersion)SAV.Game);
int lang = (int)Legal.GetSafeLanguage(Generation, (LanguageID)SAV.Language);
int level = LevelMin;
var pk = PKMConverter.GetBlank(Generation, Version);
- int nature = Util.Rand.Next(25);
SAV.ApplyToPKM(pk);
pk.Species = Species;
- int gender = pk.PersonalInfo.RandomGender;
pk.Language = lang;
pk.CurrentLevel = level;
pk.Version = (int)version;
pk.Nickname = PKX.GetSpeciesNameGeneration(Species, lang, Generation);
- pk.Ball = GetBall();
- pk.AltForm = GetWildAltForm(Form, pk, SAV);
-
- if (pk.Format > 2 || Version == GameVersion.C)
- {
- pk.Met_Location = Location;
- pk.Met_Level = level;
- if (Version == GameVersion.C && pk is PK2 pk2 && this is EncounterSlot1 slot)
- pk2.Met_TimeOfDay = slot.Time.RandomValidTime();
-
- if (pk.Format >= 4)
- pk.MetDate = DateTime.Today;
- }
+ pk.Ball = (int)Type.GetBall();
pk.Language = lang;
+ pk.OT_Friendship = pk.PersonalInfo.BaseFriendship;
+ pk.AltForm = GetWildAltForm(pk, Form, SAV);
- var ability = Util.Rand.Next(2);
- var pidtype = GetPIDType();
- if (pidtype == PIDType.PokeSpot)
- PIDGenerator.SetRandomPokeSpotPID(pk, nature, gender, ability, SlotNumber);
- else
- PIDGenerator.SetRandomWildPID(pk, pk.Format, nature, ability, gender, pidtype);
+ SetMetData(pk, level, Location);
+ SetNatureGenderAbility(pk, criteria);
- if (Permissions.IsDexNav)
- {
- pk.RefreshAbility(2);
- var eggMoves = MoveEgg.GetEggMoves(pk, Species, pk.AltForm, Version);
- if (eggMoves.Length > 0)
- pk.RelearnMove1 = eggMoves[Util.Rand.Next(eggMoves.Length)];
- }
-
- switch (pk.Format)
- {
- case 1 when Species == 64 && Version == GameVersion.YW: // Kadabra
- ((PK1)pk).Catch_Rate = 96;
- break;
- case 1 when Species == 148 && Version == GameVersion.YW: // Dragonair
- ((PK1)pk).Catch_Rate = 27;
- break;
- case 3:
- case 4:
- if (pk.Format == 4)
- pk.EncounterType = TypeEncounter.GetIndex();
- pk.Gender = gender;
- break;
- case 5:
- if (Type == SlotType.HiddenGrotto)
- pk.RefreshAbility(2);
- break;
- case 6:
- pk.SetRandomMemory6();
- break;
- }
+ SetFormatSpecificData(pk);
var moves = this is EncounterSlotMoves m ? m.Moves : MoveLevelUp.GetEncounterMoves(pk, level, version);
- if (Version == GameVersion.XD)
- pk.FatefulEncounter = true;
pk.Moves = moves;
pk.SetMaximumPPCurrent(moves);
- pk.OT_Friendship = pk.PersonalInfo.BaseFriendship;
+
if (pk.Format < 6)
return pk;
@@ -148,7 +86,72 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
return pk;
}
- private static int GetWildAltForm(int form, PKM pk, ITrainerInfo SAV)
+ private void SetFormatSpecificData(PKM pk)
+ {
+ if (pk is PK1 pk1)
+ {
+ if (Species == 64 && Version == GameVersion.YW) // Kadabra
+ pk1.Catch_Rate = 96;
+ else if (Species == 148 && Version == GameVersion.YW) // Dragonair
+ pk1.Catch_Rate = 27;
+ else
+ pk1.Catch_Rate = PersonalTable.RB[Species].CatchRate; // RB
+ }
+ else if (pk is PK2 pk2)
+ {
+ if (Version == GameVersion.C && this is EncounterSlot1 slot)
+ pk2.Met_TimeOfDay = slot.Time.RandomValidTime();
+ }
+ else if (pk is XK3 xk3)
+ {
+ xk3.FatefulEncounter = true; // PokeSpot
+ }
+ else if (pk is PK4 pk4)
+ {
+ pk4.EncounterType = TypeEncounter.GetIndex();
+ }
+ else if (pk is PK6 pk6)
+ {
+ if (Permissions.IsDexNav)
+ {
+ var eggMoves = MoveEgg.GetEggMoves(pk, Species, pk.AltForm, Version);
+ if (eggMoves.Length > 0)
+ pk6.RelearnMove1 = eggMoves[Util.Rand.Next(eggMoves.Length)];
+ }
+ pk.SetRandomMemory6();
+ }
+ }
+
+ private void SetNatureGenderAbility(PKM pk, EncounterCriteria criteria)
+ {
+ int gender = criteria.GetGender(-1, pk.PersonalInfo);
+ int nature = (int)criteria.GetNature(Nature.Random);
+
+ var ability = Util.Rand.Next(2);
+ if (Type == SlotType.HiddenGrotto) // don't force hidden for DexNav
+ ability = 2;
+
+ var pidtype = GetPIDType();
+ if (pidtype == PIDType.PokeSpot)
+ PIDGenerator.SetRandomPokeSpotPID(pk, nature, gender, ability, SlotNumber);
+ else
+ PIDGenerator.SetRandomWildPID(pk, pk.Format, nature, ability, gender, pidtype);
+ pk.Gender = gender;
+ }
+
+ private void SetMetData(PKM pk, int level, int location)
+ {
+ if (pk.Format <= 2 && Version != GameVersion.C)
+ return;
+
+ pk.Met_Location = location;
+ pk.Met_Level = level;
+
+ if (pk.Format >= 4)
+ pk.MetDate = DateTime.Today;
+ }
+
+ private static int GetWildAltForm(PKM pk, int form, ITrainerInfo SAV)
{
if (form < 30)
{
@@ -171,14 +174,5 @@ private PIDType GetPIDType()
return PIDType.PokeSpot;
return PIDType.None; // depends on format, let the program auto-detect.
}
-
- private int GetBall()
- {
- if (Type == SlotType.BugContest)
- return 24; // Sport
- if (Type.IsSafariType())
- return 5; // Safari
- return 4; // Poké Ball
- }
}
}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterSlot1.cs b/PKHeX.Core/Legality/Encounters/EncounterSlot1.cs
index 6bc64c828..9a5f2ab89 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterSlot1.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterSlot1.cs
@@ -7,7 +7,7 @@
/// Contains Time data which is present in origin data.
/// Contains identification, as this Version value is not stored in or formats.
///
- internal class EncounterSlot1 : EncounterSlot
+ internal sealed class EncounterSlot1 : EncounterSlot
{
public int Rate;
internal EncounterTime Time;
diff --git a/PKHeX.Core/Legality/Encounters/EncounterSlotMoves.cs b/PKHeX.Core/Legality/Encounters/EncounterSlotMoves.cs
index e387be192..0d7890986 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterSlotMoves.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterSlotMoves.cs
@@ -1,6 +1,6 @@
namespace PKHeX.Core
{
- internal class EncounterSlotMoves : EncounterSlot, IMoveset
+ internal sealed class EncounterSlotMoves : EncounterSlot, IMoveset
{
public int[] Moves { get; set; }
}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterSlotPermissions.cs b/PKHeX.Core/Legality/Encounters/EncounterSlotPermissions.cs
new file mode 100644
index 000000000..dc6fb6f27
--- /dev/null
+++ b/PKHeX.Core/Legality/Encounters/EncounterSlotPermissions.cs
@@ -0,0 +1,19 @@
+namespace PKHeX.Core
+{
+ public sealed class EncounterSlotPermissions
+ {
+ public int StaticIndex { get; set; } = -1;
+ public int MagnetPullIndex { get; set; } = -1;
+ public int StaticCount { get; set; }
+ public int MagnetPullCount { get; set; }
+
+ public bool AllowDexNav { get; set; }
+ public bool Pressure { get; set; }
+ public bool DexNav { get; set; }
+ public bool WhiteFlute { get; set; }
+ public bool BlackFlute { get; set; }
+ public bool IsNormalLead => !(WhiteFlute || BlackFlute || DexNav);
+ public bool IsDexNav => AllowDexNav && DexNav;
+ public EncounterSlotPermissions Clone() => (EncounterSlotPermissions)MemberwiseClone();
+ }
+}
\ No newline at end of file
diff --git a/PKHeX.Core/Legality/Encounters/EncounterStatic.cs b/PKHeX.Core/Legality/Encounters/EncounterStatic.cs
index ab6cd4610..77bf08c3f 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterStatic.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterStatic.cs
@@ -68,7 +68,9 @@ internal virtual EncounterStatic Clone()
private const string _name = "Static Encounter";
public string Name => Version == GameVersion.Any ? _name : $"{_name} ({Version})";
- public PKM ConvertToPKM(ITrainerInfo SAV)
+ public PKM ConvertToPKM(ITrainerInfo SAV) => ConvertToPKM(SAV, EncounterCriteria.Unrestricted);
+
+ public PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria)
{
var version = this.GetCompatibleVersion((GameVersion)SAV.Game);
SanityCheckVersion(ref version);
@@ -88,6 +90,9 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
pk.Version = (int)version;
pk.Nickname = PKX.GetSpeciesNameGeneration(Species, lang, Generation);
pk.Ball = Ball;
+ pk.AltForm = Form;
+ pk.HeldItem = HeldItem;
+ pk.OT_Friendship = pk.PersonalInfo.BaseFriendship;
if (pk.Format > 2 || Version == GameVersion.C)
{
@@ -99,11 +104,13 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
if (pk.Format >= 4)
pk.MetDate = DateTime.Today;
}
+
if (EggEncounter)
{
- bool traded = (int)Version == SAV.Game;
pk.Met_Location = Math.Max(0, EncounterSuggestion.GetSuggestedEggMetLocation(pk));
pk.Met_Level = EncounterSuggestion.GetSuggestedEncounterEggMetLevel(pk);
+
+ bool traded = (int)Version == SAV.Game;
if (pk.GenNumber >= 4)
{
pk.Egg_Location = EncounterSuggestion.GetSuggestedEncounterEggLocationEgg(pk, traded);
@@ -113,8 +120,6 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
pk.EggMetDate = today;
}
- pk.AltForm = Form;
-
if (this is EncounterStaticPID p)
{
pk.PID = p.PID;
@@ -142,18 +147,16 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
SetIVs(pk);
}
- switch (pk.Format)
+ switch (pk)
{
- case 3:
- if (this is EncounterStaticShadow)
- ((PK3)pk).RibbonNational = true;
+ case PK3 pk3 when this is EncounterStaticShadow:
+ pk3.RibbonNational = true;
break;
- case 4:
- if (this is EncounterStaticTyped t)
- pk.EncounterType = t.TypeEncounter.GetIndex();
+ case PK4 pk4 when this is EncounterStaticTyped t:
+ pk4.EncounterType = t.TypeEncounter.GetIndex();
break;
- case 6:
- pk.SetRandomMemory6();
+ case PK6 pk6:
+ pk6.SetRandomMemory6();
break;
}
@@ -161,12 +164,10 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
this.CopyContestStatsTo(s);
var moves = Moves ?? MoveLevelUp.GetEncounterMoves(pk, level, version);
- pk.HeldItem = HeldItem;
pk.Moves = moves;
pk.SetMaximumPPCurrent(moves);
if (pk.Format >= 6 && Relearn.Length > 0)
pk.RelearnMoves = Relearn;
- pk.OT_Friendship = pk.PersonalInfo.BaseFriendship;
if (Fateful)
pk.FatefulEncounter = true;
@@ -347,7 +348,7 @@ public bool IsMatch(PKM pkm, int lvl)
{
for (int i = 0; i < 6; i++)
{
- if (IVs[i] != -1 && IVs[i] != pkm.IVs[i])
+ if (IVs[i] != -1 && IVs[i] != pkm.GetIV(i))
return false;
}
}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterStaticPID.cs b/PKHeX.Core/Legality/Encounters/EncounterStaticPID.cs
index cab084fec..716e95f09 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterStaticPID.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterStaticPID.cs
@@ -1,6 +1,6 @@
namespace PKHeX.Core
{
- internal class EncounterStaticPID : EncounterStatic
+ internal sealed class EncounterStaticPID : EncounterStatic
{
public uint PID { get; set; }
public bool NSparkle { get; set; }
diff --git a/PKHeX.Core/Legality/Encounters/EncounterStaticShadow.cs b/PKHeX.Core/Legality/Encounters/EncounterStaticShadow.cs
index 9b918b8fd..dee6de8c0 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterStaticShadow.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterStaticShadow.cs
@@ -2,7 +2,7 @@
namespace PKHeX.Core
{
- public class EncounterStaticShadow : EncounterStatic
+ public sealed class EncounterStaticShadow : EncounterStatic
{
public TeamLock[] Locks { get; internal set; } = Array.Empty();
public int Gauge { get; internal set; }
diff --git a/PKHeX.Core/Legality/Encounters/EncounterStaticTyped.cs b/PKHeX.Core/Legality/Encounters/EncounterStaticTyped.cs
index c6f3bdb38..e4403928a 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterStaticTyped.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterStaticTyped.cs
@@ -1,6 +1,6 @@
namespace PKHeX.Core
{
- public class EncounterStaticTyped : EncounterStatic
+ public sealed class EncounterStaticTyped : EncounterStatic
{
public EncounterType TypeEncounter { get; internal set; } = EncounterType.None;
}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterTrade.cs b/PKHeX.Core/Legality/Encounters/EncounterTrade.cs
index 3a6793361..b54f6cacc 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterTrade.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterTrade.cs
@@ -25,13 +25,6 @@ public class EncounterTrade : IEncounterable, IMoveset, IGeneration, ILocation,
public int SID { get; set; }
public GameVersion Version { get; set; } = GameVersion.Any;
public int[] IVs { get; set; }
- public int[] Contest { set => this.SetContestStats(value); }
- public int CNT_Cool { get; set; }
- public int CNT_Beauty { get; set; }
- public int CNT_Cute { get; set; }
- public int CNT_Smart { get; set; }
- public int CNT_Tough { get; set; }
- public int CNT_Sheen { get; set; }
public int Form { get; set; }
public virtual Shiny Shiny { get; set; } = Shiny.Never;
public int Gender { get; set; } = -1;
@@ -42,6 +35,14 @@ public class EncounterTrade : IEncounterable, IMoveset, IGeneration, ILocation,
public int Ball { get; set; } = 4;
public int CurrentLevel { get; set; } = -1;
+ public int[] Contest { set => this.SetContestStats(value); }
+ public int CNT_Cool { get; set; }
+ public int CNT_Beauty { get; set; }
+ public int CNT_Cute { get; set; }
+ public int CNT_Smart { get; set; }
+ public int CNT_Tough { get; set; }
+ public int CNT_Sheen { get; set; }
+
public int TID7
{
set
@@ -67,67 +68,51 @@ public int TID7
0, 126, 254, 2001, 30002, 30001, 30001,
};
- public PKM ConvertToPKM(ITrainerInfo SAV)
+ public PKM ConvertToPKM(ITrainerInfo SAV) => ConvertToPKM(SAV, EncounterCriteria.Unrestricted);
+
+ public PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria)
{
+ var pk = PKMConverter.GetBlank(Generation, Version);
var version = this.GetCompatibleVersion((GameVersion)SAV.Game);
int lang = (int)Legal.GetSafeLanguage(Generation, (LanguageID)SAV.Language);
int level = CurrentLevel > 0 ? CurrentLevel : LevelMin;
if (level == 0)
level = 25; // avoid some cases
- var pk = PKMConverter.GetBlank(Generation, Version);
-
- pk.EncryptionConstant = Util.Rand32();
- pk.Species = Species;
- pk.CurrentLevel = level;
- int gender = Gender < 0 ? pk.PersonalInfo.RandomGender : Gender;
- int nature = Nature == Nature.Random ? Util.Rand.Next(25) : (int)Nature;
SAV.ApplyToPKM(pk);
- pk.Nature = nature;
+
+ int species = Species;
+ if (EvolveOnTrade)
+ species++;
+
+ pk.EncryptionConstant = Util.Rand32();
+ pk.Species = species;
+ pk.CurrentLevel = level;
pk.Version = (int)version;
pk.AltForm = Form;
-
- if (this is EncounterTradePID p)
- {
- pk.PID = p.PID;
- pk.Gender = PKX.GetGenderFromPID(Species, p.PID);
- pk.RefreshAbility(Ability >> 1);
- }
- else
- {
- int ability = Ability >> 1;
- PIDGenerator.SetRandomWildPID(pk, Generation, nature, ability, gender);
- pk.Gender = gender;
- pk.RefreshAbility(ability);
- }
pk.Ball = Ball;
- if (pk.Format != 2 || version == GameVersion.C)
- {
- pk.Met_Level = level;
- pk.Met_Location = Location > 0 ? Location : DefaultMetLocation[Generation - 1];
- }
- var today = DateTime.Today;
- pk.MetDate = today;
- if (EggLocation != 0)
- {
- pk.Egg_Location = EggLocation;
- pk.EggMetDate = today;
- }
-
pk.Language = lang;
pk.TID = TID;
pk.SID = SID;
pk.OT_Name = pk.Format == 1 ? StringConverter.G1TradeOTStr : GetOT(lang) ?? SAV.OT;
pk.OT_Gender = GetOT(lang) != null ? Math.Max(0, OTGender) : SAV.Gender;
pk.SetNickname(GetNickname(lang));
+ pk.OT_Friendship = pk.PersonalInfo.BaseFriendship;
+
+ SetNatureGenderAbility(pk, criteria);
if (IVs != null)
pk.SetRandomIVs(IVs, 0);
else
pk.SetRandomIVs(flawless: 3);
- if (pk.Format == 6)
- pk.SetRandomMemory6();
+ if (pk.Format != 2 || version == GameVersion.C)
+ {
+ var location = Location > 0 ? Location : DefaultMetLocation[Generation - 1];
+ SetMetData(pk, level, location);
+ }
+ if (EggLocation != 0)
+ SetEggMetData(pk);
if (pk is PK1 pk1 && this is EncounterTradeCatchRate c)
pk1.Catch_Rate = (int)c.Catch_Rate;
@@ -135,32 +120,71 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
if (pk is IContestStats s)
this.CopyContestStatsTo(s);
- var moves = Moves ?? MoveLevelUp.GetEncounterMoves(pk, level, version);
- if (pk.Format == 1 && moves.All(z => z == 0))
- moves = ((PersonalInfoG1)PersonalTable.RB[Species]).Moves;
- pk.Moves = moves;
- pk.SetMaximumPPCurrent(moves);
- pk.OT_Friendship = pk.PersonalInfo.BaseFriendship;
+ SetMoves(pk, version, level);
+
if (Fateful)
pk.FatefulEncounter = true;
UpdateEdgeCase(pk);
- if (EvolveOnTrade)
- ++pk.Species;
-
if (pk.Format < 6)
return pk;
SAV.ApplyHandlingTrainerInfo(pk, force: true);
pk.SetRandomEC();
- if (pk.Format == 7)
+ if (pk.Format == 6)
+ pk.SetRandomMemory6();
+ else if (pk.Format == 7)
SetSMOTMemory(pk);
return pk;
}
+ private void SetNatureGenderAbility(PKM pk, EncounterCriteria criteria)
+ {
+ int gender = criteria.GetGender(Gender, pk.PersonalInfo);
+ int nature = (int)criteria.GetNature(Nature);
+ int ability = Ability >> 1;
+
+ if (this is EncounterTradePID p)
+ {
+ pk.PID = p.PID;
+ pk.Nature = nature;
+ pk.Gender = PKX.GetGenderFromPID(Species, p.PID);
+ pk.RefreshAbility(ability);
+ }
+ else
+ {
+ PIDGenerator.SetRandomWildPID(pk, Generation, nature, ability, gender);
+ pk.Nature = nature;
+ pk.Gender = gender;
+ pk.RefreshAbility(ability);
+ }
+ }
+
+ private void SetMoves(PKM pk, GameVersion version, int level)
+ {
+ var moves = Moves ?? MoveLevelUp.GetEncounterMoves(pk, level, version);
+ if (pk.Format == 1 && moves.All(z => z == 0))
+ moves = ((PersonalInfoG1)PersonalTable.RB[Species]).Moves;
+ pk.Moves = moves;
+ pk.SetMaximumPPCurrent(moves);
+ }
+
+ private void SetEggMetData(PKM pk)
+ {
+ pk.Egg_Location = EggLocation;
+ pk.EggMetDate = DateTime.Today;
+ }
+
+ private static void SetMetData(PKM pk, int level, int location)
+ {
+ pk.Met_Level = level;
+ pk.Met_Location = location;
+ pk.MetDate = DateTime.Today;
+ }
+
private void UpdateEdgeCase(PKM pkm)
{
switch (Generation)
diff --git a/PKHeX.Core/Legality/Encounters/EncounterTradeCatchRate.cs b/PKHeX.Core/Legality/Encounters/EncounterTradeCatchRate.cs
index 926827caf..0af0dc180 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterTradeCatchRate.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterTradeCatchRate.cs
@@ -6,7 +6,7 @@
///
/// Generation 1 specific value used in detecting unmodified/untraded Generation 1 Trade Encounter data.
///
- public class EncounterTradeCatchRate : EncounterTrade
+ public sealed class EncounterTradeCatchRate : EncounterTrade
{
public uint Catch_Rate;
}
diff --git a/PKHeX.Core/Legality/Encounters/EncounterTradePID.cs b/PKHeX.Core/Legality/Encounters/EncounterTradePID.cs
index ba0238508..90c452989 100644
--- a/PKHeX.Core/Legality/Encounters/EncounterTradePID.cs
+++ b/PKHeX.Core/Legality/Encounters/EncounterTradePID.cs
@@ -3,7 +3,7 @@
///
/// Trade Encounter data with a fixed PID.
///
- public class EncounterTradePID : EncounterTrade
+ public sealed class EncounterTradePID : EncounterTrade
{
public uint PID;
public override Shiny Shiny { get; set; } = Shiny.FixedValue;
diff --git a/PKHeX.Core/Legality/Encounters/LegalInfo.cs b/PKHeX.Core/Legality/Encounters/LegalInfo.cs
index 9020d0684..b62f761db 100644
--- a/PKHeX.Core/Legality/Encounters/LegalInfo.cs
+++ b/PKHeX.Core/Legality/Encounters/LegalInfo.cs
@@ -5,7 +5,7 @@ namespace PKHeX.Core
///
/// Calculated Information storage with properties useful for parsing the legality of the input .
///
- public class LegalInfo
+ public sealed class LegalInfo
{
/// The object used for comparisons.
private readonly PKM pkm;
diff --git a/PKHeX.Core/Legality/Structures/IEncounterable.cs b/PKHeX.Core/Legality/Structures/IEncounterable.cs
index 683dd1691..b336acd08 100644
--- a/PKHeX.Core/Legality/Structures/IEncounterable.cs
+++ b/PKHeX.Core/Legality/Structures/IEncounterable.cs
@@ -12,6 +12,7 @@ public interface IEncounterable
int LevelMax { get; }
PKM ConvertToPKM(ITrainerInfo SAV);
+ PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria);
}
public static partial class Extensions
diff --git a/PKHeX.Core/MysteryGifts/MysteryGift.cs b/PKHeX.Core/MysteryGifts/MysteryGift.cs
index 6893d746e..03b9c902a 100644
--- a/PKHeX.Core/MysteryGifts/MysteryGift.cs
+++ b/PKHeX.Core/MysteryGifts/MysteryGift.cs
@@ -82,7 +82,8 @@ public static MysteryGift GetMysteryGift(byte[] data)
public byte[] Data { get; set; }
public abstract int Format { get; }
- public abstract PKM ConvertToPKM(ITrainerInfo SAV);
+ public PKM ConvertToPKM(ITrainerInfo SAV) => ConvertToPKM(SAV, EncounterCriteria.Unrestricted);
+ public abstract PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria);
protected abstract bool IsMatchExact(PKM pkm, IEnumerable vs);
protected abstract bool IsMatchDeferred(PKM pkm);
diff --git a/PKHeX.Core/MysteryGifts/PCD.cs b/PKHeX.Core/MysteryGifts/PCD.cs
index 825fa3ee1..a76aec861 100644
--- a/PKHeX.Core/MysteryGifts/PCD.cs
+++ b/PKHeX.Core/MysteryGifts/PCD.cs
@@ -126,9 +126,9 @@ public bool GiftEquals(PGT pgt)
return true;
}
- public override PKM ConvertToPKM(ITrainerInfo SAV)
+ public override PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria)
{
- return Gift.ConvertToPKM(SAV);
+ return Gift.ConvertToPKM(SAV, criteria);
}
public bool CanBeReceivedBy(int pkmVersion) => (CardCompatibility >> pkmVersion & 1) == 1;
diff --git a/PKHeX.Core/MysteryGifts/PGF.cs b/PKHeX.Core/MysteryGifts/PGF.cs
index 056b89f9b..5b64f16b5 100644
--- a/PKHeX.Core/MysteryGifts/PGF.cs
+++ b/PKHeX.Core/MysteryGifts/PGF.cs
@@ -162,7 +162,7 @@ public override int[] IVs
public override bool IsItem { get => CardType == 2; set { if (value) CardType = 2; } }
public bool IsPower { get => CardType == 3; set { if (value) CardType = 3; } }
- public override PKM ConvertToPKM(ITrainerInfo SAV)
+ public override PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria)
{
if (!IsPokémon)
return null;
diff --git a/PKHeX.Core/MysteryGifts/PGT.cs b/PKHeX.Core/MysteryGifts/PGT.cs
index 00bc80297..d8bb57fb9 100644
--- a/PKHeX.Core/MysteryGifts/PGT.cs
+++ b/PKHeX.Core/MysteryGifts/PGT.cs
@@ -119,7 +119,7 @@ private void EncryptPK()
public override int Location { get => PK.Met_Location; set => PK.Met_Location = value; }
public override int EggLocation { get => PK.Egg_Location; set => PK.Egg_Location = value; }
- public override PKM ConvertToPKM(ITrainerInfo SAV)
+ public override PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria)
{
if (!IsPokémon)
return null;
diff --git a/PKHeX.Core/MysteryGifts/WB7.cs b/PKHeX.Core/MysteryGifts/WB7.cs
index 9993ede07..8805ebf90 100644
--- a/PKHeX.Core/MysteryGifts/WB7.cs
+++ b/PKHeX.Core/MysteryGifts/WB7.cs
@@ -116,14 +116,6 @@ private uint Day
public bool MultiObtain { get => Data[CardStart + 0x53] == 1; set => Data[CardStart + 0x53] = (byte)(value ? 1 : 0); }
- // BP Properties
- public override bool IsBP { get => CardType == 3; set { if (value) CardType = 3; } }
- public override int BP { get => ItemID; set => ItemID = value; }
-
- // Bean (Mame) Properties
- public override bool IsBean { get => CardType == 2; set { if (value) CardType = 2; } }
- public override int Bean { get => ItemID; set => ItemID = value; }
-
// Item Properties
public override bool IsItem { get => CardType == 1; set { if (value) CardType = 1; } }
public override int ItemID { get => BitConverter.ToUInt16(Data, CardStart + 0x68); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, CardStart + 0x68); }
@@ -320,7 +312,7 @@ private int GetOTOffset(int language)
return 0xEE + (index * 0x1A);
}
- public override PKM ConvertToPKM(ITrainerInfo SAV)
+ public override PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria)
{
if (!IsPokémon)
return null;
diff --git a/PKHeX.Core/MysteryGifts/WC3.cs b/PKHeX.Core/MysteryGifts/WC3.cs
index 1982638c6..adb33217d 100644
--- a/PKHeX.Core/MysteryGifts/WC3.cs
+++ b/PKHeX.Core/MysteryGifts/WC3.cs
@@ -70,7 +70,7 @@ public int Met_Level
set => _metLevel = value;
}
- public override PKM ConvertToPKM(ITrainerInfo SAV)
+ public override PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria)
{
PK3 pk = new PK3
{
@@ -151,22 +151,19 @@ public override PKM ConvertToPKM(ITrainerInfo SAV)
pk.Nickname = PKX.GetSpeciesNameGeneration(Species, pk.Language, 3); // will be set to Egg nickname if appropriate by PK3 setter
// Generate PIDIV
- var seed = Util.Rand32();
- switch (Method)
- {
- case PIDType.BACD_R:
- seed &= 0xFFFF;
- break;
- case PIDType.BACD_R_S:
- seed &= 0xFF;
- break;
- }
- PIDGenerator.SetValuesFromSeed(pk, Method, seed);
+ SetPIDValues(pk);
+ pk.HeldItem = 0; // clear, only random for Jirachis(?), no loss
if (Version == GameVersion.XD)
pk.FatefulEncounter = true; // pk3 is already converted from xk3
+ SetMoves(pk);
+ pk.RefreshChecksum();
+ return pk;
+ }
- if (Moves == null || Moves.Length == 0) // not completely defined
+ private void SetMoves(PK3 pk)
+ {
+ if (Moves.Length == 0) // not completely defined
Moves = Legal.GetBaseEggMoves(pk, Species, (GameVersion)pk.Version, Level);
if (Moves.Length != 4)
{
@@ -177,9 +174,26 @@ public override PKM ConvertToPKM(ITrainerInfo SAV)
pk.Moves = Moves;
pk.SetMaximumPPCurrent(Moves);
- pk.HeldItem = 0; // clear, only random for Jirachis(?), no loss
- pk.RefreshChecksum();
- return pk;
+ }
+
+ private void SetPIDValues(PK3 pk)
+ {
+ var seed = Util.Rand32();
+ SetPIDValues(pk, seed);
+ }
+
+ private void SetPIDValues(PK3 pk, uint seed)
+ {
+ switch (Method)
+ {
+ case PIDType.BACD_R:
+ seed &= 0xFFFF;
+ break;
+ case PIDType.BACD_R_S:
+ seed &= 0xFF;
+ break;
+ }
+ PIDGenerator.SetValuesFromSeed(pk, Method, seed);
}
private static LanguageID GetSafeLanguage(LanguageID hatchLang, LanguageID supplied)
diff --git a/PKHeX.Core/MysteryGifts/WC6.cs b/PKHeX.Core/MysteryGifts/WC6.cs
index 55f2ac8ae..154a60418 100644
--- a/PKHeX.Core/MysteryGifts/WC6.cs
+++ b/PKHeX.Core/MysteryGifts/WC6.cs
@@ -284,7 +284,7 @@ public override int[] RelearnMoves
}
}
- public override PKM ConvertToPKM(ITrainerInfo SAV)
+ public override PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria)
{
if (!IsPokémon)
return null;
diff --git a/PKHeX.Core/MysteryGifts/WC7.cs b/PKHeX.Core/MysteryGifts/WC7.cs
index 68ddbb110..b6c970bac 100644
--- a/PKHeX.Core/MysteryGifts/WC7.cs
+++ b/PKHeX.Core/MysteryGifts/WC7.cs
@@ -326,7 +326,7 @@ public override int[] RelearnMoves
}
}
- public override PKM ConvertToPKM(ITrainerInfo SAV)
+ public override PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria)
{
if (!IsPokémon)
return null;