Fantafaust Posted April 27, 2023 Share Posted April 27, 2023 I want to play a holotape from another inventory, like Hud Plus Plus does. Sadly Hud Plus Plus has many issues and causes the game to crash, and I'm not really interested in its other functions. But its source code is available, so is it possible to make this function, PlayHolotape, into a standalone F4SE papyrus function via plugin?I do not have a setup for F4SE plugin compiling, and this is the only function holding me back from a release of my mod, everything else is ready to go.Relevant info below.From Defination.cpp: elocAddr<_PlayHolotape> PlayHolotape = 0xB8EC70; // called by pipboy menu. From ScaleForm.cpp: class InputControl : public BSInputEventUser { public: InputControl() : BSInputEventUser(true) {} virtual ~InputControl() {} virtual bool IsEnabled(InputEvent * inputEvent) override { if (inputEvent->eventType == InputEvent::kEventType_Button) return true; //_MESSAGE("controlID: %s | %d", inputEvent->GetControlID()->c_str(), inputEvent->eventType); return false; }; virtual void OnButtonEvent(ButtonEvent * inputEvent) override { UInt32 keyCode; UInt32 deviceType = inputEvent->deviceType; UInt32 keyMask = inputEvent->keyMask; if ((*g_ui) && (*g_ui)->menuMode) return; // Mouse if (deviceType == InputEvent::kDeviceType_Mouse) keyCode = InputMap::kMacro_MouseButtonOffset + keyMask; // Gamepad else if (deviceType == InputEvent::kDeviceType_Gamepad) keyCode = InputMap::GamepadMaskToKeycode(keyMask); // Keyboard else keyCode = keyMask; //ESSAGE("keyCode=%d", keyCode); if (keyCode == ModSettings::iQuickUseHotkey && inputEvent->IsDown()) { if ((*g_HUDDataModel) != nullptr) { auto pQC = (*g_HUDDataModel)->GetQCData(); TESObjectREFR * pRef = nullptr; LookupREFRByHandle(&pQC->refHandle, &pRef); if (pRef != nullptr) { SimpleLocker locker(&g_quickContainerLock); TESForm * pForm = nullptr; BGSInventoryItem::Stack * pStack = nullptr; bool tlsState[2]; RelocAddr<void(*)(bool[], bool, bool)> IncTLSRef = 0xEC0180; IncTLSRef(tlsState, true, false); if ((pQC->type == 0 || pQC->type == 6) && pQC->dataLen && pQC->selectedIndex >= 0\ && !pQC->unk228 && pQC->selectedIndex < pQC->dataLen) { auto pEntry = &pQC->entry[pQC->selectedIndex]; RelocAddr<TESForm*(*)(uintptr_t, HUDQuickContainerDataModel::Entry*)> GetSelectedForm = 0x1A3740; pForm = GetSelectedForm((*RelocPtr<uintptr_t>(0x58F2D80)), pEntry); if (pForm != nullptr) { RelocAddr<BGSInventoryItem *(*)(uintptr_t, HUDQuickContainerDataModel::Entry*)> GetSelectedInventoryItem = 0x1A3650; auto pItem = GetSelectedInventoryItem((*RelocPtr<uintptr_t>(0x58F2D80)), pEntry); SInt16 stackIndex = (pEntry->flags & 0x80000000) ? pEntry->stackIndex.index : (*pEntry->stackIndex.indexs); auto GetStack = [](BGSInventoryItem * pItem, SInt16 index)->BGSInventoryItem::Stack * { if (!pItem->stack) return nullptr; auto pStack = pItem->stack; while (index-- && (pStack = pStack->next, pStack)) {} return pStack; }; pStack = GetStack(pItem, stackIndex); } } if (pForm != nullptr && pForm->formType == kFormType_NOTE) { auto pNote = static_cast<BGSNote*>(pForm); if (pNote->holotapeType == BGSNote::kNote_SECN \ || pNote->holotapeType > 3) { //need to check whether activate is disabled... (*g_player)->StopPlayHolotape(false); (*g_player)->note = pNote; (*g_player)->PlayHolotape(pNote); //without animation. } else if ((*g_pipboyManager) != nullptr) { (*g_player)->StopPlayHolotape(false); (*g_player)->note = pNote; (*g_pipboyManager)->PlayHolotape(pNote, false); //with animation. } //pQC->PickUpItem(); //mutex lock. } if (pForm && pForm->formType == kFormType_BOOK && pStack && pStack->extraData) { BSString str; auto pBook = static_cast<TESObjectBOOK*>(pForm); if (pBook->flags & TESObjectBOOK::kType_Read || !(pBook->flags & TESObjectBOOK::kType_AddPerk)) { auto pDesc = &(pBook->description); pDesc->Get(str, nullptr); NiNode* pNode = (*g_player)->GetObjectRootNode(); DisplayBookMenu(str, pStack->extraData, nullptr, pBook, pNode->m_worldTransform.pos, pNode->m_worldTransform.rot, pNode->m_localTransform.scale, false); } } RelocAddr<void(*)(bool[])> DecTLSRef = 0xEC01D0; DecTLSRef(tlsState); pRef->handleRefObject.DecRefHandle(); pQC->PickUpItem(); } } } }; static void Register() { if (!(*g_menuControls)) { _MESSAGE("failed to find menu input controller..."); return; } static BSInputEventUser * pInputHandler = new InputControl(); tArray<BSInputEventUser*>& inputEvents = (*g_menuControls)->inputEvents; SInt64 index = inputEvents.GetItemIndex(pInputHandler); if (index == -1) { inputEvents.Push(pInputHandler); } } }; Link to comment Share on other sites More sharing options...
Recommended Posts