Fixes for damage calculation: Adds missing + 2, and handles rounding correctly.
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
7fe7c8becf
commit
037ff590f0
|
@ -5,22 +5,28 @@
|
||||||
|
|
||||||
using HitData = const CreatureLib::Battling::ExecutingAttack::HitData;
|
using HitData = const CreatureLib::Battling::ExecutingAttack::HitData;
|
||||||
|
|
||||||
|
inline constexpr float to_f(i32 a) { return static_cast<float>(a); }
|
||||||
|
inline constexpr float fl(float a) { return std::floor(a); }
|
||||||
|
|
||||||
uint32_t PkmnLib::Battling::DamageLibrary::GetDamage(CreatureLib::Battling::ExecutingAttack* attack,
|
uint32_t PkmnLib::Battling::DamageLibrary::GetDamage(CreatureLib::Battling::ExecutingAttack* attack,
|
||||||
CreatureLib::Battling::Creature* target, uint8_t hitIndex,
|
CreatureLib::Battling::Creature* target, uint8_t hitIndex,
|
||||||
const HitData& hitData) const {
|
const HitData& hitData) const {
|
||||||
auto levelMod = static_cast<float>(2 * attack->GetUser()->GetLevel()) / 5;
|
auto levelMod = fl((2 * attack->GetUser()->GetLevel()) / 5.0f) + 2;
|
||||||
auto bp = hitData.GetBasePower();
|
auto bp = hitData.GetBasePower();
|
||||||
auto statMod = GetStatModifier(attack, target, hitIndex, hitData);
|
auto statMod = GetStatModifier(attack, target, hitIndex, hitData);
|
||||||
auto damageMod = GetDamageModifier(attack, target, hitIndex, hitData);
|
auto damageMod = GetDamageModifier(attack, target, hitIndex, hitData);
|
||||||
// HOOK: Modify stat modifier
|
// HOOK: Modify stat modifier
|
||||||
|
|
||||||
auto floatDamage = (((levelMod * static_cast<float>(bp) * statMod) / 50) + 2) * damageMod;
|
auto floatDamage = fl(levelMod * bp);
|
||||||
uint32_t damage;
|
floatDamage = fl(floatDamage * statMod);
|
||||||
|
floatDamage = fl(floatDamage / 50) + 2;
|
||||||
|
floatDamage = fl(floatDamage * damageMod);
|
||||||
|
uint32_t damage = 0;
|
||||||
if (floatDamage < 0) {
|
if (floatDamage < 0) {
|
||||||
damage = 0;
|
damage = 0;
|
||||||
} else if (floatDamage >= (float)UINT32_MAX) {
|
} else if (floatDamage >= (float)UINT32_MAX) {
|
||||||
damage = UINT32_MAX;
|
damage = UINT32_MAX;
|
||||||
} else { // TODO: C++ 20 - add [[likely]] attribute when supported by both gcc and Clang
|
} else {
|
||||||
damage = static_cast<uint32_t>(floatDamage);
|
damage = static_cast<uint32_t>(floatDamage);
|
||||||
}
|
}
|
||||||
// HOOK: Override damage
|
// HOOK: Override damage
|
||||||
|
@ -82,8 +88,8 @@ float PkmnLib::Battling::DamageLibrary::GetDamageModifier(CreatureLib::Battling:
|
||||||
PKMN_HOOK(OverrideCriticalModifier, attack, attack, target, hitIndex, &critModifier);
|
PKMN_HOOK(OverrideCriticalModifier, attack, attack, target, hitIndex, &critModifier);
|
||||||
mod *= critModifier;
|
mod *= critModifier;
|
||||||
}
|
}
|
||||||
Ensure(attack->GetUser()->GetBattle().GetValue());
|
|
||||||
if (_hasRandomness) {
|
if (_hasRandomness) {
|
||||||
|
Ensure(attack->GetUser()->GetBattle().GetValue());
|
||||||
float randPercentage = 85 + attack->GetUser()->GetBattle().GetValue()->GetRandom()->Get(0, 16);
|
float randPercentage = 85 + attack->GetUser()->GetBattle().GetValue()->GetRandom()->Get(0, 16);
|
||||||
mod *= randPercentage / 100.0;
|
mod *= randPercentage / 100.0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
#ifdef TESTS_BUILD
|
||||||
|
#include "../../extern/doctest.hpp"
|
||||||
|
#include "../../src/Battling/Library/DamageLibrary.hpp"
|
||||||
|
#include "../../src/Battling/Pokemon/CreatePokemon.hpp"
|
||||||
|
#include "../TestLibrary/TestLibrary.hpp"
|
||||||
|
|
||||||
|
using namespace PkmnLib::Battling;
|
||||||
|
|
||||||
|
TEST_CASE("Correct rounding for damage.") {
|
||||||
|
auto lib = TestLibrary::GetLibrary();
|
||||||
|
auto mon1 = CreatePokemon(lib, "testCharizard"_cnc, 100)
|
||||||
|
.WithIndividualValues(31, 31, 31, 31, 31, 31)
|
||||||
|
.WithEffortValues(0, 0, 0, 0, 0, 0)
|
||||||
|
.WithNature("neutralNature"_cnc)
|
||||||
|
.WithGender(CreatureLib::Library::Gender::Male)
|
||||||
|
.IsAllowedExperienceGain(false)
|
||||||
|
.Build();
|
||||||
|
auto mon2 = CreatePokemon(lib, "testVenusaur"_cnc, 100)
|
||||||
|
.WithIndividualValues(31, 31, 31, 31, 31, 31)
|
||||||
|
.WithEffortValues(0, 0, 0, 0, 0, 0)
|
||||||
|
.WithNature("neutralNature"_cnc)
|
||||||
|
.WithGender(CreatureLib::Library::Gender::Male)
|
||||||
|
.IsAllowedExperienceGain(false)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
auto move = PkmnLib::Library::MoveData("test", 0, PkmnLib::Library::MoveCategory::Physical, 55, 100, 10,
|
||||||
|
CreatureLib::Library::AttackTarget::All, 0, nullptr, {});
|
||||||
|
|
||||||
|
auto attack = PkmnLib::Battling::LearnedMove(&move, CreatureLib::Battling::AttackLearnMethod::Unknown);
|
||||||
|
|
||||||
|
auto executingAttack = CreatureLib::Battling::ExecutingAttack({mon2}, 1, mon1, &attack, &move, nullptr);
|
||||||
|
|
||||||
|
auto hit = executingAttack.GetHitData(mon2, 0);
|
||||||
|
hit.SetBasePower(55);
|
||||||
|
hit.SetEffectiveness(2.0f);
|
||||||
|
hit.SetCritical(0);
|
||||||
|
|
||||||
|
auto damage = lib->GetDamageLibrary()->GetDamage(&executingAttack, mon2, 0, hit);
|
||||||
|
REQUIRE_EQ(144, damage);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -37,6 +37,23 @@ PkmnLib::Library::SpeciesLibrary* TestLibrary::BuildSpeciesLibrary() {
|
||||||
{"testHiddenAbility"_cnc}, new PkmnLib::Library::LearnableMoves(100)),
|
{"testHiddenAbility"_cnc}, new PkmnLib::Library::LearnableMoves(100)),
|
||||||
0.5f, "testGrowthRate"_cnc, 100, 100, {"testEggGroup"_cnc}));
|
0.5f, "testGrowthRate"_cnc, 100, 100, {"testEggGroup"_cnc}));
|
||||||
|
|
||||||
|
lib->Insert("testCharizard"_cnc.GetHash(),
|
||||||
|
new PkmnLib::Library::PokemonSpecies(
|
||||||
|
5, "testCharizard"_cnc,
|
||||||
|
new PkmnLib::Library::PokemonForme(
|
||||||
|
"default"_cnc, 1.7f, 90.5f, 240, {0, 4},
|
||||||
|
CreatureLib::Library::StatisticSet<uint16_t>(78, 84, 78, 109, 85, 100), {"testAbility"_cnc},
|
||||||
|
{"testHiddenAbility"_cnc}, new PkmnLib::Library::LearnableMoves(100)),
|
||||||
|
0.5f, "testGrowthRate"_cnc, 100, 100, {"testEggGroup"_cnc}));
|
||||||
|
lib->Insert("testVenusaur"_cnc.GetHash(),
|
||||||
|
new PkmnLib::Library::PokemonSpecies(
|
||||||
|
6, "testVenusaur"_cnc,
|
||||||
|
new PkmnLib::Library::PokemonForme(
|
||||||
|
"default"_cnc, 2.0f, 100.0f, 236, {0, 4},
|
||||||
|
CreatureLib::Library::StatisticSet<uint16_t>(80, 82, 83, 100, 100, 80), {"testAbility"_cnc},
|
||||||
|
{"testHiddenAbility"_cnc}, new PkmnLib::Library::LearnableMoves(100)),
|
||||||
|
0.5f, "testGrowthRate"_cnc, 100, 100, {"testEggGroup"_cnc}));
|
||||||
|
|
||||||
return lib;
|
return lib;
|
||||||
}
|
}
|
||||||
PkmnLib::Library::MoveLibrary* TestLibrary::BuildMoveLibrary() {
|
PkmnLib::Library::MoveLibrary* TestLibrary::BuildMoveLibrary() {
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
auto statCalc = new PkmnLib::Battling::StatCalculator();
|
auto statCalc = new PkmnLib::Battling::StatCalculator();
|
||||||
auto scriptResolver = PkmnLib::Battling::BattleLibrary::CreateScriptResolver();
|
auto scriptResolver = PkmnLib::Battling::BattleLibrary::CreateScriptResolver();
|
||||||
auto lib = new PkmnLib::Battling::BattleLibrary(
|
auto lib = new PkmnLib::Battling::BattleLibrary(
|
||||||
BuildStaticLibrary(), statCalc, new PkmnLib::Battling::DamageLibrary(),
|
BuildStaticLibrary(), statCalc, new PkmnLib::Battling::DamageLibrary(false),
|
||||||
new PkmnLib::Battling::ExperienceLibrary(), scriptResolver, new PkmnLib::Battling::MiscLibrary(GetTime));
|
new PkmnLib::Battling::ExperienceLibrary(), scriptResolver, new PkmnLib::Battling::MiscLibrary(GetTime));
|
||||||
scriptResolver->Initialize(lib);
|
scriptResolver->Initialize(lib);
|
||||||
return lib;
|
return lib;
|
||||||
|
|
Loading…
Reference in New Issue