mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-10 14:44:24 +00:00
Minor clean
Use some enums, save a few virtual/static fetches
This commit is contained in:
parent
15da92f9bc
commit
bb1d23e112
8 changed files with 223 additions and 195 deletions
|
@ -106,7 +106,7 @@ namespace PKHeX.Core
|
|||
public static void SetRandomEC(this PKM pk)
|
||||
{
|
||||
int gen = pk.Generation;
|
||||
if (2 < gen && gen < 6)
|
||||
if (gen is 3 or 4 or 5)
|
||||
{
|
||||
pk.EncryptionConstant = pk.PID;
|
||||
return;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PKHeX.Core
|
||||
|
@ -48,6 +49,19 @@ namespace PKHeX.Core
|
|||
return ((atk & 3) << 2) | (def & 3);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modifies the provided <see cref="IVs"/> to have the requested <see cref="hiddenPowerType"/> for Generations 1 & 2
|
||||
/// </summary>
|
||||
/// <param name="hiddenPowerType">Hidden Power Type</param>
|
||||
/// <param name="IVs">Current IVs</param>
|
||||
/// <returns>True if the Hidden Power of the <see cref="IVs"/> is obtained, with or without modifications</returns>
|
||||
public static bool SetTypeGB(int hiddenPowerType, int[] IVs)
|
||||
{
|
||||
IVs[1] = (IVs[1] & ~3) | (hiddenPowerType >> 2);
|
||||
IVs[2] = (IVs[2] & ~3) | (hiddenPowerType & 3);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modifies the provided <see cref="IVs"/> to have the requested <see cref="hiddenPowerType"/>.
|
||||
/// </summary>
|
||||
|
@ -58,11 +72,7 @@ namespace PKHeX.Core
|
|||
public static bool SetIVsForType(int hiddenPowerType, int[] IVs, int format)
|
||||
{
|
||||
if (format <= 2)
|
||||
{
|
||||
IVs[1] = (IVs[1] & ~3) | (hiddenPowerType >> 2);
|
||||
IVs[2] = (IVs[2] & ~3) | (hiddenPowerType & 3);
|
||||
return true;
|
||||
}
|
||||
return SetTypeGB(hiddenPowerType, IVs);
|
||||
return SetIVsForType(hiddenPowerType, IVs);
|
||||
}
|
||||
|
||||
|
@ -74,7 +84,7 @@ namespace PKHeX.Core
|
|||
/// <returns>True if the Hidden Power of the <see cref="IVs"/> is obtained, with or without modifications</returns>
|
||||
public static bool SetIVsForType(int hpVal, int[] IVs)
|
||||
{
|
||||
if (IVs.All(z => z == 31))
|
||||
if (Array.TrueForAll(IVs, z => z == 31))
|
||||
{
|
||||
SetIVs(hpVal, IVs); // Get IVs
|
||||
return true;
|
||||
|
@ -101,9 +111,9 @@ namespace PKHeX.Core
|
|||
var permutations = GetPermutations(flawless, flawless.Length);
|
||||
int flawedCount = 0;
|
||||
int[]? best = null;
|
||||
int[] ivs = (int[])IVs.Clone();
|
||||
foreach (var permute in permutations)
|
||||
{
|
||||
var ivs = (int[])IVs.Clone();
|
||||
foreach (var item in permute)
|
||||
{
|
||||
ivs[item] ^= 1;
|
||||
|
@ -115,9 +125,11 @@ namespace PKHeX.Core
|
|||
break; // any further flaws are always worse
|
||||
|
||||
flawedCount = ct;
|
||||
best = ivs;
|
||||
best = (int[])ivs.Clone();
|
||||
break; // any further flaws are always worse
|
||||
}
|
||||
// Restore IVs for another iteration
|
||||
Array.Copy(IVs, 0, ivs, 0, ivs.Length);
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
@ -158,7 +170,7 @@ namespace PKHeX.Core
|
|||
/// These are just precomputed for fast modification.
|
||||
/// Individual Values (H/A/B/S/C/D)
|
||||
/// </remarks>
|
||||
public static readonly int[,] DefaultLowBits =
|
||||
public static readonly byte[,] DefaultLowBits =
|
||||
{
|
||||
{ 1, 1, 0, 0, 0, 0 }, // Fighting
|
||||
{ 0, 0, 0, 1, 0, 0 }, // Flying
|
||||
|
|
|
@ -166,8 +166,9 @@ namespace PKHeX.Core
|
|||
: ParseMovesWasEggPreRelearn(pkm, currentMoves, info, e);
|
||||
}
|
||||
|
||||
// Not all games have a re-learner. Initial moves may not fill out all 4 slots.
|
||||
int gen = info.EncounterMatch.Generation;
|
||||
if (gen <= 2 && (gen == 1 || (gen == 2 && !ParseSettings.AllowGen2MoveReminder(pkm)))) // fixed encounter moves without relearning
|
||||
if (gen == 1 || (gen == 2 && !AllowGen2MoveReminder(pkm)))
|
||||
return ParseMovesGenGB(pkm, currentMoves, info);
|
||||
|
||||
return ParseMovesSpecialMoveset(pkm, currentMoves, info);
|
||||
|
@ -176,13 +177,13 @@ namespace PKHeX.Core
|
|||
private static CheckMoveResult[] ParseMovesGenGB(PKM pkm, IReadOnlyList<int> currentMoves, LegalInfo info)
|
||||
{
|
||||
var res = new CheckMoveResult[4];
|
||||
var G1Encounter = info.EncounterMatch;
|
||||
var enc = info.EncounterMatch;
|
||||
var InitialMoves = Array.Empty<int>();
|
||||
var SpecialMoves = GetSpecialMoves(info.EncounterMatch);
|
||||
var games = info.EncounterMatch.Generation == 1 ? GBRestrictions.GetGen1Versions(info) : GBRestrictions.GetGen2Versions(info, pkm.Korean);
|
||||
var SpecialMoves = GetSpecialMoves(enc);
|
||||
var games = enc.Generation == 1 ? GBRestrictions.GetGen1Versions(enc) : GBRestrictions.GetGen2Versions(enc, pkm.Korean);
|
||||
foreach (var ver in games)
|
||||
{
|
||||
var VerInitialMoves = MoveLevelUp.GetEncounterMoves(G1Encounter.Species, 0, G1Encounter.LevelMin, ver);
|
||||
var VerInitialMoves = MoveLevelUp.GetEncounterMoves(enc.Species, 0, enc.LevelMin, ver);
|
||||
if (VerInitialMoves.Intersect(InitialMoves).Count() == VerInitialMoves.Length)
|
||||
return res;
|
||||
|
||||
|
@ -546,22 +547,22 @@ namespace PKHeX.Core
|
|||
{
|
||||
// Vaporeon in Yellow learns Mist and Haze at level 42, Mist can only be learned if it leveled up in the daycare
|
||||
// Vaporeon in Red/Blue learns Acid Armor at level 42 and level 47 in Yellow
|
||||
case (int)Species.Vaporeon when pkm.CurrentLevel < 47 && currentMoves.Contains(151):
|
||||
case (int)Species.Vaporeon when pkm.CurrentLevel < 47 && currentMoves.Contains((int)Move.AcidArmor):
|
||||
{
|
||||
var incompatible = new List<int>(3);
|
||||
if (currentMoves.Contains(54))
|
||||
incompatible.Add(54);
|
||||
if (currentMoves.Contains(114))
|
||||
incompatible.Add(114);
|
||||
if (currentMoves.Contains((int)Move.Mist))
|
||||
incompatible.Add((int)Move.Mist);
|
||||
if (currentMoves.Contains((int)Move.Haze))
|
||||
incompatible.Add((int)Move.Haze);
|
||||
if (incompatible.Count != 0)
|
||||
incompatible.Add(151);
|
||||
incompatible.Add((int)Move.AcidArmor);
|
||||
return incompatible;
|
||||
}
|
||||
|
||||
// Flareon in Yellow learns Smog at level 42
|
||||
// Flareon in Red Blue learns Leer at level 42 and level 47 in Yellow
|
||||
case (int)Species.Flareon when pkm.CurrentLevel < 47 && currentMoves.Contains(43) && currentMoves.Contains(123):
|
||||
return new[] {43, 123};
|
||||
case (int)Species.Flareon when pkm.CurrentLevel < 47 && currentMoves.Contains((int)Move.Leer) && currentMoves.Contains((int)Move.Smog):
|
||||
return new[] { (int)Move.Leer, (int)Move.Smog };
|
||||
|
||||
default: return Array.Empty<int>();
|
||||
}
|
||||
|
@ -664,25 +665,25 @@ namespace PKHeX.Core
|
|||
{
|
||||
case (int)Species.MrMime: // Mr. Mime (Mime Jr with Mimic)
|
||||
case (int)Species.Sudowoodo: // Sudowoodo (Bonsly with Mimic)
|
||||
ValidMoves.Add(102);
|
||||
ValidMoves.Add((int)Move.Mimic);
|
||||
break;
|
||||
case (int)Species.Ambipom: // Ambipom (Aipom with Double Hit)
|
||||
ValidMoves.Add(458);
|
||||
ValidMoves.Add((int)Move.DoubleHit);
|
||||
break;
|
||||
case (int)Species.Lickilicky: // Lickilicky (Lickitung with Rollout)
|
||||
ValidMoves.Add(205);
|
||||
ValidMoves.Add((int)Move.Rollout);
|
||||
break;
|
||||
case (int)Species.Tangrowth: // Tangrowth (Tangela with Ancient Power)
|
||||
case (int)Species.Yanmega: // Yanmega (Yanma with Ancient Power)
|
||||
case (int)Species.Mamoswine: // Mamoswine (Piloswine with Ancient Power)
|
||||
ValidMoves.Add(246);
|
||||
ValidMoves.Add((int)Move.AncientPower);
|
||||
break;
|
||||
case (int)Species.Sylveon: // Sylveon (Eevee with Fairy Move)
|
||||
// Add every fairy moves without checking if Eevee learn it or not; pokemon moves are determined legal before this function
|
||||
ValidMoves.AddRange(EvolutionRestrictions.FairyMoves);
|
||||
break;
|
||||
case (int)Species.Tsareena: // Tsareena (Steenee with Stomp)
|
||||
ValidMoves.Add(023);
|
||||
ValidMoves.Add((int)Move.Stomp);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,123 +20,103 @@ namespace PKHeX.Core
|
|||
|
||||
internal static readonly int[] BabyEvolutionWithMove =
|
||||
{
|
||||
122, // Mr. Mime (Mime Jr with Mimic)
|
||||
185, // Sudowoodo (Bonsly with Mimic)
|
||||
(int)Species.MrMime, // (Mime Jr with Mimic)
|
||||
(int)Species.Sudowoodo, // (Bonsly with Mimic)
|
||||
};
|
||||
|
||||
// List of species that evolve from a previous species having a move while leveling up
|
||||
internal static readonly int[] SpeciesEvolutionWithMove =
|
||||
{
|
||||
122, // Mr. Mime (Mime Jr with Mimic)
|
||||
185, // Sudowoodo (Bonsly with Mimic)
|
||||
424, // Ambipom (Aipom with Double Hit)
|
||||
463, // Lickilicky (Lickitung with Rollout)
|
||||
465, // Tangrowth (Tangela with Ancient Power)
|
||||
469, // Yanmega (Yamma with Ancient Power)
|
||||
473, // Mamoswine (Piloswine with Ancient Power)
|
||||
700, // Sylveon (Eevee with Fairy Move)
|
||||
763, // Tsareena (Steenee with Stomp)
|
||||
(int)Species.MrMime, // Mr. Mime (Mime Jr with Mimic)
|
||||
(int)Species.Sudowoodo, // Sudowoodo (Bonsly with Mimic)
|
||||
(int)Species.Ambipom, // Ambipom (Aipom with Double Hit)
|
||||
(int)Species.Lickilicky, // Lickilicky (Lickitung with Rollout)
|
||||
(int)Species.Tangrowth, // Tangrowth (Tangela with Ancient Power)
|
||||
(int)Species.Yanmega, // Yanmega (Yamma with Ancient Power)
|
||||
(int)Species.Mamoswine, // Mamoswine (Piloswine with Ancient Power)
|
||||
(int)Species.Sylveon, // Sylveon (Eevee with Fairy Move)
|
||||
(int)Species.Tsareena, // Tsareena (Steenee with Stomp)
|
||||
(int)Species.Grapploct // (Clobbopus with Taunt)
|
||||
};
|
||||
|
||||
internal static readonly int[] FairyMoves =
|
||||
{
|
||||
186, // Sweet Kiss
|
||||
204, // Charm
|
||||
236, // Moonlight
|
||||
574, // Disarming Voice
|
||||
577, // Draining Kiss
|
||||
578, // Crafty Shield
|
||||
579, // Flower Shield
|
||||
581, // Misty Terrain
|
||||
583, // Play Rough
|
||||
584, // Fairy Wind
|
||||
585, // Moonblast
|
||||
587, // Fairy Lock
|
||||
597, // Aromatic Mist
|
||||
601, // Geomancy
|
||||
605, // Dazzling Gleam
|
||||
608, // Baby-Doll Eyes
|
||||
617, // Light of Ruin
|
||||
656, // Twinkle Tackle
|
||||
657, // Twinkle Tackle
|
||||
666, // Floral Healing
|
||||
698, // Guardian of Alola
|
||||
705, // Fleur Cannon
|
||||
717, // Nature's Madness
|
||||
726, // Let's Snuggle Forever
|
||||
740, // Sparkly Swirl
|
||||
767, // Max Starfall
|
||||
777, // Decorate
|
||||
789, // Spirit Break
|
||||
790, // Strange Steam
|
||||
802, // Misty Explosion
|
||||
(int)Move.SweetKiss,
|
||||
(int)Move.Charm,
|
||||
(int)Move.Moonlight,
|
||||
(int)Move.DisarmingVoice,
|
||||
(int)Move.DrainingKiss,
|
||||
(int)Move.CraftyShield,
|
||||
(int)Move.FlowerShield,
|
||||
(int)Move.MistyTerrain,
|
||||
(int)Move.PlayRough,
|
||||
(int)Move.FairyWind,
|
||||
(int)Move.Moonblast,
|
||||
(int)Move.FairyLock,
|
||||
(int)Move.AromaticMist,
|
||||
(int)Move.Geomancy,
|
||||
(int)Move.DazzlingGleam,
|
||||
(int)Move.BabyDollEyes,
|
||||
(int)Move.LightofRuin,
|
||||
(int)Move.TwinkleTackleP,
|
||||
(int)Move.TwinkleTackleS,
|
||||
(int)Move.FloralHealing,
|
||||
(int)Move.GuardianofAlola,
|
||||
(int)Move.FleurCannon,
|
||||
(int)Move.NaturesMadness,
|
||||
(int)Move.LetsSnuggleForever,
|
||||
(int)Move.SparklySwirl,
|
||||
(int)Move.MaxStarfall,
|
||||
(int)Move.Decorate,
|
||||
(int)Move.SpiritBreak,
|
||||
(int)Move.StrangeSteam,
|
||||
(int)Move.MistyExplosion,
|
||||
};
|
||||
|
||||
// Moves that trigger the evolution by move
|
||||
private static readonly int[][] MoveEvolutionWithMove =
|
||||
{
|
||||
new [] { 102 }, // Mr. Mime (Mime Jr with Mimic)
|
||||
new [] { 102 }, // Sudowoodo (Bonsly with Mimic)
|
||||
new [] { 458 }, // Ambipom (Aipom with Double Hit)
|
||||
new [] { 205 }, // Lickilicky (Lickitung with Rollout)
|
||||
new [] { 246 }, // Tangrowth (Tangela with Ancient Power)
|
||||
new [] { 246 }, // Yanmega (Yamma with Ancient Power)
|
||||
new [] { 246 }, // Mamoswine (Piloswine with Ancient Power)
|
||||
new [] { (int)Move.Mimic }, // Mr. Mime (Mime Jr with Mimic)
|
||||
new [] { (int)Move.Mimic }, // Sudowoodo (Bonsly with Mimic)
|
||||
new [] { (int)Move.DoubleHit }, // Ambipom (Aipom with Double Hit)
|
||||
new [] { (int)Move.Rollout }, // Lickilicky (Lickitung with Rollout)
|
||||
new [] { (int)Move.AncientPower }, // Tangrowth (Tangela with Ancient Power)
|
||||
new [] { (int)Move.AncientPower }, // Yanmega (Yamma with Ancient Power)
|
||||
new [] { (int)Move.AncientPower }, // Mamoswine (Piloswine with Ancient Power)
|
||||
FairyMoves, // Sylveon (Eevee with Fairy Move)
|
||||
new [] { 023 }, // Tsareena (Steenee with Stomp)
|
||||
new [] { 269 }, // Grapploct (Clobbopus with Taunt)
|
||||
new [] { (int)Move.Stomp }, // Tsareena (Steenee with Stomp)
|
||||
new [] { (int)Move.Taunt }, // Grapploct (Clobbopus with Taunt)
|
||||
};
|
||||
|
||||
// Min level for any species for every generation to learn the move for evolution by move
|
||||
// 0 means it cant be learned in that generation
|
||||
private static readonly int[][] MinLevelEvolutionWithMove =
|
||||
{
|
||||
// Mr. Mime (Mime Jr with Mimic)
|
||||
new [] { 0, 0, 0, 0, 18, 15, 15, 2, 2 },
|
||||
// Sudowoodo (Bonsly with Mimic)
|
||||
new [] { 0, 0, 0, 0, 17, 17, 15, 2, 2 },
|
||||
// Ambipom (Aipom with Double Hit)
|
||||
new [] { 0, 0, 0, 0, 32, 32, 32, 2, 2 },
|
||||
// Lickilicky (Lickitung with Rollout)
|
||||
new [] { 0, 0, 2, 0, 2, 33, 33, 2, 2 },
|
||||
// Tangrowth (Tangela with Ancient Power)
|
||||
new [] { 0, 0, 0, 0, 2, 36, 38, 2, 2 },
|
||||
// Yanmega (Yanma with Ancient Power)
|
||||
new [] { 0, 0, 0, 0, 2, 33, 33, 2, 2 },
|
||||
// Mamoswine (Piloswine with Ancient Power)
|
||||
new [] { 0, 0, 0, 0, 2, 2, 2, 2, 2 },
|
||||
// Sylveon (Eevee with Fairy Move)
|
||||
new [] { 0, 0, 0, 0, 0, 29, 9, 2, 2 },
|
||||
// Tsareena (Steenee with Stomp)
|
||||
new [] { 0, 0, 0, 0, 0, 0, 0, 2, 28 },
|
||||
// Grapploct (Clobbopus with Taunt)
|
||||
new [] { 0, 0, 0, 0, 0, 0, 0, 0, 35 },
|
||||
new [] { 00, 00, 00, 00, 18, 15, 15, 02, 02 }, // Mr. Mime (Mime Jr with Mimic)
|
||||
new [] { 00, 00, 00, 00, 17, 17, 15, 02, 02 }, // Sudowoodo (Bonsly with Mimic)
|
||||
new [] { 00, 00, 00, 00, 32, 32, 32, 02, 02 }, // Ambipom (Aipom with Double Hit)
|
||||
new [] { 00, 00, 02, 00, 02, 33, 33, 02, 02 }, // Lickilicky (Lickitung with Rollout)
|
||||
new [] { 00, 00, 00, 00, 02, 36, 38, 02, 02 }, // Tangrowth (Tangela with Ancient Power)
|
||||
new [] { 00, 00, 00, 00, 02, 33, 33, 02, 02 }, // Yanmega (Yanma with Ancient Power)
|
||||
new [] { 00, 00, 00, 00, 02, 02, 02, 02, 02 }, // Mamoswine (Piloswine with Ancient Power)
|
||||
new [] { 00, 00, 00, 00, 00, 29, 09, 02, 02 }, // Sylveon (Eevee with Fairy Move)
|
||||
new [] { 00, 00, 00, 00, 00, 00, 00, 02, 28 }, // Tsareena (Steenee with Stomp)
|
||||
new [] { 00, 00, 00, 00, 00, 00, 00, 00, 35 }, // Grapploct (Clobbopus with Taunt)
|
||||
};
|
||||
|
||||
// True -> the pokemon could hatch from an egg with the move for evolution as an egg move
|
||||
private static readonly bool[][] EggMoveEvolutionWithMove =
|
||||
{
|
||||
// Mr. Mime (Mime Jr with Mimic)
|
||||
new [] { false, false, false, false, true, true, true, true, true },
|
||||
// Sudowoodo (Bonsly with Mimic)
|
||||
new [] { false, false, false, false, true, true, true, true, true },
|
||||
// Ambipom (Aipom with Double Hit)
|
||||
new [] { false, false, false, false, true, true, true, true, true },
|
||||
// Lickilicky (Lickitung with Rollout)
|
||||
new [] { false, false, true, false, true, true, true, true, true },
|
||||
// Tangrowth (Tangela with Ancient Power)
|
||||
new [] { false, false, false, false, true, true, true, true, true },
|
||||
// Yanmega (Yanma with Ancient Power)
|
||||
new [] { false, false, false, false, true, true, true, true, true },
|
||||
// Mamoswine (Piloswine with Ancient Power)
|
||||
new [] { false, false, true, true, true, true, true, true, true },
|
||||
// Sylveon (Eevee with Fairy Move)
|
||||
new [] { false, false, true, true, true, true, true, true, true },
|
||||
// Tsareena (Steenee with Stomp)
|
||||
new [] { false, false, false, false, false, false, false, false, false },
|
||||
// Grapploct (Clobbopus with Taunt)
|
||||
new [] { false, false, false, false, false, false, false, false, true },
|
||||
new [] { false, false, false, false, true, true, true, true, true }, // Mr. Mime (Mime Jr with Mimic)
|
||||
new [] { false, false, false, false, true, true, true, true, true }, // Sudowoodo (Bonsly with Mimic)
|
||||
new [] { false, false, false, false, true, true, true, true, true }, // Ambipom (Aipom with Double Hit)
|
||||
new [] { false, false, true, false, true, true, true, true, true }, // Lickilicky (Lickitung with Rollout)
|
||||
new [] { false, false, false, false, true, true, true, true, true }, // Tangrowth (Tangela with Ancient Power)
|
||||
new [] { false, false, false, false, true, true, true, true, true }, // Yanmega (Yanma with Ancient Power)
|
||||
new [] { false, false, true, true, true, true, true, true, true }, // Mamoswine (Piloswine with Ancient Power)
|
||||
new [] { false, false, true, true, true, true, true, true, true }, // Sylveon (Eevee with Fairy Move)
|
||||
new [] { false, false, false, false, false, false, false, false, false }, // Tsareena (Steenee with Stomp)
|
||||
new [] { false, false, false, false, false, false, false, false, true }, // Grapploct (Clobbopus with Taunt)
|
||||
};
|
||||
|
||||
public static bool IsEvolutionValidWithMove(PKM pkm, LegalInfo info)
|
||||
|
|
|
@ -4,6 +4,8 @@ using System.Linq;
|
|||
using PKHeX.Core;
|
||||
|
||||
using static PKHeX.Core.Legal;
|
||||
using static PKHeX.Core.GameVersion;
|
||||
using static PKHeX.Core.Species;
|
||||
|
||||
namespace PKHeX
|
||||
{
|
||||
|
@ -26,20 +28,35 @@ namespace PKHeX
|
|||
|
||||
private static readonly HashSet<int> Stadium_GiftSpecies = new()
|
||||
{
|
||||
001, // Bulbasaur
|
||||
004, // Charmander
|
||||
007, // Squirtle
|
||||
054, // Psyduck (Amnesia)
|
||||
106, // Hitmonlee
|
||||
107, // Hitmonchan
|
||||
133, // Eevee
|
||||
138, // Omanyte
|
||||
140, // Kabuto
|
||||
(int)Bulbasaur,
|
||||
(int)Charmander,
|
||||
(int)Squirtle,
|
||||
(int)Psyduck,
|
||||
(int)Hitmonlee,
|
||||
(int)Hitmonchan,
|
||||
(int)Eevee,
|
||||
(int)Omanyte,
|
||||
(int)Kabuto,
|
||||
};
|
||||
|
||||
private static readonly HashSet<int> SpecialMinMoveSlots = new()
|
||||
{
|
||||
25, 26, 29, 30, 31, 32, 33, 34, 36, 38, 40, 59, 91, 103, 114, 121,
|
||||
(int)Pikachu,
|
||||
(int)Raichu,
|
||||
(int)NidoranF,
|
||||
(int)Nidorina,
|
||||
(int)Nidoqueen,
|
||||
(int)NidoranM,
|
||||
(int)Nidorino,
|
||||
(int)Nidoking,
|
||||
(int)Clefable,
|
||||
(int)Ninetales,
|
||||
(int)Wigglytuff,
|
||||
(int)Arcanine,
|
||||
(int)Cloyster,
|
||||
(int)Exeggutor,
|
||||
(int)Tangela,
|
||||
(int)Starmie,
|
||||
};
|
||||
|
||||
internal static bool TypeIDExists(int type) => Types_Gen1.Contains(type);
|
||||
|
@ -49,17 +66,35 @@ namespace PKHeX
|
|||
0, 1, 2, 3, 4, 5, 7, 8, 20, 21, 22, 23, 24, 25, 26
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Species that have a catch rate value that is different from their pre-evolutions, and cannot be obtained directly.
|
||||
/// </summary>
|
||||
internal static readonly HashSet<int> Species_NotAvailable_CatchRate = new()
|
||||
{
|
||||
12, 18, 31, 34, 38, 45, 53, 59, 62, 65, 68, 71, 78, 91, 103, 121
|
||||
(int)Butterfree,
|
||||
(int)Pidgeot,
|
||||
(int)Nidoqueen,
|
||||
(int)Nidoking,
|
||||
(int)Ninetales,
|
||||
(int)Vileplume,
|
||||
(int)Persian,
|
||||
(int)Arcanine,
|
||||
(int)Poliwrath,
|
||||
(int)Alakazam,
|
||||
(int)Machamp,
|
||||
(int)Victreebel,
|
||||
(int)Rapidash,
|
||||
(int)Cloyster,
|
||||
(int)Exeggutor,
|
||||
(int)Starmie,
|
||||
};
|
||||
|
||||
internal static readonly HashSet<int> Trade_Evolution1 = new()
|
||||
{
|
||||
064,
|
||||
067,
|
||||
075,
|
||||
093
|
||||
(int)Kadabra,
|
||||
(int)Machoke,
|
||||
(int)Graveler,
|
||||
(int)Haunter,
|
||||
};
|
||||
|
||||
private static int[] GetMinLevelLearnMoveG1(int species, List<int> moves)
|
||||
|
@ -108,7 +143,7 @@ namespace PKHeX
|
|||
{
|
||||
switch (pkm.Species)
|
||||
{
|
||||
case (int)Species.Nidoking when moves.Contains(31) && moves.Contains(37):
|
||||
case (int)Nidoking when moves.Contains(31) && moves.Contains(37):
|
||||
// Nidoking learns Thrash at level 23
|
||||
// Nidorino learns Fury Attack at level 36, Nidoran♂ at level 30
|
||||
// Other moves are either learned by Nidoran♂ up to level 23 or by TM
|
||||
|
@ -117,7 +152,7 @@ namespace PKHeX
|
|||
previousspecies = 33;
|
||||
return;
|
||||
|
||||
case (int)Species.Exeggutor when moves.Contains(23) && moves.Any(m => G1Exeggcute_IncompatibleMoves.Contains(m)):
|
||||
case (int)Exeggutor when moves.Contains(23) && moves.Any(m => G1Exeggcute_IncompatibleMoves.Contains(m)):
|
||||
// Exeggutor learns Stomp at level 28
|
||||
// Exeggcute learns Stun Spore at 32, PoisonPowder at 37 and Sleep Powder at 48
|
||||
incompatible_current = new[] { 23 };
|
||||
|
@ -125,12 +160,12 @@ namespace PKHeX
|
|||
previousspecies = 103;
|
||||
return;
|
||||
|
||||
case (int)Species.Vaporeon or (int)Species.Jolteon or (int)Species.Flareon:
|
||||
case (int)Vaporeon or (int)Jolteon or (int)Flareon:
|
||||
incompatible_previous = new List<int>();
|
||||
incompatible_current = new List<int>();
|
||||
previousspecies = 133;
|
||||
var ExclusiveMoves = GetExclusiveMovesG1((int)Species.Eevee, pkm.Species, tmhm, moves);
|
||||
var EeveeLevels = GetMinLevelLearnMoveG1((int)Species.Eevee, ExclusiveMoves[0]);
|
||||
var ExclusiveMoves = GetExclusiveMovesG1((int)Eevee, pkm.Species, tmhm, moves);
|
||||
var EeveeLevels = GetMinLevelLearnMoveG1((int)Eevee, ExclusiveMoves[0]);
|
||||
var EvoLevels = GetMaxLevelLearnMoveG1(pkm.Species, ExclusiveMoves[1]);
|
||||
|
||||
for (int i = 0; i < ExclusiveMoves[0].Count; i++)
|
||||
|
@ -191,15 +226,15 @@ namespace PKHeX
|
|||
int catch_rate = ((PK1)pk).Catch_Rate;
|
||||
// Caterpie and Metapod evolution lines have different count of possible slots available if captured in different evolutionary phases
|
||||
// Example: a level 7 caterpie evolved into metapod will have 3 learned moves, a captured metapod will have only 1 move
|
||||
if ((species == (int)Species.Metapod || species == (int)Species.Butterfree) && catch_rate == 120)
|
||||
if ((species == (int)Metapod || species == (int)Butterfree) && catch_rate == 120)
|
||||
{
|
||||
// Captured as Metapod without Caterpie moves
|
||||
return initialmoves.Union(learn[1]).Distinct().Count(lm => lm != 0 && !G1CaterpieMoves.Contains(lm));
|
||||
// There is no valid Butterfree encounter in generation 1 games
|
||||
}
|
||||
if ((species == (int)Species.Kakuna || species == (int)Species.Beedrill) && (catch_rate == 45 || catch_rate == 120))
|
||||
if ((species == (int)Kakuna || species == (int)Beedrill) && (catch_rate == 45 || catch_rate == 120))
|
||||
{
|
||||
if (species == (int)Species.Beedrill && catch_rate == 45) // Captured as Beedril without Weedle and Kakuna moves
|
||||
if (species == (int)Beedrill && catch_rate == 45) // Captured as Beedril without Weedle and Kakuna moves
|
||||
return initialmoves.Union(learn[1]).Distinct().Count(lm => lm != 0 && !G1KakunaMoves.Contains(lm));
|
||||
|
||||
// Captured as Kakuna without Weedle moves
|
||||
|
@ -214,13 +249,13 @@ namespace PKHeX
|
|||
// Species that evolve and learn the 4th move as evolved species at a greater level than base species
|
||||
// The 4th move is included in the level up table set as a pre-evolution move,
|
||||
// it should be removed from the used slots count if is not the learn move
|
||||
(int)Species.Pidgeotto => level < 21 && !moves.Contains(018), // Whirlwind
|
||||
(int)Species.Sandslash => level < 27 && !moves.Contains(040), // Poison Sting
|
||||
(int)Species.Parasect => level < 30 && !moves.Contains(147), // Spore
|
||||
(int)Species.Golduck => level < 39 && !moves.Contains(093), // Confusion
|
||||
(int)Species.Dewgong => level < 44 && !moves.Contains(156), // Rest
|
||||
(int)Species.Weezing => level < 39 && !moves.Contains(108), // Smoke Screen
|
||||
(int)Species.Haunter or (int) Species.Gengar => level < 29 && !moves.Contains(095), // Hypnosis
|
||||
(int)Pidgeotto => level < 21 && !moves.Contains(018), // Whirlwind
|
||||
(int)Sandslash => level < 27 && !moves.Contains(040), // Poison Sting
|
||||
(int)Parasect => level < 30 && !moves.Contains(147), // Spore
|
||||
(int)Golduck => level < 39 && !moves.Contains(093), // Confusion
|
||||
(int)Dewgong => level < 44 && !moves.Contains(156), // Rest
|
||||
(int)Weezing => level < 39 && !moves.Contains(108), // Smoke Screen
|
||||
(int)Haunter or (int)Gengar => level < 29 && !moves.Contains(095), // Hypnosis
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
@ -229,20 +264,20 @@ namespace PKHeX
|
|||
int usedslots = initialmoves.Union(learn[1]).Where(m => m != 0).Distinct().Count();
|
||||
switch (pk.Species)
|
||||
{
|
||||
case (int)Species.Venonat: // Venonat; ignore Venomoth (by the time Venonat evolves it will always have 4 moves)
|
||||
case (int)Venonat: // Venonat; ignore Venomoth (by the time Venonat evolves it will always have 4 moves)
|
||||
if (pk.CurrentLevel >= 11 && !moves.Contains(48)) // Supersonic
|
||||
usedslots--;
|
||||
if (pk.CurrentLevel >= 19 && !moves.Contains(93)) // Confusion
|
||||
usedslots--;
|
||||
break;
|
||||
case (int)Species.Kadabra or (int)Species.Alakazam: // Abra & Kadabra
|
||||
case (int)Kadabra or (int)Alakazam: // Abra & Kadabra
|
||||
int catch_rate = ((PK1)pk).Catch_Rate;
|
||||
if (catch_rate != 100)// Initial Yellow Kadabra Kinesis (move 134)
|
||||
usedslots--;
|
||||
if (catch_rate == 200 && pk.CurrentLevel < 20) // Kadabra Disable, not learned until 20 if captured as Abra (move 50)
|
||||
usedslots--;
|
||||
break;
|
||||
case (int)Species.Cubone or (int)Species.Marowak: // Cubone & Marowak
|
||||
case (int)Cubone or (int)Marowak: // Cubone & Marowak
|
||||
if (!moves.Contains(39)) // Initial Yellow Tail Whip
|
||||
usedslots--;
|
||||
if (!moves.Contains(125)) // Initial Yellow Bone Club
|
||||
|
@ -250,15 +285,15 @@ namespace PKHeX
|
|||
if (pk.Species == 105 && pk.CurrentLevel < 33 && !moves.Contains(116)) // Marowak evolved without Focus Energy
|
||||
usedslots--;
|
||||
break;
|
||||
case (int)Species.Chansey:
|
||||
case (int)Chansey:
|
||||
if (!moves.Contains(39)) // Yellow Initial Tail Whip
|
||||
usedslots--;
|
||||
if (!moves.Contains(3)) // Yellow Lvl 12 and Initial Red/Blue Double Slap
|
||||
usedslots--;
|
||||
break;
|
||||
case (int)Species.Mankey when pk.CurrentLevel >= 9 && !moves.Contains(67): // Mankey (Low Kick)
|
||||
case (int)Species.Pinsir when pk.CurrentLevel >= 21 && !moves.Contains(20): // Pinsir (Bind)
|
||||
case (int)Species.Gyarados when pk.CurrentLevel < 32: // Gyarados
|
||||
case (int)Mankey when pk.CurrentLevel >= 9 && !moves.Contains(67): // Mankey (Low Kick)
|
||||
case (int)Pinsir when pk.CurrentLevel >= 21 && !moves.Contains(20): // Pinsir (Bind)
|
||||
case (int)Gyarados when pk.CurrentLevel < 32: // Gyarados
|
||||
usedslots--;
|
||||
break;
|
||||
default: return usedslots;
|
||||
|
@ -274,17 +309,17 @@ namespace PKHeX
|
|||
var mandatory = GetRequiredMoveCountLevel(pk);
|
||||
switch (pk.Species)
|
||||
{
|
||||
case (int)Species.Exeggutor when pk.CurrentLevel >= 28: // Exeggutor
|
||||
case (int)Exeggutor when pk.CurrentLevel >= 28: // Exeggutor
|
||||
// At level 28 learn different move if is a Exeggute or Exeggutor
|
||||
if (moves.Contains(73))
|
||||
mandatory.Add(73); // Leech Seed level 28 Exeggute
|
||||
if (moves.Contains(23))
|
||||
mandatory.Add(23); // Stomp level 28 Exeggutor
|
||||
break;
|
||||
case (int)Species.Pikachu when pk.CurrentLevel >= 33:
|
||||
case (int)Pikachu when pk.CurrentLevel >= 33:
|
||||
mandatory.Add(97); // Pikachu always learns Agility
|
||||
break;
|
||||
case (int)Species.Tangela:
|
||||
case (int)Tangela:
|
||||
mandatory.Add(132); // Tangela always has Constrict as Initial Move
|
||||
break;
|
||||
}
|
||||
|
@ -300,12 +335,12 @@ namespace PKHeX
|
|||
int maxlevel = 1;
|
||||
int minlevel = 1;
|
||||
|
||||
if (species == (int)Species.Tangela) // Tangela moves before level 32 are different in RB vs Y
|
||||
if (species == (int)Tangela) // Tangela moves before level 32 are different in RB vs Y
|
||||
{
|
||||
minlevel = 32;
|
||||
maxlevel = pk.CurrentLevel;
|
||||
}
|
||||
else if ((int)Species.NidoranF <= species && species <= (int)Species.Nidoking && pk.CurrentLevel >= 8)
|
||||
else if (species is >= (int)NidoranF and <= (int)Nidoking && pk.CurrentLevel >= 8)
|
||||
{
|
||||
maxlevel = 8; // Always learns a third move at level 8
|
||||
}
|
||||
|
@ -316,31 +351,31 @@ namespace PKHeX
|
|||
return MoveLevelUp.GetMovesLevelUp1(basespecies, 0, maxlevel, minlevel);
|
||||
}
|
||||
|
||||
internal static IEnumerable<GameVersion> GetGen2Versions(LegalInfo Info, bool korean)
|
||||
internal static IEnumerable<GameVersion> GetGen2Versions(IEncounterable enc, bool korean)
|
||||
{
|
||||
if (ParseSettings.AllowGen2Crystal(korean) && Info.Game.Contains(GameVersion.C))
|
||||
yield return GameVersion.C;
|
||||
yield return GameVersion.GS;
|
||||
if (ParseSettings.AllowGen2Crystal(korean) && enc.Version is C or GSC)
|
||||
yield return C;
|
||||
yield return GS;
|
||||
}
|
||||
|
||||
internal static IEnumerable<GameVersion> GetGen1Versions(LegalInfo Info)
|
||||
internal static IEnumerable<GameVersion> GetGen1Versions(IEncounterable enc)
|
||||
{
|
||||
if (Info.EncounterMatch.Species == (int)Species.Eevee && Info.Game == GameVersion.Stadium)
|
||||
if (enc.Species == (int)Eevee && enc.Version == Stadium)
|
||||
{
|
||||
// Stadium Eevee; check for RB and yellow initial moves
|
||||
yield return GameVersion.RB;
|
||||
yield return GameVersion.YW;
|
||||
yield return RB;
|
||||
yield return YW;
|
||||
yield break;
|
||||
}
|
||||
if (Info.Game == GameVersion.YW)
|
||||
if (enc.Version == YW)
|
||||
{
|
||||
yield return GameVersion.YW;
|
||||
yield return YW;
|
||||
yield break;
|
||||
}
|
||||
|
||||
// Any encounter marked with version RBY is for pokemon with the same moves and catch rate in RB and Y,
|
||||
// it is sufficient to check just RB's case
|
||||
yield return GameVersion.RB;
|
||||
yield return RB;
|
||||
}
|
||||
|
||||
private static bool GetCatchRateMatchesPreEvolution(PKM pkm, int catch_rate, IEnumerable<int> gen1)
|
||||
|
@ -352,7 +387,7 @@ namespace PKHeX
|
|||
// Dragonite's Catch Rate is different than Dragonair's in Yellow, but there is no Dragonite encounter.
|
||||
bool IsCatchRateRBY(IEnumerable<int> ds) => ds.Any(s => catch_rate == PersonalTable.RB[s].CatchRate || (s != 149 && catch_rate == PersonalTable.Y[s].CatchRate));
|
||||
// Krabby encounter trade special catch rate
|
||||
bool IsCatchRateTrade() => catch_rate == 204 && (pkm.Species == (int)Species.Krabby || pkm.Species == (int)Species.Kingler);
|
||||
bool IsCatchRateTrade() => catch_rate == 204 && (pkm.Species == (int)Krabby || pkm.Species == (int)Kingler);
|
||||
bool IsCatchRateStadium() => Stadium_GiftSpecies.Contains(pkm.Species) && Stadium_CatchRate.Contains(catch_rate);
|
||||
}
|
||||
|
||||
|
@ -429,28 +464,27 @@ namespace PKHeX
|
|||
|
||||
internal static bool IsTradedKadabraG1(PKM pkm)
|
||||
{
|
||||
if (pkm is not PK1 pk1 || pk1.Species != (int)Species.Kadabra)
|
||||
if (pkm is not PK1 pk1 || pk1.Species != (int)Kadabra)
|
||||
return false;
|
||||
if (pk1.TradebackStatus == TradebackType.WasTradeback)
|
||||
return true;
|
||||
if (ParseSettings.ActiveTrainer.Game == (int)GameVersion.Any)
|
||||
if (ParseSettings.ActiveTrainer.Game == (int)Any)
|
||||
return false;
|
||||
var IsYellow = ParseSettings.ActiveTrainer.Game == (int)GameVersion.YW;
|
||||
var IsYellow = ParseSettings.ActiveTrainer.Game == (int)YW;
|
||||
if (pk1.TradebackStatus == TradebackType.Gen1_NotTradeback)
|
||||
{
|
||||
// If catch rate is Abra catch rate it wont trigger as invalid trade without evolution, it could be traded as Abra
|
||||
// Yellow Kadabra catch rate in Red/Blue game, must be Alakazam
|
||||
var table = IsYellow ? PersonalTable.RB : PersonalTable.Y;
|
||||
if (pk1.Catch_Rate == table[(int)Species.Kadabra].CatchRate)
|
||||
if (pk1.Catch_Rate == table[(int)Kadabra].CatchRate)
|
||||
return true;
|
||||
}
|
||||
if (IsYellow)
|
||||
return false;
|
||||
// Yellow only moves in Red/Blue game, must be Alakazam
|
||||
var moves = pk1.Moves;
|
||||
if (moves.Contains(134)) // Kinesis, yellow only move
|
||||
if (pk1.HasMove((int)Move.Kinesis)) // Kinesis, yellow only move
|
||||
return true;
|
||||
if (pk1.CurrentLevel < 20 && moves.Contains(50)) // Obtaining Disable below level 20 implies a yellow only move
|
||||
if (pk1.CurrentLevel < 20 && pk1.HasMove((int)Move.Disable)) // Obtaining Disable below level 20 implies a yellow only move
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
|
@ -24,8 +24,7 @@ namespace PKHeX.Core
|
|||
|
||||
// Check for PID relationship to Gender & Nature if applicable
|
||||
int gen = data.Info.Generation;
|
||||
|
||||
if (3 <= gen && gen <= 5)
|
||||
if (gen is 3 or 4 or 5)
|
||||
{
|
||||
// Gender-PID & Nature-PID relationship check
|
||||
var result = IsValidGenderPID(data) ? GetValid(LPIDGenderMatch) : GetInvalid(LPIDGenderMismatch);
|
||||
|
|
|
@ -125,7 +125,7 @@ namespace PKHeX.Core
|
|||
}
|
||||
|
||||
// Gen3-5 => Gen6 have PID==EC with an edge case exception.
|
||||
if (3 <= Info.Generation && Info.Generation <= 5)
|
||||
if (Info.Generation is 3 or 4 or 5)
|
||||
{
|
||||
VerifyTransferEC(data);
|
||||
return;
|
||||
|
|
|
@ -491,12 +491,13 @@ namespace PKHeX.Core
|
|||
get => 15 * HPBitValType / 63;
|
||||
set
|
||||
{
|
||||
IV_HP = (IV_HP & ~1) + HiddenPower.DefaultLowBits[value, 0];
|
||||
IV_ATK = (IV_ATK & ~1) + HiddenPower.DefaultLowBits[value, 1];
|
||||
IV_DEF = (IV_DEF & ~1) + HiddenPower.DefaultLowBits[value, 2];
|
||||
IV_SPE = (IV_SPE & ~1) + HiddenPower.DefaultLowBits[value, 3];
|
||||
IV_SPA = (IV_SPA & ~1) + HiddenPower.DefaultLowBits[value, 4];
|
||||
IV_SPD = (IV_SPD & ~1) + HiddenPower.DefaultLowBits[value, 5];
|
||||
var dlb = HiddenPower.DefaultLowBits;
|
||||
IV_HP = (IV_HP & ~1) + dlb[value, 0];
|
||||
IV_ATK = (IV_ATK & ~1) + dlb[value, 1];
|
||||
IV_DEF = (IV_DEF & ~1) + dlb[value, 2];
|
||||
IV_SPE = (IV_SPE & ~1) + dlb[value, 3];
|
||||
IV_SPA = (IV_SPA & ~1) + dlb[value, 4];
|
||||
IV_SPD = (IV_SPD & ~1) + dlb[value, 5];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -591,7 +592,8 @@ namespace PKHeX.Core
|
|||
if (species < 0)
|
||||
species = Species;
|
||||
|
||||
if (Format == generation)
|
||||
var format = Format;
|
||||
if (format == generation)
|
||||
return true;
|
||||
|
||||
if (!IsOriginValid)
|
||||
|
@ -602,21 +604,21 @@ namespace PKHeX.Core
|
|||
return false;
|
||||
|
||||
// Trade generation 1 -> 2
|
||||
if (Format == 2 && generation == 1 && !Gen2_NotTradeback)
|
||||
if (format == 2 && generation == 1 && !Gen2_NotTradeback)
|
||||
return true;
|
||||
|
||||
// Trade generation 2 -> 1
|
||||
if (Format == 1 && generation == 2 && !Gen1_NotTradeback)
|
||||
if (format == 1 && generation == 2 && !Gen1_NotTradeback)
|
||||
return true;
|
||||
|
||||
if (Format < generation)
|
||||
if (format < generation)
|
||||
return false; // Future
|
||||
|
||||
int gen = Generation;
|
||||
return generation switch
|
||||
{
|
||||
1 => Format == 1 || VC, // species compat checked via sanity above
|
||||
2 => Format == 2 || VC,
|
||||
1 => format == 1 || VC, // species compat checked via sanity above
|
||||
2 => format == 2 || VC,
|
||||
3 => Gen3,
|
||||
4 => gen is >= 3 and <= 4,
|
||||
5 => gen is >= 3 and <= 5,
|
||||
|
|
Loading…
Reference in a new issue