Skip to content

Commit e0714e2

Browse files
marthofdoomclaude
andcommitted
DIAG v10: fix SNDR resolution (typed BSISoundDescriptor cast, not void*)
The CommonLib header settled it: BGSSoundDescriptorForm multiply-inherits BSISoundDescriptor at +0x28 (TESForm is the offset-0 base), and the inner BGSSoundDescriptor is-a BSISoundDescriptor at offset 0. So the descriptor the game passes is either form+0x28 or the inner descriptor. v8/v9 compared void* of the form base (offset 0), which never matches form+0x28 -> SNDR 00000000. v10 compares static_cast<BSISoundDescriptor*>(snd) and static_cast<BSISoundDescriptor*>(snd->soundDescriptor) against a_desc, letting the compiler apply the base adjustment. Now the enchant SFX resolves to its real FormID + editorID -> the target for the static dummy-replace. vtbl dump retained as backup. Still pure log-only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent b40d1c2 commit e0714e2

1 file changed

Lines changed: 10 additions & 2 deletions

File tree

native/plugin.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5770,13 +5770,21 @@ namespace sndhook {
57705770
// at most 12 times total, never at shutdown since it's in-window only).
57715771
// Match either the form pointer itself OR its inner soundDescriptor —
57725772
// PlaySound may hand us either.
5773+
// BGSSoundDescriptorForm multiply-inherits BSISoundDescriptor at +0x28, and
5774+
// its inner BGSSoundDescriptor also IS-A BSISoundDescriptor (at offset 0). The
5775+
// game may hand BuildSound EITHER subobject, so compare with proper typed casts
5776+
// (the compiler applies the base-offset adjustment) — a void* compare misses the
5777+
// form-subobject case, which is what left v8/v9 at SNDR 00000000.
57735778
std::uint32_t fid = 0;
57745779
const char* edid = "";
57755780
void* dp = static_cast<void*>(a_desc);
57765781
if (auto* dh = RE::TESDataHandler::GetSingleton()) {
57775782
for (auto* snd : dh->GetFormArray<RE::BGSSoundDescriptorForm>()) {
5778-
if (snd && (static_cast<void*>(snd) == dp ||
5779-
static_cast<void*>(snd->soundDescriptor) == dp)) {
5783+
if (!snd) continue;
5784+
const bool hitForm = static_cast<RE::BSISoundDescriptor*>(snd) == a_desc;
5785+
const bool hitInner = snd->soundDescriptor &&
5786+
static_cast<RE::BSISoundDescriptor*>(snd->soundDescriptor) == a_desc;
5787+
if (hitForm || hitInner) {
57805788
fid = snd->GetFormID();
57815789
edid = snd->GetFormEditorID();
57825790
break;

0 commit comments

Comments
 (0)