2019-01-07 00:22:45 +00:00
|
|
|
using static PKHeX.Core.EvolutionType;
|
2018-05-19 19:07:50 +00:00
|
|
|
|
|
|
|
namespace PKHeX.Core
|
|
|
|
{
|
|
|
|
/// <summary>
|
|
|
|
/// Criteria for evolving to this branch in the <see cref="EvolutionTree"/>
|
|
|
|
/// </summary>
|
2018-07-02 02:55:23 +00:00
|
|
|
public sealed class EvolutionMethod
|
2018-05-19 19:07:50 +00:00
|
|
|
{
|
|
|
|
public int Method;
|
|
|
|
public int Species;
|
|
|
|
public int Argument;
|
2019-12-07 01:36:36 +00:00
|
|
|
public int Form = AnyForm;
|
2018-05-19 19:07:50 +00:00
|
|
|
public int Level;
|
|
|
|
|
2019-12-07 01:36:36 +00:00
|
|
|
public const int AnyForm = -1;
|
|
|
|
|
2019-01-07 00:22:45 +00:00
|
|
|
// Not stored in binary data
|
2019-12-06 06:32:47 +00:00
|
|
|
public bool RequiresLevelUp; // tracks if this method requires a Level Up, lazily set
|
2018-05-19 19:07:50 +00:00
|
|
|
|
2020-01-11 00:02:22 +00:00
|
|
|
public int GetDestinationForm(int form)
|
|
|
|
{
|
|
|
|
if (Method == (int)LevelUpFormFemale1)
|
|
|
|
return 1;
|
|
|
|
if (Form == AnyForm)
|
|
|
|
return form;
|
|
|
|
return Form;
|
|
|
|
}
|
2019-12-07 01:36:36 +00:00
|
|
|
|
2019-01-07 00:22:45 +00:00
|
|
|
/// <summary>
|
|
|
|
/// Checks the <see cref="EvolutionMethod"/> for validity by comparing against the <see cref="PKM"/> data.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="pkm">Entity to check</param>
|
|
|
|
/// <param name="lvl">Current level</param>
|
|
|
|
/// <param name="skipChecks">Option to skip some comparisons to return a 'possible' evolution.</param>
|
2019-12-06 06:32:47 +00:00
|
|
|
/// <returns>True if a evolution criteria is valid.</returns>
|
2018-05-19 19:07:50 +00:00
|
|
|
public bool Valid(PKM pkm, int lvl, bool skipChecks)
|
|
|
|
{
|
|
|
|
RequiresLevelUp = false;
|
2019-01-07 00:22:45 +00:00
|
|
|
switch ((EvolutionType)Method)
|
2018-05-19 19:07:50 +00:00
|
|
|
{
|
2019-01-07 00:22:45 +00:00
|
|
|
case UseItem:
|
|
|
|
case UseItemWormhole:
|
2019-11-16 19:52:40 +00:00
|
|
|
case Crit3:
|
|
|
|
case HPDownBy49:
|
|
|
|
case SpinType:
|
2018-05-19 19:07:50 +00:00
|
|
|
return true;
|
2019-01-07 00:22:45 +00:00
|
|
|
case UseItemMale:
|
2018-05-19 19:07:50 +00:00
|
|
|
return pkm.Gender == 0;
|
2019-01-07 00:22:45 +00:00
|
|
|
case UseItemFemale:
|
2018-05-19 19:07:50 +00:00
|
|
|
return pkm.Gender == 1;
|
|
|
|
|
2019-01-07 00:22:45 +00:00
|
|
|
case Trade:
|
|
|
|
case TradeHeldItem:
|
|
|
|
case TradeSpecies:
|
2018-05-19 19:07:50 +00:00
|
|
|
return !pkm.IsUntraded || skipChecks;
|
|
|
|
|
2019-11-16 19:01:00 +00:00
|
|
|
case LevelUpNatureAmped when GetAmpLowKeyResult(pkm.Nature) != pkm.AltForm && !skipChecks:
|
|
|
|
case LevelUpNatureLowKey when GetAmpLowKeyResult(pkm.Nature) != pkm.AltForm && !skipChecks:
|
|
|
|
return false;
|
|
|
|
|
2019-02-24 21:57:10 +00:00
|
|
|
// Special Level Up Cases -- return false if invalid
|
2019-01-07 00:22:45 +00:00
|
|
|
case LevelUpBeauty when !(pkm is IContestStats s) || s.CNT_Beauty < Argument:
|
2018-08-28 03:48:57 +00:00
|
|
|
return skipChecks;
|
2019-01-07 00:22:45 +00:00
|
|
|
case LevelUpMale when pkm.Gender != 0:
|
2018-08-28 03:48:57 +00:00
|
|
|
return false;
|
2019-01-07 00:22:45 +00:00
|
|
|
case LevelUpFemale when pkm.Gender != 1:
|
2018-08-28 03:48:57 +00:00
|
|
|
return false;
|
2019-01-07 00:22:45 +00:00
|
|
|
case LevelUpFormFemale1 when pkm.Gender != 1 || pkm.AltForm != 1:
|
2018-08-28 03:48:57 +00:00
|
|
|
return false;
|
2018-05-19 19:07:50 +00:00
|
|
|
|
2019-01-07 00:22:45 +00:00
|
|
|
case LevelUpVersion when ((pkm.Version & 1) != (Argument & 1) && pkm.IsUntraded) || skipChecks:
|
|
|
|
case LevelUpVersionDay when ((pkm.Version & 1) != (Argument & 1) && pkm.IsUntraded) || skipChecks:
|
|
|
|
case LevelUpVersionNight when ((pkm.Version & 1) != (Argument & 1) && pkm.IsUntraded) || skipChecks:
|
2018-08-28 03:48:57 +00:00
|
|
|
return skipChecks; // Version checks come in pairs, check for any pair match
|
2018-05-19 19:07:50 +00:00
|
|
|
|
2019-02-24 21:57:10 +00:00
|
|
|
// Level Up (any); the above Level Up (with condition) cases will reach here if they were valid
|
2018-05-19 19:07:50 +00:00
|
|
|
default:
|
|
|
|
if (Level == 0 && lvl < 2)
|
|
|
|
return false;
|
|
|
|
if (lvl < Level)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
RequiresLevelUp = true;
|
|
|
|
if (skipChecks)
|
|
|
|
return lvl >= Level;
|
|
|
|
|
|
|
|
// Check Met Level for extra validity
|
2019-01-07 00:22:45 +00:00
|
|
|
return HasMetLevelIncreased(pkm, lvl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private bool HasMetLevelIncreased(PKM pkm, int lvl)
|
|
|
|
{
|
|
|
|
int origin = pkm.GenNumber;
|
|
|
|
switch (origin)
|
|
|
|
{
|
2019-02-24 21:57:10 +00:00
|
|
|
case 1: // No met data in RBY
|
|
|
|
case 2: // No met data in GS, Crystal met data can be reset
|
2019-01-07 00:22:45 +00:00
|
|
|
return true;
|
|
|
|
case 3:
|
|
|
|
case 4:
|
|
|
|
if (pkm.Format > origin) // Pal Park / PokeTransfer updates Met Level
|
|
|
|
return true;
|
|
|
|
return pkm.Met_Level < lvl;
|
|
|
|
|
|
|
|
case 5: // Bank keeps current level
|
|
|
|
case 6:
|
|
|
|
case 7:
|
2019-11-16 01:34:18 +00:00
|
|
|
case 8:
|
2019-01-07 00:22:45 +00:00
|
|
|
return lvl >= Level && (!pkm.IsNative || pkm.Met_Level < lvl);
|
|
|
|
|
|
|
|
default: return false;
|
2018-05-19 19:07:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-06 06:32:47 +00:00
|
|
|
public EvoCriteria GetEvoCriteria(int species, int form, int lvl)
|
2018-05-19 19:07:50 +00:00
|
|
|
{
|
2019-12-06 07:04:24 +00:00
|
|
|
return new EvoCriteria(species, form)
|
2018-05-19 19:07:50 +00:00
|
|
|
{
|
|
|
|
Level = lvl,
|
2019-12-06 06:32:47 +00:00
|
|
|
Method = Method,
|
2018-05-19 19:07:50 +00:00
|
|
|
};
|
|
|
|
}
|
2019-11-16 19:01:00 +00:00
|
|
|
|
2019-11-18 06:04:41 +00:00
|
|
|
public static int GetAmpLowKeyResult(int n)
|
2019-11-16 19:01:00 +00:00
|
|
|
{
|
|
|
|
if ((uint)(n - 1) > 22)
|
|
|
|
return 0;
|
|
|
|
return (0x5BCA51 >> (n - 1)) & 1;
|
|
|
|
}
|
2018-05-19 19:07:50 +00:00
|
|
|
}
|
|
|
|
}
|