Last active
August 21, 2019 22:28
-
-
Save Nukem9/be036cc899dd5197bd9092b0ae2205b6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
std::unordered_map<uint32_t, const char *> g_EditorNameMap; | |
std::mutex g_NameMapLock; | |
// TESForm::GetName() is the vfunc at +0x130 | |
// TESForm::GetId() returns the form id | |
class TESForm : public BaseFormComponent | |
{ | |
public: | |
uint32_t GetId() const | |
{ | |
return *(uint32_t *)((uintptr_t)this + 0xC); | |
} | |
uint8_t GetType() const | |
{ | |
return *(uint8_t *)((uintptr_t)this + 0x4); | |
} | |
void hk_GetFullTypeName(char *Buffer, uint32_t BufferSize); | |
const char *hk_GetName(); | |
bool hk_SetEditorId(const char *Name); | |
}; | |
// vftable + 0x90 | |
void TESForm::hk_GetFullTypeName(char *Buffer, uint32_t BufferSize) | |
{ | |
const char *typeName = ((const char *(__thiscall *)(void *))(0x00440E30))(this); | |
_snprintf_s(Buffer, _TRUNCATE, BufferSize, "%s Form '%s' (%08X)", typeName, GetName(), GetId()); | |
} | |
// vftable + 0x130 | |
const char *TESForm::hk_GetName() | |
{ | |
std::lock_guard<std::mutex> lock(g_NameMapLock); | |
auto itr = g_EditorNameMap.find(GetId()); | |
if (itr != g_EditorNameMap.end()) | |
return itr->second; | |
// By default the game returns an empty string | |
return ""; | |
} | |
// vftable + 0x134 | |
bool TESForm::hk_SetEditorId(const char *Name) | |
{ | |
std::lock_guard<std::mutex> lock(g_NameMapLock); | |
g_EditorNameMap.insert(std::make_pair(GetId(), _strdup(Name))); | |
return true; | |
} | |
// 0x0055D480 | |
const char *TESObjectREFR::hk_GetName() | |
{ | |
if (!*(bool *)0x11C40C8) | |
{ | |
*(bool *)0x11C40C8 = true; | |
const char *name = GetName(); | |
*(bool *)0x11C40C8 = false; | |
if (name && strlen(name) > 0) | |
return name; | |
} | |
TESForm *base = GetBaseObject(); | |
// TESDataHandler::IsInitDone - omitted because I don't care | |
if (!base) | |
return ""; | |
const char *name = base->GetName(); | |
if (name && strlen(name) > 0) | |
return name; | |
// Now it tries fetching any ExtraData - omitted because I don't care | |
return ""; | |
} | |
// Example with TESWeather | |
WriteDword(0x0103168C + 0x90, &TESForm::hk_GetFullTypeName); | |
WriteDword(0x0103168C + 0x130, &TESForm::hk_GetName); | |
WriteDword(0x0103168C + 0x134, &TESForm::hk_SetEditorId); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment