mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-26 05:50:22 +00:00
parent
9d83ce1855
commit
c021f893f8
18 changed files with 127 additions and 57 deletions
|
@ -6,6 +6,7 @@ public sealed class EvolutionGroup1 : IEvolutionGroup, IEvolutionEnvironment
|
|||
{
|
||||
public static readonly EvolutionGroup1 Instance = new();
|
||||
private static readonly EvolutionTree Tree = EvolutionTree.Evolves1;
|
||||
private static EvolutionRuleTweak Tweak => EvolutionRuleTweak.Default;
|
||||
|
||||
public IEvolutionGroup GetNext(PKM pk, EvolutionOrigin enc) => EvolutionGroup2.Instance;
|
||||
public IEvolutionGroup? GetPrevious(PKM pk, EvolutionOrigin enc) => pk.Format == 1 && ParseSettings.AllowGen1Tradeback ? EvolutionGroup2.Instance : null;
|
||||
|
@ -43,9 +44,10 @@ public sealed class EvolutionGroup1 : IEvolutionGroup, IEvolutionEnvironment
|
|||
return present;
|
||||
}
|
||||
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result)
|
||||
where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
|
||||
public int Evolve(Span<EvoCriteria> result, PKM pk, EvolutionOrigin enc, EvolutionHistory history)
|
||||
|
@ -75,6 +77,6 @@ public sealed class EvolutionGroup1 : IEvolutionGroup, IEvolutionEnvironment
|
|||
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ public sealed class EvolutionGroup2 : IEvolutionGroup
|
|||
private static readonly EvolutionTree Tree = EvolutionTree.Evolves2;
|
||||
private const int Generation = 2;
|
||||
private static PersonalTable2 Personal => PersonalTable.C;
|
||||
private static EvolutionRuleTweak Tweak => EvolutionRuleTweak.Default;
|
||||
|
||||
public IEvolutionGroup? GetNext(PKM pk, EvolutionOrigin enc) => pk.Format > Generation ? EvolutionGroup7.Instance : null;
|
||||
public IEvolutionGroup? GetPrevious(PKM pk, EvolutionOrigin enc) => pk.Format != 1 ? EvolutionGroup1.Instance : null;
|
||||
|
@ -45,7 +46,7 @@ public sealed class EvolutionGroup2 : IEvolutionGroup
|
|||
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
|
||||
public int Evolve(Span<EvoCriteria> result, PKM pk, EvolutionOrigin enc, EvolutionHistory history)
|
||||
|
@ -75,6 +76,6 @@ public sealed class EvolutionGroup2 : IEvolutionGroup
|
|||
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ public sealed class EvolutionGroup3 : IEvolutionGroup
|
|||
private static readonly EvolutionTree Tree = EvolutionTree.Evolves3;
|
||||
private const int Generation = 3;
|
||||
private static PersonalTable3 Personal => PersonalTable.E;
|
||||
private static EvolutionRuleTweak Tweak => EvolutionRuleTweak.Default;
|
||||
|
||||
public IEvolutionGroup? GetNext(PKM pk, EvolutionOrigin enc) => pk.Format > Generation ? EvolutionGroup4.Instance : null;
|
||||
public IEvolutionGroup? GetPrevious(PKM pk, EvolutionOrigin enc) => null;
|
||||
|
@ -39,7 +40,7 @@ public sealed class EvolutionGroup3 : IEvolutionGroup
|
|||
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
|
||||
public int Evolve(Span<EvoCriteria> result, PKM pk, EvolutionOrigin enc, EvolutionHistory history)
|
||||
|
@ -69,6 +70,6 @@ public sealed class EvolutionGroup3 : IEvolutionGroup
|
|||
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ public sealed class EvolutionGroup4 : IEvolutionGroup
|
|||
private static readonly EvolutionTree Tree = EvolutionTree.Evolves4;
|
||||
private const int Generation = 4;
|
||||
private static PersonalTable4 Personal => PersonalTable.HGSS;
|
||||
private static EvolutionRuleTweak Tweak => EvolutionRuleTweak.Default;
|
||||
|
||||
public IEvolutionGroup? GetNext(PKM pk, EvolutionOrigin enc) => pk.Format > Generation ? EvolutionGroup5.Instance : null;
|
||||
public IEvolutionGroup? GetPrevious(PKM pk, EvolutionOrigin enc) => enc.Generation == 3 ? EvolutionGroup3.Instance : null;
|
||||
|
@ -39,7 +40,7 @@ public sealed class EvolutionGroup4 : IEvolutionGroup
|
|||
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
|
||||
public int Evolve(Span<EvoCriteria> result, PKM pk, EvolutionOrigin enc, EvolutionHistory history)
|
||||
|
@ -71,6 +72,6 @@ public sealed class EvolutionGroup4 : IEvolutionGroup
|
|||
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ public sealed class EvolutionGroup5 : IEvolutionGroup
|
|||
private static readonly EvolutionTree Tree = EvolutionTree.Evolves5;
|
||||
private const int Generation = 5;
|
||||
private static PersonalTable5B2W2 Personal => PersonalTable.B2W2;
|
||||
private static EvolutionRuleTweak Tweak => EvolutionRuleTweak.Default;
|
||||
|
||||
public IEvolutionGroup? GetNext(PKM pk, EvolutionOrigin enc) => pk.Format > Generation ? EvolutionGroup6.Instance : null;
|
||||
public IEvolutionGroup? GetPrevious(PKM pk, EvolutionOrigin enc) => enc.Generation < Generation ? EvolutionGroup4.Instance : null;
|
||||
|
@ -32,7 +33,7 @@ public sealed class EvolutionGroup5 : IEvolutionGroup
|
|||
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
|
||||
public int Evolve(Span<EvoCriteria> result, PKM pk, EvolutionOrigin enc, EvolutionHistory history)
|
||||
|
@ -62,6 +63,6 @@ public sealed class EvolutionGroup5 : IEvolutionGroup
|
|||
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ public sealed class EvolutionGroup6 : IEvolutionGroup
|
|||
private static readonly EvolutionTree Tree = EvolutionTree.Evolves6;
|
||||
private const int Generation = 6;
|
||||
private static PersonalTable6AO Personal => PersonalTable.AO;
|
||||
private static EvolutionRuleTweak Tweak => EvolutionRuleTweak.Default;
|
||||
|
||||
public IEvolutionGroup? GetNext(PKM pk, EvolutionOrigin enc) => pk.Format > Generation ? EvolutionGroup7.Instance : null;
|
||||
public IEvolutionGroup? GetPrevious(PKM pk, EvolutionOrigin enc) => enc.Generation < Generation ? EvolutionGroup5.Instance : null;
|
||||
|
@ -39,7 +40,7 @@ public sealed class EvolutionGroup6 : IEvolutionGroup
|
|||
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
|
||||
public int Evolve(Span<EvoCriteria> result, PKM pk, EvolutionOrigin enc, EvolutionHistory history)
|
||||
|
@ -66,6 +67,6 @@ public sealed class EvolutionGroup6 : IEvolutionGroup
|
|||
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ public sealed class EvolutionGroup7 : IEvolutionGroup
|
|||
private static readonly EvolutionTree Tree = EvolutionTree.Evolves7;
|
||||
private const int Generation = 7;
|
||||
private static PersonalTable7 Personal => PersonalTable.USUM;
|
||||
private static EvolutionRuleTweak Tweak => EvolutionRuleTweak.Default;
|
||||
|
||||
public IEvolutionGroup? GetNext(PKM pk, EvolutionOrigin enc) => pk.Format > Generation ? EvolutionGroupHOME.Instance : null;
|
||||
public IEvolutionGroup? GetPrevious(PKM pk, EvolutionOrigin enc)
|
||||
|
@ -75,12 +76,12 @@ public sealed class EvolutionGroup7 : IEvolutionGroup
|
|||
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
var b = Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
var b = Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
return b && !IsEvolutionBanned(pk, result);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ public sealed class EvolutionGroup7b : IEvolutionGroup
|
|||
private static readonly EvolutionTree Tree = EvolutionTree.Evolves7b;
|
||||
private const int Generation = 7;
|
||||
private static PersonalTable7GG Personal => PersonalTable.GG;
|
||||
private static EvolutionRuleTweak Tweak => EvolutionRuleTweak.Default;
|
||||
|
||||
public IEvolutionGroup? GetNext(PKM pk, EvolutionOrigin enc) => pk.Format > Generation ? EvolutionGroupHOME.Instance : null;
|
||||
public IEvolutionGroup? GetPrevious(PKM pk, EvolutionOrigin enc) => null;
|
||||
|
@ -32,7 +33,7 @@ public sealed class EvolutionGroup7b : IEvolutionGroup
|
|||
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
|
||||
public int Evolve(Span<EvoCriteria> result, PKM pk, EvolutionOrigin enc, EvolutionHistory history)
|
||||
|
@ -59,6 +60,6 @@ public sealed class EvolutionGroup7b : IEvolutionGroup
|
|||
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,15 +215,16 @@ public sealed class EvolutionGroupHOME : IEvolutionGroup
|
|||
public sealed class EvolutionEnvironment8 : IEvolutionEnvironment
|
||||
{
|
||||
private static readonly EvolutionTree Tree = EvolutionTree.Evolves8;
|
||||
private static EvolutionRuleTweak Tweak => EvolutionRuleTweak.Default;
|
||||
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
var b = Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
var b = Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
return b && !IsEvolutionBanned(pk, head);
|
||||
}
|
||||
|
||||
|
@ -240,38 +241,35 @@ public sealed class EvolutionEnvironment8 : IEvolutionEnvironment
|
|||
public sealed class EvolutionEnvironment8a : IEvolutionEnvironment
|
||||
{
|
||||
private static readonly EvolutionTree Tree = EvolutionTree.Evolves8a;
|
||||
private static EvolutionRuleTweak Tweak => EvolutionRuleTweak.Default;
|
||||
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
=> Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
=> Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
=> Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
=> Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
|
||||
public sealed class EvolutionEnvironment8b : IEvolutionEnvironment
|
||||
{
|
||||
private static readonly EvolutionTree Tree = EvolutionTree.Evolves8b;
|
||||
private static EvolutionRuleTweak Tweak => EvolutionRuleTweak.Default;
|
||||
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
=> Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
=> Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
=> Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
=> Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
|
||||
public sealed class EvolutionEnvironment9 : IEvolutionEnvironment
|
||||
{
|
||||
private static readonly EvolutionTree Tree = EvolutionTree.Evolves9;
|
||||
private static EvolutionRuleTweak Tweak => EvolutionRuleTweak.Level100;
|
||||
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
=> Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
=> Tree.Reverse.TryDevolve(head, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
var b = Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return b && !IsEvolutionBanned(head);
|
||||
}
|
||||
|
||||
// Unreleased Item
|
||||
private static bool IsEvolutionBanned(in ISpeciesForm head) => false;
|
||||
=> Tree.Forward.TryEvolve(head, next, pk, currentMaxLevel, levelMin, skipChecks, Tweak, out result);
|
||||
}
|
||||
|
|
22
PKHeX.Core/Legality/Evolutions/EvolutionRuleTweak.cs
Normal file
22
PKHeX.Core/Legality/Evolutions/EvolutionRuleTweak.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Tweaks to Evolution rules to account for game-specific behaviors.
|
||||
/// </summary>
|
||||
public sealed class EvolutionRuleTweak
|
||||
{
|
||||
/// <summary>
|
||||
/// Default Evolution logic (no tweaks).
|
||||
/// </summary>
|
||||
public static readonly EvolutionRuleTweak Default = new();
|
||||
|
||||
/// <summary>
|
||||
/// In Scarlet & Violet, level 100 Pokemon can trigger evolution methods via Rare Candy level up.
|
||||
/// </summary>
|
||||
public static readonly EvolutionRuleTweak Level100 = new() { AllowLevelUpEvolution100 = true };
|
||||
|
||||
/// <summary>
|
||||
/// Allow Level Up Evolutions to trigger if already level 100.
|
||||
/// </summary>
|
||||
public bool AllowLevelUpEvolution100 { get; init; }
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
|
@ -36,7 +37,7 @@ public sealed class EvolutionForwardPersonal(EvolutionMethod[][] Entries, IPerso
|
|||
}
|
||||
}
|
||||
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, EvolutionRuleTweak tweak, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
var methods = GetForward(head.Species, head.Form);
|
||||
foreach (var method in methods.Span)
|
||||
|
@ -47,11 +48,11 @@ public sealed class EvolutionForwardPersonal(EvolutionMethod[][] Entries, IPerso
|
|||
if (next.Form != expectForm)
|
||||
continue;
|
||||
|
||||
var chk = method.Check(pk, currentMaxLevel, levelMin, skipChecks);
|
||||
var chk = method.Check(pk, currentMaxLevel, levelMin, skipChecks, tweak);
|
||||
if (chk != EvolutionCheckResult.Valid)
|
||||
continue;
|
||||
|
||||
result = Create(next.Species, next.Form, method, currentMaxLevel, levelMin);
|
||||
result = Create(next.Species, next.Form, method, currentMaxLevel, levelMin, tweak);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -59,7 +60,7 @@ public sealed class EvolutionForwardPersonal(EvolutionMethod[][] Entries, IPerso
|
|||
return false;
|
||||
}
|
||||
|
||||
private static EvoCriteria Create(ushort species, byte form, EvolutionMethod method, byte currentMaxLevel, byte min) => new()
|
||||
private static EvoCriteria Create(ushort species, byte form, EvolutionMethod method, byte currentMaxLevel, byte min, EvolutionRuleTweak tweak) => new()
|
||||
{
|
||||
Species = species,
|
||||
Form = form,
|
||||
|
@ -68,6 +69,20 @@ public sealed class EvolutionForwardPersonal(EvolutionMethod[][] Entries, IPerso
|
|||
|
||||
// Temporarily store these and overwrite them when we clean the list.
|
||||
LevelMin = Math.Max(min, method.Level),
|
||||
LevelUpRequired = method.LevelUp,
|
||||
LevelUpRequired = GetLevelUp(method.LevelUp, currentMaxLevel, tweak),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets the level up requirement for the evolution.
|
||||
/// </summary>
|
||||
/// <seealso cref="EvolutionReversal.GetLevelUp"/>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static byte GetLevelUp(byte flag, byte currentMaxLevel, EvolutionRuleTweak tweak)
|
||||
{
|
||||
if (flag == 0)
|
||||
return 0;
|
||||
if (currentMaxLevel == 100 && tweak.AllowLevelUpEvolution100)
|
||||
return 0;
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,8 @@ public sealed class EvolutionForwardSpecies(EvolutionMethod[][] Entries) : IEvol
|
|||
}
|
||||
}
|
||||
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
public bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks,
|
||||
EvolutionRuleTweak tweak, out EvoCriteria result) where T : ISpeciesForm
|
||||
{
|
||||
var methods = GetForward(head.Species, head.Form);
|
||||
foreach (var method in methods.Span)
|
||||
|
@ -48,7 +49,7 @@ public sealed class EvolutionForwardSpecies(EvolutionMethod[][] Entries) : IEvol
|
|||
if (next.Form != expectForm)
|
||||
continue;
|
||||
|
||||
var chk = method.Check(pk, currentMaxLevel, levelMin, skipChecks);
|
||||
var chk = method.Check(pk, currentMaxLevel, levelMin, skipChecks, tweak);
|
||||
if (chk != EvolutionCheckResult.Valid)
|
||||
continue;
|
||||
|
||||
|
@ -69,6 +70,6 @@ public sealed class EvolutionForwardSpecies(EvolutionMethod[][] Entries) : IEvol
|
|||
|
||||
// Temporarily store these and overwrite them when we clean the list.
|
||||
LevelMin = Math.Max(min, method.Level),
|
||||
LevelUpRequired = method.LevelUp,
|
||||
LevelUpRequired = method.LevelUp, // No need to tweak this, all games of this Type have the same default behavior.
|
||||
};
|
||||
}
|
||||
|
|
|
@ -30,7 +30,8 @@ public interface IEvolutionForward
|
|||
/// <param name="currentMaxLevel">Maximum allowed level for the result</param>
|
||||
/// <param name="levelMin">Minimum level for the result</param>
|
||||
/// <param name="skipChecks">Skip evolution exclusion checks</param>
|
||||
/// <param name="tweak">Rule tweaks to use when checking evolution criteria</param>
|
||||
/// <param name="result">Resulting evolution criteria</param>
|
||||
/// <returns>True if the evolution is possible and <see cref="result"/> is valid.</returns>
|
||||
bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm;
|
||||
bool TryEvolve<T>(T head, ISpeciesForm next, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, EvolutionRuleTweak tweak, out EvoCriteria result) where T : ISpeciesForm;
|
||||
}
|
||||
|
|
|
@ -39,8 +39,9 @@ public readonly record struct EvolutionMethod(ushort Species, ushort Argument, b
|
|||
/// <param name="lvl">Current level</param>
|
||||
/// <param name="levelMin">Minimum level to sanity check with</param>
|
||||
/// <param name="skipChecks">Option to skip some comparisons to return a 'possible' evolution.</param>
|
||||
/// <param name="tweak"></param>
|
||||
/// <returns>True if the evolution criteria is valid.</returns>
|
||||
public EvolutionCheckResult Check(PKM pk, byte lvl, byte levelMin, bool skipChecks)
|
||||
public EvolutionCheckResult Check(PKM pk, byte lvl, byte levelMin, bool skipChecks, EvolutionRuleTweak tweak)
|
||||
{
|
||||
if (!Method.IsLevelUpRequired())
|
||||
return ValidNotLevelUp(pk, skipChecks);
|
||||
|
@ -57,7 +58,11 @@ public readonly record struct EvolutionMethod(ushort Species, ushort Argument, b
|
|||
if (Level == 0 && lvl < 2)
|
||||
return InsufficientLevel;
|
||||
if (lvl < levelMin + LevelUp && !skipChecks)
|
||||
{
|
||||
if (lvl == 100 && tweak.AllowLevelUpEvolution100)
|
||||
return Valid;
|
||||
return InsufficientLevel;
|
||||
}
|
||||
|
||||
return Valid;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
|
@ -19,19 +20,20 @@ public static class EvolutionReversal
|
|||
/// <param name="levelMax">Maximum the entity may exist as</param>
|
||||
/// <param name="stopSpecies">Species ID that should be the last node, if at all. Provide 0 to fully devolve.</param>
|
||||
/// <param name="skipChecks">Option to bypass some evolution criteria</param>
|
||||
/// <param name="tweak">Rule tweaks to use when checking evolution criteria</param>
|
||||
/// <returns>Reversed evolution lineage, with the lowest index being the current species-form.</returns>
|
||||
public static int Devolve(this IEvolutionLookup lineage, Span<EvoCriteria> result, ushort species, byte form,
|
||||
PKM pk, byte levelMin, byte levelMax, ushort stopSpecies, bool skipChecks)
|
||||
PKM pk, byte levelMin, byte levelMax, ushort stopSpecies, bool skipChecks, EvolutionRuleTweak tweak)
|
||||
{
|
||||
// Store our results -- trim at the end when we place it on the heap.
|
||||
var head = result[0] = new EvoCriteria { Species = species, Form = form, LevelMax = levelMax };
|
||||
int ctr = Devolve(lineage, result, head, pk, levelMax, levelMin, skipChecks, stopSpecies);
|
||||
int ctr = Devolve(lineage, result, head, pk, levelMax, levelMin, skipChecks, stopSpecies, tweak);
|
||||
EvolutionUtil.CleanDevolve(result[..ctr], levelMin);
|
||||
return ctr;
|
||||
}
|
||||
|
||||
private static int Devolve(IEvolutionLookup lineage, Span<EvoCriteria> result, EvoCriteria head,
|
||||
PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, ushort stopSpecies)
|
||||
PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, ushort stopSpecies, EvolutionRuleTweak tweak)
|
||||
{
|
||||
// There aren't any circular evolution paths, and all lineages have at most 3 evolutions total.
|
||||
// There aren't any convergent evolution paths, so only yield the first connection.
|
||||
|
@ -39,7 +41,7 @@ public static class EvolutionReversal
|
|||
while (head.Species != stopSpecies)
|
||||
{
|
||||
ref readonly var node = ref lineage[head.Species, head.Form];
|
||||
if (!node.TryDevolve(pk, currentMaxLevel, levelMin, skipChecks, out var x))
|
||||
if (!node.TryDevolve(pk, currentMaxLevel, levelMin, skipChecks, tweak, out var x))
|
||||
return ctr;
|
||||
|
||||
result[ctr++] = x;
|
||||
|
@ -48,7 +50,7 @@ public static class EvolutionReversal
|
|||
return ctr;
|
||||
}
|
||||
|
||||
public static bool TryDevolve(this EvolutionNode node, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result)
|
||||
public static bool TryDevolve(this EvolutionNode node, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, EvolutionRuleTweak tweak, out EvoCriteria result)
|
||||
{
|
||||
// Multiple methods can exist to devolve to the same species-form.
|
||||
// The first method is less restrictive (no LevelUp req), if two {level/other} methods exist.
|
||||
|
@ -59,10 +61,10 @@ public static class EvolutionReversal
|
|||
return false;
|
||||
}
|
||||
|
||||
var chk = link.Method.Check(pk, currentMaxLevel, levelMin, skipChecks);
|
||||
var chk = link.Method.Check(pk, currentMaxLevel, levelMin, skipChecks, tweak);
|
||||
if (chk == EvolutionCheckResult.Valid)
|
||||
{
|
||||
result = Create(link, currentMaxLevel);
|
||||
result = Create(link, currentMaxLevel, tweak);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -73,10 +75,10 @@ public static class EvolutionReversal
|
|||
return false;
|
||||
}
|
||||
|
||||
chk = link.Method.Check(pk, currentMaxLevel, levelMin, skipChecks);
|
||||
chk = link.Method.Check(pk, currentMaxLevel, levelMin, skipChecks, tweak);
|
||||
if (chk == EvolutionCheckResult.Valid)
|
||||
{
|
||||
result = Create(link, currentMaxLevel);
|
||||
result = Create(link, currentMaxLevel, tweak);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -84,7 +86,7 @@ public static class EvolutionReversal
|
|||
return false;
|
||||
}
|
||||
|
||||
private static EvoCriteria Create(in EvolutionLink link, byte currentMaxLevel) => new()
|
||||
private static EvoCriteria Create(in EvolutionLink link, byte currentMaxLevel, EvolutionRuleTweak tweak) => new()
|
||||
{
|
||||
Species = link.Species,
|
||||
Form = link.Form,
|
||||
|
@ -93,6 +95,20 @@ public static class EvolutionReversal
|
|||
|
||||
// Temporarily store these and overwrite them when we clean the list.
|
||||
LevelMin = link.Method.Level,
|
||||
LevelUpRequired = link.Method.LevelUp,
|
||||
LevelUpRequired = GetLevelUp(link.Method.LevelUp, currentMaxLevel, tweak),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets the level up requirement for the evolution.
|
||||
/// </summary>
|
||||
/// <seealso cref="EvolutionForwardPersonal.GetLevelUp"/>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static byte GetLevelUp(byte flag, byte currentMaxLevel, EvolutionRuleTweak tweak)
|
||||
{
|
||||
if (flag == 0)
|
||||
return 0;
|
||||
if (currentMaxLevel == 100 && tweak.AllowLevelUpEvolution100)
|
||||
return 0;
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,9 +47,10 @@ public sealed class EvolutionReversePersonal(EvolutionMethod[][] Entries, IPerso
|
|||
yield return (s.Species, s.Form);
|
||||
}
|
||||
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, EvolutionRuleTweak tweak, out EvoCriteria result)
|
||||
where T : ISpeciesForm
|
||||
{
|
||||
ref readonly var node = ref Lineage[head.Species, head.Form];
|
||||
return node.TryDevolve(pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return node.TryDevolve(pk, currentMaxLevel, levelMin, skipChecks, tweak, out result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,9 +47,10 @@ public sealed class EvolutionReverseSpecies(EvolutionMethod[][] Entries, IPerson
|
|||
yield return (s.Species, s.Form);
|
||||
}
|
||||
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm
|
||||
public bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, EvolutionRuleTweak tweak, out EvoCriteria result)
|
||||
where T : ISpeciesForm
|
||||
{
|
||||
ref readonly var node = ref Lineage[head.Species, head.Form];
|
||||
return node.TryDevolve(pk, currentMaxLevel, levelMin, skipChecks, out result);
|
||||
return node.TryDevolve(pk, currentMaxLevel, levelMin, skipChecks, tweak, out result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,8 @@ public interface IEvolutionReverse
|
|||
/// <param name="currentMaxLevel">Maximum allowed level for the result</param>
|
||||
/// <param name="levelMin">Minimum level for the result</param>
|
||||
/// <param name="skipChecks">Skip evolution exclusion checks</param>
|
||||
/// <param name="tweak">Rule tweaks to use when checking evolution criteria</param>
|
||||
/// <param name="result">Resulting evolution criteria</param>
|
||||
/// <returns>True if the de-evolution is possible and <see cref="result"/> is valid.</returns>
|
||||
bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, out EvoCriteria result) where T : ISpeciesForm;
|
||||
bool TryDevolve<T>(T head, PKM pk, byte currentMaxLevel, byte levelMin, bool skipChecks, EvolutionRuleTweak tweak, out EvoCriteria result) where T : ISpeciesForm;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue