From 23a7661d0b58c976593f549d5d048e5291aead54 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sun, 3 Sep 2023 02:45:18 +0200 Subject: [PATCH] Control UI pause from Lua --- apps/openmw/mwbase/windowmanager.hpp | 2 +- apps/openmw/mwgui/windowmanagerimp.cpp | 10 +++++--- apps/openmw/mwgui/windowmanagerimp.hpp | 2 +- apps/openmw/mwworld/datetimemanager.cpp | 4 +++- .../source/reference/lua-scripting/events.rst | 19 +++++++++++++++ files/data/CMakeLists.txt | 1 + files/data/builtin.omwscripts | 1 + files/data/scripts/omw/ui.lua | 23 ++++++++++++++++++- files/data/scripts/omw/worldeventhandlers.lua | 10 ++++++++ 9 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 files/data/scripts/omw/worldeventhandlers.lua diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 727aee4abc..df6893c1ba 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -134,8 +134,8 @@ namespace MWBase virtual bool isGuiMode() const = 0; virtual bool isConsoleMode() const = 0; - virtual bool isPostProcessorHudVisible() const = 0; + virtual bool isInteractiveMessageBoxActive() const = 0; virtual void toggleVisible(MWGui::GuiWindow wnd) = 0; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index b9c52136c1..9bcfb3e158 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1539,8 +1539,7 @@ namespace MWGui bool WindowManager::isGuiMode() const { - return !mGuiModes.empty() || isConsoleMode() || (mPostProcessorHud && mPostProcessorHud->isVisible()) - || (mMessageBoxManager && mMessageBoxManager->isInteractiveMessageBox()); + return !mGuiModes.empty() || isConsoleMode() || isPostProcessorHudVisible() || isInteractiveMessageBoxActive(); } bool WindowManager::isConsoleMode() const @@ -1550,7 +1549,12 @@ namespace MWGui bool WindowManager::isPostProcessorHudVisible() const { - return mPostProcessorHud->isVisible(); + return mPostProcessorHud && mPostProcessorHud->isVisible(); + } + + bool WindowManager::isInteractiveMessageBoxActive() const + { + return mMessageBoxManager && mMessageBoxManager->isInteractiveMessageBox(); } MWGui::GuiMode WindowManager::getMode() const diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 9d79e0a0d7..fae3bb1ec9 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -160,8 +160,8 @@ namespace MWGui bool isGuiMode() const override; bool isConsoleMode() const override; - bool isPostProcessorHudVisible() const override; + bool isInteractiveMessageBoxActive() const override; void toggleVisible(GuiWindow wnd) override; diff --git a/apps/openmw/mwworld/datetimemanager.cpp b/apps/openmw/mwworld/datetimemanager.cpp index 7559242bef..78565cef60 100644 --- a/apps/openmw/mwworld/datetimemanager.cpp +++ b/apps/openmw/mwworld/datetimemanager.cpp @@ -263,6 +263,8 @@ namespace MWWorld void DateTimeManager::updateIsPaused() { - mPaused = !mPausedTags.empty() || MWBase::Environment::get().getWindowManager()->isGuiMode(); + auto wm = MWBase::Environment::get().getWindowManager(); + mPaused = !mPausedTags.empty() || wm->isConsoleMode() || wm->isPostProcessorHudVisible() + || wm->isInteractiveMessageBoxActive(); } } diff --git a/docs/source/reference/lua-scripting/events.rst b/docs/source/reference/lua-scripting/events.rst index 22cf4710d4..3e689078d0 100644 --- a/docs/source/reference/lua-scripting/events.rst +++ b/docs/source/reference/lua-scripting/events.rst @@ -42,3 +42,22 @@ and ``arg`` (for example in the mode ``Book`` the argument is the book the playe print('UiModeChanged from', data.oldMode , 'to', data.newMode, '('..tostring(data.arg)..')') end } + +World events +------------ + +Global events that just call the corresponding function in `openmw.world`. + +.. code-block:: Lua + + -- world.pause(tag) + core.sendGlobalEvent('Pause', tag) + + -- world.unpause(tag) + core.sendGlobalEvent('Unpause', tag) + + -- world.setGameTimeScale(scale) + core.sendGlobalEvent('SetGameTimeScale', scale) + + -- world.setSimulationTimeScale(scale) + core.sendGlobalEvent('SetSimulationTimeScale', scale) diff --git a/files/data/CMakeLists.txt b/files/data/CMakeLists.txt index afab9b4c79..dbf86cc44d 100644 --- a/files/data/CMakeLists.txt +++ b/files/data/CMakeLists.txt @@ -91,6 +91,7 @@ set(BUILTIN_DATA_FILES scripts/omw/mwui/init.lua scripts/omw/ui.lua scripts/omw/usehandlers.lua + scripts/omw/worldeventhandlers.lua shaders/adjustments.omwfx shaders/bloomlinear.omwfx diff --git a/files/data/builtin.omwscripts b/files/data/builtin.omwscripts index b86bedc509..ec08c5299d 100644 --- a/files/data/builtin.omwscripts +++ b/files/data/builtin.omwscripts @@ -9,6 +9,7 @@ PLAYER: scripts/omw/settings/player.lua GLOBAL: scripts/omw/activationhandlers.lua GLOBAL: scripts/omw/cellhandlers.lua GLOBAL: scripts/omw/usehandlers.lua +GLOBAL: scripts/omw/worldeventhandlers.lua PLAYER: scripts/omw/mechanics/playercontroller.lua PLAYER: scripts/omw/playercontrols.lua PLAYER: scripts/omw/camera/camera.lua diff --git a/files/data/scripts/omw/ui.lua b/files/data/scripts/omw/ui.lua index 0c15e53bc3..8199aec8f0 100644 --- a/files/data/scripts/omw/ui.lua +++ b/files/data/scripts/omw/ui.lua @@ -1,6 +1,7 @@ local ui = require('openmw.ui') local util = require('openmw.util') local self = require('openmw.self') +local core = require('openmw.core') local ambient = require('openmw.ambient') local MODE = ui._getAllUiModes() @@ -10,6 +11,11 @@ local replacedWindows = {} local hiddenWindows = {} local modeStack = {} +local modePause = {} +for _, mode in pairs(MODE) do + modePause[mode] = true +end + local function registerWindow(window, showFn, hideFn) if not WINDOW[window] then error('At the moment it is only possible to override existing windows. Window "'.. @@ -114,6 +120,15 @@ local function onUiModeChanged(arg) end end end + local shouldPause = false + for _, m in pairs(modeStack) do + shouldPause = shouldPause or modePause[m] + end + if shouldPause then + core.sendGlobalEvent('Pause', 'ui') + else + core.sendGlobalEvent('Unpause', 'ui') + end self:sendEvent('UiModeChanged', {oldMode = oldMode, newMode = mode, arg = arg}) oldMode = mode end @@ -145,7 +160,7 @@ return { interface = { --- Interface version -- @field [parent=#UI] #number version - version = 0, + version = 1, --- All available UI modes. -- Use `view(I.UI.MODE)` in `luap` console mode to see the list. @@ -204,6 +219,12 @@ return { -- @param #string mode Mode to drop removeMode = removeMode, + --- Set whether the mode should pause the game. + -- @function [parent=#UI] setPauseOnMode + -- @param #string mode Mode to configure + -- @param #boolean shouldPause + setPauseOnMode = function(mode, shouldPause) modePause[mode] = shouldPause end + -- TODO -- registerHudElement = function(name, showFn, hideFn) end, -- showHud = function(bool) end, diff --git a/files/data/scripts/omw/worldeventhandlers.lua b/files/data/scripts/omw/worldeventhandlers.lua new file mode 100644 index 0000000000..4bf6044178 --- /dev/null +++ b/files/data/scripts/omw/worldeventhandlers.lua @@ -0,0 +1,10 @@ +local world = require('openmw.world') + +return { + eventHandlers = { + Pause = function(tag) world.pause(tag) end, + Unpause = function(tag) world.unpause(tag) end, + SetGameTimeScale = function(scale) world.setGameTimeScale(scale) end, + SetSimulationTimeScale = function(scale) world.setSimulationTimeScale(scale) end, + }, +}