diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 3c29baf3aa..6d58e880ed 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -57,7 +57,7 @@ add_openmw_dir (mwscript add_openmw_dir (mwlua luamanagerimp actions object worldview userdataserializer eventqueue query - luabindings localscripts objectbindings cellbindings asyncbindings camerabindings uibindings + luabindings localscripts objectbindings cellbindings asyncbindings camerabindings uibindings settingsbindings ) add_openmw_dir (mwsound diff --git a/apps/openmw/mwlua/luabindings.cpp b/apps/openmw/mwlua/luabindings.cpp index ebb24401fc..ca800f2dd4 100644 --- a/apps/openmw/mwlua/luabindings.cpp +++ b/apps/openmw/mwlua/luabindings.cpp @@ -31,7 +31,7 @@ namespace MWLua { auto* lua = context.mLua; sol::table api(lua->sol(), sol::create); - api["API_VERSION"] = 0; + api["API_VERSION"] = 1; api["sendGlobalEvent"] = [context](std::string eventName, const sol::object& eventData) { context.mGlobalEventQueue->push_back({std::move(eventName), LuaUtil::serialize(eventData, context.mSerializer)}); diff --git a/apps/openmw/mwlua/luabindings.hpp b/apps/openmw/mwlua/luabindings.hpp index 8be96763a5..568eb4e1ef 100644 --- a/apps/openmw/mwlua/luabindings.hpp +++ b/apps/openmw/mwlua/luabindings.hpp @@ -59,6 +59,11 @@ namespace MWLua // Implemented in uibindings.cpp sol::table initUserInterfacePackage(const Context&); + // Implemented in settingsbindings.cpp + sol::table initGlobalSettingsPackage(const Context&); + sol::table initLocalSettingsPackage(const Context&); + sol::table initPlayerSettingsPackage(const Context&); + // openmw.self package is implemented in localscripts.cpp } diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index b02dbbc296..bbfe0b8c3a 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -60,9 +60,12 @@ namespace MWLua mLua.addCommonPackage("openmw.core", initCorePackage(context)); mLua.addCommonPackage("openmw.query", initQueryPackage(context)); mGlobalScripts.addPackage("openmw.world", initWorldPackage(context)); + mGlobalScripts.addPackage("openmw.settings", initGlobalSettingsPackage(context)); mCameraPackage = initCameraPackage(localContext); mUserInterfacePackage = initUserInterfacePackage(localContext); mNearbyPackage = initNearbyPackage(localContext); + mLocalSettingsPackage = initLocalSettingsPackage(localContext); + mPlayerSettingsPackage = initPlayerSettingsPackage(localContext); mKeyPressEvents.clear(); for (const std::string& path : mGlobalScriptList) @@ -291,9 +294,13 @@ namespace MWLua scripts = std::make_shared(&mLua, LObject(getId(ptr), mWorldView.getObjectRegistry())); scripts->addPackage("openmw.ui", mUserInterfacePackage); scripts->addPackage("openmw.camera", mCameraPackage); + scripts->addPackage("openmw.settings", mPlayerSettingsPackage); } else + { scripts = std::make_shared(&mLua, LObject(getId(ptr), mWorldView.getObjectRegistry())); + scripts->addPackage("openmw.settings", mLocalSettingsPackage); + } scripts->addPackage("openmw.nearby", mNearbyPackage); scripts->setSerializer(mLocalSerializer.get()); diff --git a/apps/openmw/mwlua/luamanagerimp.hpp b/apps/openmw/mwlua/luamanagerimp.hpp index a212f213c0..48cdeba026 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -75,6 +75,8 @@ namespace MWLua sol::table mNearbyPackage; sol::table mUserInterfacePackage; sol::table mCameraPackage; + sol::table mLocalSettingsPackage; + sol::table mPlayerSettingsPackage; std::vector mGlobalScriptList; GlobalScripts mGlobalScripts{&mLua}; diff --git a/apps/openmw/mwlua/settingsbindings.cpp b/apps/openmw/mwlua/settingsbindings.cpp new file mode 100644 index 0000000000..0e267182ac --- /dev/null +++ b/apps/openmw/mwlua/settingsbindings.cpp @@ -0,0 +1,72 @@ +#include "luabindings.hpp" + +#include + +#include "../mwworld/esmstore.hpp" +#include "../mwworld/store.hpp" + +namespace MWLua +{ + + static sol::table initSettingsPackage(const Context& context, bool /*global*/, bool player) + { + LuaUtil::LuaState* lua = context.mLua; + sol::table config(lua->sol(), sol::create); + + // Access to settings.cfg. Temporary, will be removed at some point. + auto checkRead = [player](std::string_view category) + { + if ((category == "Camera" || category == "GUI" || category == "Hud" || + category == "Windows" || category == "Input") && !player) + throw std::runtime_error("This setting is only available in player scripts"); + }; + config["_getBoolFromSettingsCfg"] = [=](const std::string& category, const std::string& setting) + { + checkRead(category); + return Settings::Manager::getBool(setting, category); + }; + config["_getIntFromSettingsCfg"] = [=](const std::string& category, const std::string& setting) + { + checkRead(category); + return Settings::Manager::getInt(setting, category); + }; + config["_getFloatFromSettingsCfg"] = [=](const std::string& category, const std::string& setting) + { + checkRead(category); + return Settings::Manager::getFloat(setting, category); + }; + config["_getStringFromSettingsCfg"] = [=](const std::string& category, const std::string& setting) + { + checkRead(category); + return Settings::Manager::getString(setting, category); + }; + config["_getVector2FromSettingsCfg"] = [=](const std::string& category, const std::string& setting) + { + checkRead(category); + return Settings::Manager::getVector2(setting, category); + }; + config["_getVector3FromSettingsCfg"] = [=](const std::string& category, const std::string& setting) + { + checkRead(category); + return Settings::Manager::getVector3(setting, category); + }; + + const MWWorld::Store* gmst = &MWBase::Environment::get().getWorld()->getStore().get(); + config["getGMST"] = [lua, gmst](const std::string setting) -> sol::object + { + const ESM::Variant& value = gmst->find(setting)->mValue; + if (value.getType() == ESM::VT_String) + return sol::make_object(lua->sol(), value.getString()); + else if (value.getType() == ESM::VT_Int) + return sol::make_object(lua->sol(), value.getInteger()); + else + return sol::make_object(lua->sol(), value.getFloat()); + }; + return lua->makeReadOnly(config); + } + + sol::table initGlobalSettingsPackage(const Context& context) { return initSettingsPackage(context, true, false); } + sol::table initLocalSettingsPackage(const Context& context) { return initSettingsPackage(context, false, false); } + sol::table initPlayerSettingsPackage(const Context& context) { return initSettingsPackage(context, false, true); } + +} diff --git a/docs/source/reference/lua-scripting/api.rst b/docs/source/reference/lua-scripting/api.rst index 3a18f2445a..356fc16cbb 100644 --- a/docs/source/reference/lua-scripting/api.rst +++ b/docs/source/reference/lua-scripting/api.rst @@ -7,6 +7,7 @@ Lua API reference engine_handlers openmw_util + openmw_settings openmw_core openmw_async openmw_query @@ -37,6 +38,9 @@ Player scripts are local scripts that are attached to a player. |:ref:`openmw.util ` | everywhere | | Defines utility functions and classes like 3D vectors, | | | | | that don't depend on the game world. | +---------------------------------------------------------+--------------------+---------------------------------------------------------------+ +|:ref:`openmw.settings ` | everywhere | | Access to GMST records in content files (implemented) and | +| | | | to mod settings (not implemented). | ++---------------------------------------------------------+--------------------+---------------------------------------------------------------+ |:ref:`openmw.core ` | everywhere | | Functions that are common for both global and local scripts | +---------------------------------------------------------+--------------------+---------------------------------------------------------------+ |:ref:`openmw.async ` | everywhere | | Timers (implemented) and coroutine utils (not implemented) | diff --git a/docs/source/reference/lua-scripting/openmw_settings.rst b/docs/source/reference/lua-scripting/openmw_settings.rst new file mode 100644 index 0000000000..f3d26882bb --- /dev/null +++ b/docs/source/reference/lua-scripting/openmw_settings.rst @@ -0,0 +1,5 @@ +Package openmw.settings +======================= + +.. raw:: html + :file: generated_html/openmw_settings.html diff --git a/docs/source/reference/lua-scripting/overview.rst b/docs/source/reference/lua-scripting/overview.rst index d3ce319d01..c193886340 100644 --- a/docs/source/reference/lua-scripting/overview.rst +++ b/docs/source/reference/lua-scripting/overview.rst @@ -299,6 +299,9 @@ Player scripts are local scripts that are attached to a player. |:ref:`openmw.util ` | everywhere | | Defines utility functions and classes like 3D vectors, | | | | | that don't depend on the game world. | +---------------------------------------------------------+--------------------+---------------------------------------------------------------+ +|:ref:`openmw.settings ` | everywhere | | Access to GMST records in content files (implemented) and | +| | | | to mod settings (not implemented). | ++---------------------------------------------------------+--------------------+---------------------------------------------------------------+ |:ref:`openmw.core ` | everywhere | | Functions that are common for both global and local scripts | +---------------------------------------------------------+--------------------+---------------------------------------------------------------+ |:ref:`openmw.async ` | everywhere | | Timers (implemented) and coroutine utils (not implemented) | diff --git a/files/lua_api/openmw/settings.lua b/files/lua_api/openmw/settings.lua new file mode 100644 index 0000000000..6c35caa8af --- /dev/null +++ b/files/lua_api/openmw/settings.lua @@ -0,0 +1,14 @@ +------------------------------------------------------------------------------- +-- `openmw.settings` provides read-only access to GMST records in content files. +-- @module settings +-- @usage +-- local settings = require('openmw.settings') + +------------------------------------------------------------------------------- +-- Get a GMST setting from content files. +-- @function [parent=#settings] getGMST +-- @param #string setting + + +return nil +