From c5ba289bc75dacd83e475b4567035d1aab7ccae1 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sun, 20 Aug 2023 17:12:22 +0200 Subject: [PATCH] Handle UI modes open/close sounds in Lua --- apps/openmw/mwbase/windowmanager.hpp | 4 +-- apps/openmw/mwgui/scrollwindow.cpp | 2 +- apps/openmw/mwgui/windowmanagerimp.cpp | 15 +++-------- apps/openmw/mwgui/windowmanagerimp.hpp | 7 ++--- .../source/reference/lua-scripting/events.rst | 4 +-- files/data/scripts/omw/ui.lua | 27 ++++++++++++++++++- 6 files changed, 36 insertions(+), 23 deletions(-) diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 7d5521da80..727aee4abc 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -119,9 +119,9 @@ namespace MWBase virtual void pushGuiMode(MWGui::GuiMode mode, const MWWorld::Ptr& arg) = 0; virtual void pushGuiMode(MWGui::GuiMode mode) = 0; - virtual void popGuiMode(bool noSound = false) = 0; + virtual void popGuiMode() = 0; - virtual void removeGuiMode(MWGui::GuiMode mode, bool noSound = false) = 0; + virtual void removeGuiMode(MWGui::GuiMode mode) = 0; ///< can be anywhere in the stack virtual void goToJail(int days) = 0; diff --git a/apps/openmw/mwgui/scrollwindow.cpp b/apps/openmw/mwgui/scrollwindow.cpp index 690bd21e85..3debf0d66d 100644 --- a/apps/openmw/mwgui/scrollwindow.cpp +++ b/apps/openmw/mwgui/scrollwindow.cpp @@ -107,6 +107,6 @@ namespace MWGui MWWorld::ActionTake take(mScroll); take.execute(MWMechanics::getPlayer()); - MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll, true); + MWBase::Environment::get().getWindowManager()->removeGuiMode(GM_Scroll); } } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 1d2083dc98..b9c52136c1 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -360,8 +360,6 @@ namespace MWGui bool questList = mResourceSystem->getVFS()->exists("textures/tx_menubook_options_over.dds"); auto journal = JournalWindow::create(JournalViewModel::create(), questList, mEncoding); mGuiModeStates[GM_Journal] = GuiModeState(journal.get()); - mGuiModeStates[GM_Journal].mCloseSound = ESM::RefId::stringRefId("book close"); - mGuiModeStates[GM_Journal].mOpenSound = ESM::RefId::stringRefId("book open"); mWindows.push_back(std::move(journal)); mMessageBoxManager = std::make_unique( @@ -398,15 +396,11 @@ namespace MWGui mScrollWindow = scrollWindow.get(); mWindows.push_back(std::move(scrollWindow)); mGuiModeStates[GM_Scroll] = GuiModeState(mScrollWindow); - mGuiModeStates[GM_Scroll].mOpenSound = ESM::RefId::stringRefId("scroll"); - mGuiModeStates[GM_Scroll].mCloseSound = ESM::RefId::stringRefId("scroll"); auto bookWindow = std::make_unique(); mBookWindow = bookWindow.get(); mWindows.push_back(std::move(bookWindow)); mGuiModeStates[GM_Book] = GuiModeState(mBookWindow); - mGuiModeStates[GM_Book].mOpenSound = ESM::RefId::stringRefId("book open"); - mGuiModeStates[GM_Book].mCloseSound = ESM::RefId::stringRefId("book close"); auto countDialog = std::make_unique(); mCountDialog = countDialog.get(); @@ -1274,7 +1268,6 @@ namespace MWGui mGuiModes.push_back(mode); mGuiModeStates[mode].update(true); - playSound(mGuiModeStates[mode].mOpenSound); } if (force) mContainerWindow->treatNextOpenAsLoot(); @@ -1311,7 +1304,7 @@ namespace MWGui return mViewer->getCamera()->getCullMask(); } - void WindowManager::popGuiMode(bool noSound) + void WindowManager::popGuiMode() { if (mDragAndDrop && mDragAndDrop->mIsOnDragAndDrop) { @@ -1324,8 +1317,6 @@ namespace MWGui mKeyboardNavigation->saveFocus(mode); mGuiModes.pop_back(); mGuiModeStates[mode].update(false); - if (!noSound) - playSound(mGuiModeStates[mode].mCloseSound); MWBase::Environment::get().getLuaManager()->uiModeChanged(MWWorld::Ptr()); } @@ -1343,11 +1334,11 @@ namespace MWGui mConsole->onOpen(); } - void WindowManager::removeGuiMode(GuiMode mode, bool noSound) + void WindowManager::removeGuiMode(GuiMode mode) { if (!mGuiModes.empty() && mGuiModes.back() == mode) { - popGuiMode(noSound); + popGuiMode(); return; } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 6074c90231..9d79e0a0d7 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -149,8 +149,8 @@ namespace MWGui void pushGuiMode(GuiMode mode, const MWWorld::Ptr& arg) override; void pushGuiMode(GuiMode mode) override; - void popGuiMode(bool noSound = false) override; - void removeGuiMode(GuiMode mode, bool noSound = false) override; ///< can be anywhere in the stack + void popGuiMode() override; + void removeGuiMode(GuiMode mode) override; ///< can be anywhere in the stack void goToJail(int days) override; @@ -488,9 +488,6 @@ namespace MWGui void update(bool visible); std::vector mWindows; - - ESM::RefId mCloseSound; - ESM::RefId mOpenSound; }; // Defines the windows that should be shown in a particular GUI mode. std::map mGuiModeStates; diff --git a/docs/source/reference/lua-scripting/events.rst b/docs/source/reference/lua-scripting/events.rst index 7d383c491e..da4b2e3812 100644 --- a/docs/source/reference/lua-scripting/events.rst +++ b/docs/source/reference/lua-scripting/events.rst @@ -17,13 +17,13 @@ Examples: UI events --------- -Every time UI mode is changed built-in scripts send to player the event ``UiModeChanged`` with arguments ``mode`` (same as ``I.UI.getMode()``) +Every time UI mode is changed built-in scripts send to player the event ``UiModeChanged`` with arguments ``oldMode, ``newMode`` (same as ``I.UI.getMode()``) and ``arg`` (for example in the mode ``Book`` the argument is the book the player is reading). .. code-block:: Lua eventHandlers = { UiModeChanged = function(data) - print('UiModeChanged to', data.mode, '('..tostring(data.arg)..')') + print('UiModeChanged from', data.oldMode , 'to', data.newMode, '('..tostring(data.arg)..')') end } diff --git a/files/data/scripts/omw/ui.lua b/files/data/scripts/omw/ui.lua index 8b4798a981..0c15e53bc3 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 ambient = require('openmw.ambient') local MODE = ui._getAllUiModes() local WINDOW = ui._getAllWindowIds() @@ -91,6 +92,7 @@ local function removeMode(mode) end end +local oldMode = nil local function onUiModeChanged(arg) local newStack = ui._getUiModeStack() for i = 1, math.max(#modeStack, #newStack) do @@ -112,7 +114,27 @@ local function onUiModeChanged(arg) end end end - self:sendEvent('UiModeChanged', {mode = mode, arg = arg}) + self:sendEvent('UiModeChanged', {oldMode = oldMode, newMode = mode, arg = arg}) + oldMode = mode +end + +local function onUiModeChangedEvent(data) + if data.oldMode == data.newMode then + return + end + -- Sounds are processed in the event handler rather than in engine handler + -- in order to allow them to be overridden in mods. + if data.newMode == MODE.Journal or data.newMode == MODE.Book then + ambient.playSound('book open', {scale = false}) + elseif data.oldMode == MODE.Journal or data.oldMode == MODE.Book then + if not ambient.isSoundPlaying('item book up') then + ambient.playSound('book close', {scale = false}) + end + elseif data.newMode == MODE.Scroll or data.oldMode == MODE.Scroll then + if not ambient.isSoundPlaying('item book up') then + ambient.playSound('scroll', {scale = false}) + end + end end return { @@ -192,4 +214,7 @@ return { engineHandlers = { _onUiModeChanged = onUiModeChanged, }, + eventHandlers = { + UiModeChanged = onUiModeChangedEvent, + }, }