mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-08-28 04:24:24 -05:00
Refactor stat loading to allow spans
Can load stats without allocating
This commit is contained in:
@@ -563,22 +563,17 @@ public void SetMasteredRecordFlag(int index, bool value)
|
||||
public override int Stat_SPD { get => ReadUInt16LittleEndian(Data.AsSpan(0x174)); set => WriteUInt16LittleEndian(Data.AsSpan(0x174), (ushort)value); }
|
||||
#endregion
|
||||
|
||||
public override ushort[] GetStats(PersonalInfo p) => CalculateStatsArceus(p);
|
||||
|
||||
public ushort[] CalculateStatsArceus(PersonalInfo p)
|
||||
public override void LoadStats(PersonalInfo p, Span<ushort> stats)
|
||||
{
|
||||
int level = CurrentLevel;
|
||||
int nature = StatNature;
|
||||
|
||||
return new[]
|
||||
{
|
||||
(ushort)(GetGanbaruStat(p.HP, HT_HP ? 31 : IV_HP, GV_HP, level) + GetStatHp(p.HP, level)),
|
||||
(ushort)(GetGanbaruStat(p.ATK, HT_ATK ? 31 : IV_ATK, GV_ATK, level) + GetStat(p.ATK, level, nature, 0)),
|
||||
(ushort)(GetGanbaruStat(p.DEF, HT_DEF ? 31 : IV_DEF, GV_DEF, level) + GetStat(p.DEF, level, nature, 1)),
|
||||
(ushort)(GetGanbaruStat(p.SPE, HT_SPE ? 31 : IV_SPE, GV_SPE, level) + GetStat(p.SPE, level, nature, 4)),
|
||||
(ushort)(GetGanbaruStat(p.SPA, HT_SPA ? 31 : IV_SPA, GV_SPA, level) + GetStat(p.SPA, level, nature, 2)),
|
||||
(ushort)(GetGanbaruStat(p.SPD, HT_SPD ? 31 : IV_SPD, GV_SPD, level) + GetStat(p.SPD, level, nature, 3)),
|
||||
};
|
||||
stats[0] = (ushort)(GetGanbaruStat(p.HP, HT_HP ? 31 : IV_HP, GV_HP, level) + GetStatHp(p.HP, level));
|
||||
stats[1] = (ushort)(GetGanbaruStat(p.ATK, HT_ATK ? 31 : IV_ATK, GV_ATK, level) + GetStat(p.ATK, level, nature, 0));
|
||||
stats[2] = (ushort)(GetGanbaruStat(p.DEF, HT_DEF ? 31 : IV_DEF, GV_DEF, level) + GetStat(p.DEF, level, nature, 1));
|
||||
stats[3] = (ushort)(GetGanbaruStat(p.SPE, HT_SPE ? 31 : IV_SPE, GV_SPE, level) + GetStat(p.SPE, level, nature, 4));
|
||||
stats[4] = (ushort)(GetGanbaruStat(p.SPA, HT_SPA ? 31 : IV_SPA, GV_SPA, level) + GetStat(p.SPA, level, nature, 2));
|
||||
stats[5] = (ushort)(GetGanbaruStat(p.SPD, HT_SPD ? 31 : IV_SPD, GV_SPD, level) + GetStat(p.SPD, level, nature, 3));
|
||||
}
|
||||
|
||||
public static int GetGanbaruStat(int baseStat, int iv, byte gv, int level)
|
||||
|
||||
@@ -364,23 +364,18 @@ public void FixMemories()
|
||||
public override int MaxBallID => Legal.MaxBallID_7;
|
||||
public override int MaxGameID => Legal.MaxGameID_7b;
|
||||
|
||||
public override ushort[] GetStats(PersonalInfo p) => CalculateStatsBeluga(p);
|
||||
|
||||
public ushort[] CalculateStatsBeluga(PersonalInfo p)
|
||||
public override void LoadStats(PersonalInfo p, Span<ushort> stats)
|
||||
{
|
||||
int level = CurrentLevel;
|
||||
int nature = Nature;
|
||||
int friend = CurrentFriendship; // stats +10% depending on friendship!
|
||||
int scalar = (int)(((friend / 255.0f / 10.0f) + 1.0f) * 100.0f);
|
||||
return new[]
|
||||
{
|
||||
(ushort)(AV_HP + GetStat(p.HP, HT_HP ? 31 : IV_HP, level) + 10 + level),
|
||||
(ushort)(AV_ATK + (scalar * GetStat(p.ATK, HT_ATK ? 31 : IV_ATK, level, nature, 0) / 100)),
|
||||
(ushort)(AV_DEF + (scalar * GetStat(p.DEF, HT_DEF ? 31 : IV_DEF, level, nature, 1) / 100)),
|
||||
(ushort)(AV_SPE + (scalar * GetStat(p.SPE, HT_SPE ? 31 : IV_SPE, level, nature, 4) / 100)),
|
||||
(ushort)(AV_SPA + (scalar * GetStat(p.SPA, HT_SPA ? 31 : IV_SPA, level, nature, 2) / 100)),
|
||||
(ushort)(AV_SPD + (scalar * GetStat(p.SPD, HT_SPD ? 31 : IV_SPD, level, nature, 3) / 100)),
|
||||
};
|
||||
stats[0] = (ushort)(AV_HP + GetStat(p.HP, HT_HP ? 31 : IV_HP, level) + 10 + level);
|
||||
stats[1] = (ushort)(AV_ATK + (scalar * GetStat(p.ATK, HT_ATK ? 31 : IV_ATK, level, nature, 0) / 100));
|
||||
stats[2] = (ushort)(AV_DEF + (scalar * GetStat(p.DEF, HT_DEF ? 31 : IV_DEF, level, nature, 1) / 100));
|
||||
stats[3] = (ushort)(AV_SPE + (scalar * GetStat(p.SPE, HT_SPE ? 31 : IV_SPE, level, nature, 4) / 100));
|
||||
stats[4] = (ushort)(AV_SPA + (scalar * GetStat(p.SPA, HT_SPA ? 31 : IV_SPA, level, nature, 2) / 100));
|
||||
stats[5] = (ushort)(AV_SPD + (scalar * GetStat(p.SPD, HT_SPD ? 31 : IV_SPD, level, nature, 3) / 100));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -709,45 +709,50 @@ public virtual void RefreshAbility(int n)
|
||||
/// </summary>
|
||||
/// <param name="p"><see cref="PersonalInfo"/> entry containing Base Stat Info</param>
|
||||
/// <returns>Battle Stats (H/A/B/S/C/D)</returns>
|
||||
public virtual ushort[] GetStats(PersonalInfo p)
|
||||
public ushort[] GetStats(PersonalInfo p)
|
||||
{
|
||||
int level = CurrentLevel;
|
||||
|
||||
ushort[] stats = this is IHyperTrain t ? GetStats(p, t, level) : GetStats(p, level);
|
||||
// Account for nature
|
||||
PKX.ModifyStatsForNature(stats, StatNature);
|
||||
ushort[] stats = new ushort[6];
|
||||
LoadStats(p, stats);
|
||||
return stats;
|
||||
}
|
||||
|
||||
private ushort[] GetStats(PersonalInfo p, IHyperTrain t, int level)
|
||||
public virtual void LoadStats(PersonalInfo p, Span<ushort> stats)
|
||||
{
|
||||
int level = CurrentLevel; // recalculate instead of checking Stat_Level
|
||||
if (this is IHyperTrain t)
|
||||
LoadStats(stats, p, t, level);
|
||||
else
|
||||
LoadStats(stats, p, level);
|
||||
|
||||
// Account for nature
|
||||
PKX.ModifyStatsForNature(stats, StatNature);
|
||||
}
|
||||
|
||||
private void LoadStats(Span<ushort> stats, PersonalInfo p, IHyperTrain t, int level)
|
||||
{
|
||||
ushort[] stats = new ushort[6];
|
||||
stats[0] = (ushort)(p.HP == 1 ? 1 : (((t.HT_HP ? 31 : IV_HP) + (2 * p.HP) + (EV_HP / 4) + 100) * level / 100) + 10);
|
||||
stats[1] = (ushort)((((t.HT_ATK ? 31 : IV_ATK) + (2 * p.ATK) + (EV_ATK / 4)) * level / 100) + 5);
|
||||
stats[2] = (ushort)((((t.HT_DEF ? 31 : IV_DEF) + (2 * p.DEF) + (EV_DEF / 4)) * level / 100) + 5);
|
||||
stats[4] = (ushort)((((t.HT_SPA ? 31 : IV_SPA) + (2 * p.SPA) + (EV_SPA / 4)) * level / 100) + 5);
|
||||
stats[5] = (ushort)((((t.HT_SPD ? 31 : IV_SPD) + (2 * p.SPD) + (EV_SPD / 4)) * level / 100) + 5);
|
||||
stats[3] = (ushort)((((t.HT_SPE ? 31 : IV_SPE) + (2 * p.SPE) + (EV_SPE / 4)) * level / 100) + 5);
|
||||
return stats;
|
||||
}
|
||||
|
||||
private ushort[] GetStats(PersonalInfo p, int level)
|
||||
private void LoadStats(Span<ushort> stats, PersonalInfo p, int level)
|
||||
{
|
||||
ushort[] stats = new ushort[6];
|
||||
stats[0] = (ushort)(p.HP == 1 ? 1 : ((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);
|
||||
return stats;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the specified stats to the <see cref="PKM"/>.
|
||||
/// </summary>
|
||||
/// <param name="stats">Battle Stats (H/A/B/S/C/D)</param>
|
||||
public void SetStats(ushort[] stats)
|
||||
public void SetStats(ReadOnlySpan<ushort> stats)
|
||||
{
|
||||
Stat_HPMax = Stat_HPCurrent = stats[0];
|
||||
Stat_ATK = stats[1];
|
||||
@@ -767,7 +772,9 @@ public void SetStats(ushort[] stats)
|
||||
/// </summary>
|
||||
public void ResetPartyStats()
|
||||
{
|
||||
SetStats(GetStats(PersonalInfo));
|
||||
Span<ushort> stats = stackalloc ushort[6];
|
||||
LoadStats(PersonalInfo, stats);
|
||||
SetStats(stats);
|
||||
Stat_Level = CurrentLevel;
|
||||
Status_Condition = 0;
|
||||
}
|
||||
|
||||
@@ -193,26 +193,21 @@ protected int TransferLanguage(int destLanguage)
|
||||
return GuessedLanguage(destLanguage);
|
||||
}
|
||||
|
||||
public sealed override ushort[] GetStats(PersonalInfo p)
|
||||
public override void LoadStats(PersonalInfo p, Span<ushort> stats)
|
||||
{
|
||||
var lv = Stat_Level;
|
||||
ushort[] stats =
|
||||
{
|
||||
GetStat(p.HP , IV_HP , EV_HP , lv),
|
||||
GetStat(p.ATK, IV_ATK, EV_ATK, lv),
|
||||
GetStat(p.DEF, IV_DEF, EV_DEF, lv),
|
||||
GetStat(p.SPE, IV_SPE, EV_SPE, lv),
|
||||
GetStat(p.SPA, IV_SPA, EV_SPA, lv),
|
||||
GetStat(p.SPD, IV_SPD, EV_SPD, lv),
|
||||
};
|
||||
stats[0] += (ushort)(5 + lv); // HP
|
||||
return stats;
|
||||
stats[0] = (ushort)(GetStat(p.HP, IV_HP, EV_HP, lv) + (5 + lv)); // HP
|
||||
stats[1] = GetStat(p.ATK, IV_ATK, EV_ATK, lv);
|
||||
stats[2] = GetStat(p.DEF, IV_DEF, EV_DEF, lv);
|
||||
stats[3] = GetStat(p.SPE, IV_SPE, EV_SPE, lv);
|
||||
stats[4] = GetStat(p.SPA, IV_SPA, EV_SPA, lv);
|
||||
stats[5] = GetStat(p.SPD, IV_SPD, EV_SPD, lv);
|
||||
}
|
||||
|
||||
protected static ushort GetStat(int BV, int IV, int EV, int LV)
|
||||
protected static ushort GetStat(int baseStat, int iv, int effort, int level)
|
||||
{
|
||||
EV = (ushort)Math.Min(255, Math.Sqrt(EV) + 1) >> 2;
|
||||
return (ushort)((((2 * (BV + IV)) + EV) * LV / 100) + 5);
|
||||
effort = (ushort)Math.Min(255, Math.Sqrt(effort) + 1) >> 2;
|
||||
return (ushort)((((2 * (baseStat + iv)) + effort) * level / 100) + 5);
|
||||
}
|
||||
|
||||
public sealed override int GetMovePP(int move, int ppUpCount)
|
||||
|
||||
@@ -100,7 +100,7 @@ public static bool GetNatureModification(int nature, out int incr, out int decr)
|
||||
/// </summary>
|
||||
/// <param name="stats">Current stats to amplify if appropriate</param>
|
||||
/// <param name="nature">Nature</param>
|
||||
public static void ModifyStatsForNature(ushort[] stats, int nature)
|
||||
public static void ModifyStatsForNature(Span<ushort> stats, int nature)
|
||||
{
|
||||
if (GetNatureModification(nature, out int incr, out int decr))
|
||||
return;
|
||||
|
||||
@@ -457,8 +457,7 @@ protected virtual void SetPartyValues(PKM pkm, bool isParty)
|
||||
return;
|
||||
if (pkm.PartyStatsPresent) // Stats already present
|
||||
return;
|
||||
pkm.SetStats(pkm.GetStats(pkm.PersonalInfo));
|
||||
pkm.Stat_Level = pkm.CurrentLevel;
|
||||
pkm.ResetPartyStats();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user