Implements experience gain on opponent faint.
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
2019-12-14 13:28:23 +01:00
parent 3baed93597
commit 649de39571
9 changed files with 119 additions and 21 deletions

View File

@@ -5,15 +5,16 @@ using namespace CreatureLib::Battling;
BattleLibrary::BattleLibrary(CreatureLib::Library::DataLibrary* staticLib, BattleStatCalculator* statCalculator,
DamageLibrary* damageLibrary, CriticalLibrary* criticalLibrary,
ScriptResolver* scriptResolver)
ExperienceLibrary* experienceLibrary, ScriptResolver* scriptResolver)
: _staticLib(staticLib), _statCalculator(statCalculator), _damageLibrary(damageLibrary),
_criticalLibrary(criticalLibrary), _scriptResolver(scriptResolver) {}
_criticalLibrary(criticalLibrary), _experienceLibrary(experienceLibrary), _scriptResolver(scriptResolver) {}
BattleLibrary::~BattleLibrary() {
delete _staticLib;
delete _statCalculator;
delete _damageLibrary;
delete _criticalLibrary;
delete _experienceLibrary;
delete _scriptResolver;
}

View File

@@ -6,6 +6,7 @@
#include "BattleStatCalculator.hpp"
#include "CriticalLibrary.hpp"
#include "DamageLibrary.hpp"
#include "ExperienceLibrary.hpp"
namespace CreatureLib::Battling {
class BattleLibrary {
@@ -13,11 +14,13 @@ namespace CreatureLib::Battling {
BattleStatCalculator* _statCalculator = nullptr;
DamageLibrary* _damageLibrary = nullptr;
CriticalLibrary* _criticalLibrary = nullptr;
ExperienceLibrary* _experienceLibrary = nullptr;
ScriptResolver* _scriptResolver = nullptr;
public:
BattleLibrary(Library::DataLibrary* staticLib, BattleStatCalculator* statCalculator,
DamageLibrary* damageLibrary, CriticalLibrary* criticalLibrary, ScriptResolver* scriptResolver);
DamageLibrary* damageLibrary, CriticalLibrary* criticalLibrary,
ExperienceLibrary* experienceLibrary, ScriptResolver* scriptResolver);
~BattleLibrary();
[[nodiscard]] const Library::LibrarySettings& GetSettings() const;
@@ -25,10 +28,14 @@ namespace CreatureLib::Battling {
[[nodiscard]] const Library::ItemLibrary* GetItemLibrary() const;
[[nodiscard]] const Library::AttackLibrary* GetAttackLibrary() const;
[[nodiscard]] const Library::TypeLibrary* GetTypeLibrary() const;
[[nodiscard]] const Library::GrowthRateLibrary* GetGrowthRateLibrary() const {
return _staticLib->GetGrowthRates();
}
[[nodiscard]] const BattleStatCalculator* GetStatCalculator() const;
[[nodiscard]] const DamageLibrary* GetDamageLibrary() const;
[[nodiscard]] const CriticalLibrary* GetCriticalLibrary() const;
[[nodiscard]] const ExperienceLibrary* GetExperienceLibrary() const { return _experienceLibrary; }
[[nodiscard]] Script* LoadScript(ScriptResolver::ScriptCategory category, const std::string& scriptName) const;
};

View File

@@ -0,0 +1,13 @@
#include "ExperienceLibrary.hpp"
#include "../Models/Creature.hpp"
void CreatureLib::Battling::ExperienceLibrary::HandleExperienceGain(
CreatureLib::Battling::Creature* faintedMon, const std::unordered_set<Creature*>& opponents) const {
for (auto opponent : opponents) {
auto levelDiff = faintedMon->GetLevel() - opponent->GetLevel() + 10;
if (levelDiff <= 0)
continue;
auto experienceGain = levelDiff * 10;
opponent->AddExperience(static_cast<uint32_t>(experienceGain));
}
}

View File

@@ -0,0 +1,16 @@
#ifndef CREATURELIB_EXPERIENCELIBRARY_HPP
#define CREATURELIB_EXPERIENCELIBRARY_HPP
#include <unordered_set>
namespace CreatureLib::Battling {
class Creature;
class ExperienceLibrary {
public:
virtual ~ExperienceLibrary() = default;
virtual void HandleExperienceGain(Creature* faintedMon, const std::unordered_set<Creature*>& opponents) const;
};
}
#endif // CREATURELIB_EXPERIENCELIBRARY_HPP

View File

@@ -92,6 +92,16 @@ Battling::BattleSide* Battling::Creature::GetBattleSide() const { return _side;
bool Battling::Creature::IsFainted() const { return this->__CurrentHealth <= 0; }
void Battling::Creature::OnFaint() {
// HOOK: On Faint
_library->GetExperienceLibrary()->HandleExperienceGain(this, _seenOpponents);
if (!_battle->CanSlotBeFilled(_side->GetSideIndex(), _side->GetCreatureIndex(this))) {
_side->MarkSlotAsUnfillable(this);
}
_battle->ValidateBattleState();
}
void Battling::Creature::Damage(uint32_t damage, Battling::DamageSource source) {
if (damage > __CurrentHealth) {
damage = __CurrentHealth;
@@ -100,10 +110,7 @@ void Battling::Creature::Damage(uint32_t damage, Battling::DamageSource source)
__CurrentHealth -= damage;
if (IsFainted() && damage > 0) {
if (!_battle->CanSlotBeFilled(_side->GetSideIndex(), _side->GetCreatureIndex(this))) {
_side->MarkSlotAsUnfillable(this);
}
_battle->ValidateBattleState();
OnFaint();
}
}
@@ -130,3 +137,16 @@ void Battling::Creature::GetActiveScripts(std::vector<ScriptWrapper>& scripts) {
_side->GetActiveScripts(scripts);
}
void Battling::Creature::ClearVolatileScripts() { _volatile.Clear(); }
void Battling::Creature::AddExperience(uint32_t amount) {
auto maxLevel = _library->GetSettings().GetMaximalLevel();
if (__Level >= maxLevel) {
return;
}
auto exp = __Experience + amount;
auto level = _library->GetGrowthRateLibrary()->CalculateLevel(this->GetSpecies()->GetGrowthRate(), exp);
if (level >= maxLevel) {
exp = _library->GetGrowthRateLibrary()->CalculateExperience(this->GetSpecies()->GetGrowthRate(), maxLevel);
}
__Experience = exp;
__Level = level;
}

View File

@@ -54,6 +54,8 @@ namespace CreatureLib::Battling {
Script* _status = nullptr;
ScriptSet _volatile = {};
void OnFaint();
public:
Creature(const BattleLibrary* library, const Library::CreatureSpecies* species,
const Library::SpeciesVariant* variant, uint8_t level, uint32_t experience,
@@ -83,6 +85,7 @@ namespace CreatureLib::Battling {
void ChangeLevel(int8_t amount);
void Damage(uint32_t damage, DamageSource source);
void OverrideActiveTalent(const std::string& talent);
void AddExperience(uint32_t amount);
void MarkOpponentAsSeen(Creature* creature) { _seenOpponents.insert(creature); }
const std::unordered_set<Creature*>& GetSeenOpponents() const { return _seenOpponents; }