pkNX/pkNX.Structures/VsTrainer/Base/StatPKM.cs
2022-10-01 17:46:11 -07:00

144 lines
4.4 KiB
C#

using System;
namespace pkNX.Structures;
public abstract class StatPKM : IPokeData
{
public abstract int Species { get; set; }
public abstract int Form { get; set; }
public abstract int Level { get; set; }
public abstract int Nature { get; set; }
public abstract int HeldItem { get; set; }
public abstract int Gender { get; set; }
public abstract int Ability { get; set; }
public abstract int IV_HP { get; set; }
public abstract int IV_ATK { get; set; }
public abstract int IV_DEF { get; set; }
public abstract int IV_SPA { get; set; }
public abstract int IV_SPD { get; set; }
public abstract int IV_SPE { get; set; }
public abstract int EV_HP { get; set; }
public abstract int EV_ATK { get; set; }
public abstract int EV_DEF { get; set; }
public abstract int EV_SPA { get; set; }
public abstract int EV_SPD { get; set; }
public abstract int EV_SPE { get; set; }
public virtual ushort[] GetStats(IPersonalInfo p)
{
ushort[] Stats = new ushort[6];
Stats[0] = (ushort)(((IV_HP + (2 * p.HP) + (EV_HP / 4) + 100) * Level / 100) + 10);
Stats[1] = (ushort)(((IV_ATK + (2 * p.ATK) + (EV_ATK / 4)) * Level / 100) + 5);
Stats[2] = (ushort)(((IV_DEF + (2 * p.DEF) + (EV_DEF / 4)) * Level / 100) + 5);
Stats[4] = (ushort)(((IV_SPA + (2 * p.SPA) + (EV_SPA / 4)) * Level / 100) + 5);
Stats[5] = (ushort)(((IV_SPD + (2 * p.SPD) + (EV_SPD / 4)) * Level / 100) + 5);
Stats[3] = (ushort)(((IV_SPE + (2 * p.SPE) + (EV_SPE / 4)) * Level / 100) + 5);
if (p.HP == 1)
Stats[0] = 1;
// Account for nature
int incr = (Nature / 5) + 1;
int decr = (Nature % 5) + 1;
if (incr != decr)
{
Stats[incr] *= 11;
Stats[incr] /= 10;
Stats[decr] *= 9;
Stats[decr] /= 10;
}
return Stats;
}
public int HiddenPowerType => 15 * ((IV_HP & 1) + (2 * (IV_ATK & 1)) + (4 * (IV_DEF & 1)) + (8 * (IV_SPE & 1)) + (16 * (IV_SPA & 1)) + (32 * (IV_SPD & 1))) / 63;
public int GetIV(int index)
{
return index switch
{
0 => IV_HP,
1 => IV_ATK,
2 => IV_DEF,
3 => IV_SPE,
4 => IV_SPA,
5 => IV_SPD,
_ => throw new ArgumentOutOfRangeException(nameof(index)),
};
}
public void SetIV(int index, int value)
{
switch (index)
{
case 0: IV_HP = value; break;
case 1: IV_ATK = value; break;
case 2: IV_DEF = value; break;
case 3: IV_SPE = value; break;
case 4: IV_SPA = value; break;
case 5: IV_SPD = value; break;
default:
throw new ArgumentOutOfRangeException(nameof(index));
}
}
public int GetEV(int index)
{
return index switch
{
0 => EV_HP,
1 => EV_ATK,
2 => EV_DEF,
3 => EV_SPE,
4 => EV_SPA,
5 => EV_SPD,
_ => throw new ArgumentOutOfRangeException(nameof(index)),
};
}
public void SetEV(int index, int value)
{
switch (index)
{
case 0: EV_HP = value; break;
case 1: EV_ATK = value; break;
case 2: EV_DEF = value; break;
case 3: EV_SPE = value; break;
case 4: EV_SPA = value; break;
case 5: EV_SPD = value; break;
default:
throw new ArgumentOutOfRangeException(nameof(index));
}
}
public void SetHPIVs(int type)
{
for (int i = 0; i < 6; i++)
{
var val = (GetIV(i) & 0x1E) + hpivs[type, i];
SetIV(i, val);
}
}
private static readonly int[,] hpivs = {
{ 1, 1, 0, 0, 0, 0 }, // Fighting
{ 0, 0, 0, 0, 0, 1 }, // Flying
{ 1, 1, 0, 0, 0, 1 }, // Poison
{ 1, 1, 1, 0, 0, 1 }, // Ground
{ 1, 1, 0, 1, 0, 0 }, // Rock
{ 1, 0, 0, 1, 0, 1 }, // Bug
{ 1, 0, 1, 1, 0, 1 }, // Ghost
{ 1, 1, 1, 1, 0, 1 }, // Steel
{ 1, 0, 1, 0, 1, 0 }, // Fire
{ 1, 0, 0, 0, 1, 1 }, // Water
{ 1, 0, 1, 0, 1, 1 }, // Grass
{ 1, 1, 1, 0, 1, 1 }, // Electric
{ 1, 0, 1, 1, 1, 0 }, // Psychic
{ 1, 0, 0, 1, 1, 1 }, // Ice
{ 1, 0, 1, 1, 1, 1 }, // Dragon
{ 1, 1, 1, 1, 1, 1 }, // Dark
};
}