PkmnLib/src/Battling/Library/ExperienceLibrary.cpp
Deukhoofd bbb2691b91
All checks were successful
continuous-integration/drone/push Build is passing
Update to latest Arbutils.
2020-12-13 12:32:52 +01:00

69 lines
2.6 KiB
C++

#include "ExperienceLibrary.hpp"
#include <CreatureLib/Battling/Models/Battle.hpp>
#include "../PkmnScriptHook.hpp"
#include "../Pokemon/Pokemon.hpp"
static inline uint32_t CalculateDynamicExperience(level_int_t level, float v1,
ArbUt::BorrowedPtr<CreatureLib::Battling::Creature> op,
ArbUt::BorrowedPtr<CreatureLib::Battling::Creature> faintedMon) {
float a = 2 * level + 10;
float b = level + op->GetLevel() + 10;
float v2 = (a * a * sqrt(a)) / (b * b * sqrt(b));
uint32_t experienceGain = v1 * v2 + 1;
// TODO: Check owner and international
PKMN_HOOK(ModifyExperienceGain, op, faintedMon.GetRaw(), op.GetRaw(), &experienceGain);
return experienceGain;
}
void PkmnLib::Battling::ExperienceLibrary::HandleExperienceGain(
CreatureLib::Battling::Creature* faintedMon,
const std::unordered_set<ArbUt::BorrowedPtr<CreatureLib::Battling::Creature>>& opponents) const {
auto fainted = dynamic_cast<Pokemon*>(faintedMon);
EnsureNotNull(fainted);
auto& forme = fainted->GetForme();
auto expGain = forme->GetBaseExperience();
auto level = fainted->GetLevel();
float v1 = (expGain * level) / 5;
for (const auto& op : opponents) {
if (!op->AllowedExperienceGain())
continue;
auto experienceGain = CalculateDynamicExperience(level, v1, op, fainted);
op->AddExperience(experienceGain);
}
auto battle = fainted->GetBattle();
if (!battle.HasValue()) {
return;
}
std::unordered_set<CreatureLib::Battling::Creature*> shareExperience;
for (const auto& party : battle.GetValue()->GetParties()) {
for (const auto& mon : party->GetParty()->GetParty()) {
if (mon == nullptr)
continue;
// If the mon is not allowed to gain experience, or is fainted, don't check for experience sharing.
if (!mon->AllowedExperienceGain() || mon->IsFainted())
continue;
// If the mon is already in the opponents set, don't check for experience sharing.
if (opponents.find(mon) != opponents.end())
continue;
bool sharedExp = false;
PKMN_HOOK(DoesShareExperience, mon, faintedMon, mon, &sharedExp);
if (sharedExp) {
shareExperience.insert(mon);
}
}
}
if (shareExperience.size() == 0)
return;
v1 /= 2;
for (auto op : shareExperience) {
auto experienceGain = CalculateDynamicExperience(level, v1, op, faintedMon);
op->AddExperience(experienceGain);
}
}