From d9c91ff3d93d85a11b4646a31dbc7a0d8d05ad8e Mon Sep 17 00:00:00 2001 From: Andrei Kortunov <andrei.kortunov@yandex.ru> Date: Wed, 16 Aug 2023 20:23:31 +0400 Subject: [PATCH] Add bindings for ESM::Sound records --- apps/openmw/mwlua/soundbindings.cpp | 41 ++++++++++++++++++++++++++++- files/lua_api/openmw/core.lua | 17 ++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwlua/soundbindings.cpp b/apps/openmw/mwlua/soundbindings.cpp index 7a89354fce..7f3bdc0ecf 100644 --- a/apps/openmw/mwlua/soundbindings.cpp +++ b/apps/openmw/mwlua/soundbindings.cpp @@ -5,6 +5,12 @@ #include "../mwbase/soundmanager.hpp" #include "../mwbase/windowmanager.hpp" +#include <components/esm3/loadsoun.hpp> +#include <components/misc/resourcehelpers.hpp> +#include <components/vfs/pathutil.hpp> + +#include "../mwworld/esmstore.hpp" + #include "luamanagerimp.hpp" namespace MWLua @@ -92,7 +98,8 @@ namespace MWLua sol::table initCoreSoundBindings(const Context& context) { - sol::table api(context.mLua->sol(), sol::create); + sol::state_view& lua = context.mLua->sol(); + sol::table api(lua, sol::create); api["playSound3d"] = [](std::string_view soundId, const Object& object, const sol::optional<sol::table>& options) { @@ -154,6 +161,38 @@ namespace MWLua }, []() { return MWBase::Environment::get().getSoundManager()->sayActive(MWWorld::ConstPtr()); }); + // Sound store + using SoundStore = MWWorld::Store<ESM::Sound>; + const SoundStore* soundStore = &MWBase::Environment::get().getWorld()->getStore().get<ESM::Sound>(); + sol::usertype<SoundStore> soundStoreT = lua.new_usertype<SoundStore>("ESM3_SoundStore"); + soundStoreT[sol::meta_function::to_string] + = [](const SoundStore& store) { return "ESM3_SoundStore{" + std::to_string(store.getSize()) + " sounds}"; }; + soundStoreT[sol::meta_function::length] = [](const SoundStore& store) { return store.getSize(); }; + soundStoreT[sol::meta_function::index] = sol::overload( + [](const SoundStore& store, size_t index) -> const ESM::Sound* { return store.at(index - 1); }, + [](const SoundStore& store, std::string_view soundId) -> const ESM::Sound* { + return store.find(ESM::RefId::deserializeText(soundId)); + }); + soundStoreT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>(); + soundStoreT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>(); + + api["sounds"] = soundStore; + + // Sound record + auto soundT = lua.new_usertype<ESM::Sound>("ESM3_Sound"); + soundT[sol::meta_function::to_string] + = [](const ESM::Sound& rec) -> std::string { return "ESM3_Sound[" + rec.mId.toDebugString() + "]"; }; + soundT["id"] = sol::readonly_property([](const ESM::Sound& rec) { return rec.mId.serializeText(); }); + soundT["volume"] + = sol::readonly_property([](const ESM::Sound& rec) -> unsigned char { return rec.mData.mVolume; }); + soundT["minRange"] + = sol::readonly_property([](const ESM::Sound& rec) -> unsigned char { return rec.mData.mMinRange; }); + soundT["maxRange"] + = sol::readonly_property([](const ESM::Sound& rec) -> unsigned char { return rec.mData.mMaxRange; }); + soundT["fileName"] = sol::readonly_property([](const ESM::Sound& rec) -> std::string { + return VFS::Path::normalizeFilename(Misc::ResourceHelpers::correctSoundPath(rec.mSound)); + }); + return LuaUtil::makeReadOnly(api); } } diff --git a/files/lua_api/openmw/core.lua b/files/lua_api/openmw/core.lua index a19913f1f5..edb481ada9 100644 --- a/files/lua_api/openmw/core.lua +++ b/files/lua_api/openmw/core.lua @@ -843,4 +843,21 @@ -- @usage -- check global voice -- local isActive = isSayActive(); +--- +-- @type Sound +-- @field #string id Sound id +-- @field #string fileName Normalized path to sound file in VFS +-- @field #number volume Raw sound volume, from 0 to 255 +-- @field #number minRange Raw minimal range value, from 0 to 255 +-- @field #number maxRange Raw maximal range value, from 0 to 255 + +--- List of all @{#Sound}s. +-- @field [parent=#Sound] #list<#Sound> sounds +-- @usage local sound = core.sound.sounds['Ashstorm'] -- get by id +-- @usage local sound = core.sound.sounds[1] -- get by index +-- @usage -- Print all sound files paths +-- for _, sound in pairs(core.sound.sounds) do +-- print(sound.fileName) +-- end + return nil