diff --git a/CInterface/Battling/Creature.cpp b/CInterface/Battling/Creature.cpp index 2d0697c..f182e1d 100644 --- a/CInterface/Battling/Creature.cpp +++ b/CInterface/Battling/Creature.cpp @@ -11,7 +11,9 @@ export uint8_t CreatureLib_Creature_Construct(Creature*& out, const BattleLibrar const char* nickname, bool secretTalent, uint8_t talent, LearnedAttack* attacks[], size_t attacksNum, bool allowedExperienceGain) { Try(auto attacksVec = List(attacks, attacks + attacksNum); - out = new Creature(library, species, variant, level, experience, uid, gender, coloring, heldItem, nickname, + out = new Creature(library, std::shared_ptr(species), variant, + level, experience, uid, gender, coloring, + std::shared_ptr(heldItem), nickname, CreatureLib::Library::TalentIndex(secretTalent, talent), attacksVec, allowedExperienceGain);) }; @@ -19,8 +21,10 @@ export void CreatureLib_Creature_Destruct(const Creature* p) { delete p; } #define SIMPLE_GET_FUNC(type, name, returnType) \ export returnType CreatureLib_##type##_##name(const type* p) { return p->name(); } +#define SIMPLE_GET_FUNC_SMART_PTR(type, name, returnType) \ + export returnType CreatureLib_##type##_##name(const type* p) { return p->name().operator->(); } -SIMPLE_GET_FUNC(Creature, GetSpecies, const CreatureLib::Library::CreatureSpecies*); +SIMPLE_GET_FUNC_SMART_PTR(Creature, GetSpecies, const CreatureLib::Library::CreatureSpecies*); SIMPLE_GET_FUNC(Creature, GetVariant, const CreatureLib::Library::SpeciesVariant*); SIMPLE_GET_FUNC(Creature, GetLevel, uint8_t); SIMPLE_GET_FUNC(Creature, GetExperience, uint32_t); @@ -31,13 +35,13 @@ export bool CreatureLib_Creature_HasHeldItem(const Creature* p, const char* name return p->HasHeldItem(ConstString(name)); } export bool CreatureLib_Creature_HasHeldItemWithHash(const Creature* p, uint32_t hash) { return p->HasHeldItem(hash); } -SIMPLE_GET_FUNC(Creature, GetHeldItem, const CreatureLib::Library::Item*); +SIMPLE_GET_FUNC_SMART_PTR(Creature, GetHeldItem, const CreatureLib::Library::Item*); export uint8_t CreatureLib_Creature_SetHeldItem(Creature* p, const char* name) { Try(p->SetHeldItem(ConstString(name));) } export uint8_t CreatureLib_Creature_SetHeldItemWithHash(Creature* p, uint32_t hash) { Try(p->SetHeldItem(hash);) } export void CreatureLib_Creature_SetHeldItemFromItem(Creature* p, const CreatureLib::Library::Item* item) { - return p->SetHeldItem(item); + return p->SetHeldItem(std::shared_ptr(item)); } SIMPLE_GET_FUNC(Creature, GetCurrentHealth, uint32_t); SIMPLE_GET_FUNC(Creature, GetBattle, Battle*); @@ -79,10 +83,10 @@ export bool CreatureLib_Creature_HasVolatileScript(Creature* p, const char* scri } export size_t CreatureLib_Creature_GetAttacksCount(Creature* p) { return p->GetAttacks().Count(); } export LearnedAttack* const* CreatureLib_Creature_GetAttacks(Creature* p) { return p->GetAttacks().RawData(); } -SIMPLE_GET_FUNC(Creature, GetDisplaySpecies, const CreatureLib::Library::CreatureSpecies*); +SIMPLE_GET_FUNC_SMART_PTR(Creature, GetDisplaySpecies, const CreatureLib::Library::CreatureSpecies*); SIMPLE_GET_FUNC(Creature, GetDisplayVariant, const CreatureLib::Library::SpeciesVariant*); export void CreatureLib_Creature_SetDisplaySpecies(Creature* p, const CreatureLib::Library::CreatureSpecies* species) { - return p->SetDisplaySpecies(species); + return p->SetDisplaySpecies(std::shared_ptr(species)); } export void CreatureLib_Creature_SetDisplayVariant(Creature* p, const CreatureLib::Library::SpeciesVariant* variant) { return p->SetDisplayVariant(variant); @@ -103,4 +107,5 @@ export int8_t CreatureLib_Creature_GetStatBoost(Creature* p, CreatureLib::Librar return p->GetStatBoost(stat); } -#undef SIMPLE_GET_FUNC \ No newline at end of file +#undef SIMPLE_GET_FUNC +#undef SIMPLE_GET_FUNC_SMART_PTR \ No newline at end of file diff --git a/CInterface/Battling/LearnedAttack.cpp b/CInterface/Battling/LearnedAttack.cpp index 2c1f9b7..4035b22 100644 --- a/CInterface/Battling/LearnedAttack.cpp +++ b/CInterface/Battling/LearnedAttack.cpp @@ -2,16 +2,19 @@ #include "../Core.hpp" using namespace CreatureLib::Battling; -export uint8_t CreatureLib_LearnedAttack_Construct(LearnedAttack*& out, CreatureLib::Library::AttackData* attack, +export uint8_t CreatureLib_LearnedAttack_Construct(LearnedAttack*& out, const CreatureLib::Library::AttackData* attack, uint8_t maxUses, AttackLearnMethod learnMethod) { - Try(out = new LearnedAttack(attack, maxUses, learnMethod);) + Try(out = new LearnedAttack(std::shared_ptr(attack), maxUses, learnMethod);) } export void CreatureLib_LearnedAttack_Destruct(LearnedAttack* p) { delete p; } #define SIMPLE_GET_FUNC(type, name, returnType) \ export returnType CreatureLib_##type##_##name(const type* p) { return p->name(); } -SIMPLE_GET_FUNC(LearnedAttack, GetAttack, const CreatureLib::Library::AttackData*); +#define SIMPLE_GET_FUNC_SMART_PTR(type, name, returnType) \ + export returnType CreatureLib_##type##_##name(const type* p) { return p->name().operator->(); } + +SIMPLE_GET_FUNC_SMART_PTR(LearnedAttack, GetAttack, const CreatureLib::Library::AttackData*); SIMPLE_GET_FUNC(LearnedAttack, GetMaxUses, uint8_t); SIMPLE_GET_FUNC(LearnedAttack, GetRemainingUses, uint8_t); SIMPLE_GET_FUNC(LearnedAttack, GetLearnMethod, AttackLearnMethod); @@ -20,3 +23,6 @@ export bool CreatureLib_LearnedAttack_TryUse(LearnedAttack* p, uint8_t uses) { r export void CreatureLib_LearnedAttack_DecreaseUses(LearnedAttack* p, uint8_t uses) { p->DecreaseUses(uses); } export void CreatureLib_LearnedAttack_RestoreUses(LearnedAttack* p, uint8_t uses) { p->RestoreUses(uses); } export void CreatureLib_LearnedAttack_RestoreAllUses(LearnedAttack* p) { p->RestoreAllUses(); } + +#undef SIMPLE_GET_FUNC +#undef SIMPLE_GET_FUNC_SMART_PTR diff --git a/CInterface/Library/BaseLibrary.cpp b/CInterface/Library/BaseLibrary.cpp index 63ee1ae..2f23279 100644 --- a/CInterface/Library/BaseLibrary.cpp +++ b/CInterface/Library/BaseLibrary.cpp @@ -16,19 +16,25 @@ export uint8_t simpleName##_DeleteWithHash(fullname* p, uint32_t hashedKey) { Try(p->Delete(hashedKey);) } \ \ export bool simpleName##_TryGet(fullname* p, const char* name, const returnType*& out) { \ - return p->TryGet(Arbutils::CaseInsensitiveConstString::GetHash(name), out); \ + std::shared_ptr o; \ + auto v = p->TryGet(Arbutils::CaseInsensitiveConstString::GetHash(name), o); \ + out = o.operator->(); \ + return v; \ } \ \ export bool simpleName##_TryGetWithHash(fullname* p, uint32_t hashedKey, const returnType*& out) { \ - return p->TryGet(hashedKey, out); \ + std::shared_ptr o; \ + auto v = p->TryGet(hashedKey, o); \ + out = o.operator->(); \ + return v; \ } \ \ export uint8_t simpleName##_Get(fullname* p, const char* name, const returnType*& out) { \ - Try(out = p->Get(Arbutils::CaseInsensitiveConstString::GetHash(name));) \ + Try(out = p->Get(Arbutils::CaseInsensitiveConstString::GetHash(name)).operator->();) \ } \ \ export uint8_t simpleName##_GetWithHash(fullname* p, uint32_t hashedKey, const returnType*& out) { \ - Try(out = p->Get(hashedKey);) \ + Try(out = p->Get(hashedKey).operator->();) \ } \ \ export size_t simpleName##_GetCount(fullname* p) { return p->GetCount(); } diff --git a/src/Battling/Library/MiscLibrary.cpp b/src/Battling/Library/MiscLibrary.cpp index bb191e1..02879fe 100644 --- a/src/Battling/Library/MiscLibrary.cpp +++ b/src/Battling/Library/MiscLibrary.cpp @@ -11,13 +11,14 @@ bool CreatureLib::Battling::MiscLibrary::IsCritical(CreatureLib::Battling::Execu } static CreatureLib::Battling::LearnedAttack* _replacementAttack = nullptr; -static CreatureLib::Library::AttackData* _replacementAttackData = nullptr; +static std::shared_ptr _replacementAttackData = nullptr; -static CreatureLib::Library::AttackData* GetReplacementAttackData() { +static const std::shared_ptr& GetReplacementAttackData() { if (_replacementAttackData == nullptr) { - _replacementAttackData = new CreatureLib::Library::AttackData( - "replacement"_cnc, 0, CreatureLib::Library::AttackCategory::Physical, 30, 255, 255, - CreatureLib::Library::AttackTarget::Any, 0, new CreatureLib::Library::SecondaryEffect(), {}); + _replacementAttackData = + std::shared_ptr(new CreatureLib::Library::AttackData( + "replacement"_cnc, 0, CreatureLib::Library::AttackCategory::Physical, 30, 255, 255, + CreatureLib::Library::AttackTarget::Any, 0, new CreatureLib::Library::SecondaryEffect(), {})); } return _replacementAttackData; } diff --git a/src/Battling/Models/CreateCreature.cpp b/src/Battling/Models/CreateCreature.cpp index d16f323..00fa248 100644 --- a/src/Battling/Models/CreateCreature.cpp +++ b/src/Battling/Models/CreateCreature.cpp @@ -32,7 +32,7 @@ CreateCreature CreateCreature::WithAttack(const Arbutils::CaseInsensitiveConstSt Creature* CreateCreature::Create() { auto rand = Arbutils::Random(); - auto species = this->_library->GetSpeciesLibrary()->Get(this->_species); + auto& species = this->_library->GetSpeciesLibrary()->Get(this->_species); auto variant = species->GetVariant(this->_variant); Library::TalentIndex talent; if (this->_talent.Empty()) { @@ -48,9 +48,9 @@ Creature* CreateCreature::Create() { if (gender == static_cast(-1)) { gender = species->GetRandomGender(rand); } - const Library::Item* heldItem = nullptr; + std::shared_ptr heldItem = nullptr; if (!this->_heldItem.Empty()) { - if (!_library->GetItemLibrary()->TryGet(this->_heldItem, heldItem)) { + if (!_library->GetItemLibrary()->TryGet(this->_heldItem.GetHash(), heldItem)) { throw CreatureException("Invalid held item."); } } diff --git a/src/Battling/Models/CreateCreature.hpp b/src/Battling/Models/CreateCreature.hpp index f97636c..7716703 100644 --- a/src/Battling/Models/CreateCreature.hpp +++ b/src/Battling/Models/CreateCreature.hpp @@ -21,7 +21,7 @@ namespace CreatureLib::Battling { uint8_t _coloring = 0; Arbutils::CaseInsensitiveConstString _heldItem = ""_cnc; uint32_t _identifier = 0; - List> _attacks; + List, AttackLearnMethod>> _attacks; public: CreateCreature(const BattleLibrary* library, const Arbutils::CaseInsensitiveConstString& species, uint8_t level) diff --git a/src/Battling/Models/Creature.cpp b/src/Battling/Models/Creature.cpp index 25d6874..5c65ddb 100644 --- a/src/Battling/Models/Creature.cpp +++ b/src/Battling/Models/Creature.cpp @@ -6,11 +6,13 @@ using namespace CreatureLib; -Battling::Creature::Creature(const BattleLibrary* library, const Library::CreatureSpecies* species, +Battling::Creature::Creature(const BattleLibrary* library, + const std::shared_ptr& 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, const Library::TalentIndex& talent, - const List& attacks, bool allowedExperienceGain) + Library::Gender gender, uint8_t coloring, + const std::shared_ptr heldItem, std::string nickname, + const Library::TalentIndex& talent, const List& attacks, + bool allowedExperienceGain) : _library(library), _species(species), _variant(variant), _level(level), _experience(experience), _uniqueIdentifier(uid), _gender(gender), _coloring(coloring), _heldItem(heldItem), _nickname(std::move(nickname)), _talentIndex(talent), _hasOverridenTalent(false), _attacks(attacks), @@ -185,7 +187,7 @@ void Battling::Creature::AddExperience(uint32_t amount) { _experience = exp; _level = level; } -const Library::CreatureSpecies* Battling::Creature::GetDisplaySpecies() const noexcept { +std::shared_ptr Battling::Creature::GetDisplaySpecies() const noexcept { auto species = _displaySpecies; if (species == nullptr) species = _species; @@ -198,14 +200,14 @@ const Library::SpeciesVariant* Battling::Creature::GetDisplayVariant() const noe return variant; } void Battling::Creature::SetHeldItem(const ConstString& itemName) { - const Library::Item* item; - if (!_library->GetItemLibrary()->TryGet(itemName, item)) { + std::shared_ptr item; + if (!_library->GetItemLibrary()->TryGet(itemName.GetHash(), item)) { throw CreatureException("Item not found."); } _heldItem = item; } void Battling::Creature::SetHeldItem(uint32_t itemNameHash) { - const Library::Item* item; + std::shared_ptr item; if (!_library->GetItemLibrary()->TryGet(itemNameHash, item)) { throw CreatureException("Item not found."); } diff --git a/src/Battling/Models/Creature.hpp b/src/Battling/Models/Creature.hpp index fb16db5..1ba2345 100644 --- a/src/Battling/Models/Creature.hpp +++ b/src/Battling/Models/Creature.hpp @@ -23,10 +23,10 @@ namespace CreatureLib::Battling { protected: const BattleLibrary* _library; - const Library::CreatureSpecies* _species; + std::shared_ptr _species; const Library::SpeciesVariant* _variant; - const Library::CreatureSpecies* _displaySpecies = nullptr; + std::shared_ptr _displaySpecies = nullptr; const Library::SpeciesVariant* _displayVariant = nullptr; uint8_t _level; @@ -34,7 +34,7 @@ namespace CreatureLib::Battling { uint32_t _uniqueIdentifier; Library::Gender _gender; uint8_t _coloring; - const Library::Item* _heldItem; + std::shared_ptr _heldItem; uint32_t _currentHealth; Library::ClampedStatisticSet _statBoost; @@ -63,10 +63,10 @@ namespace CreatureLib::Battling { void OnFaint(); public: - Creature(const BattleLibrary* library, const Library::CreatureSpecies* species, + Creature(const BattleLibrary* library, const std::shared_ptr& 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, - const Library::TalentIndex& talent, const List& attacks, + Library::Gender gender, uint8_t coloring, const std::shared_ptr heldItem, + std::string nickname, const Library::TalentIndex& talent, const List& attacks, bool allowedExperienceGain = true); virtual ~Creature() { @@ -82,7 +82,7 @@ namespace CreatureLib::Battling { _currentHealth = GetBoostedStat(Library::Statistic::Health); } - inline const Library::CreatureSpecies* GetSpecies() const noexcept { return _species; } + inline const std::shared_ptr& GetSpecies() const noexcept { return _species; } inline const Library::SpeciesVariant* GetVariant() const noexcept { return _variant; } inline uint8_t GetLevel() const noexcept { return _level; } inline uint32_t GetExperience() const noexcept { return _experience; } @@ -94,10 +94,10 @@ namespace CreatureLib::Battling { inline bool HasHeldItem(uint32_t nameHash) const noexcept { return _heldItem != nullptr && _heldItem->GetName() == nameHash; } - inline const Library::Item* GetHeldItem() const noexcept { return _heldItem; } + inline const std::shared_ptr& GetHeldItem() const noexcept { return _heldItem; } void SetHeldItem(const ConstString& itemName); void SetHeldItem(uint32_t itemNameHash); - inline void SetHeldItem(const Library::Item* item) noexcept { _heldItem = item; }; + inline void SetHeldItem(const std::shared_ptr& item) noexcept { _heldItem = item; }; inline uint32_t GetCurrentHealth() const noexcept { return _currentHealth; } @@ -135,10 +135,12 @@ namespace CreatureLib::Battling { const List& GetAttacks() noexcept { return _attacks; } - const Library::CreatureSpecies* GetDisplaySpecies() const noexcept; + std::shared_ptr GetDisplaySpecies() const noexcept; const Library::SpeciesVariant* GetDisplayVariant() const noexcept; - void SetDisplaySpecies(const Library::CreatureSpecies* species) noexcept { _displaySpecies = species; } + void SetDisplaySpecies(const std::shared_ptr& species) noexcept { + _displaySpecies = species; + } void SetDisplayVariant(const Library::SpeciesVariant* variant) noexcept { _displayVariant = variant; }; inline bool AllowedExperienceGain() const noexcept { return _allowedExperienceGain; } diff --git a/src/Battling/Models/LearnedAttack.cpp b/src/Battling/Models/LearnedAttack.cpp index a012027..bac76b7 100644 --- a/src/Battling/Models/LearnedAttack.cpp +++ b/src/Battling/Models/LearnedAttack.cpp @@ -1,18 +1,20 @@ #include "LearnedAttack.hpp" #include -CreatureLib::Battling::LearnedAttack::LearnedAttack(const CreatureLib::Library::AttackData* attack, uint8_t maxUses, - AttackLearnMethod learnMethod) +CreatureLib::Battling::LearnedAttack::LearnedAttack( + const std::shared_ptr& attack, uint8_t maxUses, + AttackLearnMethod learnMethod) : _attack(attack), _maxUses(maxUses), _remainingUses(maxUses), _learnMethod(learnMethod) { AssertNotNull(_attack) } -CreatureLib::Battling::LearnedAttack::LearnedAttack(const CreatureLib::Library::AttackData* attack, - AttackLearnMethod learnMethod) +CreatureLib::Battling::LearnedAttack::LearnedAttack( + const std::shared_ptr& attack, AttackLearnMethod learnMethod) : _attack(attack), _maxUses(attack->GetBaseUsages()), _remainingUses(_maxUses), _learnMethod(learnMethod) { AssertNotNull(_attack) } -const CreatureLib::Library::AttackData* CreatureLib::Battling::LearnedAttack::GetAttack() const noexcept { +const std::shared_ptr& +CreatureLib::Battling::LearnedAttack::GetAttack() const noexcept { return _attack; } diff --git a/src/Battling/Models/LearnedAttack.hpp b/src/Battling/Models/LearnedAttack.hpp index a035b04..8ee83b1 100644 --- a/src/Battling/Models/LearnedAttack.hpp +++ b/src/Battling/Models/LearnedAttack.hpp @@ -1,23 +1,26 @@ #ifndef CREATURELIB_LEARNEDATTACK_HPP #define CREATURELIB_LEARNEDATTACK_HPP +#include #include "../../Library/Attacks/AttackData.hpp" #include "AttackLearnMethod.hpp" namespace CreatureLib::Battling { class LearnedAttack { - const Library::AttackData* _attack; + std::shared_ptr _attack; uint8_t _maxUses; uint8_t _remainingUses; AttackLearnMethod _learnMethod; public: - LearnedAttack(const Library::AttackData* attack, uint8_t maxUses, AttackLearnMethod learnMethod); - LearnedAttack(const Library::AttackData* attack, AttackLearnMethod learnMethod); + LearnedAttack(const std::shared_ptr& attack, uint8_t maxUses, + AttackLearnMethod learnMethod); + LearnedAttack(const std::shared_ptr& attack, + AttackLearnMethod learnMethod); virtual ~LearnedAttack() = default; - const Library::AttackData* GetAttack() const noexcept; + const std::shared_ptr& GetAttack() const noexcept; uint8_t GetMaxUses() const noexcept; uint8_t GetRemainingUses() const noexcept; AttackLearnMethod GetLearnMethod() const noexcept; diff --git a/src/Library/BaseLibrary.hpp b/src/Library/BaseLibrary.hpp index cdf41e0..8cfdd14 100644 --- a/src/Library/BaseLibrary.hpp +++ b/src/Library/BaseLibrary.hpp @@ -7,23 +7,19 @@ #include #include #include +#include #include namespace CreatureLib::Library { template class BaseLibrary { - Arbutils::Collections::Dictionary _values; + Arbutils::Collections::Dictionary> _values; Arbutils::Collections::List _listValues; size_t _index; public: BaseLibrary(size_t initialCapacity = 32) : _values(initialCapacity), _listValues(initialCapacity) {} - virtual ~BaseLibrary() { - for (const auto& v : _values) { - delete v.second; - } - _values.Clear(); - } + virtual ~BaseLibrary() { _values.Clear(); } inline void Insert(const Arbutils::CaseInsensitiveConstString& key, const T* value) { AssertNotNull(value) @@ -32,7 +28,7 @@ namespace CreatureLib::Library { } inline void Insert(uint32_t hashedKey, const T* value) { AssertNotNull(value) - _values.Insert(hashedKey, value); + _values.Insert(hashedKey, std::shared_ptr(value)); _listValues.Append(hashedKey); } @@ -47,31 +43,38 @@ namespace CreatureLib::Library { _listValues.Remove(k); } - bool TryGet(const Arbutils::CaseInsensitiveConstString& name, const T*& out) const { + bool TryGet(const Arbutils::CaseInsensitiveConstString& name, const std::shared_ptr& out) const { return TryGet(name.GetHash(), out); } - bool TryGet(uint32_t hashedKey, const T*& out) const { return _values.TryGet(hashedKey, out); } + bool TryGet(uint32_t hashedKey, std::shared_ptr& out) const { return _values.TryGet(hashedKey, out); } - [[nodiscard]] inline const T* Get(const Arbutils::CaseInsensitiveConstString& name) const { + [[nodiscard]] inline const std::shared_ptr& + Get(const Arbutils::CaseInsensitiveConstString& name) const { return _values.Get(name.GetHash()); } - [[nodiscard]] inline const T* Get(uint32_t hashedKey) const { return _values.Get(hashedKey); } + [[nodiscard]] inline const std::shared_ptr& Get(uint32_t hashedKey) const { + return _values.Get(hashedKey); + } - [[nodiscard]] inline const T* operator[](const Arbutils::CaseInsensitiveConstString& name) const { + [[nodiscard]] inline const std::shared_ptr& + operator[](const Arbutils::CaseInsensitiveConstString& name) const { return Get(name); } - [[nodiscard]] inline const T* operator[](uint32_t hashedKey) const { return Get(hashedKey); } - [[nodiscard]] inline const Arbutils::Collections::Dictionary& GetIterator() const { + [[nodiscard]] inline const std::shared_ptr& operator[](uint32_t hashedKey) const { + return Get(hashedKey); + } + [[nodiscard]] inline const Arbutils::Collections::Dictionary>& + GetIterator() const { return _values; } [[nodiscard]] size_t GetCount() const { return _values.Count(); } - inline const T* GetRandomValue(Arbutils::Random rand = Arbutils::Random()) const { + inline const std::shared_ptr& GetRandomValue(Arbutils::Random rand = Arbutils::Random()) const { auto i = rand.Get(_listValues.Count()); return _values[_listValues[i]]; } - inline const T* GetRandomValue(Arbutils::Random* rand) const { + inline const std::shared_ptr& GetRandomValue(Arbutils::Random* rand) const { auto i = rand->Get(_listValues.Count()); return _values[_listValues[i]]; }