2019-10-24 11:37:55 +00:00
|
|
|
#ifndef CREATURELIB_BATTLECREATURE_HPP
|
|
|
|
#define CREATURELIB_BATTLECREATURE_HPP
|
|
|
|
|
2020-08-19 18:11:00 +00:00
|
|
|
#include "../../Defines.hpp"
|
2020-04-22 19:48:00 +00:00
|
|
|
#include "../../Library/ClampedStatisticSet.hpp"
|
2019-11-05 15:20:47 +00:00
|
|
|
#include "../../Library/CreatureData/CreatureSpecies.hpp"
|
|
|
|
#include "../../Library/Items/Item.hpp"
|
2019-11-09 11:15:45 +00:00
|
|
|
#include "../ScriptHandling/ScriptAggregator.hpp"
|
2019-11-28 11:55:22 +00:00
|
|
|
#include "../ScriptHandling/ScriptSet.hpp"
|
2019-11-09 11:15:45 +00:00
|
|
|
#include "../ScriptHandling/ScriptSource.hpp"
|
2021-05-08 09:53:32 +00:00
|
|
|
#include "CreatureIndex.hpp"
|
2019-11-28 11:55:22 +00:00
|
|
|
#include "DamageSource.hpp"
|
|
|
|
#include "LearnedAttack.hpp"
|
2019-10-24 11:37:55 +00:00
|
|
|
|
2019-11-28 11:55:22 +00:00
|
|
|
namespace CreatureLib::Battling {
|
2019-10-24 11:37:55 +00:00
|
|
|
// Forward declare battle class
|
|
|
|
class Battle;
|
2019-10-29 10:19:25 +00:00
|
|
|
class BattleSide;
|
2019-11-05 15:20:47 +00:00
|
|
|
class BattleLibrary;
|
2019-10-24 11:37:55 +00:00
|
|
|
|
2019-11-28 11:55:22 +00:00
|
|
|
class Creature : public ScriptSource {
|
2020-01-02 17:38:56 +00:00
|
|
|
protected:
|
2020-06-02 14:20:47 +00:00
|
|
|
ArbUt::BorrowedPtr<const BattleLibrary> _library;
|
2019-12-05 11:56:41 +00:00
|
|
|
|
2020-05-26 16:31:06 +00:00
|
|
|
ArbUt::BorrowedPtr<const Library::CreatureSpecies> _species;
|
|
|
|
ArbUt::BorrowedPtr<const Library::SpeciesVariant> _variant;
|
2019-11-10 16:08:42 +00:00
|
|
|
|
2020-12-12 11:22:48 +00:00
|
|
|
ArbUt::OptionalBorrowedPtr<const Library::CreatureSpecies> _displaySpecies = nullptr;
|
|
|
|
ArbUt::OptionalBorrowedPtr<const Library::SpeciesVariant> _displayVariant = nullptr;
|
2020-02-03 15:49:28 +00:00
|
|
|
|
2020-08-19 18:11:00 +00:00
|
|
|
level_int_t _level;
|
2020-01-12 16:04:42 +00:00
|
|
|
uint32_t _experience;
|
|
|
|
uint32_t _uniqueIdentifier;
|
|
|
|
Library::Gender _gender;
|
|
|
|
uint8_t _coloring;
|
2020-12-12 12:40:30 +00:00
|
|
|
ArbUt::OptionalBorrowedPtr<const Library::Item> _heldItem;
|
2020-06-02 16:02:37 +00:00
|
|
|
uint32_t _currentHealth = -1;
|
2019-10-24 11:37:55 +00:00
|
|
|
|
2020-04-22 19:48:00 +00:00
|
|
|
Library::ClampedStatisticSet<int8_t, -6, 6> _statBoost;
|
2020-03-22 09:11:53 +00:00
|
|
|
Library::StatisticSet<uint32_t> _flatStats;
|
|
|
|
Library::StatisticSet<uint32_t> _boostedStats;
|
2019-10-24 11:37:55 +00:00
|
|
|
|
2021-05-08 09:26:35 +00:00
|
|
|
struct BattleData {
|
2021-05-08 09:53:32 +00:00
|
|
|
bool OnBattleField = false;
|
2021-05-08 09:26:35 +00:00
|
|
|
ArbUt::OptionalBorrowedPtr<Battle> Battle = nullptr;
|
|
|
|
ArbUt::OptionalBorrowedPtr<BattleSide> Side = nullptr;
|
2021-05-08 09:53:32 +00:00
|
|
|
CreatureIndex Index = {};
|
2021-05-08 09:26:35 +00:00
|
|
|
std::unordered_set<ArbUt::BorrowedPtr<Creature>> SeenOpponents;
|
2021-05-08 09:53:32 +00:00
|
|
|
} _battleData = {};
|
2019-10-24 11:37:55 +00:00
|
|
|
|
2021-09-19 09:40:18 +00:00
|
|
|
std::optional<std::string> _nickname = {};
|
2021-05-08 09:26:35 +00:00
|
|
|
CreatureLib::Library::TalentIndex _talentIndex = {};
|
|
|
|
std::unique_ptr<BattleScript> _activeTalent = {};
|
2019-11-17 10:25:52 +00:00
|
|
|
|
2021-05-08 09:26:35 +00:00
|
|
|
bool _hasOverridenTalent = false;
|
|
|
|
ArbUt::StringView _overridenTalentName = {};
|
2019-11-18 17:41:55 +00:00
|
|
|
|
2021-05-08 09:26:35 +00:00
|
|
|
ArbUt::OptionalUniquePtrList<LearnedAttack> _attacks = {};
|
|
|
|
bool _allowedExperienceGain = {};
|
2019-10-24 11:37:55 +00:00
|
|
|
|
2021-03-07 09:26:41 +00:00
|
|
|
std::unique_ptr<BattleScript> _status = nullptr;
|
2019-11-08 17:45:43 +00:00
|
|
|
ScriptSet _volatile = {};
|
|
|
|
|
2021-05-08 09:26:35 +00:00
|
|
|
std::vector<u8> _types = {};
|
2020-06-05 14:38:27 +00:00
|
|
|
|
2020-01-02 17:43:16 +00:00
|
|
|
private:
|
2019-12-14 12:28:23 +00:00
|
|
|
void OnFaint();
|
|
|
|
|
2019-10-24 11:37:55 +00:00
|
|
|
public:
|
2021-04-11 13:20:50 +00:00
|
|
|
Creature(const ArbUt::BorrowedPtr<const BattleLibrary>& library,
|
2020-06-02 14:20:47 +00:00
|
|
|
const ArbUt::BorrowedPtr<const Library::CreatureSpecies>& species,
|
2020-08-19 18:11:00 +00:00
|
|
|
const ArbUt::BorrowedPtr<const Library::SpeciesVariant>& variant, level_int_t level,
|
|
|
|
uint32_t experience, uint32_t uid, Library::Gender gender, uint8_t coloring,
|
2021-09-19 09:40:18 +00:00
|
|
|
ArbUt::OptionalBorrowedPtr<const Library::Item> heldItem, std::optional<std::string> nickname,
|
2020-05-31 15:26:39 +00:00
|
|
|
const Library::TalentIndex& talent, const std::vector<LearnedAttack*>& attacks,
|
2020-05-20 13:18:27 +00:00
|
|
|
bool allowedExperienceGain = true);
|
2019-12-05 11:56:41 +00:00
|
|
|
|
2021-08-28 17:05:52 +00:00
|
|
|
virtual ~Creature();
|
2019-11-10 13:37:06 +00:00
|
|
|
|
2020-01-05 12:43:47 +00:00
|
|
|
virtual void Initialize() {
|
|
|
|
RecalculateFlatStats();
|
2020-03-22 09:11:53 +00:00
|
|
|
_currentHealth = GetBoostedStat(Library::Statistic::Health);
|
2020-01-05 12:43:47 +00:00
|
|
|
}
|
|
|
|
|
2020-07-25 13:02:11 +00:00
|
|
|
inline const ArbUt::BorrowedPtr<const BattleLibrary>& GetLibrary() const noexcept { return _library; }
|
2020-05-26 16:31:06 +00:00
|
|
|
inline const ArbUt::BorrowedPtr<const Library::CreatureSpecies>& GetSpecies() const noexcept {
|
|
|
|
return _species;
|
|
|
|
}
|
|
|
|
inline const ArbUt::BorrowedPtr<const Library::SpeciesVariant>& GetVariant() const noexcept { return _variant; }
|
2020-08-13 08:38:56 +00:00
|
|
|
virtual void ChangeSpecies(const ArbUt::BorrowedPtr<const Library::CreatureSpecies>& species,
|
|
|
|
const ArbUt::BorrowedPtr<const Library::SpeciesVariant>& variant);
|
|
|
|
virtual void ChangeVariant(const ArbUt::BorrowedPtr<const Library::SpeciesVariant>& variant);
|
2020-08-19 18:11:00 +00:00
|
|
|
inline level_int_t GetLevel() const noexcept { return _level; }
|
2020-03-22 12:42:26 +00:00
|
|
|
inline uint32_t GetExperience() const noexcept { return _experience; }
|
2020-08-09 09:48:40 +00:00
|
|
|
inline uint32_t GetUniqueIdentifier() const noexcept { return _uniqueIdentifier; }
|
2020-03-22 12:42:26 +00:00
|
|
|
inline Library::Gender GetGender() const noexcept { return _gender; }
|
|
|
|
inline uint8_t GetColoring() const noexcept { return _coloring; }
|
2020-06-26 15:08:23 +00:00
|
|
|
inline bool HasHeldItem(const ArbUt::BasicStringView& name) const noexcept {
|
2020-12-12 12:40:30 +00:00
|
|
|
return _heldItem.HasValue() && _heldItem.GetValue()->GetName() == name;
|
2020-02-17 16:16:28 +00:00
|
|
|
}
|
2020-03-22 12:42:26 +00:00
|
|
|
inline bool HasHeldItem(uint32_t nameHash) const noexcept {
|
2020-12-12 12:40:30 +00:00
|
|
|
return _heldItem.HasValue() && _heldItem.GetValue()->GetName() == nameHash;
|
2020-03-05 10:25:41 +00:00
|
|
|
}
|
2020-12-12 12:40:30 +00:00
|
|
|
inline const ArbUt::OptionalBorrowedPtr<const Library::Item>& GetHeldItem() const noexcept { return _heldItem; }
|
2020-06-26 15:08:23 +00:00
|
|
|
void SetHeldItem(const ArbUt::BasicStringView& itemName);
|
2020-03-05 10:25:41 +00:00
|
|
|
void SetHeldItem(uint32_t itemNameHash);
|
2020-05-26 16:31:06 +00:00
|
|
|
inline void SetHeldItem(const ArbUt::BorrowedPtr<const Library::Item>& item) noexcept { _heldItem = item; };
|
2020-02-17 16:16:28 +00:00
|
|
|
|
2020-03-22 12:42:26 +00:00
|
|
|
inline uint32_t GetCurrentHealth() const noexcept { return _currentHealth; }
|
2020-01-12 16:04:42 +00:00
|
|
|
|
2020-12-12 11:22:48 +00:00
|
|
|
void SetBattleData(const ArbUt::BorrowedPtr<Battle>& battle, const ArbUt::BorrowedPtr<BattleSide>& side);
|
2020-12-28 12:40:39 +00:00
|
|
|
void ClearBattleData() noexcept;
|
2021-05-08 09:26:35 +00:00
|
|
|
inline const ArbUt::OptionalBorrowedPtr<Battle>& GetBattle() const { return _battleData.Battle; }
|
|
|
|
inline const ArbUt::OptionalBorrowedPtr<BattleSide>& GetBattleSide() const { return _battleData.Side; }
|
|
|
|
inline void SetOnBattleField(bool value) { _battleData.OnBattleField = value; }
|
2021-05-08 09:53:32 +00:00
|
|
|
inline void SetBattleIndex(const CreatureIndex& index) { _battleData.Index = index; }
|
|
|
|
inline const CreatureIndex& GetBattleIndex() const noexcept { return _battleData.Index; }
|
2021-05-08 09:26:35 +00:00
|
|
|
inline bool IsOnBattleField() const { return _battleData.OnBattleField; }
|
2019-10-29 10:19:25 +00:00
|
|
|
|
2021-09-19 09:40:18 +00:00
|
|
|
inline std::optional<std::string_view> GetNickname() const noexcept {
|
|
|
|
if (_nickname.has_value()) {
|
|
|
|
return _nickname.value();
|
|
|
|
}
|
|
|
|
return {};
|
|
|
|
}
|
2020-12-22 15:11:23 +00:00
|
|
|
inline void SetNickname(std::string nickname) noexcept { _nickname = nickname; }
|
2020-09-05 12:51:06 +00:00
|
|
|
const CreatureLib::Library::TalentIndex& GetRealTalent() const noexcept { return _talentIndex; }
|
2020-06-26 15:08:23 +00:00
|
|
|
const ArbUt::StringView& GetActiveTalent() const;
|
2019-11-18 17:41:55 +00:00
|
|
|
|
2021-06-19 10:33:31 +00:00
|
|
|
/// Are we allowed to use this creature in a battle?
|
|
|
|
[[nodiscard]] virtual bool IsUsable() const noexcept;
|
2020-03-22 12:42:26 +00:00
|
|
|
[[nodiscard]] bool IsFainted() const noexcept;
|
2020-10-23 14:51:15 +00:00
|
|
|
[[nodiscard]] const std::vector<uint8_t>& GetTypes() const noexcept;
|
2020-03-22 12:42:26 +00:00
|
|
|
[[nodiscard]] bool HasType(uint8_t type) const noexcept;
|
2019-11-02 12:57:43 +00:00
|
|
|
|
2020-03-22 12:42:26 +00:00
|
|
|
uint32_t GetMaxHealth() const noexcept { return _boostedStats.GetHealth(); }
|
2020-03-05 10:25:41 +00:00
|
|
|
void ChangeLevelBy(int8_t amount);
|
2019-11-18 17:41:55 +00:00
|
|
|
void Damage(uint32_t damage, DamageSource source);
|
2020-03-09 15:29:41 +00:00
|
|
|
void Heal(uint32_t amount, bool canRevive = false);
|
2020-08-08 09:38:11 +00:00
|
|
|
void RestoreAllAttackUses() noexcept;
|
2020-06-26 15:08:23 +00:00
|
|
|
void OverrideActiveTalent(const ArbUt::StringView& talent);
|
2019-12-14 12:28:23 +00:00
|
|
|
void AddExperience(uint32_t amount);
|
2019-11-18 17:41:55 +00:00
|
|
|
|
2021-05-08 09:26:35 +00:00
|
|
|
void MarkOpponentAsSeen(ArbUt::BorrowedPtr<Creature> creature) { _battleData.SeenOpponents.insert(creature); }
|
|
|
|
const std::unordered_set<ArbUt::BorrowedPtr<Creature>>& GetSeenOpponents() const {
|
|
|
|
return _battleData.SeenOpponents;
|
|
|
|
}
|
2019-12-14 11:40:50 +00:00
|
|
|
|
2020-04-25 09:33:25 +00:00
|
|
|
size_t ScriptCount() const override;
|
2020-05-26 16:31:06 +00:00
|
|
|
void GetActiveScripts(ArbUt::List<ScriptWrapper>& scripts) override;
|
2021-10-29 17:31:08 +00:00
|
|
|
void GetOwnScripts(ArbUt::List<ScriptWrapper>& scripts) override;
|
2019-12-14 11:15:30 +00:00
|
|
|
void ClearVolatileScripts();
|
2021-03-27 15:36:20 +00:00
|
|
|
BattleScript* AddVolatileScript(const ArbUt::StringView& name);
|
|
|
|
BattleScript* AddVolatileScript(BattleScript* script);
|
2020-06-26 15:08:23 +00:00
|
|
|
void RemoveVolatileScript(const ArbUt::BasicStringView& name);
|
2021-03-07 09:26:41 +00:00
|
|
|
void RemoveVolatileScript(BattleScript* script);
|
2020-06-26 15:08:23 +00:00
|
|
|
bool HasVolatileScript(const ArbUt::BasicStringView& name) const;
|
2019-11-18 17:41:55 +00:00
|
|
|
|
2020-12-12 14:10:18 +00:00
|
|
|
const ArbUt::OptionalUniquePtrList<LearnedAttack>& GetAttacks() noexcept { return _attacks; }
|
2020-08-09 09:48:40 +00:00
|
|
|
bool HasAttack(const ArbUt::StringView& name) {
|
|
|
|
for (auto& a : _attacks) {
|
|
|
|
if (a == nullptr)
|
|
|
|
continue;
|
|
|
|
if (a->GetAttack()->GetName() == name)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2019-10-24 11:37:55 +00:00
|
|
|
|
2020-12-12 11:22:48 +00:00
|
|
|
ArbUt::OptionalBorrowedPtr<const Library::CreatureSpecies> GetDisplaySpecies() const noexcept;
|
|
|
|
ArbUt::OptionalBorrowedPtr<const Library::SpeciesVariant> GetDisplayVariant() const noexcept;
|
2020-02-03 15:49:28 +00:00
|
|
|
|
2020-05-26 16:31:06 +00:00
|
|
|
void SetDisplaySpecies(const ArbUt::BorrowedPtr<const Library::CreatureSpecies>& species) noexcept {
|
2020-12-12 11:22:48 +00:00
|
|
|
_displaySpecies = species.GetRaw();
|
2020-05-24 18:57:22 +00:00
|
|
|
}
|
2020-06-02 16:02:37 +00:00
|
|
|
void SetDisplayVariant(ArbUt::BorrowedPtr<const Library::SpeciesVariant> variant) noexcept {
|
2020-12-12 11:22:48 +00:00
|
|
|
_displayVariant = variant.GetRaw();
|
2020-06-02 16:02:37 +00:00
|
|
|
};
|
2020-05-20 13:18:27 +00:00
|
|
|
|
|
|
|
inline bool AllowedExperienceGain() const noexcept { return _allowedExperienceGain; }
|
|
|
|
inline void SetAllowedExperienceGain(bool allowed) noexcept { _allowedExperienceGain = allowed; }
|
2019-12-21 13:32:45 +00:00
|
|
|
|
2020-08-12 15:51:06 +00:00
|
|
|
uint8_t GetAvailableAttackSlot() const noexcept;
|
|
|
|
void AddAttack(LearnedAttack* attack);
|
|
|
|
void ReplaceAttack(size_t index, LearnedAttack* attack);
|
2020-08-12 16:54:01 +00:00
|
|
|
void SwapAttacks(size_t a, size_t b) { _attacks.Swap(a, b); }
|
2020-08-12 15:51:06 +00:00
|
|
|
|
2021-07-09 13:33:30 +00:00
|
|
|
void SetStatus(const ArbUt::StringView& name);
|
|
|
|
void ClearStatus();
|
2021-09-21 20:19:26 +00:00
|
|
|
const ArbUt::StringView& GetStatusName() const noexcept {
|
2021-07-09 13:33:30 +00:00
|
|
|
if (_status == nullptr)
|
|
|
|
return ArbUt::StringView::EmptyString();
|
|
|
|
return _status->GetName();
|
|
|
|
}
|
|
|
|
|
2019-12-05 11:56:41 +00:00
|
|
|
// region Stat APIs
|
2019-10-24 11:37:55 +00:00
|
|
|
|
2020-04-22 19:48:00 +00:00
|
|
|
bool ChangeStatBoost(Library::Statistic stat, int8_t diffAmount);
|
2020-04-25 14:15:27 +00:00
|
|
|
[[nodiscard]] inline uint32_t GetFlatStat(Library::Statistic stat) const { return _flatStats.GetStat(stat); }
|
|
|
|
[[nodiscard]] inline uint32_t GetBoostedStat(Library::Statistic stat) const {
|
|
|
|
return _boostedStats.GetStat(stat);
|
|
|
|
}
|
|
|
|
[[nodiscard]] inline uint32_t GetBaseStat(Library::Statistic stat) const {
|
|
|
|
return _variant->GetStatistic(stat);
|
|
|
|
}
|
|
|
|
[[nodiscard]] inline int8_t GetStatBoost(Library::Statistic stat) const { return _statBoost.GetStat(stat); }
|
2019-10-24 11:37:55 +00:00
|
|
|
void RecalculateFlatStats();
|
|
|
|
void RecalculateBoostedStats();
|
2020-03-22 09:11:53 +00:00
|
|
|
void RecalculateFlatStat(Library::Statistic);
|
|
|
|
void RecalculateBoostedStat(Library::Statistic);
|
2019-11-10 16:08:42 +00:00
|
|
|
|
2019-11-28 11:55:22 +00:00
|
|
|
// endregion
|
2021-04-11 13:20:50 +00:00
|
|
|
|
2021-04-11 14:01:18 +00:00
|
|
|
virtual Creature* Clone() const;
|
2019-10-24 11:37:55 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-11-28 11:55:22 +00:00
|
|
|
#endif // CREATURELIB_CREATURE_HPP
|