#include "Creature.hpp" #include #include #include "../Models/Battle.hpp" using namespace CreatureLib; Battling::Creature::Creature(const BattleLibrary* library, const Library::CreatureSpecies* species, const Library::SpeciesVariant* variant, uint8_t level, uint32_t experience, Core::StatisticSet statExp, Core::StatisticSet statPotential, uint32_t uid, Library::Gender gender, uint8_t coloring, const Library::Item* heldItem, std::string nickname, int8_t talent, std::vector attacks) : _library(library), __Species(species), __Variant(variant), __Level(level), __Experience(experience), __StatExperience(statExp), __StatPotential(statPotential), __UniqueIdentifier(uid), __Gender(gender), __Coloring(coloring), __HeldItem(heldItem), _nickname(std::move(nickname)), _talentIndex(talent), _hasOverridenTalent(false), _attacks(std::move(attacks)) { RecalculateFlatStats(); __CurrentHealth = GetBoostedStat(Core::Statistic::Health); _activeTalent = _library->LoadScript(ScriptResolver::ScriptCategory::Talent, GetActiveTalent()); } void Battling::Creature::ChangeLevel(int8_t amount) { this->__Level += amount; RecalculateFlatStats(); } const std::string& Battling::Creature::GetNickname() const { if (_nickname.empty()) return __Species->GetName(); return _nickname; } const std::string& Battling::Creature::GetActiveTalent() const { if (_hasOverridenTalent) { return _overridenTalentName; } return __Variant->GetTalent(_talentIndex); } void Battling::Creature::SetBattleData(Battling::Battle* battle, Battling::BattleSide* side) { _battle = battle; _side = side; } // region Stat APIs void Battling::Creature::ChangeStatBoost(Core::Statistic stat, int8_t diffAmount) { if (diffAmount > 0) this->_statBoost.IncreaseStatBy(stat, diffAmount); else this->_statBoost.DecreaseStatBy(stat, diffAmount); this->RecalculateBoostedStat(stat); } uint32_t Battling::Creature::GetFlatStat(Core::Statistic stat) const { return _flatStats.GetStat(stat); } uint32_t Battling::Creature::GetBoostedStat(Core::Statistic stat) const { return _boostedStats.GetStat(stat); } uint32_t Battling::Creature::GetBaseStat(Core::Statistic stat) const { return __Variant->GetStatistic(stat); } uint32_t Battling::Creature::GetStatPotential(Core::Statistic stat) const { return __StatPotential.GetStat(stat); } uint32_t Battling::Creature::GetStatExperience(Core::Statistic stat) const { return __StatExperience.GetStat(stat); } int8_t Battling::Creature::GetStatBoost(Core::Statistic stat) const { return _statBoost.GetStat(stat); } void Battling::Creature::RecalculateFlatStats() { auto statCalc = this->_library->GetStatCalculator(); this->_flatStats = statCalc->CalculateFlatStats(this); RecalculateBoostedStats(); } void Battling::Creature::RecalculateBoostedStats() { this->_boostedStats = this->_library->GetStatCalculator()->CalculateFlatStats(this); } void Battling::Creature::RecalculateFlatStat(Core::Statistic stat) { auto s = this->_library->GetStatCalculator()->CalculateFlatStat(this, stat); this->_flatStats.SetStat(stat, s); RecalculateBoostedStat(stat); } void Battling::Creature::RecalculateBoostedStat(Core::Statistic stat) { auto s = this->_library->GetStatCalculator()->CalculateBoostedStat(this, stat); this->_boostedStats.SetStat(stat, s); } // endregion Battling::Battle* Battling::Creature::GetBattle() const { return _battle; } Battling::BattleSide* Battling::Creature::GetBattleSide() const { return _side; } bool Battling::Creature::IsFainted() const { return this->__CurrentHealth <= 0; } void Battling::Creature::Damage(uint32_t damage, Battling::DamageSource source) { if (damage > __CurrentHealth) { damage = __CurrentHealth; } // HOOK: On Damage __CurrentHealth -= damage; if (IsFainted() && damage > 0) { if (!_battle->CanSlotBeFilled(_side->GetSideIndex(), _side->GetCreatureIndex(this))) { _side->MarkSlotAsUnfillable(this); } _battle->ValidateBattleState(); } } void Battling::Creature::OverrideActiveTalent(const std::string& talent) { _hasOverridenTalent = true; _overridenTalentName = talent; _activeTalent = this->_library->LoadScript(ScriptResolver::ScriptCategory::Talent, talent); } const std::vector& Battling::Creature::GetTypes() const { // HOOK: override types. return this->__Variant->GetTypes(); } bool Battling::Creature::HasType(uint8_t type) const { auto t = GetTypes(); return std::find(t.begin(), t.end(), type) != t.end(); } void Battling::Creature::GetActiveScripts(std::vector& scripts) { scripts.emplace_back(&_activeTalent); scripts.emplace_back(&_status); scripts.emplace_back(&_volatile); _side->GetActiveScripts(scripts); } void Battling::Creature::ClearVolatileScripts() { _volatile.Clear(); }