#pragma once #include "Util.h" inline bool bTabBlocked = false; class DialogueMenuPatch final : public RE::DialogueMenu { public: static void Install() { REL::Relocation vtbl(RE::VTABLE_DialogueMenu[0]); _ProcessMessageFn = vtbl.write_vfunc(0x4, &ProcessMessageEx); } static void BlockTab(bool a_block = true) { bTabBlocked = a_block; } private: RE::UI_MESSAGE_RESULTS ProcessMessageEx(RE::UIMessage& a_message) { if (bTabBlocked && a_message.type == RE::UI_MESSAGE_TYPE::kScaleformEvent) { RE::BSUIScaleformData* data = static_cast(a_message.data); if (data && data->scaleformEvent->type == RE::GFxEvent::EventType::kKeyDown) { RE::GFxKeyEvent* key = (RE::GFxKeyEvent*)data->scaleformEvent; // Escape triggers a kTab event, added kEscape just in case if (key && (key->keyCode == RE::GFxKey::kTab || key->keyCode == RE::GFxKey::kEscape) && !RE::UI::GetSingleton()->IsMenuOpen(RE::ContainerMenu::MENU_NAME) && !RE::UI::GetSingleton()->IsMenuOpen(RE::BarterMenu::MENU_NAME)) { OpenJournal(false); return RE::UI_MESSAGE_RESULTS::kIgnore; } } } return _ProcessMessageFn(this, a_message); } using ProcessMessageFn = decltype(&RE::DialogueMenu::ProcessMessage); inline static REL::Relocation _ProcessMessageFn; };