diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index 7262d945c5..ab0aa6c890 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -243,6 +243,7 @@ namespace MWLua void LuaManager::applyDelayedActions() { + mApplyingDelayedActions = true; for (DelayedAction& action : mActionQueue) action.apply(); mActionQueue.clear(); @@ -250,6 +251,7 @@ namespace MWLua if (mTeleportPlayerAction) mTeleportPlayerAction->apply(); mTeleportPlayerAction.reset(); + mApplyingDelayedActions = false; } void LuaManager::clear() @@ -318,7 +320,7 @@ namespace MWLua return; PlayerScripts* playerScripts = dynamic_cast(mPlayer.getRefData().getLuaScripts()); if (playerScripts) - playerScripts->uiModeChanged(arg); + playerScripts->uiModeChanged(arg, mApplyingDelayedActions); } void LuaManager::objectAddedToScene(const MWWorld::Ptr& ptr) @@ -558,6 +560,8 @@ namespace MWLua void LuaManager::addAction(std::function action, std::string_view name) { + if (mApplyingDelayedActions) + throw std::runtime_error("DelayedAction is not allowed to create another DelayedAction"); mActionQueue.emplace_back(&mLua, std::move(action), name); } diff --git a/apps/openmw/mwlua/luamanagerimp.hpp b/apps/openmw/mwlua/luamanagerimp.hpp index 03efa3f066..c14c9ace5b 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -153,6 +153,7 @@ namespace MWLua bool mInitialized = false; bool mGlobalScriptsStarted = false; bool mProcessingInputEvents = false; + bool mApplyingDelayedActions = false; bool mNewGameStarted = false; LuaUtil::ScriptsConfiguration mConfiguration; LuaUtil::LuaState mLua; diff --git a/apps/openmw/mwlua/playerscripts.hpp b/apps/openmw/mwlua/playerscripts.hpp index de48064734..e8cad4968c 100644 --- a/apps/openmw/mwlua/playerscripts.hpp +++ b/apps/openmw/mwlua/playerscripts.hpp @@ -66,12 +66,12 @@ namespace MWLua } // `arg` is either forwarded from MWGui::pushGuiMode or empty - void uiModeChanged(const MWWorld::Ptr& arg) + void uiModeChanged(const MWWorld::Ptr& arg, bool byLuaAction) { if (arg.isEmpty()) - callEngineHandlers(mUiModeChanged); + callEngineHandlers(mUiModeChanged, byLuaAction); else - callEngineHandlers(mUiModeChanged, LObject(arg)); + callEngineHandlers(mUiModeChanged, byLuaAction, LObject(arg)); } private: diff --git a/files/data/scripts/omw/ui.lua b/files/data/scripts/omw/ui.lua index 8199aec8f0..5837b01f36 100644 --- a/files/data/scripts/omw/ui.lua +++ b/files/data/scripts/omw/ui.lua @@ -99,7 +99,7 @@ local function removeMode(mode) end local oldMode = nil -local function onUiModeChanged(arg) +local function onUiModeChanged(changedByLua, arg) local newStack = ui._getUiModeStack() for i = 1, math.max(#modeStack, #newStack) do modeStack[i] = newStack[i] @@ -112,6 +112,9 @@ local function onUiModeChanged(arg) end local mode = newStack[#newStack] if mode then + if not changedByLua then + updateHidden(mode) + end for _, w in pairs(ui._getAllowedWindows(mode)) do local state = replacedWindows[w] if state and not hiddenWindows[w] then