#ifndef CREATURELIB_BATTLECREATURE_HPP #define CREATURELIB_BATTLECREATURE_HPP #include "../../Library/CreatureData/CreatureSpecies.hpp" #include "../../Library/Items/Item.hpp" #include "../ScriptHandling/ScriptAggregator.hpp" #include "../ScriptHandling/ScriptSet.hpp" #include "../ScriptHandling/ScriptSource.hpp" #include "DamageSource.hpp" #include "LearnedAttack.hpp" namespace CreatureLib::Battling { // Forward declare battle class class Battle; class BattleSide; class BattleLibrary; class Creature : public ScriptSource { protected: const BattleLibrary* _library; const Library::CreatureSpecies* _species; const Library::SpeciesVariant* _variant; uint8_t _level; uint32_t _experience; uint32_t _uniqueIdentifier; Library::Gender _gender; uint8_t _coloring; const Library::Item* _heldItem; uint32_t _currentHealth; Core::StatisticSet _statBoost; Core::StatisticSet _flatStats; Core::StatisticSet _boostedStats; Battle* _battle = nullptr; BattleSide* _side = nullptr; bool _onBattleField = false; std::string _nickname = ""; int8_t _talentIndex; Script* _activeTalent = nullptr; bool _hasOverridenTalent; std::string _overridenTalentName = ""; std::unordered_set _seenOpponents = {}; std::vector _attacks; Script* _status = nullptr; ScriptSet _volatile = {}; private: void OnFaint(); public: Creature(const BattleLibrary* library, const Library::CreatureSpecies* species, const Library::SpeciesVariant* variant, uint8_t level, uint32_t experience, uint32_t uid, Library::Gender gender, uint8_t coloring, const Library::Item* heldItem, std::string nickname, int8_t talent, std::vector attacks); virtual ~Creature() { for (auto attack : _attacks) { delete attack; } }; virtual void Initialize() { RecalculateFlatStats(); _currentHealth = GetBoostedStat(Core::Statistic::Health); } inline const Library::CreatureSpecies* GetSpecies() const { return _species; } inline const Library::SpeciesVariant* GetVariant() const { return _variant; } inline uint8_t GetLevel() const { return _level; } inline uint32_t GetExperience() const { return _experience; } inline Library::Gender GetGender() const { return _gender; } inline uint8_t GetColoring() const { return _coloring; } inline const Library::Item* GetHeldItem() const { return _heldItem; } inline uint32_t GetCurrentHealth() const { return _currentHealth; } void SetBattleData(Battle* battle, BattleSide* side); Battle* GetBattle() const; BattleSide* GetBattleSide() const; void SetOnBattleField(bool value) { _onBattleField = value; } bool IsOnBattleField() const { return _onBattleField; } const std::string& GetNickname() const; const std::string& GetActiveTalent() const; [[nodiscard]] bool IsFainted() const; [[nodiscard]] const std::vector& GetTypes() const; [[nodiscard]] bool HasType(uint8_t type) const; 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& GetSeenOpponents() const { return _seenOpponents; } void GetActiveScripts(std::vector& scripts) override; void ClearVolatileScripts(); std::vector& GetAttacks() { return _attacks; } const Library::CreatureSpecies* GetDisplaySpecies(); const Library::SpeciesVariant* GetDisplayVariant(); // region Stat APIs void ChangeStatBoost(Core::Statistic stat, int8_t diffAmount); [[nodiscard]] uint32_t GetFlatStat(Core::Statistic stat) const; [[nodiscard]] uint32_t GetBoostedStat(Core::Statistic stat) const; [[nodiscard]] uint32_t GetBaseStat(Core::Statistic stat) const; [[nodiscard]] int8_t GetStatBoost(Core::Statistic stat) const; void RecalculateFlatStats(); void RecalculateBoostedStats(); void RecalculateFlatStat(Core::Statistic); void RecalculateBoostedStat(Core::Statistic); // endregion }; } #endif // CREATURELIB_CREATURE_HPP