#pragma once #include "RE/B/BGSKeyword.h" #include "RE/B/BSContainer.h" #include "RE/B/BSTArray.h" #include "RE/B/BaseFormComponent.h" #include "RE/I/IKeywordFormBase.h" namespace RE { class __declspec(novtable) BGSKeywordForm : public BaseFormComponent, // 00 public IKeywordFormBase // 08 { public: static constexpr auto RTTI{ RTTI::BGSKeywordForm }; static constexpr auto VTABLE{ VTABLE::BGSKeywordForm }; // override (BaseFormComponent) void InitializeDataComponent() override { return; } // 02 void ClearDataComponent() override; // 03 void InitComponent() override { return; } // 04 void CopyComponent(BaseFormComponent*) override; // 06 // override (IKeywordFormBase) bool HasKeyword(const BGSKeyword* a_keyword, const TBO_InstanceData* a_data = nullptr) const override; // 01 void CollectAllKeywords(BSScrapArray&, const TBO_InstanceData*) const override; // 02 // add virtual BGSKeyword* GetDefaultKeyword() const { return nullptr; } // 07 void CopyKeywords(const std::vector& a_copiedData); void AddKeyword(BGSKeyword* a_keyword) { using func_t = decltype(&BGSKeywordForm::AddKeyword); static REL::Relocation func{ ID::BGSKeywordForm::AddKeyword }; return func(this, a_keyword); } bool AddKeywords(const std::vector& a_keywords); [[nodiscard]] bool ContainsKeywordString(std::string_view a_editorID) const; [[nodiscard]] bool HasKeywordID(TESFormID a_formID) const; [[nodiscard]] bool HasKeywordString(std::string_view a_editorID) const; void ForEachKeyword(std::function a_callback) const { if (keywords) { for (std::uint32_t idx = 0; idx < numKeywords; ++idx) { if (keywords[idx] && a_callback(keywords[idx]) == BSContainer::ForEachResult::kStop) { return; } } } } [[nodiscard]] std::optional GetKeywordAt(std::uint32_t a_idx) const { if (a_idx < numKeywords) { return std::make_optional(keywords[a_idx]); } else { return std::nullopt; } } [[nodiscard]] std::optional GetKeywordIndex(BGSKeyword* a_keyword) const { if (keywords) { for (std::uint32_t i = 0; i < numKeywords; ++i) { if (keywords[i] == a_keyword) { return i; } } } return std::nullopt; } [[nodiscard]] std::uint32_t GetNumKeywords() const { return numKeywords; }; void RemoveKeyword(BGSKeyword* a_keyword) { using func_t = decltype(&BGSKeywordForm::RemoveKeyword); static REL::Relocation func{ ID::BGSKeywordForm::RemoveKeyword }; return func(this, a_keyword); } bool RemoveKeywords(const std::vector& a_keywords); // members BGSKeyword** keywords; // 10 std::uint32_t numKeywords; // 18 }; static_assert(sizeof(BGSKeywordForm) == 0x20); }