CreatureLib/src/Library/CreatureData/SpeciesVariant.cpp

142 lines
7.3 KiB
C++

#include "SpeciesVariant.hpp"
namespace CreatureLib::Library {
struct SpeciesVariant::impl {
private:
ArbUt::StringView _name;
float _height;
float _weight;
u32 _baseExperience;
ArbUt::List<u8> _types;
Library::StatisticSet<u16> _baseStatistics;
ArbUt::List<ArbUt::BorrowedPtr<const Talent>> _talents;
ArbUt::List<ArbUt::BorrowedPtr<const Talent>> _secretTalents;
std::unique_ptr<const LearnableAttacks> _attacks;
std::unordered_set<u32> _flags;
public:
impl(const ArbUt::StringView& name, float height, float weight, u32 baseExperience, ArbUt::List<u8> types,
Library::StatisticSet<u16> baseStats, ArbUt::List<ArbUt::BorrowedPtr<const Talent>> talents,
ArbUt::List<ArbUt::BorrowedPtr<const Talent>> secretTalents, const LearnableAttacks* non_null attacks,
std::unordered_set<u32> flags)
: _name(name), _height(height), _weight(weight), _baseExperience(baseExperience),
_types(std::move((types))), _baseStatistics(baseStats), _talents(std::move(talents)),
_secretTalents(std::move(secretTalents)), _attacks(attacks), _flags(std::move(flags)){};
inline const ArbUt::StringView& GetName() const { return _name; }
inline float GetHeight() const { return _height; }
inline float GetWeight() const { return _weight; }
inline u32 GetBaseExperience() const { return _baseExperience; }
[[nodiscard]] inline size_t GetTypeCount() const { return _types.Count(); }
[[nodiscard]] inline u8 GetType(size_t index) const { return _types[index]; }
[[nodiscard]] inline const ArbUt::List<u8>& GetTypes() const { return _types; }
[[nodiscard]] inline const Library::StatisticSet<u16>& GetStatistics() const { return _baseStatistics; }
[[nodiscard]] inline u16 GetStatistic(Library::Statistic stat) const { return _baseStatistics.GetStat(stat); }
[[nodiscard]] inline size_t GetTalentCount() const noexcept { return _talents.Count(); }
[[nodiscard]] inline size_t GetSecretTalentCount() const noexcept { return _secretTalents.Count(); }
[[nodiscard]] const ArbUt::BorrowedPtr<const Talent>& GetTalent(const TalentIndex& index) const {
if (index.IsSecret() && _secretTalents.Count() > 0) {
auto usedIndex = index.GetIndex();
if (usedIndex >= _secretTalents.Count()) {
usedIndex = _secretTalents.Count() - 1;
}
return _secretTalents.At(usedIndex);
}
auto usedIndex = index.GetIndex();
if (usedIndex >= _talents.Count()) {
usedIndex = _talents.Count() - 1;
}
return _talents.At(usedIndex);
}
[[nodiscard]] TalentIndex GetTalentIndex(const ArbUt::BorrowedPtr<Talent>& talent) const {
for (size_t i = 0; i < _talents.Count(); i++) {
if (_talents.At(i) == talent) {
return TalentIndex(false, i);
}
}
for (size_t i = 0; i < _secretTalents.Count(); i++) {
if (_secretTalents.At(i) == talent) {
return TalentIndex(true, i);
}
}
THROW("The given talent is not a valid talent for this creature.");
}
[[nodiscard]] TalentIndex GetTalentIndex(const ArbUt::StringView& talentName) const {
for (size_t i = 0; i < _talents.Count(); i++) {
if (_talents.At(i)->GetName() == talentName) {
return TalentIndex(false, i);
}
}
for (size_t i = 0; i < _secretTalents.Count(); i++) {
if (_secretTalents.At(i)->GetName() == talentName) {
return TalentIndex(true, i);
}
}
THROW("The given talent name is not a valid talent for this creature.");
}
[[nodiscard]] inline ArbUt::BorrowedPtr<const CreatureLib::Library::LearnableAttacks>
GetLearnableAttacks() const {
return _attacks;
}
[[nodiscard]] inline TalentIndex GetRandomTalent(ArbUt::Random& rand) const noexcept {
return TalentIndex(false, rand.Get(_talents.Count()));
}
[[nodiscard]] inline const ArbUt::List<ArbUt::BorrowedPtr<const Talent>>& GetTalents() const {
return _talents;
}
[[nodiscard]] inline const ArbUt::List<ArbUt::BorrowedPtr<const Talent>>& GetSecretTalents() const {
return _secretTalents;
}
inline bool HasFlag(const ArbUt::StringView& key) const noexcept {
return this->_flags.find(key) != this->_flags.end();
}
inline bool HasFlag(u32 keyHash) const noexcept { return this->_flags.find(keyHash) != this->_flags.end(); }
};
SpeciesVariant::SpeciesVariant(const ArbUt::StringView& name, float height, float weight, u32 baseExperience,
const ArbUt::List<u8>& types, StatisticSet<u16> baseStats,
const ArbUt::List<ArbUt::BorrowedPtr<const Talent>>& talents,
const ArbUt::List<ArbUt::BorrowedPtr<const Talent>>& secretTalents,
const LearnableAttacks* non_null attacks, const std::unordered_set<u32>& flags)
: _impl(new impl(name, height, weight, baseExperience, types, baseStats, talents, secretTalents, attacks,
flags)) {}
SpeciesVariant::~SpeciesVariant() = default;
#define ImplGetter(type, func) \
type SpeciesVariant::func() const noexcept { return _impl->func(); }
ImplGetter(const ArbUt::StringView&, GetName);
ImplGetter(float, GetHeight);
ImplGetter(float, GetWeight);
ImplGetter(u32, GetBaseExperience);
ImplGetter(size_t, GetTypeCount);
u8 SpeciesVariant::GetType(size_t index) const { return _impl->GetType(index); }
ImplGetter(const ArbUt::List<u8>&, GetTypes);
ImplGetter(const Library::StatisticSet<u16>&, GetStatistics);
u16 SpeciesVariant::GetStatistic(Library::Statistic stat) const noexcept { return _impl->GetStatistic(stat); }
ImplGetter(size_t, GetTalentCount);
ImplGetter(size_t, GetSecretTalentCount);
const ArbUt::BorrowedPtr<const Talent>& SpeciesVariant::GetTalent(const TalentIndex& index) const {
return _impl->GetTalent(index);
}
TalentIndex SpeciesVariant::GetTalentIndex(const ArbUt::BorrowedPtr<Talent>& talent) const {
return _impl->GetTalentIndex(talent);
}
TalentIndex SpeciesVariant::GetTalentIndex(const ArbUt::StringView& talentName) const {
return _impl->GetTalentIndex(talentName);
}
ImplGetter(ArbUt::BorrowedPtr<const LearnableAttacks>, GetLearnableAttacks);
TalentIndex SpeciesVariant::GetRandomTalent(ArbUt::Random& rand) const noexcept {
return _impl->GetRandomTalent(rand);
}
ImplGetter(const ArbUt::List<ArbUt::BorrowedPtr<const Talent>>&, GetTalents);
ImplGetter(const ArbUt::List<ArbUt::BorrowedPtr<const Talent>>&, GetSecretTalents);
bool SpeciesVariant::HasFlag(const ArbUt::StringView& key) const noexcept { return _impl->HasFlag(key); }
bool SpeciesVariant::HasFlag(u32 keyHash) const noexcept { return _impl->HasFlag(keyHash); }
}