using System;
using static PKHeX.Core.NatureAmpRequest;
namespace PKHeX.Core;
///
/// Logic for mutating a nature to amplify certain stats.
///
public static class NatureAmp
{
///
/// Mutate the nature amp indexes to match the request
///
/// Request type to modify the provided
/// Stat Index to mutate
/// Current nature to derive the current amps from
/// New nature value
public static int GetNewNature(this NatureAmpRequest type, int statIndex, int currentNature)
{
if (currentNature > (int)Nature.Quirky)
return -1;
var (up, dn) = GetNatureModification(currentNature);
return GetNewNature(type, statIndex, up, dn);
}
///
public static int GetNewNature(NatureAmpRequest type, int statIndex, int up, int dn)
{
//
switch (type)
{
case Increase when up != statIndex:
up = statIndex;
break;
case Decrease when dn != statIndex:
dn = statIndex;
break;
case Neutral when up != statIndex && dn != statIndex:
up = dn = statIndex;
break;
default:
return -1; // failure
}
return CreateNatureFromAmps(up, dn);
}
///
/// Recombine the stat amps into a nature value.
///
/// Increased stat
/// Decreased stat
/// Nature
public static int CreateNatureFromAmps(int up, int dn)
{
if ((uint)up > 5 || (uint)dn > 5)
return -1;
return (up * 5) + dn;
}
///
/// Decompose the nature to the two stat indexes that are modified
///
public static (int up, int dn) GetNatureModification(int nature)
{
var up = (nature / 5) + 1;
var dn = (nature % 5) + 1;
return (up, dn);
}
///
/// Checks if the nature is out of range or the stat amplifications are not neutral.
///
/// Nature
/// Increased stat
/// Decreased stat
/// True if nature modification values are equal or the Nature is out of range.
public static bool IsNeutralOrInvalid(int nature, int up, int dn)
{
return up == dn || nature >= 25; // invalid
}
///
public static bool IsNeutralOrInvalid(int nature)
{
var (up, dn) = GetNatureModification(nature);
return IsNeutralOrInvalid(nature, up, dn);
}
///
/// Updates stats according to the specified nature.
///
/// Current stats to amplify if appropriate
/// Nature
public static void ModifyStatsForNature(Span stats, int nature)
{
var (up, dn) = GetNatureModification(nature);
if (IsNeutralOrInvalid(nature, up, dn))
return;
stats[up] *= 11; stats[up] /= 10;
stats[dn] *= 9; stats[dn] /= 10;
}
}
public enum NatureAmpRequest
{
Neutral,
Increase,
Decrease,
}