diff --git a/CMakeLists.txt b/CMakeLists.txt index 6103ddcb33..78d9aae646 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -82,7 +82,7 @@ message(STATUS "Configuring OpenMW...") set(OPENMW_VERSION_MAJOR 0) set(OPENMW_VERSION_MINOR 50) set(OPENMW_VERSION_RELEASE 0) -set(OPENMW_LUA_API_REVISION 82) +set(OPENMW_LUA_API_REVISION 83) set(OPENMW_POSTPROCESSING_API_REVISION 3) set(OPENMW_VERSION_COMMITHASH "") diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 4dc2fd1fd1..2a5ad2d18d 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -63,7 +63,7 @@ add_openmw_dir (mwlua context menuscripts globalscripts localscripts playerscripts luabindings objectbindings cellbindings coremwscriptbindings mwscriptbindings camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings dialoguebindings postprocessingbindings stats recordstore debugbindings corebindings worldbindings worker landbindings magicbindings factionbindings - classbindings itemdata inputprocessor animationbindings birthsignbindings racebindings markupbindings + classbindings itemdata inputprocessor animationbindings birthsignbindings racebindings markupbindings weatherbindings 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 diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f268ed0e52..956a038f11 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -22,6 +22,7 @@ namespace osg { class Vec3f; + class Vec4f; class Matrixf; class Quat; class Image; @@ -93,6 +94,7 @@ namespace MWWorld class RefData; class Cell; class DateTimeManager; + class Weather; typedef std::vector> PtrMovementList; } @@ -216,9 +218,21 @@ namespace MWBase virtual void changeWeather(const ESM::RefId& region, const unsigned int id) = 0; - virtual int getCurrentWeather() const = 0; + virtual void changeWeather(const ESM::RefId& region, const ESM::RefId& id) = 0; - virtual int getNextWeather() const = 0; + virtual const std::vector& getAllWeather() const = 0; + + virtual int getCurrentWeatherScriptId() const = 0; + + virtual const MWWorld::Weather& getCurrentWeather() const = 0; + + virtual const MWWorld::Weather* getWeather(size_t index) const = 0; + + virtual const MWWorld::Weather* getWeather(const ESM::RefId& id) const = 0; + + virtual int getNextWeatherScriptId() const = 0; + + virtual const MWWorld::Weather* getNextWeather() const = 0; virtual float getWeatherTransition() const = 0; @@ -478,6 +492,7 @@ namespace MWBase // Allow NPCs to use torches? virtual bool useTorches() const = 0; + virtual const osg::Vec4f& getSunLightPosition() const = 0; virtual float getSunVisibility() const = 0; virtual float getSunPercentage() const = 0; diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index b7d4a1361c..a5a3be85f9 100644 --- a/apps/openmw/mwdialogue/filter.cpp +++ b/apps/openmw/mwdialogue/filter.cpp @@ -501,7 +501,7 @@ int MWDialogue::Filter::getSelectStructInteger(const SelectWrapper& select) cons case ESM::DialogueCondition::Function_Weather: - return MWBase::Environment::get().getWorld()->getCurrentWeather(); + return MWBase::Environment::get().getWorld()->getCurrentWeatherScriptId(); case ESM::DialogueCondition::Function_Reputation: if (!mActor.getClass().isNpc()) diff --git a/apps/openmw/mwlua/corebindings.cpp b/apps/openmw/mwlua/corebindings.cpp index b85c14578c..8eb90b48fe 100644 --- a/apps/openmw/mwlua/corebindings.cpp +++ b/apps/openmw/mwlua/corebindings.cpp @@ -27,6 +27,7 @@ #include "magicbindings.hpp" #include "soundbindings.hpp" #include "stats.hpp" +#include "weatherbindings.hpp" namespace MWLua { @@ -104,6 +105,9 @@ namespace MWLua api["land"] = context.cachePackage("openmw_core_land", [context]() { return initCoreLandBindings(context); }); + api["weather"] + = context.cachePackage("openmw_core_weather", [context]() { return initCoreWeatherBindings(context); }); + api["factions"] = context.cachePackage("openmw_core_factions", [context]() { return initCoreFactionBindings(context); }); api["dialogue"] diff --git a/apps/openmw/mwlua/weatherbindings.cpp b/apps/openmw/mwlua/weatherbindings.cpp new file mode 100644 index 0000000000..daabd08620 --- /dev/null +++ b/apps/openmw/mwlua/weatherbindings.cpp @@ -0,0 +1,185 @@ +#include "weatherbindings.hpp" + +#include + +#include +#include +#include +#include +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" +#include "../mwworld/esmstore.hpp" +#include "../mwworld/weather.hpp" + +#include "context.hpp" + +namespace +{ + class WeatherStore + { + public: + const MWWorld::Weather* get(size_t index) const + { + return MWBase::Environment::get().getWorld()->getWeather(index); + } + const MWWorld::Weather* get(const ESM::RefId& id) const + { + return MWBase::Environment::get().getWorld()->getWeather(id); + } + size_t size() const { return MWBase::Environment::get().getWorld()->getAllWeather().size(); } + }; + + Misc::Color color(const osg::Vec4f& color) + { + return Misc::Color(color.r(), color.g(), color.b(), color.a()); + } +} + +namespace MWLua +{ + sol::table initCoreWeatherBindings(const Context& context) + { + sol::state_view lua = context.sol(); + sol::table api(lua, sol::create); + + auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS(); + auto weatherT = lua.new_usertype("Weather"); + weatherT[sol::meta_function::to_string] + = [](const MWWorld::Weather& w) -> std::string { return "Weather[" + w.mName + "]"; }; + weatherT["name"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mName; }); + weatherT["windSpeed"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mWindSpeed; }); + weatherT["cloudSpeed"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mCloudSpeed; }); + weatherT["cloudTexture"] = sol::readonly_property([vfs](const MWWorld::Weather& w) { + return Misc::ResourceHelpers::correctTexturePath(w.mCloudTexture, vfs); + }); + weatherT["cloudsMaximumPercent"] + = sol::readonly_property([](const MWWorld::Weather& w) { return w.mCloudsMaximumPercent; }); + weatherT["isStorm"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mIsStorm; }); + weatherT["stormDirection"] + = sol::readonly_property([](const MWWorld::Weather& w) { return w.mStormDirection; }); + weatherT["glareView"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mGlareView; }); + weatherT["rainSpeed"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainSpeed; }); + weatherT["rainEntranceSpeed"] + = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainEntranceSpeed; }); + weatherT["rainEffect"] = sol::readonly_property([](const MWWorld::Weather& w) -> sol::optional { + if (w.mRainEffect.empty()) + return sol::nullopt; + return w.mRainEffect; + }); + weatherT["rainMaxRaindrops"] + = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainMaxRaindrops; }); + weatherT["rainDiameter"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainDiameter; }); + weatherT["rainThreshold"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainThreshold; }); + weatherT["rainMaxHeight"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainMaxHeight; }); + weatherT["rainMinHeight"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainMinHeight; }); + weatherT["rainLoopSoundID"] + = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainLoopSoundID.serializeText(); }); + weatherT["thunderSoundID"] = sol::readonly_property([lua](const MWWorld::Weather& w) { + sol::table result(lua, sol::create); + for (const auto& soundId : w.mThunderSoundID) + result.add(soundId.serializeText()); + return result; + }); + weatherT["sunDiscSunsetColor"] + = sol::readonly_property([](const MWWorld::Weather& w) { return color(w.mSunDiscSunsetColor); }); + weatherT["ambientLoopSoundID"] + = sol::readonly_property([](const MWWorld::Weather& w) { return w.mAmbientLoopSoundID.serializeText(); }); + weatherT["ambientColor"] = sol::readonly_property([lua](const MWWorld::Weather& w) { + sol::table result(lua, sol::create); + result["sunrise"] = color(w.mAmbientColor.getSunriseValue()); + result["day"] = color(w.mAmbientColor.getDayValue()); + result["sunset"] = color(w.mAmbientColor.getSunsetValue()); + result["night"] = color(w.mAmbientColor.getNightValue()); + return result; + }); + weatherT["fogColor"] = sol::readonly_property([lua](const MWWorld::Weather& w) { + sol::table result(lua, sol::create); + result["sunrise"] = color(w.mFogColor.getSunriseValue()); + result["day"] = color(w.mFogColor.getDayValue()); + result["sunset"] = color(w.mFogColor.getSunsetValue()); + result["night"] = color(w.mFogColor.getNightValue()); + return result; + }); + weatherT["skyColor"] = sol::readonly_property([lua](const MWWorld::Weather& w) { + sol::table result(lua, sol::create); + result["sunrise"] = color(w.mSkyColor.getSunriseValue()); + result["day"] = color(w.mSkyColor.getDayValue()); + result["sunset"] = color(w.mSkyColor.getSunsetValue()); + result["night"] = color(w.mSkyColor.getNightValue()); + return result; + }); + weatherT["sunColor"] = sol::readonly_property([lua](const MWWorld::Weather& w) { + sol::table result(lua, sol::create); + result["sunrise"] = color(w.mSunColor.getSunriseValue()); + result["day"] = color(w.mSunColor.getDayValue()); + result["sunset"] = color(w.mSunColor.getSunsetValue()); + result["night"] = color(w.mSunColor.getNightValue()); + return result; + }); + weatherT["landFogDepth"] = sol::readonly_property([lua](const MWWorld::Weather& w) { + sol::table result(lua, sol::create); + result["sunrise"] = w.mLandFogDepth.getSunriseValue(); + result["day"] = w.mLandFogDepth.getDayValue(); + result["sunset"] = w.mLandFogDepth.getSunsetValue(); + result["night"] = w.mLandFogDepth.getNightValue(); + return result; + }); + weatherT["particleEffect"] + = sol::readonly_property([](const MWWorld::Weather& w) -> sol::optional { + if (w.mParticleEffect.empty()) + return sol::nullopt; + return w.mParticleEffect; + }); + weatherT["distantLandFogFactor"] + = sol::readonly_property([](const MWWorld::Weather& w) { return w.mDL.FogFactor; }); + weatherT["distantLandFogOffset"] + = sol::readonly_property([](const MWWorld::Weather& w) { return w.mDL.FogOffset; }); + weatherT["scriptId"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mScriptId; }); + weatherT["recordId"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mId.serializeText(); }); + + api["getCurrent"] = []() { return MWBase::Environment::get().getWorld()->getCurrentWeather(); }; + api["getNext"] + = []() -> const MWWorld::Weather* { return MWBase::Environment::get().getWorld()->getNextWeather(); }; + api["getTransition"] = []() { return MWBase::Environment::get().getWorld()->getWeatherTransition(); }; + + api["changeWeather"] = [](std::string_view regionId, const MWWorld::Weather& weather) { + ESM::RefId region = ESM::RefId::deserializeText(regionId); + MWBase::Environment::get().getESMStore()->get().find(region); + MWBase::Environment::get().getWorld()->changeWeather(region, weather.mId); + }; + + sol::usertype storeT = lua.new_usertype("WeatherWorldStore"); + storeT[sol::meta_function::to_string] + = [](const WeatherStore& store) { return "{" + std::to_string(store.size()) + " Weather records}"; }; + storeT[sol::meta_function::length] = [](const WeatherStore& store) { return store.size(); }; + storeT[sol::meta_function::index] = sol::overload( + [](const WeatherStore& store, size_t index) -> const MWWorld::Weather* { + return store.get(LuaUtil::fromLuaIndex(index)); + }, + [](const WeatherStore& store, std::string_view id) -> const MWWorld::Weather* { + return store.get(ESM::RefId::deserializeText(id)); + }); + storeT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get(); + storeT[sol::meta_function::pairs] = lua["ipairsForArray"].template get(); + + // Provide access to the store. + api["records"] = WeatherStore{}; + + api["getCurrentSunLightDirection"] = []() { + osg::Vec4f sunPos = MWBase::Environment::get().getWorld()->getSunLightPosition(); + // normalize to get the direction towards the sun + sunPos.normalize(); + + // and invert it to get the direction of the sun light + return -sunPos; + }; + api["getCurrentSunVisibility"] = []() { return MWBase::Environment::get().getWorld()->getSunVisibility(); }; + api["getCurrentSunPercentage"] = []() { return MWBase::Environment::get().getWorld()->getSunPercentage(); }; + api["getCurrentWindSpeed"] = []() { return MWBase::Environment::get().getWorld()->getWindSpeed(); }; + api["getCurrentStormDirection"] = []() { return MWBase::Environment::get().getWorld()->getStormDirection(); }; + + return LuaUtil::makeReadOnly(api); + } +} diff --git a/apps/openmw/mwlua/weatherbindings.hpp b/apps/openmw/mwlua/weatherbindings.hpp new file mode 100644 index 0000000000..c4686602ff --- /dev/null +++ b/apps/openmw/mwlua/weatherbindings.hpp @@ -0,0 +1,14 @@ +#ifndef MWLUA_WEATHERBINDINGS_H +#define MWLUA_WEATHERBINDINGS_H + +#include + +namespace MWLua +{ + struct Context; + + sol::table initCoreWeatherBindings(const Context&); + +} + +#endif // MWLUA_WEATHERBINDINGS_H diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 6afbfcfe7d..0698e8c4ae 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -943,8 +943,8 @@ namespace MWRender stateUpdater->setIsUnderwater(isUnderwater); stateUpdater->setFogColor(fogColor); stateUpdater->setGameHour(world->getTimeStamp().getHour()); - stateUpdater->setWeatherId(world->getCurrentWeather()); - stateUpdater->setNextWeatherId(world->getNextWeather()); + stateUpdater->setWeatherId(world->getCurrentWeatherScriptId()); + stateUpdater->setNextWeatherId(world->getNextWeatherScriptId()); stateUpdater->setWeatherTransition(world->getWeatherTransition()); stateUpdater->setWindSpeed(world->getWindSpeed()); stateUpdater->setSkyColor(mSky->getSkyColor()); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 2e573f8276..4723c59b8a 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -139,6 +139,7 @@ namespace MWRender int skyGetSecundaPhase() const; void skySetMoonColour(bool red); + const osg::Vec4f& getSunLightPosition() const { return mSunLight->getPosition(); } void setSunDirection(const osg::Vec3f& direction); void setSunColour(const osg::Vec4f& diffuse, const osg::Vec4f& specular, float sunVis); void setNight(bool isNight) { mNight = isNight; } diff --git a/apps/openmw/mwscript/skyextensions.cpp b/apps/openmw/mwscript/skyextensions.cpp index d2b41fb87a..b354bb5ce2 100644 --- a/apps/openmw/mwscript/skyextensions.cpp +++ b/apps/openmw/mwscript/skyextensions.cpp @@ -71,7 +71,7 @@ namespace MWScript public: void execute(Interpreter::Runtime& runtime) override { - runtime.push(MWBase::Environment::get().getWorld()->getCurrentWeather()); + runtime.push(MWBase::Environment::get().getWorld()->getCurrentWeatherScriptId()); } }; diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 2ee77458d4..f2cffb5611 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -1,5 +1,6 @@ #include "weather.hpp" +#include #include #include @@ -141,9 +142,12 @@ namespace MWWorld return direction; } - Weather::Weather(const std::string& name, float stormWindSpeed, float rainSpeed, float dlFactor, float dlOffset, - const std::string& particleEffect) - : mCloudTexture(Fallback::Map::getString("Weather_" + name + "_Cloud_Texture")) + Weather::Weather(ESM::RefId id, int scriptId, const std::string& name, float stormWindSpeed, float rainSpeed, + float dlFactor, float dlOffset, const std::string& particleEffect) + : mId(id) + , mScriptId(scriptId) + , mName(name) + , mCloudTexture(Fallback::Map::getString("Weather_" + name + "_Cloud_Texture")) , mSkyColor(Fallback::Map::getColour("Weather_" + name + "_Sky_Sunrise_Color"), Fallback::Map::getColour("Weather_" + name + "_Sky_Day_Color"), Fallback::Map::getColour("Weather_" + name + "_Sky_Sunset_Color"), @@ -676,6 +680,41 @@ namespace MWWorld stopSounds(); } + const Weather* WeatherManager::getWeather(size_t index) const + { + if (index < mWeatherSettings.size()) + return &mWeatherSettings[index]; + + return nullptr; + } + + const Weather* WeatherManager::getWeather(const ESM::RefId& id) const + { + auto it = std::find_if( + mWeatherSettings.begin(), mWeatherSettings.end(), [id](const auto& weather) { return weather.mId == id; }); + + if (it != mWeatherSettings.end()) + return &*it; + + return nullptr; + } + + void WeatherManager::changeWeather(const ESM::RefId& regionID, const ESM::RefId& weatherID) + { + auto wIt = std::find_if(mWeatherSettings.begin(), mWeatherSettings.end(), + [weatherID](const auto& weather) { return weather.mId == weatherID; }); + + if (wIt != mWeatherSettings.end()) + { + auto rIt = mRegions.find(regionID); + if (rIt != mRegions.end()) + { + rIt->second.setWeather(std::distance(mWeatherSettings.begin(), wIt)); + regionalWeatherChanged(rIt->first, rIt->second); + } + } + } + void WeatherManager::changeWeather(const ESM::RefId& regionID, const unsigned int weatherID) { // In Morrowind, this seems to have the following behavior, when applied to the current region: @@ -1053,8 +1092,9 @@ namespace MWWorld const std::string& name, float dlFactor, float dlOffset, const std::string& particleEffect) { static const float fStromWindSpeed = mStore.get().find("fStromWindSpeed")->mValue.getFloat(); - - Weather weather(name, fStromWindSpeed, mRainSpeed, dlFactor, dlOffset, particleEffect); + ESM::StringRefId id(name); + Weather weather( + id, mWeatherSettings.size(), name, fStromWindSpeed, mRainSpeed, dlFactor, dlOffset, particleEffect); mWeatherSettings.push_back(weather); } diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index 7c27a10316..ddc96f0ae6 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -109,6 +109,11 @@ namespace MWWorld T getValue(const float gameHour, const TimeOfDaySettings& timeSettings, const std::string& prefix) const; + const T& getSunriseValue() const { return mSunriseValue; } + const T& getDayValue() const { return mDayValue; } + const T& getSunsetValue() const { return mSunsetValue; } + const T& getNightValue() const { return mNightValue; } + private: T mSunriseValue, mDayValue, mSunsetValue, mNightValue; }; @@ -119,9 +124,12 @@ namespace MWWorld public: static osg::Vec3f defaultDirection(); - Weather(const std::string& name, float stormWindSpeed, float rainSpeed, float dlFactor, float dlOffset, - const std::string& particleEffect); + Weather(const ESM::RefId id, const int scriptId, const std::string& name, float stormWindSpeed, float rainSpeed, + float dlFactor, float dlOffset, const std::string& particleEffect); + ESM::RefId mId; + int mScriptId; + std::string mName; std::string mCloudTexture; // Sky (atmosphere) color @@ -289,11 +297,12 @@ namespace MWWorld ~WeatherManager(); /** - * Change the weather in the specified region + * Change the weather in the specified region by id of the weather * @param region that should be changed * @param ID of the weather setting to shift to */ void changeWeather(const ESM::RefId& regionID, const unsigned int weatherID); + void changeWeather(const ESM::RefId& regionID, const ESM::RefId& weatherID); void modRegion(const ESM::RefId& regionID, const std::vector& chances); void playerTeleported(const ESM::RefId& playerRegion, bool isExterior); @@ -316,8 +325,23 @@ namespace MWWorld void advanceTime(double hours, bool incremental); + const std::vector& getAllWeather() { return mWeatherSettings; } + + const Weather& getWeather() { return mWeatherSettings[mCurrentWeather]; } + + const Weather* getWeather(size_t index) const; + + const Weather* getWeather(const ESM::RefId& id) const; + int getWeatherID() const { return mCurrentWeather; } + const Weather* getNextWeather() + { + if (mNextWeather > -1) + return &mWeatherSettings[mNextWeather]; + return nullptr; + } + int getNextWeatherID() const { return mNextWeather; } float getTransitionFactor() const { return mTransitionFactor; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 97788669d5..02b93706b3 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1868,14 +1868,43 @@ namespace MWWorld return ESM::Cell::sDefaultWorldspaceId; } - int World::getCurrentWeather() const + const std::vector& World::getAllWeather() const { - return mWeatherManager->getWeatherID(); + return mWeatherManager->getAllWeather(); } - int World::getNextWeather() const + int World::getCurrentWeatherScriptId() const { - return mWeatherManager->getNextWeatherID(); + return mWeatherManager->getWeather().mScriptId; + } + + const MWWorld::Weather& World::getCurrentWeather() const + { + return mWeatherManager->getWeather(); + } + + const MWWorld::Weather* World::getWeather(size_t index) const + { + return mWeatherManager->getWeather(index); + } + + const MWWorld::Weather* World::getWeather(const ESM::RefId& id) const + { + return mWeatherManager->getWeather(id); + } + + int World::getNextWeatherScriptId() const + { + auto next = mWeatherManager->getNextWeather(); + if (next == nullptr) + return -1; + + return next->mScriptId; + } + + const MWWorld::Weather* World::getNextWeather() const + { + return mWeatherManager->getNextWeather(); } float World::getWeatherTransition() const @@ -1893,6 +1922,11 @@ namespace MWWorld mWeatherManager->changeWeather(region, id); } + void World::changeWeather(const ESM::RefId& region, const ESM::RefId& id) + { + mWeatherManager->changeWeather(region, id); + } + void World::modRegion(const ESM::RefId& regionid, const std::vector& chances) { mWeatherManager->modRegion(regionid, chances); @@ -3133,6 +3167,11 @@ namespace MWWorld } } + const osg::Vec4f& World::getSunLightPosition() const + { + return mRendering->getSunLightPosition(); + } + float World::getSunVisibility() const { return mWeatherManager->getSunVisibility(); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index b1286d5532..a9af507857 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -317,9 +317,16 @@ namespace MWWorld void changeWeather(const ESM::RefId& region, const unsigned int id) override; - int getCurrentWeather() const override; + void changeWeather(const ESM::RefId& region, const ESM::RefId& id) override; - int getNextWeather() const override; + const std::vector& getAllWeather() const override; + + int getCurrentWeatherScriptId() const override; + const MWWorld::Weather& getCurrentWeather() const override; + const MWWorld::Weather* getWeather(size_t index) const override; + const MWWorld::Weather* getWeather(const ESM::RefId& id) const override; + int getNextWeatherScriptId() const override; + const MWWorld::Weather* getNextWeather() const override; float getWeatherTransition() const override; @@ -573,6 +580,7 @@ namespace MWWorld // Allow NPCs to use torches? bool useTorches() const override; + const osg::Vec4f& getSunLightPosition() const override; float getSunVisibility() const override; float getSunPercentage() const override; diff --git a/files/lua_api/openmw/core.lua b/files/lua_api/openmw/core.lua index 94fefb2b6d..ceb3829cd3 100644 --- a/files/lua_api/openmw/core.lua +++ b/files/lua_api/openmw/core.lua @@ -1198,4 +1198,100 @@ -- @field #string id MWScript id -- @field #string text MWScript content + +--- @{#Weather}: Weather +-- @field [parent=#core] #Weather weather + +--- List of all @{#WeatherRecord}s. +-- @field [parent=#Weather] #list<#WeatherRecord> records A read-only list of all @{#WeatherRecord}s in the world database, may be indexed by recordId. +-- Implements [iterables#List](iterables.html#List) of #WeatherRecord. +-- @usage local weather = core.weather.records['Cloudy'] -- get by id +-- @usage local weather = core.weather.records[1] -- get by index +-- @usage -- Print all storms +-- for _, weather in pairs(core.weather.records) do +-- if weather.isStorm then +-- print(weather.name) +-- end +-- end + +--- +-- Get the current weather +-- @function [parent=#Weather] getCurrent +-- @return #WeatherData + +--- +-- Get the next weather if any +-- @function [parent=#Weather] getNext +-- @return #any can be nil + +--- +-- Get current weather transition value +-- @function [parent=#Weather] getTransition +-- @return #number + +--- +-- Change the weather +-- @function [parent=#Weather] changeWeather +-- @param #string regionId +-- @param #WeatherData The weather to change to + +--- +-- Get the current direction of the light of the sun. +-- @function [parent=#Weather] getCurrentSunLightDirection +-- @return openmw.util#Vector4 + +--- +-- Get the current sun visibility taking weather transition into account. +-- @function [parent=#Weather] getCurrentSunVisibility +-- @return #number + +--- +-- Get the current sun percentage taking weather transition into account. +-- @function [parent=#Weather] getCurrentSunPercentage +-- @return #number + +--- +-- Get the current wind speed taking weather transition into account. +-- @function [parent=#Weather] getCurrentWindSpeed +-- @return #number + +--- +-- Get the current storm direction taking weather transition into account. +-- @function [parent=#Weather] getCurrentStormDirection +-- @return openmw.util#Vector3 + +--- +-- Weather data +-- @type WeatherRecord +-- @extends #userdata +-- @field #string recordId +-- @field #number scriptId +-- @field #string name +-- @field #number windSpeed +-- @field #number cloudSpeed +-- @field #string cloudTexture +-- @field #number cloudsMaximumPercent +-- @field #boolean isStorm +-- @field openmw.util#Vector3 stormDirection +-- @field #number glareView +-- @field #number rainSpeed +-- @field #number rainEntranceSpeed +-- @field #string rainEffect Will return nil if weather has no rainEffect +-- @field #number rainMaxRaindrops +-- @field #number rainDiameter +-- @field #number rainMaxHeight +-- @field #number rainMinHeight +-- @field #string rainLoopSoundID +-- @field #table thunderSoundID An array containing the recordIds of the thunder sounds +-- @field #string ambientLoopSoundID +-- @field #string particleEffect Will return nil if weather has no particleEffect +-- @field #number distantLandFogFactor +-- @field #number distantLandFogOffset +-- @field openmw.util#Color sunDiscSunsetColor +-- @field #table landFogDepth A table with the keys "sunrise", "day", "sunset" and "night" +-- @field #table skyColor A table with the keys "sunrise", "day", "sunset" and "night". Each is a @{openmw.util#Color}. +-- @field #table ambientColor A table with the keys "sunrise", "day", "sunset" and "night". Each is a @{openmw.util#Color}. +-- @field #table fogColor A table with the keys "sunrise", "day", "sunset" and "night". Each is a @{openmw.util#Color}. +-- @field #table sunColor A table with the keys "sunrise", "day", "sunset" and "night". Each is a @{openmw.util#Color}. + return nil