@@ -10,7 +10,7 @@ namespace Hooks
10
10
static std::tuple<bool , bool , Biped> get_slot_info (const SlotKeyVec& a_vec, std::function<bool (Biped a_slot)> a_func)
11
11
{
12
12
for (const auto & data : a_vec | std::views::values) {
13
- const auto & [autoToggle, slots] = data;
13
+ const auto & [autoToggle, slots] = data;
14
14
for (auto & slot : slots) {
15
15
if (a_func (slot)) {
16
16
return { true , autoToggle, slot };
@@ -20,17 +20,6 @@ namespace Hooks
20
20
return { false , true , Biped::kNone };
21
21
}
22
22
23
- static std::pair<bool , bool > get_head_slots ()
24
- {
25
- for (auto & data : armorSlots | std::views::values) {
26
- const auto & [autoToggle, slots] = data;
27
- if (std::ranges::includes (slots, headSlots)) {
28
- return { true , autoToggle };
29
- }
30
- }
31
- return { false , false };
32
- }
33
-
34
23
static void hide_armor (const RE::BipedAnim* a_biped, RE::NiAVObject* a_object, std::int32_t a_slot)
35
24
{
36
25
if (const auto ref = a_biped->actorRef .get (); ref) {
@@ -41,7 +30,7 @@ namespace Hooks
41
30
auto [contains, autoToggle, matchingSlot] = get_slot_info (armorSlots, [&](const auto & b_slot) {
42
31
return b_slot == slot;
43
32
});
44
- if (contains && Graphics::Slot::get_toggle_data (root , slot, autoToggle)) {
33
+ if (contains && Graphics::Slot::get_toggle_data (actor , slot, autoToggle)) {
45
34
a_object->CullNode (true );
46
35
}
47
36
}
@@ -101,9 +90,9 @@ namespace Hooks
101
90
if (actor && Settings::GetSingleton ()->CanToggleEquipment (actor)) {
102
91
auto slot = static_cast <Biped>(a_slot);
103
92
auto [contains, autoToggle, matchingSlot] = detail::get_slot_info (weaponSlots, [&](const auto & b_slot) {
104
- return b_slot == slot;
93
+ return b_slot == slot;
105
94
});
106
- if (contains && Graphics::Slot::get_toggle_data (a_root3D , slot, autoToggle)) {
95
+ if (contains && Graphics::Slot::get_toggle_data (actor , slot, autoToggle)) {
107
96
object->CullNode (true );
108
97
}
109
98
}
@@ -122,7 +111,7 @@ namespace Hooks
122
111
123
112
switch (Settings::GetSingleton ()->autoToggleType ) {
124
113
case Type::kPlayerOnly :
125
- stl::write_thunk_call<AttachWeaponModelToActor>(target.address () + OFFSET (0x17F , 0x2B1 ));
114
+ stl::write_thunk_call<AttachWeaponModelToActor>(target.address () + OFFSET (0x17F , 0x2B1 ));
126
115
break ;
127
116
case Type::kFollowerOnly :
128
117
stl::write_thunk_call<AttachWeaponModelToActor>(target.address () + OFFSET (0x1D0 , 0x2FA ));
@@ -142,17 +131,17 @@ namespace Hooks
142
131
143
132
namespace Head
144
133
{
145
- struct GetRootNode
134
+ struct GetRootNode // HEAD
146
135
{
147
136
static RE::NiAVObject* thunk (RE::Actor* a_actor)
148
137
{
149
138
const auto root = func (a_actor);
150
139
151
140
if (a_actor && root && Settings::GetSingleton ()->CanToggleEquipment (a_actor)) {
152
- auto [contains, autoToggle ] = detail ::get_head_slots ();
153
- if (contains && Graphics::Slot::get_toggle_data (root , Biped::kHair , autoToggle)) {
154
- Graphics::Head::UpdateHair (a_actor, root , true );
155
- return nullptr ;
141
+ auto [autoToggle, slots ] = Graphics::Slot ::get_head_slots ();
142
+ if (!slots. empty () && Graphics::Slot::get_toggle_data (a_actor , Biped::kHead , autoToggle)) {
143
+ Graphics::Slot::ToggleActorHeadParts (a_actor, true );
144
+ return nullptr ;
156
145
}
157
146
}
158
147
@@ -165,20 +154,17 @@ namespace Hooks
165
154
{
166
155
static void thunk (RE::BipedAnim* a_biped, RE::NiAVObject* a_geometry, std::uint32_t a_slot)
167
156
{
168
- if (a_biped) {
169
- if (const auto ref = a_biped->actorRef .get (); ref) {
170
- const auto actor = ref->As <RE::Actor>();
171
- if (actor && Settings::GetSingleton ()->CanToggleEquipment (actor)) {
172
- if (const auto root = a_biped->root ; root) {
173
- auto slot = static_cast <Biped>(a_slot);
174
- auto [contains, autoToggle, matchingSlot] = detail::get_slot_info (armorSlots, [&slot](const auto & b_slot) {
175
- return slot = b_slot;
176
- });
177
- if (contains && Graphics::Slot::get_toggle_data (root, slot, autoToggle)) {
178
- Graphics::Head::UpdateFacePartitions (actor, a_geometry, slot, true );
179
- return ;
180
- }
181
- }
157
+ const auto ref = a_biped ? a_biped->actorRef .get () : RE::NiPointer<RE::TESObjectREFR>();
158
+ const auto actor = ref ? ref->As <RE::Actor>() : nullptr ;
159
+
160
+ if (a_biped && actor && Settings::GetSingleton ()->CanToggleEquipment (actor)) {
161
+ if (const auto root = a_biped->root ; root) {
162
+ auto slot = static_cast <Biped>(a_slot);
163
+ auto [contains, autoToggle, matchingSlot] = detail::get_slot_info (armorSlots, [&slot](const auto & b_slot) {
164
+ return slot = b_slot;
165
+ });
166
+ if (contains && Graphics::Slot::get_toggle_data (actor, slot, autoToggle)) {
167
+ return ;
182
168
}
183
169
}
184
170
}
@@ -193,7 +179,7 @@ namespace Hooks
193
179
REL::Relocation<std::uintptr_t > UpdateHairAndHead{ RELOCATION_ID (24220 , 24724 ), OFFSET (0x1A , 0x19 ) };
194
180
stl::write_thunk_call<GetRootNode>(UpdateHairAndHead.address ());
195
181
196
- REL::Relocation<std::uintptr_t > ProcessArmorDismemberment{ RELOCATION_ID (15539 , 15715 ), OFFSET (0x70 , 0x2C2 ) }; // everything got inlined in AE
182
+ REL::Relocation<std::uintptr_t > ProcessArmorDismemberment{ RELOCATION_ID (15539 , 15715 ), OFFSET (0x70 , 0x2C2 ) }; // everything got inlined in AE
197
183
stl::write_thunk_call<UpdateDismemberPartition>(ProcessArmorDismemberment.address ());
198
184
}
199
185
}
0 commit comments