Skip to content

Commit 60420af

Browse files
authored
feat: merge pr #16 from Zzyxz/main
Updated Members and added functions: addKeyword and removeKeyword
2 parents 56aafd5 + 83bc6a6 commit 60420af

1 file changed

Lines changed: 73 additions & 7 deletions

File tree

include/RE/B/BGSTypedKeywordValueArray.h

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ namespace RE
3333
class BGSTypedKeywordValue
3434
{
3535
public:
36-
// members
3736
std::uint16_t keywordIndex; // 0
37+
std::uint16_t pad02; // 2
38+
std::uint32_t pad04; // 4
3839
};
40+
static_assert(sizeof(BGSTypedKeywordValue<KeywordType::kNone>) == 0x8);
3941

4042
namespace detail
4143
{
@@ -48,19 +50,83 @@ namespace RE
4850
public:
4951
[[nodiscard]] bool HasKeyword(BGSKeyword* a_keyword)
5052
{
51-
for (std::uint32_t i = 0; i < size; ++i) {
52-
const auto kywd = detail::BGSKeywordGetTypedKeywordByIndex(TYPE, array[i].keywordIndex);
53+
if (!a_keyword) {
54+
return false;
55+
}
56+
57+
for (auto it = begin; it != end; ++it) {
58+
const auto kywd = detail::BGSKeywordGetTypedKeywordByIndex(TYPE, it->keywordIndex);
5359
if (kywd == a_keyword) {
5460
return true;
5561
}
5662
}
5763
return false;
5864
}
5965

60-
// members
61-
BGSTypedKeywordValue<TYPE>* array; // 00
62-
std::uint32_t size; // 08
63-
std::uint64_t unk10; // 10
66+
[[nodiscard]] bool AddKeyword(BGSKeyword* a_keyword)
67+
{
68+
if (!a_keyword) {
69+
return false;
70+
}
71+
72+
auto first = reinterpret_cast<BGSKeyword**>(begin);
73+
auto last = reinterpret_cast<BGSKeyword**>(end);
74+
75+
for (auto it = first; it != last; ++it) {
76+
if (*it && (*it)->formID == a_keyword->formID) {
77+
return false;
78+
}
79+
}
80+
81+
const auto oldSize = static_cast<std::size_t>(last - first);
82+
const auto newSize = oldSize + 1;
83+
84+
auto* newData = static_cast<BGSKeyword**>(
85+
RE::MemoryManager::GetSingleton()->Allocate(sizeof(BGSKeyword*) * newSize, 0, false));
86+
87+
if (!newData) {
88+
return false;
89+
}
90+
91+
for (std::size_t i = 0; i < oldSize; ++i) {
92+
newData[i] = first[i];
93+
}
94+
95+
newData[oldSize] = a_keyword;
96+
auto oldFirst = first;
97+
auto oldLast = last;
98+
auto oldCap = reinterpret_cast<BGSKeyword**>(capacityEnd);
99+
100+
begin = reinterpret_cast<BGSTypedKeywordValue<TYPE>*>(newData);
101+
end = reinterpret_cast<BGSTypedKeywordValue<TYPE>*>(newData + newSize);
102+
capacityEnd = reinterpret_cast<BGSTypedKeywordValue<TYPE>*>(newData + newSize);
103+
return true;
104+
}
105+
106+
[[nodiscard]] bool RemoveKeyword(BGSKeyword* a_keyword)
107+
{
108+
if (!a_keyword) {
109+
return false;
110+
}
111+
auto first = reinterpret_cast<BGSKeyword**>(begin);
112+
auto last = reinterpret_cast<BGSKeyword**>(end);
113+
for (auto it = first; it != last; ++it) {
114+
if (*it && (*it)->formID == a_keyword->formID) {
115+
for (auto jt = it; jt + 1 != last; ++jt) {
116+
*jt = *(jt + 1);
117+
}
118+
--last;
119+
*last = nullptr;
120+
end = reinterpret_cast<BGSTypedKeywordValue<TYPE>*>(last);
121+
return true;
122+
}
123+
}
124+
return false;
125+
}
126+
127+
BGSTypedKeywordValue<TYPE>* begin; // 00
128+
BGSTypedKeywordValue<TYPE>* end; // 08
129+
BGSTypedKeywordValue<TYPE>* capacityEnd; // 10
64130
};
65131
static_assert(sizeof(BGSTypedKeywordValueArray<KeywordType::kNone>) == 0x18);
66132
}

0 commit comments

Comments
 (0)