From 893d569529724dc2cf782a34d0f8c832c0c9b72b Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Wed, 1 Dec 2021 18:21:21 +0100 Subject: [PATCH 1/2] Force the loot UI open if it was open while resurrecting the lootee --- apps/openmw/mwbase/windowmanager.hpp | 1 + apps/openmw/mwgui/container.cpp | 5 ++++- apps/openmw/mwgui/container.hpp | 3 ++- apps/openmw/mwgui/windowmanagerimp.cpp | 21 +++++++++++++++++---- apps/openmw/mwgui/windowmanagerimp.hpp | 4 ++++ apps/openmw/mwscript/statsextensions.cpp | 7 ++++++- 6 files changed, 34 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 961a63ac79..958bb466ab 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -355,6 +355,7 @@ namespace MWBase virtual const std::string& getVersionDescription() const = 0; virtual void onDeleteCustomData(const MWWorld::Ptr& ptr) = 0; + virtual void forceLootMode(const MWWorld::Ptr& ptr) = 0; }; } diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index de771051ef..fdfd192cc1 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -38,6 +38,7 @@ namespace MWGui , mSortModel(nullptr) , mModel(nullptr) , mSelectedItem(-1) + , mTreatNextOpenAsLoot(false) { getWidget(mDisposeCorpseButton, "DisposeCorpseButton"); getWidget(mTakeButton, "TakeButton"); @@ -121,13 +122,15 @@ namespace MWGui void ContainerWindow::setPtr(const MWWorld::Ptr& container) { + bool lootAnyway = mTreatNextOpenAsLoot; + mTreatNextOpenAsLoot = false; mPtr = container; bool loot = mPtr.getClass().isActor() && mPtr.getClass().getCreatureStats(mPtr).isDead(); if (mPtr.getClass().hasInventoryStore(mPtr)) { - if (mPtr.getClass().isNpc() && !loot) + if (mPtr.getClass().isNpc() && !loot && !lootAnyway) { // we are stealing stuff mModel = new PickpocketItemModel(mPtr, new InventoryItemModel(container), diff --git a/apps/openmw/mwgui/container.hpp b/apps/openmw/mwgui/container.hpp index 2a0dee44e2..66a20e7ef5 100644 --- a/apps/openmw/mwgui/container.hpp +++ b/apps/openmw/mwgui/container.hpp @@ -37,6 +37,7 @@ namespace MWGui void onDeleteCustomData(const MWWorld::Ptr& ptr) override; + void treatNextOpenAsLoot() { mTreatNextOpenAsLoot = true; }; private: DragAndDrop* mDragAndDrop; @@ -44,7 +45,7 @@ namespace MWGui SortFilterItemModel* mSortModel; ItemModel* mModel; int mSelectedItem; - + bool mTreatNextOpenAsLoot; MyGUI::Button* mDisposeCorpseButton; MyGUI::Button* mTakeButton; MyGUI::Button* mCloseButton; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index a935d7f900..3417fb479b 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -165,6 +165,7 @@ namespace MWGui , mScreenFader(nullptr) , mDebugWindow(nullptr) , mJailScreen(nullptr) + , mContainerWindow(nullptr) , mTranslationDataStorage (translationDataStorage) , mCharGen(nullptr) , mInputBlocker(nullptr) @@ -360,10 +361,10 @@ namespace MWGui mGuiModeStates[GM_Dialogue] = GuiModeState(mDialogueWindow); mTradeWindow->eventTradeDone += MyGUI::newDelegate(mDialogueWindow, &DialogueWindow::onTradeComplete); - ContainerWindow* containerWindow = new ContainerWindow(mDragAndDrop); - mWindows.push_back(containerWindow); - trackWindow(containerWindow, "container"); - mGuiModeStates[GM_Container] = GuiModeState({containerWindow, mInventoryWindow}); + mContainerWindow = new ContainerWindow(mDragAndDrop); + mWindows.push_back(mContainerWindow); + trackWindow(mContainerWindow, "container"); + mGuiModeStates[GM_Container] = GuiModeState({mContainerWindow, mInventoryWindow}); mHud = new HUD(mCustomMarkers, mDragAndDrop, mLocalMapRender); mWindows.push_back(mHud); @@ -1166,6 +1167,16 @@ namespace MWGui } void WindowManager::pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg) + { + pushGuiMode(mode, arg, false); + } + + void WindowManager::forceLootMode(const MWWorld::Ptr& ptr) + { + pushGuiMode(MWGui::GM_Container, ptr, true); + } + + void WindowManager::pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg, bool force) { if (mode==GM_Inventory && mAllowed==GW_None) return; @@ -1188,6 +1199,8 @@ namespace MWGui mGuiModeStates[mode].update(true); playSound(mGuiModeStates[mode].mOpenSound); } + if(force) + mContainerWindow->treatNextOpenAsLoot(); for (WindowBase* window : mGuiModeStates[mode].mWindows) window->setPtr(arg); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 9ec79e0c82..f68592cb5d 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -389,6 +389,7 @@ namespace MWGui const std::string& getVersionDescription() const override; void onDeleteCustomData(const MWWorld::Ptr& ptr) override; + void forceLootMode(const MWWorld::Ptr& ptr) override; private: unsigned int mOldUpdateMask; unsigned int mOldCullMask; @@ -447,6 +448,7 @@ namespace MWGui ScreenFader* mScreenFader; DebugWindow* mDebugWindow; JailScreen* mJailScreen; + ContainerWindow* mContainerWindow; std::vector mWindows; @@ -573,6 +575,8 @@ namespace MWGui void enableScene(bool enable); void handleScheduledMessageBoxes(); + + void pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg, bool force); }; } diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index ccad186a0d..c53588ed22 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -1195,7 +1195,9 @@ namespace MWScript bool wasEnabled = ptr.getRefData().isEnabled(); MWBase::Environment::get().getWorld()->undeleteObject(ptr); MWBase::Environment::get().getWorld()->removeContainerScripts(ptr); - MWBase::Environment::get().getWindowManager()->onDeleteCustomData(ptr); + auto windowManager = MWBase::Environment::get().getWindowManager(); + bool wasOpen = windowManager->containsMode(MWGui::GM_Container); + windowManager->onDeleteCustomData(ptr); // HACK: disable/enable object to re-add it to the scene properly (need a new Animation). MWBase::Environment::get().getWorld()->disable(ptr); @@ -1203,6 +1205,9 @@ namespace MWScript ptr.getRefData().setCustomData(nullptr); if (wasEnabled) MWBase::Environment::get().getWorld()->enable(ptr); + // Reopen the loot GUI if it was closed because we resurrected the actor we were looting + if (wasOpen && !windowManager->containsMode(MWGui::GM_Container)) + windowManager->forceLootMode(ptr); } } }; From 58b888a38ee7a59fd6402b0978220c299bc34c22 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Thu, 2 Dec 2021 20:36:42 +0100 Subject: [PATCH 2/2] Preserve inventories when resurrecting actors while looting them --- apps/openmw/mwscript/statsextensions.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index c53588ed22..d7120af53a 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -1194,20 +1194,25 @@ namespace MWScript { bool wasEnabled = ptr.getRefData().isEnabled(); MWBase::Environment::get().getWorld()->undeleteObject(ptr); - MWBase::Environment::get().getWorld()->removeContainerScripts(ptr); auto windowManager = MWBase::Environment::get().getWindowManager(); bool wasOpen = windowManager->containsMode(MWGui::GM_Container); windowManager->onDeleteCustomData(ptr); - // HACK: disable/enable object to re-add it to the scene properly (need a new Animation). MWBase::Environment::get().getWorld()->disable(ptr); - // resets runtime state such as inventory, stats and AI. does not reset position in the world - ptr.getRefData().setCustomData(nullptr); + if (wasOpen && !windowManager->containsMode(MWGui::GM_Container)) + { + // Reopen the loot GUI if it was closed because we resurrected the actor we were looting + MWBase::Environment::get().getMechanicsManager()->resurrect(ptr); + windowManager->forceLootMode(ptr); + } + else + { + MWBase::Environment::get().getWorld()->removeContainerScripts(ptr); + // resets runtime state such as inventory, stats and AI. does not reset position in the world + ptr.getRefData().setCustomData(nullptr); + } if (wasEnabled) MWBase::Environment::get().getWorld()->enable(ptr); - // Reopen the loot GUI if it was closed because we resurrected the actor we were looting - if (wasOpen && !windowManager->containsMode(MWGui::GM_Container)) - windowManager->forceLootMode(ptr); } } };