From e1cae5a029632c36b4bb63b41baa73057686671d Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 18 Aug 2023 11:03:37 +0400 Subject: [PATCH 1/8] Rework music system --- CHANGELOG.md | 2 ++ apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/mechanicsmanager.hpp | 8 +++++ apps/openmw/mwbase/soundmanager.hpp | 16 +++++++-- apps/openmw/mwgui/levelupdialog.cpp | 3 +- apps/openmw/mwlua/luabindings.cpp | 2 ++ apps/openmw/mwlua/musicbindings.cpp | 24 +++++++++++++ apps/openmw/mwlua/musicbindings.hpp | 13 +++++++ apps/openmw/mwmechanics/actors.cpp | 21 +++--------- apps/openmw/mwmechanics/actors.hpp | 13 ++----- .../mwmechanics/mechanicsmanagerimp.cpp | 29 ++++++++++++++++ .../mwmechanics/mechanicsmanagerimp.hpp | 11 ++++++ apps/openmw/mwscript/soundextensions.cpp | 5 +-- apps/openmw/mwsound/soundmanagerimp.cpp | 34 ++++++++++++++----- apps/openmw/mwsound/soundmanagerimp.hpp | 9 +++-- apps/openmw/mwworld/worldimp.cpp | 3 ++ components/misc/resourcehelpers.cpp | 5 +++ components/misc/resourcehelpers.hpp | 3 ++ docs/source/reference/lua-scripting/api.rst | 1 + .../reference/lua-scripting/openmw_music.rst | 7 ++++ .../lua-scripting/tables/packages.rst | 2 ++ files/data/scripts/omw/console/player.lua | 1 + files/lua_api/CMakeLists.txt | 1 + files/lua_api/openmw/music.lua | 19 +++++++++++ 24 files changed, 188 insertions(+), 46 deletions(-) create mode 100644 apps/openmw/mwlua/musicbindings.cpp create mode 100644 apps/openmw/mwlua/musicbindings.hpp create mode 100644 docs/source/reference/lua-scripting/openmw_music.rst create mode 100644 files/lua_api/openmw/music.lua diff --git a/CHANGELOG.md b/CHANGELOG.md index fb0cb5d54e..83892500dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,7 @@ Feature #3537: Shader-based water ripples Feature #5492: Let rain and snow collide with statics Feature #6149: Dehardcode Lua API_REVISION + Feature #6152: Playing music via lua scripts Feature #6447: Add LOD support to Object Paging Feature #6491: Add support for Qt6 Feature #6556: Lua API for sounds @@ -99,6 +100,7 @@ Feature #7477: NegativeLight Magic Effect flag Feature #7499: OpenMW-CS: Generate record filters by drag & dropping cell content to the filters field Feature #7546: Start the game on Fredas + Feature #7568: Uninterruptable scripted music Task #5896: Do not use deprecated MyGUI properties Task #7113: Move from std::atoi to std::from_char Task #7117: Replace boost::scoped_array with std::vector diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 96d54949b1..1fe34b9fd1 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -61,7 +61,7 @@ add_openmw_dir (mwscript add_openmw_dir (mwlua luamanagerimp object objectlists userdataserializer luaevents engineevents objectvariant context globalscripts localscripts playerscripts luabindings objectbindings cellbindings mwscriptbindings - camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings postprocessingbindings stats debugbindings + camerabindings vfsbindings musicbindings uibindings soundbindings inputbindings nearbybindings postprocessingbindings stats debugbindings types/types types/door types/item types/actor types/container types/lockable types/weapon types/npc types/creature types/player types/activator types/book types/lockpick types/probe types/apparatus types/potion types/ingredient types/misc types/repair types/armor types/light types/static types/clothing types/levelledlist types/terminal worker magicbindings factionbindings ) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 5319ab6dde..b8e0fd1bde 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -26,6 +26,11 @@ namespace ESM class ESMWriter; } +namespace MWSound +{ + enum class MusicType; +} + namespace MWWorld { class Ptr; @@ -282,6 +287,9 @@ namespace MWBase virtual float getAngleToPlayer(const MWWorld::Ptr& ptr) const = 0; virtual MWMechanics::GreetingState getGreetingState(const MWWorld::Ptr& ptr) const = 0; virtual bool isTurningToPlayer(const MWWorld::Ptr& ptr) const = 0; + + virtual MWSound::MusicType getMusicType() const = 0; + virtual void setMusicType(MWSound::MusicType type) = 0; }; } diff --git a/apps/openmw/mwbase/soundmanager.hpp b/apps/openmw/mwbase/soundmanager.hpp index 3dd9cd3b33..bf19255e6f 100644 --- a/apps/openmw/mwbase/soundmanager.hpp +++ b/apps/openmw/mwbase/soundmanager.hpp @@ -29,6 +29,14 @@ namespace MWSound MaxCount }; + enum class MusicType + { + Special, + Explore, + Battle, + Scripted + }; + class Sound; class Stream; struct Sound_Decoder; @@ -104,9 +112,13 @@ namespace MWBase virtual void stopMusic() = 0; ///< Stops music if it's playing - virtual void streamMusic(const std::string& filename) = 0; + virtual void streamMusic( + const std::string& filename, MWSound::MusicType type = MWSound::MusicType::Scripted, float fade = 1.f) + = 0; ///< Play a soundifle - /// \param filename name of a sound file in "Music/" in the data directory. + /// \param filename name of a sound file in the data directory. + /// \param type music type. + /// \param fade time in seconds to fade out current track before start this one. virtual bool isMusicPlaying() = 0; ///< Returns true if music is playing diff --git a/apps/openmw/mwgui/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index b13fdbeeb9..41b2dadeb9 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -214,7 +214,8 @@ namespace MWGui center(); // Play LevelUp Music - MWBase::Environment::get().getSoundManager()->streamMusic("Special/MW_Triumph.mp3"); + MWBase::Environment::get().getSoundManager()->streamMusic( + "Music/Special/MW_Triumph.mp3", MWSound::MusicType::Special); } void LevelupDialog::onOkButtonClicked(MyGUI::Widget* sender) diff --git a/apps/openmw/mwlua/luabindings.cpp b/apps/openmw/mwlua/luabindings.cpp index ef13adb936..25385b7404 100644 --- a/apps/openmw/mwlua/luabindings.cpp +++ b/apps/openmw/mwlua/luabindings.cpp @@ -40,6 +40,7 @@ #include "factionbindings.hpp" #include "inputbindings.hpp" #include "magicbindings.hpp" +#include "musicbindings.hpp" #include "nearbybindings.hpp" #include "objectbindings.hpp" #include "postprocessingbindings.hpp" @@ -392,6 +393,7 @@ namespace MWLua { "openmw.input", initInputPackage(context) }, { "openmw.postprocessing", initPostprocessingPackage(context) }, { "openmw.ui", initUserInterfacePackage(context) }, + { "openmw.music", initMusicPackage(context) }, }; } diff --git a/apps/openmw/mwlua/musicbindings.cpp b/apps/openmw/mwlua/musicbindings.cpp new file mode 100644 index 0000000000..f319070c06 --- /dev/null +++ b/apps/openmw/mwlua/musicbindings.cpp @@ -0,0 +1,24 @@ +#include "musicbindings.hpp" +#include "luabindings.hpp" + +#include "../mwbase/environment.hpp" +#include "../mwbase/soundmanager.hpp" +#include "../mwbase/windowmanager.hpp" + +#include "context.hpp" +#include "luamanagerimp.hpp" + +namespace MWLua +{ + sol::table initMusicPackage(const Context& context) + { + sol::table api(context.mLua->sol(), sol::create); + api["streamMusic"] = [](std::string_view fileName) { + MWBase::Environment::get().getSoundManager()->streamMusic(std::string(fileName)); + }; + + api["stopMusic"] = []() { MWBase::Environment::get().getSoundManager()->stopMusic(); }; + + return LuaUtil::makeReadOnly(api); + } +} diff --git a/apps/openmw/mwlua/musicbindings.hpp b/apps/openmw/mwlua/musicbindings.hpp new file mode 100644 index 0000000000..0d4f88bd4c --- /dev/null +++ b/apps/openmw/mwlua/musicbindings.hpp @@ -0,0 +1,13 @@ +#ifndef MWLUA_MUSICBINDINGS_H +#define MWLUA_MUSICBINDINGS_H + +#include + +#include "context.hpp" + +namespace MWLua +{ + sol::table initMusicPackage(const Context&); +} + +#endif // MWLUA_MUSICBINDINGS_H diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index ec53bdec71..743c5d5ab5 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1285,7 +1285,7 @@ namespace MWMechanics } } - void Actors::updateCombatMusic() + bool Actors::playerHasHostiles() const { const MWWorld::Ptr player = getPlayer(); const osg::Vec3f playerPos = player.getRefData().getPosition().asVec3(); @@ -1315,19 +1315,7 @@ namespace MWMechanics } } - // check if we still have any player enemies to switch music - if (mCurrentMusic != MusicType::Explore && !hasHostiles - && !(player.getClass().getCreatureStats(player).isDead() - && MWBase::Environment::get().getSoundManager()->isMusicPlaying())) - { - MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore")); - mCurrentMusic = MusicType::Explore; - } - else if (mCurrentMusic != MusicType::Battle && hasHostiles) - { - MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Battle")); - mCurrentMusic = MusicType::Battle; - } + return hasHostiles; } void Actors::predictAndAvoidCollisions(float duration) const @@ -1735,8 +1723,6 @@ namespace MWMechanics killDeadActors(); updateSneaking(playerCharacter, duration); } - - updateCombatMusic(); } void Actors::notifyDied(const MWWorld::Ptr& actor) @@ -1806,7 +1792,8 @@ namespace MWMechanics // player's death animation is over MWBase::Environment::get().getStateManager()->askLoadRecent(); // Play Death Music if it was the player dying - MWBase::Environment::get().getSoundManager()->streamMusic("Special/MW_Death.mp3"); + MWBase::Environment::get().getSoundManager()->streamMusic( + "Music/Special/MW_Death.mp3", MWSound::MusicType::Special); } else { diff --git a/apps/openmw/mwmechanics/actors.hpp b/apps/openmw/mwmechanics/actors.hpp index 1c5799159e..98c64397ab 100644 --- a/apps/openmw/mwmechanics/actors.hpp +++ b/apps/openmw/mwmechanics/actors.hpp @@ -74,9 +74,6 @@ namespace MWMechanics void dropActors(const MWWorld::CellStore* cellStore, const MWWorld::Ptr& ignore); ///< Deregister all actors (except for \a ignore) in the given cell. - void updateCombatMusic(); - ///< Update combat music state - void update(float duration, bool paused); ///< Update actor stats and store desired velocity vectors in \a movement @@ -159,19 +156,14 @@ namespace MWMechanics bool isReadyToBlock(const MWWorld::Ptr& ptr) const; bool isAttackingOrSpell(const MWWorld::Ptr& ptr) const; + bool playerHasHostiles() const; + int getGreetingTimer(const MWWorld::Ptr& ptr) const; float getAngleToPlayer(const MWWorld::Ptr& ptr) const; GreetingState getGreetingState(const MWWorld::Ptr& ptr) const; bool isTurningToPlayer(const MWWorld::Ptr& ptr) const; private: - enum class MusicType - { - Title, - Explore, - Battle - }; - std::map mDeathCount; std::list mActors; std::map::iterator> mIndex; @@ -182,7 +174,6 @@ namespace MWMechanics float mTimerUpdateHello = 0; float mSneakTimer = 0; // Times update of sneak icon float mSneakSkillTimer = 0; // Times sneak skill progress from "avoid notice" - MusicType mCurrentMusic = MusicType::Title; void updateVisibility(const MWWorld::Ptr& ptr, CharacterController& ctrl) const; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index b960e0d38f..071ac164f3 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -24,6 +24,7 @@ #include "../mwbase/dialoguemanager.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwbase/statemanager.hpp" #include "../mwbase/windowmanager.hpp" #include "../mwbase/world.hpp" @@ -257,6 +258,7 @@ namespace MWMechanics , mClassSelected(false) , mRaceSelected(false) , mAI(true) + , mMusicType(MWSound::MusicType::Special) { // buildPlayer no longer here, needs to be done explicitly after all subsystems are up and running } @@ -340,6 +342,8 @@ namespace MWMechanics mActors.update(duration, paused); mObjects.update(duration, paused); + + updateMusicState(); } void MechanicsManager::processChangedSettings(const Settings::CategorySettingVector& changed) @@ -1572,6 +1576,31 @@ namespace MWMechanics return (Misc::Rng::roll0to99(prng) >= target); } + void MechanicsManager::updateMusicState() + { + bool musicPlaying = MWBase::Environment::get().getSoundManager()->isMusicPlaying(); + + // Can not interrupt scripted music by built-in playlists + if (mMusicType == MWSound::MusicType::Scripted && musicPlaying) + return; + + const MWWorld::Ptr& player = MWMechanics::getPlayer(); + bool hasHostiles = mActors.playerHasHostiles(); + + // check if we still have any player enemies to switch music + if (mMusicType != MWSound::MusicType::Explore && !hasHostiles + && !(player.getClass().getCreatureStats(player).isDead() && musicPlaying)) + { + MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore")); + mMusicType = MWSound::MusicType::Explore; + } + else if (mMusicType != MWSound::MusicType::Battle && hasHostiles) + { + MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Battle")); + mMusicType = MWSound::MusicType::Battle; + } + } + void MechanicsManager::startCombat(const MWWorld::Ptr& ptr, const MWWorld::Ptr& target) { CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 748965a682..36bb18e022 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -11,6 +11,11 @@ #include "npcstats.hpp" #include "objects.hpp" +namespace MWSound +{ + enum class MusicType; +} + namespace MWWorld { class CellStore; @@ -33,6 +38,8 @@ namespace MWMechanics typedef std::map StolenItemsMap; StolenItemsMap mStolenItems; + MWSound::MusicType mMusicType; + public: void buildPlayer(); ///< build player according to stored class/race/birthsign information. Will @@ -232,7 +239,11 @@ namespace MWMechanics GreetingState getGreetingState(const MWWorld::Ptr& ptr) const override; bool isTurningToPlayer(const MWWorld::Ptr& ptr) const override; + MWSound::MusicType getMusicType() const override { return mMusicType; } + void setMusicType(MWSound::MusicType type) override { mMusicType = type; } + private: + void updateMusicState(); bool canCommitCrimeAgainst(const MWWorld::Ptr& victim, const MWWorld::Ptr& attacker); bool canReportCrime( const MWWorld::Ptr& actor, const MWWorld::Ptr& victim, std::set& playerFollowers); diff --git a/apps/openmw/mwscript/soundextensions.cpp b/apps/openmw/mwscript/soundextensions.cpp index f1ac2a7a08..3d982c8eab 100644 --- a/apps/openmw/mwscript/soundextensions.cpp +++ b/apps/openmw/mwscript/soundextensions.cpp @@ -63,10 +63,11 @@ namespace MWScript public: void execute(Interpreter::Runtime& runtime) override { - std::string sound{ runtime.getStringLiteral(runtime[0].mInteger) }; + std::string music{ runtime.getStringLiteral(runtime[0].mInteger) }; runtime.pop(); - MWBase::Environment::get().getSoundManager()->streamMusic(sound); + MWBase::Environment::get().getSoundManager()->streamMusic( + Misc::ResourceHelpers::correctMusicPath(music)); } }; diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index d5f1758f03..9cc67f5af4 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -14,6 +14,7 @@ #include #include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/statemanager.hpp" #include "../mwbase/world.hpp" @@ -250,7 +251,7 @@ namespace MWSound if (filename.empty()) return; - Log(Debug::Info) << "Playing " << filename; + Log(Debug::Info) << "Playing \"" << filename << "\""; mLastPlayedMusic = filename; DecoderPtr decoder = getDecoder(); @@ -260,7 +261,7 @@ namespace MWSound } catch (std::exception& e) { - Log(Debug::Error) << "Failed to load audio from " << filename << ": " << e.what(); + Log(Debug::Error) << "Failed to load audio from \"" << filename << "\": " << e.what(); return; } @@ -274,7 +275,7 @@ namespace MWSound mOutput->streamSound(decoder, mMusic.get()); } - void SoundManager::advanceMusic(const std::string& filename) + void SoundManager::advanceMusic(const std::string& filename, float fadeOut) { if (!isMusicPlaying()) { @@ -284,7 +285,7 @@ namespace MWSound mNextMusic = filename; - mMusic->setFadeout(1.f); + mMusic->setFadeout(fadeOut); } void SoundManager::startRandomTitle() @@ -319,14 +320,28 @@ namespace MWSound tracklist.pop_back(); } - void SoundManager::streamMusic(const std::string& filename) + bool SoundManager::isMusicPlaying() { - advanceMusic("Music/" + filename); + return mMusic && mOutput->isStreamPlaying(mMusic.get()); } - bool SoundManager::isMusicPlaying() + void SoundManager::streamMusic(const std::string& filename, MusicType type, float fade) { - return mMusic && mOutput->isStreamPlaying(mMusic.get()); + const auto mechanicsManager = MWBase::Environment::get().getMechanicsManager(); + + // Can not interrupt scripted music by built-in playlists + if (mechanicsManager->getMusicType() == MusicType::Scripted && type != MusicType::Scripted + && type != MusicType::Special) + return; + + std::string normalizedName = VFS::Path::normalizeFilename(filename); + + mechanicsManager->setMusicType(type); + advanceMusic(normalizedName, fade); + if (type == MWSound::MusicType::Battle) + mCurrentPlaylist = "Battle"; + else if (type == MWSound::MusicType::Explore) + mCurrentPlaylist = "Explore"; } void SoundManager::playPlaylist(const std::string& playlist) @@ -337,7 +352,8 @@ namespace MWSound if (mMusicFiles.find(playlist) == mMusicFiles.end()) { std::vector filelist; - for (const auto& name : mVFS->getRecursiveDirectoryIterator("Music/" + playlist + '/')) + auto playlistPath = Misc::ResourceHelpers::correctMusicPath(playlist) + '/'; + for (const auto& name : mVFS->getRecursiveDirectoryIterator(playlistPath)) filelist.push_back(name); mMusicFiles[playlist] = filelist; diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index 7453ce86f4..a8eb37f55b 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -127,7 +127,7 @@ namespace MWSound StreamPtr playVoice(DecoderPtr decoder, const osg::Vec3f& pos, bool playlocal); void streamMusicFull(const std::string& filename); - void advanceMusic(const std::string& filename); + void advanceMusic(const std::string& filename, float fadeOut = 1.f); void startRandomTitle(); void cull3DSound(SoundBase* sound); @@ -176,9 +176,12 @@ namespace MWSound void stopMusic() override; ///< Stops music if it's playing - void streamMusic(const std::string& filename) override; + void streamMusic(const std::string& filename, MWSound::MusicType type = MWSound::MusicType::Scripted, + float fade = 1.f) override; ///< Play a soundifle - /// \param filename name of a sound file in "Music/" in the data directory. + /// \param filename name of a sound file in the data directory. + /// \param type music type. + /// \param fade time in seconds to fade out current track before start this one. bool isMusicPlaying() override; ///< Returns true if music is playing diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 241d252615..28407b29b3 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -391,7 +391,10 @@ namespace MWWorld { std::string_view video = Fallback::Map::getString("Movies_New_Game"); if (!video.empty()) + { + MWBase::Environment::get().getSoundManager()->stopMusic(); MWBase::Environment::get().getWindowManager()->playVideo(video, true); + } } // enable collision diff --git a/components/misc/resourcehelpers.cpp b/components/misc/resourcehelpers.cpp index 55fef5cdbd..0ae45c6c26 100644 --- a/components/misc/resourcehelpers.cpp +++ b/components/misc/resourcehelpers.cpp @@ -156,6 +156,11 @@ std::string Misc::ResourceHelpers::correctSoundPath(const std::string& resPath) return "sound\\" + resPath; } +std::string Misc::ResourceHelpers::correctMusicPath(const std::string& resPath) +{ + return "music\\" + resPath; +} + std::string_view Misc::ResourceHelpers::meshPathForESM3(std::string_view resPath) { constexpr std::string_view prefix = "meshes"; diff --git a/components/misc/resourcehelpers.hpp b/components/misc/resourcehelpers.hpp index 0597c7bc16..37932ea155 100644 --- a/components/misc/resourcehelpers.hpp +++ b/components/misc/resourcehelpers.hpp @@ -38,6 +38,9 @@ namespace Misc // Adds "sound\\". std::string correctSoundPath(const std::string& resPath); + // Adds "music\\". + std::string correctMusicPath(const std::string& resPath); + // Removes "meshes\\". std::string_view meshPathForESM3(std::string_view resPath); diff --git a/docs/source/reference/lua-scripting/api.rst b/docs/source/reference/lua-scripting/api.rst index 6d27db0515..acb5963992 100644 --- a/docs/source/reference/lua-scripting/api.rst +++ b/docs/source/reference/lua-scripting/api.rst @@ -23,6 +23,7 @@ Lua API reference openmw_nearby openmw_input openmw_ambient + openmw_music openmw_ui openmw_camera openmw_postprocessing diff --git a/docs/source/reference/lua-scripting/openmw_music.rst b/docs/source/reference/lua-scripting/openmw_music.rst new file mode 100644 index 0000000000..87fbb71899 --- /dev/null +++ b/docs/source/reference/lua-scripting/openmw_music.rst @@ -0,0 +1,7 @@ +Package openmw.music +==================== + +.. include:: version.rst + +.. raw:: html + :file: generated_html/openmw_music.html diff --git a/docs/source/reference/lua-scripting/tables/packages.rst b/docs/source/reference/lua-scripting/tables/packages.rst index 67709bbf7b..dbe05b0adc 100644 --- a/docs/source/reference/lua-scripting/tables/packages.rst +++ b/docs/source/reference/lua-scripting/tables/packages.rst @@ -27,6 +27,8 @@ +------------------------------------------------------------+--------------------+---------------------------------------------------------------+ |:ref:`openmw.input ` | by player scripts | | User input. | +------------------------------------------------------------+--------------------+---------------------------------------------------------------+ +|:ref:`openmw.music ` | by player scripts | | Music system. | ++------------------------------------------------------------+--------------------+---------------------------------------------------------------+ |:ref:`openmw.ui ` | by player scripts | | Controls :ref:`user interface `. | +------------------------------------------------------------+--------------------+---------------------------------------------------------------+ |:ref:`openmw.camera ` | by player scripts | | Controls camera. | diff --git a/files/data/scripts/omw/console/player.lua b/files/data/scripts/omw/console/player.lua index c614d2d962..be818f6145 100644 --- a/files/data/scripts/omw/console/player.lua +++ b/files/data/scripts/omw/console/player.lua @@ -77,6 +77,7 @@ local env = { nearby = require('openmw.nearby'), self = require('openmw.self'), input = require('openmw.input'), + music = require('openmw.music'), ui = require('openmw.ui'), camera = require('openmw.camera'), aux_util = require('openmw_aux.util'), diff --git a/files/lua_api/CMakeLists.txt b/files/lua_api/CMakeLists.txt index 96409e803e..3d25006735 100644 --- a/files/lua_api/CMakeLists.txt +++ b/files/lua_api/CMakeLists.txt @@ -13,6 +13,7 @@ set(LUA_API_FILES openmw/async.lua openmw/core.lua openmw/debug.lua + openmw/music.lua openmw/nearby.lua openmw/postprocessing.lua openmw/self.lua diff --git a/files/lua_api/openmw/music.lua b/files/lua_api/openmw/music.lua new file mode 100644 index 0000000000..fe7c30ffa8 --- /dev/null +++ b/files/lua_api/openmw/music.lua @@ -0,0 +1,19 @@ +--- +-- `openmw.music` provides access to music system. +-- @module music +-- @usage local music = require('openmw.music') + + + +--- +-- Play a sound file as a music track +-- @function [parent=#music] streamMusic +-- @param #string fileName Path to file in VFS +-- @usage music.streamMusic("Music\\Test\\Test.mp3"); + +--- +-- Stop to play current music +-- @function [parent=#music] stopMusic +-- @usage music.stopMusic(); + +return nil From 18fe6a8ae70fbcb0ffe71b899966789f220c2b98 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 12 Sep 2023 14:04:30 +0400 Subject: [PATCH 2/8] Remove default argument --- apps/openmw/mwbase/soundmanager.hpp | 4 +--- apps/openmw/mwlua/musicbindings.cpp | 3 ++- apps/openmw/mwscript/soundextensions.cpp | 2 +- apps/openmw/mwsound/soundmanagerimp.hpp | 3 +-- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwbase/soundmanager.hpp b/apps/openmw/mwbase/soundmanager.hpp index bf19255e6f..85062ace8d 100644 --- a/apps/openmw/mwbase/soundmanager.hpp +++ b/apps/openmw/mwbase/soundmanager.hpp @@ -112,9 +112,7 @@ namespace MWBase virtual void stopMusic() = 0; ///< Stops music if it's playing - virtual void streamMusic( - const std::string& filename, MWSound::MusicType type = MWSound::MusicType::Scripted, float fade = 1.f) - = 0; + virtual void streamMusic(const std::string& filename, MWSound::MusicType type, float fade = 1.f) = 0; ///< Play a soundifle /// \param filename name of a sound file in the data directory. /// \param type music type. diff --git a/apps/openmw/mwlua/musicbindings.cpp b/apps/openmw/mwlua/musicbindings.cpp index f319070c06..919e8b0590 100644 --- a/apps/openmw/mwlua/musicbindings.cpp +++ b/apps/openmw/mwlua/musicbindings.cpp @@ -14,7 +14,8 @@ namespace MWLua { sol::table api(context.mLua->sol(), sol::create); api["streamMusic"] = [](std::string_view fileName) { - MWBase::Environment::get().getSoundManager()->streamMusic(std::string(fileName)); + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + sndMgr->streamMusic(std::string(fileName), MWSound::MusicType::Scripted); }; api["stopMusic"] = []() { MWBase::Environment::get().getSoundManager()->stopMusic(); }; diff --git a/apps/openmw/mwscript/soundextensions.cpp b/apps/openmw/mwscript/soundextensions.cpp index 3d982c8eab..44cdc25064 100644 --- a/apps/openmw/mwscript/soundextensions.cpp +++ b/apps/openmw/mwscript/soundextensions.cpp @@ -67,7 +67,7 @@ namespace MWScript runtime.pop(); MWBase::Environment::get().getSoundManager()->streamMusic( - Misc::ResourceHelpers::correctMusicPath(music)); + Misc::ResourceHelpers::correctMusicPath(music), MWSound::MusicType::Scripted); } }; diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index a8eb37f55b..87fb109791 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -176,8 +176,7 @@ namespace MWSound void stopMusic() override; ///< Stops music if it's playing - void streamMusic(const std::string& filename, MWSound::MusicType type = MWSound::MusicType::Scripted, - float fade = 1.f) override; + void streamMusic(const std::string& filename, MWSound::MusicType type, float fade = 1.f) override; ///< Play a soundifle /// \param filename name of a sound file in the data directory. /// \param type music type. From e25e867d775ebeb296caeda7e7546e894eb9f71d Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 12 Sep 2023 14:30:24 +0400 Subject: [PATCH 3/8] Remove 'music' package --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwlua/luabindings.cpp | 2 -- apps/openmw/mwlua/musicbindings.cpp | 25 ------------------- apps/openmw/mwlua/musicbindings.hpp | 13 ---------- apps/openmw/mwlua/soundbindings.cpp | 7 ++++++ docs/source/reference/lua-scripting/api.rst | 1 - .../reference/lua-scripting/openmw_music.rst | 7 ------ .../lua-scripting/tables/packages.rst | 2 -- files/data/scripts/omw/console/player.lua | 1 - files/lua_api/CMakeLists.txt | 1 - files/lua_api/openmw/ambient.lua | 11 ++++++++ files/lua_api/openmw/music.lua | 19 -------------- 12 files changed, 19 insertions(+), 72 deletions(-) delete mode 100644 apps/openmw/mwlua/musicbindings.cpp delete mode 100644 apps/openmw/mwlua/musicbindings.hpp delete mode 100644 docs/source/reference/lua-scripting/openmw_music.rst delete mode 100644 files/lua_api/openmw/music.lua diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 1fe34b9fd1..96d54949b1 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -61,7 +61,7 @@ add_openmw_dir (mwscript add_openmw_dir (mwlua luamanagerimp object objectlists userdataserializer luaevents engineevents objectvariant context globalscripts localscripts playerscripts luabindings objectbindings cellbindings mwscriptbindings - camerabindings vfsbindings musicbindings uibindings soundbindings inputbindings nearbybindings postprocessingbindings stats debugbindings + camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings postprocessingbindings stats debugbindings types/types types/door types/item types/actor types/container types/lockable types/weapon types/npc types/creature types/player types/activator types/book types/lockpick types/probe types/apparatus types/potion types/ingredient types/misc types/repair types/armor types/light types/static types/clothing types/levelledlist types/terminal worker magicbindings factionbindings ) diff --git a/apps/openmw/mwlua/luabindings.cpp b/apps/openmw/mwlua/luabindings.cpp index 25385b7404..ef13adb936 100644 --- a/apps/openmw/mwlua/luabindings.cpp +++ b/apps/openmw/mwlua/luabindings.cpp @@ -40,7 +40,6 @@ #include "factionbindings.hpp" #include "inputbindings.hpp" #include "magicbindings.hpp" -#include "musicbindings.hpp" #include "nearbybindings.hpp" #include "objectbindings.hpp" #include "postprocessingbindings.hpp" @@ -393,7 +392,6 @@ namespace MWLua { "openmw.input", initInputPackage(context) }, { "openmw.postprocessing", initPostprocessingPackage(context) }, { "openmw.ui", initUserInterfacePackage(context) }, - { "openmw.music", initMusicPackage(context) }, }; } diff --git a/apps/openmw/mwlua/musicbindings.cpp b/apps/openmw/mwlua/musicbindings.cpp deleted file mode 100644 index 919e8b0590..0000000000 --- a/apps/openmw/mwlua/musicbindings.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "musicbindings.hpp" -#include "luabindings.hpp" - -#include "../mwbase/environment.hpp" -#include "../mwbase/soundmanager.hpp" -#include "../mwbase/windowmanager.hpp" - -#include "context.hpp" -#include "luamanagerimp.hpp" - -namespace MWLua -{ - sol::table initMusicPackage(const Context& context) - { - sol::table api(context.mLua->sol(), sol::create); - api["streamMusic"] = [](std::string_view fileName) { - MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); - sndMgr->streamMusic(std::string(fileName), MWSound::MusicType::Scripted); - }; - - api["stopMusic"] = []() { MWBase::Environment::get().getSoundManager()->stopMusic(); }; - - return LuaUtil::makeReadOnly(api); - } -} diff --git a/apps/openmw/mwlua/musicbindings.hpp b/apps/openmw/mwlua/musicbindings.hpp deleted file mode 100644 index 0d4f88bd4c..0000000000 --- a/apps/openmw/mwlua/musicbindings.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef MWLUA_MUSICBINDINGS_H -#define MWLUA_MUSICBINDINGS_H - -#include - -#include "context.hpp" - -namespace MWLua -{ - sol::table initMusicPackage(const Context&); -} - -#endif // MWLUA_MUSICBINDINGS_H diff --git a/apps/openmw/mwlua/soundbindings.cpp b/apps/openmw/mwlua/soundbindings.cpp index b5dae8a7a8..318f120365 100644 --- a/apps/openmw/mwlua/soundbindings.cpp +++ b/apps/openmw/mwlua/soundbindings.cpp @@ -95,6 +95,13 @@ namespace MWLua return MWBase::Environment::get().getSoundManager()->getSoundPlaying(MWWorld::Ptr(), fileName); }; + api["streamMusic"] = [](std::string_view fileName) { + MWBase::SoundManager* sndMgr = MWBase::Environment::get().getSoundManager(); + sndMgr->streamMusic(std::string(fileName), MWSound::MusicType::Scripted); + }; + + api["stopMusic"] = []() { MWBase::Environment::get().getSoundManager()->stopMusic(); }; + return LuaUtil::makeReadOnly(api); } diff --git a/docs/source/reference/lua-scripting/api.rst b/docs/source/reference/lua-scripting/api.rst index acb5963992..6d27db0515 100644 --- a/docs/source/reference/lua-scripting/api.rst +++ b/docs/source/reference/lua-scripting/api.rst @@ -23,7 +23,6 @@ Lua API reference openmw_nearby openmw_input openmw_ambient - openmw_music openmw_ui openmw_camera openmw_postprocessing diff --git a/docs/source/reference/lua-scripting/openmw_music.rst b/docs/source/reference/lua-scripting/openmw_music.rst deleted file mode 100644 index 87fbb71899..0000000000 --- a/docs/source/reference/lua-scripting/openmw_music.rst +++ /dev/null @@ -1,7 +0,0 @@ -Package openmw.music -==================== - -.. include:: version.rst - -.. raw:: html - :file: generated_html/openmw_music.html diff --git a/docs/source/reference/lua-scripting/tables/packages.rst b/docs/source/reference/lua-scripting/tables/packages.rst index dbe05b0adc..67709bbf7b 100644 --- a/docs/source/reference/lua-scripting/tables/packages.rst +++ b/docs/source/reference/lua-scripting/tables/packages.rst @@ -27,8 +27,6 @@ +------------------------------------------------------------+--------------------+---------------------------------------------------------------+ |:ref:`openmw.input ` | by player scripts | | User input. | +------------------------------------------------------------+--------------------+---------------------------------------------------------------+ -|:ref:`openmw.music ` | by player scripts | | Music system. | -+------------------------------------------------------------+--------------------+---------------------------------------------------------------+ |:ref:`openmw.ui ` | by player scripts | | Controls :ref:`user interface `. | +------------------------------------------------------------+--------------------+---------------------------------------------------------------+ |:ref:`openmw.camera ` | by player scripts | | Controls camera. | diff --git a/files/data/scripts/omw/console/player.lua b/files/data/scripts/omw/console/player.lua index be818f6145..c614d2d962 100644 --- a/files/data/scripts/omw/console/player.lua +++ b/files/data/scripts/omw/console/player.lua @@ -77,7 +77,6 @@ local env = { nearby = require('openmw.nearby'), self = require('openmw.self'), input = require('openmw.input'), - music = require('openmw.music'), ui = require('openmw.ui'), camera = require('openmw.camera'), aux_util = require('openmw_aux.util'), diff --git a/files/lua_api/CMakeLists.txt b/files/lua_api/CMakeLists.txt index 3d25006735..96409e803e 100644 --- a/files/lua_api/CMakeLists.txt +++ b/files/lua_api/CMakeLists.txt @@ -13,7 +13,6 @@ set(LUA_API_FILES openmw/async.lua openmw/core.lua openmw/debug.lua - openmw/music.lua openmw/nearby.lua openmw/postprocessing.lua openmw/self.lua diff --git a/files/lua_api/openmw/ambient.lua b/files/lua_api/openmw/ambient.lua index 3722cb8c0f..671e0b0ee6 100644 --- a/files/lua_api/openmw/ambient.lua +++ b/files/lua_api/openmw/ambient.lua @@ -72,4 +72,15 @@ -- @return #boolean -- @usage local isPlaying = ambient.isSoundFilePlaying("Sound\\test.mp3"); +--- +-- Play a sound file as a music track +-- @function [parent=#ambient] streamMusic +-- @param #string fileName Path to file in VFS +-- @usage ambient.streamMusic("Music\\Test\\Test.mp3"); + +--- +-- Stop to play current music +-- @function [parent=#ambient] stopMusic +-- @usage ambient.stopMusic(); + return nil diff --git a/files/lua_api/openmw/music.lua b/files/lua_api/openmw/music.lua deleted file mode 100644 index fe7c30ffa8..0000000000 --- a/files/lua_api/openmw/music.lua +++ /dev/null @@ -1,19 +0,0 @@ ---- --- `openmw.music` provides access to music system. --- @module music --- @usage local music = require('openmw.music') - - - ---- --- Play a sound file as a music track --- @function [parent=#music] streamMusic --- @param #string fileName Path to file in VFS --- @usage music.streamMusic("Music\\Test\\Test.mp3"); - ---- --- Stop to play current music --- @function [parent=#music] stopMusic --- @usage music.stopMusic(); - -return nil From cbb4c1bb9a6faad6b3b55689ba581385768d2d02 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 12 Sep 2023 14:50:19 +0400 Subject: [PATCH 4/8] Fix music during a new game start --- apps/openmw/mwworld/worldimp.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 28407b29b3..748187d868 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -392,7 +392,9 @@ namespace MWWorld std::string_view video = Fallback::Map::getString("Movies_New_Game"); if (!video.empty()) { + // Make sure that we do not continue to play a Title music after a new game video. MWBase::Environment::get().getSoundManager()->stopMusic(); + MWBase::Environment::get().getSoundManager()->playPlaylist(std::string("Explore")); MWBase::Environment::get().getWindowManager()->playVideo(video, true); } } From 64db68e0aa46fa7c9e3dc57531be92edd6d1b304 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 13 Sep 2023 09:12:42 +0400 Subject: [PATCH 5/8] Increase Lua API version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 380903f25c..d3a16c285f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,7 @@ message(STATUS "Configuring OpenMW...") set(OPENMW_VERSION_MAJOR 0) set(OPENMW_VERSION_MINOR 49) set(OPENMW_VERSION_RELEASE 0) -set(OPENMW_LUA_API_REVISION 47) +set(OPENMW_LUA_API_REVISION 48) set(OPENMW_VERSION_COMMITHASH "") set(OPENMW_VERSION_TAGHASH "") From 655c4442bc3159a740b0bf26b7cc83f85524c099 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 13 Sep 2023 17:48:49 +0400 Subject: [PATCH 6/8] Implement isMusicPlaying --- apps/openmw/mwlua/soundbindings.cpp | 2 ++ files/lua_api/openmw/ambient.lua | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/apps/openmw/mwlua/soundbindings.cpp b/apps/openmw/mwlua/soundbindings.cpp index 318f120365..102f88ce61 100644 --- a/apps/openmw/mwlua/soundbindings.cpp +++ b/apps/openmw/mwlua/soundbindings.cpp @@ -100,6 +100,8 @@ namespace MWLua sndMgr->streamMusic(std::string(fileName), MWSound::MusicType::Scripted); }; + api["isMusicPlaying"] = []() { return MWBase::Environment::get().getSoundManager()->isMusicPlaying(); }; + api["stopMusic"] = []() { MWBase::Environment::get().getSoundManager()->stopMusic(); }; return LuaUtil::makeReadOnly(api); diff --git a/files/lua_api/openmw/ambient.lua b/files/lua_api/openmw/ambient.lua index 671e0b0ee6..917ec86c85 100644 --- a/files/lua_api/openmw/ambient.lua +++ b/files/lua_api/openmw/ambient.lua @@ -83,4 +83,10 @@ -- @function [parent=#ambient] stopMusic -- @usage ambient.stopMusic(); +--- +-- Check if music is playing +-- @function [parent=#ambient] isMusicPlaying +-- @return #boolean +-- @usage local isPlaying = ambient.isMusicPlaying(); + return nil From ebb75008f8552ad3e4a1ee7d46d28efa586b691a Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 14 Sep 2023 09:17:59 +0400 Subject: [PATCH 7/8] Do not use playlist for title music --- apps/openmw/engine.cpp | 8 +++++++- apps/openmw/mwsound/soundmanagerimp.cpp | 17 ++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 2966800014..df89cd3eb6 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -913,7 +913,13 @@ void OMW::Engine::go() { // start in main menu mWindowManager->pushGuiMode(MWGui::GM_MainMenu); - mSoundManager->playPlaylist("Title"); + + std::string titlefile = "music/special/morrowind title.mp3"; + if (mVFS->exists(titlefile)) + mSoundManager->streamMusic(titlefile, MWSound::MusicType::Special); + else + Log(Debug::Warning) << "Title music not found"; + std::string_view logo = Fallback::Map::getString("Movies_Morrowind_Logo"); if (!logo.empty()) mWindowManager->playVideo(logo, /*allowSkipping*/ true, /*overrideSounds*/ false); diff --git a/apps/openmw/mwsound/soundmanagerimp.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp index 9cc67f5af4..be8bae20a6 100644 --- a/apps/openmw/mwsound/soundmanagerimp.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -132,15 +132,6 @@ namespace MWSound Log(Debug::Info) << stream.str(); } - - // TODO: dehardcode this - std::vector titleMusic; - std::string_view titlefile = "music/special/morrowind title.mp3"; - if (mVFS->exists(titlefile)) - titleMusic.emplace_back(titlefile); - else - Log(Debug::Warning) << "Title music not found"; - mMusicFiles["Title"] = titleMusic; } SoundManager::~SoundManager() @@ -1143,6 +1134,14 @@ namespace MWSound if (!mOutput->isInitialized() || mPlaybackPaused) return; + MWBase::StateManager::State state = MWBase::Environment::get().getStateManager()->getState(); + if (state == MWBase::StateManager::State_NoGame && !isMusicPlaying()) + { + std::string titlefile = "music/special/morrowind title.mp3"; + if (mVFS->exists(titlefile)) + streamMusic(titlefile, MWSound::MusicType::Special); + } + updateSounds(duration); if (MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_NoGame) { From db72a9118094acc17734af22266cc78c8af6da00 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 14 Sep 2023 12:54:20 +0400 Subject: [PATCH 8/8] Add a way to check if sound system is enabled --- apps/openmw/mwbase/soundmanager.hpp | 3 +++ apps/openmw/mwlua/soundbindings.cpp | 2 ++ apps/openmw/mwsound/soundmanagerimp.hpp | 3 +++ files/lua_api/openmw/core.lua | 7 +++++++ 4 files changed, 15 insertions(+) diff --git a/apps/openmw/mwbase/soundmanager.hpp b/apps/openmw/mwbase/soundmanager.hpp index 85062ace8d..1f0337869b 100644 --- a/apps/openmw/mwbase/soundmanager.hpp +++ b/apps/openmw/mwbase/soundmanager.hpp @@ -109,6 +109,9 @@ namespace MWBase virtual void processChangedSettings(const std::set>& settings) = 0; + virtual bool isEnabled() const = 0; + ///< Returns true if sound system is enabled + virtual void stopMusic() = 0; ///< Stops music if it's playing diff --git a/apps/openmw/mwlua/soundbindings.cpp b/apps/openmw/mwlua/soundbindings.cpp index 102f88ce61..dc45a672b4 100644 --- a/apps/openmw/mwlua/soundbindings.cpp +++ b/apps/openmw/mwlua/soundbindings.cpp @@ -112,6 +112,8 @@ namespace MWLua sol::state_view& lua = context.mLua->sol(); sol::table api(lua, sol::create); + api["isEnabled"] = []() { return MWBase::Environment::get().getSoundManager()->isEnabled(); }; + api["playSound3d"] = [](std::string_view soundId, const Object& object, const sol::optional& options) { auto args = getPlaySoundArgs(options); diff --git a/apps/openmw/mwsound/soundmanagerimp.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp index 87fb109791..94d407c11b 100644 --- a/apps/openmw/mwsound/soundmanagerimp.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -173,6 +173,9 @@ namespace MWSound void processChangedSettings(const Settings::CategorySettingVector& settings) override; + bool isEnabled() const override { return mOutput->isInitialized(); } + ///< Returns true if sound system is enabled + void stopMusic() override; ///< Stops music if it's playing diff --git a/files/lua_api/openmw/core.lua b/files/lua_api/openmw/core.lua index af09274981..a6e9cb361c 100644 --- a/files/lua_api/openmw/core.lua +++ b/files/lua_api/openmw/core.lua @@ -749,6 +749,13 @@ --- @{#Sound}: Sounds and Speech -- @field [parent=#core] #Sound sound +--- +-- Checks if sound system is enabled (any functions to play sounds are no-ops when it is disabled). +-- It can not be enabled or disabled during runtime. +-- @function [parent=#Sound] isEnabled +-- @return #boolean +-- @usage local enabled = core.sound.isEnabled(); + --- -- Play a 3D sound, attached to object -- @function [parent=#Sound] playSound3d