#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(((2 * base + iv + static_cast(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(((2 * base + iv + static_cast(ev / 4)) * level) / 100) + 5; return static_cast(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 PkmnLib::Battling::StatCalculator::CalculateFlatStats(CreatureLib::Battling::Creature* creature) const { auto pkmn = dynamic_cast(creature); return CreatureLib::Library::StatisticSet(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 PkmnLib::Battling::StatCalculator::CalculateBoostedStats(CreatureLib::Battling::Creature* creature) const { return CreatureLib::Library::StatisticSet(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(creature)); return CalculateOtherStat(dynamic_cast(creature), stat); } u32 PkmnLib::Battling::StatCalculator::CalculateBoostedStat(CreatureLib::Battling::Creature* creature, CreatureLib::Library::Statistic stat) const { return creature->GetFlatStat(stat) * GetStatBoostModifier(creature, stat); }