Skip to content

Commit 076f0aa

Browse files
authored
hopefully fix recursive setnodetransforms bug
1 parent 11b9cc1 commit 076f0aa

1 file changed

Lines changed: 37 additions & 27 deletions

File tree

src/GameEventHandler.cpp

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ std::recursive_mutex morph_task_mutex;
4242
std::recursive_mutex qupdatenormalmap_lock;
4343
std::recursive_mutex loading_game_mutex;
4444
std::recursive_mutex custom_main_task_pool_lock;
45-
static void* nitransforminterface=nullptr;
45+
static void* nitransforminterface = nullptr;
4646
std::uint64_t qupdatenormalmap_recursion = 0;
4747
std::queue<std::function<void()>> custom_main_task_pool;
4848
auto original_process_task = (void (*)(void* main, void* arg2, void* arg3, void* arg4)) nullptr;
@@ -856,44 +856,57 @@ namespace plugin {
856856
}
857857
}
858858
}
859-
859+
static std::atomic_int32_t setnodetransformhook_norecursion=0;
860860
static void SetNodeTransformsHook_fn(void* arg1, uint32_t formID, uint64_t immediate, bool reset) {
861861
if (PARALLEL_TRANSFORM_FIX) {
862+
auto original_recursion = setnodetransformhook_norecursion.fetch_add(1);
863+
if (original_recursion != 0) {
864+
setnodetransformhook_norecursion.fetch_sub(1);
865+
return;
866+
} else {
867+
setnodetransformhook_norecursion.fetch_sub(1);
868+
}
862869
if (auto task_int = SKSE::GetTaskInterface()) {
863870
immediate = true;
864871
if (!is_main_thread()) {
865-
AddMainTask(
866-
[arg1 = arg1, arg2 = formID, arg3 = immediate, arg4 = reset] {
867-
if (auto arg2_form = RE::TESForm::LookupByID(arg2)) {
868-
if (auto actor = arg2_form->As<RE::Actor>()) {
869-
if (!actor->Is3DLoaded()) {
870-
logger::warn("Loading 3D for node transform");
871-
actor->Load3D(true);
872-
}
872+
AddMainTask([arg1 = arg1, arg2 = formID, arg3 = immediate, arg4 = reset] {
873+
if (auto arg2_form = RE::TESForm::LookupByID(arg2)) {
874+
if (auto actor = arg2_form->As<RE::Actor>()) {
875+
if (!actor->Is3DLoaded()) {
876+
logger::warn("Loading 3D for node transform");
877+
setnodetransformhook_norecursion.fetch_add(1);
878+
actor->Load3D(true);
879+
setnodetransformhook_norecursion.fetch_sub(1);
873880
}
874881
}
875-
SetNodeTransformsHook(arg1, arg2, arg3, arg4);
876-
877-
});
882+
}
883+
setnodetransformhook_norecursion.fetch_add(1);
884+
SetNodeTransformsHook(arg1, arg2, arg3, arg4);
885+
setnodetransformhook_norecursion.fetch_sub(1);
886+
});
878887
} else {
879888
AddMainTask([arg1 = arg1, arg2 = formID, arg3 = immediate, arg4 = reset] {
880889
if (auto arg2_form = RE::TESForm::LookupByID(arg2)) {
881890
if (auto actor = arg2_form->As<RE::Actor>()) {
882891
if (!actor->Is3DLoaded()) {
883892
logger::warn("Loading 3D for node transform");
893+
setnodetransformhook_norecursion.fetch_add(1);
884894
actor->Load3D(true);
895+
setnodetransformhook_norecursion.fetch_sub(1);
885896
}
886897
}
887898
}
899+
setnodetransformhook_norecursion.fetch_add(1);
888900
SetNodeTransformsHook(arg1, arg2, arg3, arg4);
901+
setnodetransformhook_norecursion.fetch_sub(1);
889902
});
890903
}
891904
}
892905
} else {
893906
SetNodeTransformsHook(arg1, formID, immediate, reset);
894907
}
895908
}
896-
909+
897910
static void UpdateNodeTransformsHook_fn(void* arg1, RE::TESObjectREFR* ref, bool firstperson, bool gender,
898911
const SKEEString* node_string) {
899912
if (PARALLEL_TRANSFORM_FIX && !is_main_thread()) {
@@ -1420,21 +1433,21 @@ namespace plugin {
14201433
DetourTransactionCommit();
14211434
if (PARALLEL_TRANSFORM_FIX) {
14221435
logger::info("SKEE64 1170 parallel node transform workaround applying");
1423-
nitransforminterface =(void*) (((uint64_t) skee64_info.lpBaseOfDll) + 0x230810);
1436+
nitransforminterface = (void*) (((uint64_t) skee64_info.lpBaseOfDll) + 0x230810);
14241437
UpdateNodeTransformsHook = (void (*)(void*, RE::TESObjectREFR*, bool, bool, const SKEEString* node_name))(
14251438
(uint64_t) skee64_info.lpBaseOfDll + 0xc68d0);
14261439
DetourTransactionBegin();
14271440
DetourUpdateThread(GetCurrentThread());
14281441
DetourAttach(&(PVOID&) UpdateNodeTransformsHook, &UpdateNodeTransformsHook_fn);
14291442
DetourTransactionCommit();
1430-
1443+
14311444
SetNodeTransformsHook = (void (*)(void* arg1, uint32_t formID, uint64_t immediate, bool reset))(
14321445
(uint64_t) skee64_info.lpBaseOfDll + 0xc72c0);
14331446
DetourTransactionBegin();
14341447
DetourUpdateThread(GetCurrentThread());
14351448
DetourAttach(&(PVOID&) SetNodeTransformsHook, &SetNodeTransformsHook_fn);
14361449
DetourTransactionCommit();
1437-
1450+
14381451
SkeletonOnAttachHook = (void (*)(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, bool arg6, void* arg7,
14391452
void* arg8))((uint64_t) skee64_info.lpBaseOfDll + 0x133330);
14401453
DetourTransactionBegin();
@@ -1567,14 +1580,14 @@ namespace plugin {
15671580
DetourUpdateThread(GetCurrentThread());
15681581
DetourAttach(&(PVOID&) UpdateNodeTransformsHook, &UpdateNodeTransformsHook_fn);
15691582
DetourTransactionCommit();
1570-
1583+
15711584
SetNodeTransformsHook = (void (*)(void* arg1, uint32_t formID, uint64_t immediate, bool reset))(
15721585
(uint64_t) skee64_info.lpBaseOfDll + 0xcad50);
15731586
DetourTransactionBegin();
15741587
DetourUpdateThread(GetCurrentThread());
15751588
DetourAttach(&(PVOID&) SetNodeTransformsHook, &SetNodeTransformsHook_fn);
15761589
DetourTransactionCommit();
1577-
1590+
15781591
SkeletonOnAttachHook = (void (*)(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, bool arg6, void* arg7,
15791592
void* arg8))((uint64_t) skee64_info.lpBaseOfDll + 0x1382a0);
15801593
DetourTransactionBegin();
@@ -1954,14 +1967,14 @@ namespace plugin {
19541967
DetourUpdateThread(GetCurrentThread());
19551968
DetourAttach(&(PVOID&) UpdateNodeTransformsHook, &UpdateNodeTransformsHook_fn);
19561969
DetourTransactionCommit();
1957-
1970+
19581971
SetNodeTransformsHook = (void (*)(void* arg1, uint32_t formID, uint64_t immediate, bool reset))(
19591972
(uint64_t) skee64_info.lpBaseOfDll + 0x97290);
19601973
DetourTransactionBegin();
19611974
DetourUpdateThread(GetCurrentThread());
19621975
DetourAttach(&(PVOID&) SetNodeTransformsHook, &SetNodeTransformsHook_fn);
19631976
DetourTransactionCommit();
1964-
1977+
19651978
SkeletonOnAttachHook = (void (*)(void* arg1, void* arg2, void* arg3, void* arg4, void* arg5, bool arg6, void* arg7,
19661979
void* arg8))((uint64_t) skee64_info.lpBaseOfDll + 0xfcb40);
19671980
DetourTransactionBegin();
@@ -2159,7 +2172,6 @@ namespace plugin {
21592172
DetourAttach(&(PVOID&) UpdateNodeTransformsHook, &UpdateNodeTransformsHook_fn);
21602173
DetourTransactionCommit();
21612174

2162-
21632175
SetNodeTransformsHook = (void (*)(void* arg1, uint32_t formID, uint64_t immediate, bool reset))(
21642176
(uint64_t) skee64_info.lpBaseOfDll + 0x7d7f0);
21652177
DetourTransactionBegin();
@@ -2377,15 +2389,13 @@ namespace plugin {
23772389
a_event->cell->ForEachReference([](RE::TESObjectREFR* ref) {
23782390
if (auto actor = ref->As<RE::Actor>()) {
23792391
if (!actor->Is3DLoaded()) {
2380-
logger::warn("Loading 3D for node transform");
2381-
actor->Load3D(false);
2392+
//logger::warn("Loading 3D for node transform");
2393+
//actor->Load3D(false);
23822394
}
23832395
if (RE::PlayerCharacter::GetSingleton()) {
23842396
RE::FormID fid = actor->formID;
23852397
if (nitransforminterface) {
2386-
AddMainTask([fid]() {
2387-
SetNodeTransformsHook_fn(nitransforminterface, (uint32_t) fid, true, false);
2388-
});
2398+
AddMainTask([fid]() { SetNodeTransformsHook_fn(nitransforminterface, (uint32_t) fid, true, false); });
23892399
}
23902400
}
23912401
}

0 commit comments

Comments
 (0)