PkmnLib/src/Battling/Library/StatCalculator.cpp

69 lines
4.1 KiB
C++

#include "StatCalculator.hpp"
#include "../Pokemon/Pokemon.hpp"
u32 PkmnLib::Battling::StatCalculator::CalculateHealthStat(const Pokemon* pkmn) const {
u32 base = pkmn->GetBaseStat(Library::Statistic::HealthPoints);
u32 iv = pkmn->GetIndividualValue(Library::Statistic::HealthPoints);
u32 ev = pkmn->GetEffortValue(Library::Statistic::HealthPoints);
uint8_t level = pkmn->GetLevel();
return static_cast<u32>(((2 * base + iv + static_cast<u32>(ev / 4)) * level) / 100) + level + 10;
}
u32 PkmnLib::Battling::StatCalculator::CalculateOtherStat(const Pokemon* pkmn,
CreatureLib::Library::Statistic stat) const {
u32 base = pkmn->GetBaseStat(stat);
u32 iv = pkmn->GetIndividualValue(stat);
u32 ev = pkmn->GetEffortValue(stat);
uint8_t level = pkmn->GetLevel();
u32 unmodified = static_cast<u32>(((2 * base + iv + static_cast<u32>(ev / 4)) * level) / 100) + 5;
return static_cast<u32>(unmodified * pkmn->GetNature()->GetStatModifier(stat));
}
float PkmnLib::Battling::StatCalculator::GetStatBoostModifier(const CreatureLib::Battling::Creature* pkmn,
CreatureLib::Library::Statistic stat) const {
int8_t boost = pkmn->GetStatBoost(stat);
switch (boost) {
case -6: return 2.0 / 8;
case -5: return 2.0 / 7;
case -4: return 2.0 / 6;
case -3: return 2.0 / 5;
case -2: return 2.0 / 4;
case -1: return 2.0 / 3;
case 0: return 1;
case 1: return 3.0 / 2;
case 2: return 4.0 / 2;
case 3: return 5.0 / 2;
case 4: return 6.0 / 2;
case 5: return 7.0 / 2;
case 6: return 8.0 / 2;
default: throw ArbUt::Exception("Stat boost was out of expected range of -6 till 6.");
}
}
CreatureLib::Library::StatisticSet<u32>
PkmnLib::Battling::StatCalculator::CalculateFlatStats(CreatureLib::Battling::Creature* creature) const {
auto pkmn = dynamic_cast<Pokemon*>(creature);
return CreatureLib::Library::StatisticSet<u32>(CalculateHealthStat(pkmn),
CalculateOtherStat(pkmn, Library::Statistic::PhysicalAttack),
CalculateOtherStat(pkmn, Library::Statistic::PhysicalDefense),
CalculateOtherStat(pkmn, Library::Statistic::SpecialAttack),
CalculateOtherStat(pkmn, Library::Statistic::SpecialDefense),
CalculateOtherStat(pkmn, Library::Statistic::Speed));
}
CreatureLib::Library::StatisticSet<u32>
PkmnLib::Battling::StatCalculator::CalculateBoostedStats(CreatureLib::Battling::Creature* creature) const {
return CreatureLib::Library::StatisticSet<u32>(CalculateBoostedStat(creature, Library::Statistic::HealthPoints),
CalculateBoostedStat(creature, Library::Statistic::PhysicalAttack),
CalculateBoostedStat(creature, Library::Statistic::PhysicalDefense),
CalculateBoostedStat(creature, Library::Statistic::SpecialAttack),
CalculateBoostedStat(creature, Library::Statistic::SpecialDefense),
CalculateBoostedStat(creature, Library::Statistic::Speed));
}
u32 PkmnLib::Battling::StatCalculator::CalculateFlatStat(CreatureLib::Battling::Creature* creature,
CreatureLib::Library::Statistic stat) const {
if (stat == Library::Statistic::HealthPoints)
return CalculateHealthStat(dynamic_cast<Pokemon*>(creature));
return CalculateOtherStat(dynamic_cast<Pokemon*>(creature), stat);
}
u32 PkmnLib::Battling::StatCalculator::CalculateBoostedStat(CreatureLib::Battling::Creature* creature,
CreatureLib::Library::Statistic stat) const {
return creature->GetFlatStat(stat) * GetStatBoostModifier(creature, stat);
}