From 63e51de42f63eeb5f2aee63673464797ccc0eb7c Mon Sep 17 00:00:00 2001 From: Sebastian Fieber Date: Fri, 24 Jan 2025 23:06:18 +0100 Subject: [PATCH 1/6] lua - add weatherbindings to world --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwlua/weatherbindings.cpp | 39 +++++++++++++++++++++++++++ apps/openmw/mwlua/weatherbindings.hpp | 15 +++++++++++ apps/openmw/mwlua/worldbindings.cpp | 2 ++ 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 apps/openmw/mwlua/weatherbindings.cpp create mode 100644 apps/openmw/mwlua/weatherbindings.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 37de0abeab..4ead1c8cc2 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 mwscriptbindings camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings dialoguebindings postprocessingbindings stats recordstore debugbindings corebindings worldbindings worker 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/mwlua/weatherbindings.cpp b/apps/openmw/mwlua/weatherbindings.cpp new file mode 100644 index 0000000000..cee390e3d2 --- /dev/null +++ b/apps/openmw/mwlua/weatherbindings.cpp @@ -0,0 +1,39 @@ +#include "weatherbindings.hpp" + +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" +#include "../mwworld/esmstore.hpp" + +namespace MWLua +{ + sol::table initWeatherBindings(const Context& context) + { + sol::state_view lua = context.sol(); + sol::table api(lua, sol::create); + + api["getCurrentWeather"] = []() { return MWBase::Environment::get().getWorld()->getCurrentWeather(); }; + + api["getNextWeather"] = []() { return MWBase::Environment::get().getWorld()->getNextWeather(); }; + + api["getWindSpeed"] = []() { return MWBase::Environment::get().getWorld()->getWindSpeed(); }; + + api["getSunVisibility"] = []() { return MWBase::Environment::get().getWorld()->getSunVisibility(); }; + + api["getSunPercentage"] = []() { return MWBase::Environment::get().getWorld()->getSunPercentage(); }; + + api["getStormDirection"] = []() { return MWBase::Environment::get().getWorld()->getStormDirection(); }; + + api["changeWeather"] = [](std::string_view regionId, int weatherId) { + ESM::RefId region = ESM::RefId::stringRefId(regionId); + const ESM::Region* reg = MWBase::Environment::get().getESMStore()->get().search(region); + if (reg) + MWBase::Environment::get().getWorld()->changeWeather(region, weatherId); + else + throw std::runtime_error("Region not found"); + }; + + return LuaUtil::makeReadOnly(api); + } +} diff --git a/apps/openmw/mwlua/weatherbindings.hpp b/apps/openmw/mwlua/weatherbindings.hpp new file mode 100644 index 0000000000..5146c5ef4a --- /dev/null +++ b/apps/openmw/mwlua/weatherbindings.hpp @@ -0,0 +1,15 @@ +#ifndef MWLUA_WEATHERBINDINGS_H +#define MWLUA_WEATHERBINDINGS_H + +#include + +#include "context.hpp" + +namespace MWLua +{ + + sol::table initWeatherBindings(const Context&); + +} + +#endif // MWLUA_WEATHERBINDINGS_H diff --git a/apps/openmw/mwlua/worldbindings.cpp b/apps/openmw/mwlua/worldbindings.cpp index ac7bd307cf..1e5a313aaf 100644 --- a/apps/openmw/mwlua/worldbindings.cpp +++ b/apps/openmw/mwlua/worldbindings.cpp @@ -28,6 +28,7 @@ #include "animationbindings.hpp" #include "corebindings.hpp" #include "mwscriptbindings.hpp" +#include "weatherbindings.hpp" namespace MWLua { @@ -138,6 +139,7 @@ namespace MWLua addWorldTimeBindings(api, context); addCellGetters(api, context); api["mwscript"] = initMWScriptBindings(context); + api["weather"] = initWeatherBindings(context); ObjectLists* objectLists = context.mObjectLists; api["activeActors"] = GObjectList{ objectLists->getActorsInScene() }; From 0484abbba5535d224028c1ed86319db45e45d9b4 Mon Sep 17 00:00:00 2001 From: Sebastian Fieber Date: Sat, 25 Jan 2025 01:22:22 +0100 Subject: [PATCH 2/6] map MWWorld::Weather to lua --- apps/openmw/mwbase/world.hpp | 7 ++- apps/openmw/mwdialogue/filter.cpp | 2 +- apps/openmw/mwlua/weatherbindings.cpp | 58 ++++++++++++++++++----- apps/openmw/mwrender/renderingmanager.cpp | 4 +- apps/openmw/mwscript/skyextensions.cpp | 2 +- apps/openmw/mwworld/weather.cpp | 32 +++++++++++-- apps/openmw/mwworld/weather.hpp | 24 ++++++++-- apps/openmw/mwworld/worldimp.cpp | 13 +++-- apps/openmw/mwworld/worldimp.hpp | 6 ++- 9 files changed, 118 insertions(+), 30 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 20a27e5bc3..f79c9d791e 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -16,6 +16,7 @@ #include "../mwworld/globalvariablename.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/spellcaststate.hpp" +#include "../mwworld/weather.hpp" #include "../mwrender/rendermode.hpp" @@ -216,9 +217,11 @@ 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 std::string name) = 0; - virtual int getNextWeather() const = 0; + virtual MWWorld::Weather* getCurrentWeather() const = 0; + + virtual MWWorld::Weather* getNextWeather() const = 0; virtual float getWeatherTransition() const = 0; diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index 295d690ce5..d194eeb1a0 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()->getCurrentWeather()->mId; case ESM::DialogueCondition::Function_Reputation: diff --git a/apps/openmw/mwlua/weatherbindings.cpp b/apps/openmw/mwlua/weatherbindings.cpp index cee390e3d2..82344eb2ff 100644 --- a/apps/openmw/mwlua/weatherbindings.cpp +++ b/apps/openmw/mwlua/weatherbindings.cpp @@ -5,6 +5,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwworld/weather.hpp" namespace MWLua { @@ -13,23 +14,58 @@ namespace MWLua sol::state_view lua = context.sol(); sol::table api(lua, sol::create); - api["getCurrentWeather"] = []() { return MWBase::Environment::get().getWorld()->getCurrentWeather(); }; + 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([](const MWWorld::Weather& w) { return w.mCloudTexture; }); + 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) { 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; }); + weatherT["thunderSoundID"] + = sol::readonly_property([](const MWWorld::Weather& w) { return w.mThunderSoundID; }); + weatherT["ambientLoopSoundID"] + = sol::readonly_property([](const MWWorld::Weather& w) { return w.mAmbientLoopSoundID; }); + weatherT["landForDepth"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mLandFogDepth; }); + weatherT["particleEffect"] + = sol::readonly_property([](const MWWorld::Weather& w) { return w.mParticleEffect; }); + weatherT["distantLandFogFactor"] + = sol::readonly_property([](const MWWorld::Weather& w) { return w.mDL.FogFactor; }); + weatherT["distandLandForOffset"] + = sol::readonly_property([](const MWWorld::Weather& w) { return w.mDL.FogOffset; }); - api["getNextWeather"] = []() { return MWBase::Environment::get().getWorld()->getNextWeather(); }; + api["getCurrent"] = []() { return *MWBase::Environment::get().getWorld()->getCurrentWeather(); }; + api["getNext"] = []() { return *MWBase::Environment::get().getWorld()->getNextWeather(); }; + api["getTransition"] = []() { return *MWBase::Environment::get().getWorld()->getWeatherTransition(); }; - api["getWindSpeed"] = []() { return MWBase::Environment::get().getWorld()->getWindSpeed(); }; + // TODO these return values that already take weather transition into account - maybe good to have? + 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(); }; - api["getSunVisibility"] = []() { return MWBase::Environment::get().getWorld()->getSunVisibility(); }; - - api["getSunPercentage"] = []() { return MWBase::Environment::get().getWorld()->getSunPercentage(); }; - - api["getStormDirection"] = []() { return MWBase::Environment::get().getWorld()->getStormDirection(); }; - - api["changeWeather"] = [](std::string_view regionId, int weatherId) { + api["changeWeather"] = [](std::string_view regionId, std::string_view weatherName) { ESM::RefId region = ESM::RefId::stringRefId(regionId); const ESM::Region* reg = MWBase::Environment::get().getESMStore()->get().search(region); if (reg) - MWBase::Environment::get().getWorld()->changeWeather(region, weatherId); + MWBase::Environment::get().getWorld()->changeWeather(region, std::string(weatherName)); else throw std::runtime_error("Region not found"); }; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 6afbfcfe7d..c16d251409 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->getCurrentWeather()->mId); + stateUpdater->setNextWeatherId(world->getNextWeather() ? world->getNextWeather()->mId : -1); stateUpdater->setWeatherTransition(world->getWeatherTransition()); stateUpdater->setWindSpeed(world->getWindSpeed()); stateUpdater->setSkyColor(mSky->getSkyColor()); diff --git a/apps/openmw/mwscript/skyextensions.cpp b/apps/openmw/mwscript/skyextensions.cpp index d2b41fb87a..260cc8689d 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()->getCurrentWeather()->mId); } }; diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 4f6f52a81a..68425dad54 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -141,9 +141,11 @@ 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(int id, const std::string& name, float stormWindSpeed, float rainSpeed, float dlFactor, + float dlOffset, const std::string& particleEffect) + : mId(id) + , 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"), @@ -603,6 +605,28 @@ namespace MWWorld stopSounds(); } + void WeatherManager::changeWeather(const ESM::RefId& regionID, const std::string weatherName) + { + int weatherID = -1; + for (const auto& weather : mWeatherSettings) + { + if (weather.mName == weatherName) + { + weatherID = weather.mId; + } + } + + if (weatherID < mWeatherSettings.size() && weatherID > -1) + { + auto it = mRegions.find(regionID); + if (it != mRegions.end()) + { + it->second.setWeather(weatherID); + regionalWeatherChanged(it->first, it->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: @@ -981,7 +1005,7 @@ namespace MWWorld { static const float fStromWindSpeed = mStore.get().find("fStromWindSpeed")->mValue.getFloat(); - Weather weather(name, fStromWindSpeed, mRainSpeed, dlFactor, dlOffset, particleEffect); + Weather weather(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 0643240dcd..45daa6257b 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -119,9 +119,11 @@ 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 int id, const std::string& name, float stormWindSpeed, float rainSpeed, float dlFactor, + float dlOffset, const std::string& particleEffect); + int mId; + std::string mName; std::string mCloudTexture; // Sky (atmosphere) color @@ -284,11 +286,18 @@ 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); + + /** + * Change the weather in the specified region by name of the weather + * @param region that should be changed + * @param name of the weather setting to shift to + */ + void changeWeather(const ESM::RefId& regionID, const std::string weatherName); void modRegion(const ESM::RefId& regionID, const std::vector& chances); void playerTeleported(const ESM::RefId& playerRegion, bool isExterior); @@ -311,8 +320,17 @@ namespace MWWorld void advanceTime(double hours, bool incremental); + Weather* getWeather() { return &mWeatherSettings[mCurrentWeather]; } + int getWeatherID() const { return mCurrentWeather; } + 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 7b2f178343..e225819c54 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1875,14 +1875,14 @@ namespace MWWorld return ESM::Cell::sDefaultWorldspaceId; } - int World::getCurrentWeather() const + MWWorld::Weather* World::getCurrentWeather() const { - return mWeatherManager->getWeatherID(); + return mWeatherManager->getWeather(); } - int World::getNextWeather() const + MWWorld::Weather* World::getNextWeather() const { - return mWeatherManager->getNextWeatherID(); + return mWeatherManager->getNextWeather(); } float World::getWeatherTransition() const @@ -1900,6 +1900,11 @@ namespace MWWorld mWeatherManager->changeWeather(region, id); } + void World::changeWeather(const ESM::RefId& region, const std::string name) + { + mWeatherManager->changeWeather(region, name); + } + void World::modRegion(const ESM::RefId& regionid, const std::vector& chances) { mWeatherManager->modRegion(regionid, chances); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 6f06812e20..962cbfb797 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -316,9 +316,11 @@ namespace MWWorld void changeWeather(const ESM::RefId& region, const unsigned int id) override; - int getCurrentWeather() const override; + void changeWeather(const ESM::RefId& region, const std::string name) override; - int getNextWeather() const override; + MWWorld::Weather* getCurrentWeather() const override; + + MWWorld::Weather* getNextWeather() const override; float getWeatherTransition() const override; From c72d84f61a146fe193be67511f08bc7542634fd7 Mon Sep 17 00:00:00 2001 From: Sebastian Fieber Date: Sun, 26 Jan 2025 23:05:24 +0100 Subject: [PATCH 3/6] getAllWeather --- apps/openmw/mwbase/world.hpp | 2 ++ apps/openmw/mwlua/weatherbindings.cpp | 15 +++++++++++---- apps/openmw/mwworld/weather.hpp | 2 ++ apps/openmw/mwworld/worldimp.cpp | 5 +++++ apps/openmw/mwworld/worldimp.hpp | 2 ++ 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f79c9d791e..7cadc444b9 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -219,6 +219,8 @@ namespace MWBase virtual void changeWeather(const ESM::RefId& region, const std::string name) = 0; + virtual std::vector getAllWeather() const = 0; + virtual MWWorld::Weather* getCurrentWeather() const = 0; virtual MWWorld::Weather* getNextWeather() const = 0; diff --git a/apps/openmw/mwlua/weatherbindings.cpp b/apps/openmw/mwlua/weatherbindings.cpp index 82344eb2ff..d830782bf4 100644 --- a/apps/openmw/mwlua/weatherbindings.cpp +++ b/apps/openmw/mwlua/weatherbindings.cpp @@ -53,12 +53,12 @@ namespace MWLua api["getCurrent"] = []() { return *MWBase::Environment::get().getWorld()->getCurrentWeather(); }; api["getNext"] = []() { return *MWBase::Environment::get().getWorld()->getNextWeather(); }; - api["getTransition"] = []() { return *MWBase::Environment::get().getWorld()->getWeatherTransition(); }; + api["getTransition"] = []() { return MWBase::Environment::get().getWorld()->getWeatherTransition(); }; // TODO these return values that already take weather transition into account - maybe good to have? - 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["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(); }; api["changeWeather"] = [](std::string_view regionId, std::string_view weatherName) { @@ -70,6 +70,13 @@ namespace MWLua throw std::runtime_error("Region not found"); }; + api["getAllWeather"] = [context]() { + sol::table allWeather(context.sol(), sol::create); + for (const auto &weather : MWBase::Environment::get().getWorld()->getAllWeather()) + allWeather.add(weather); + return allWeather; + }; + return LuaUtil::makeReadOnly(api); } } diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index 45daa6257b..9b4325445c 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -320,6 +320,8 @@ namespace MWWorld void advanceTime(double hours, bool incremental); + std::vector getAllWeather() { return mWeatherSettings; } + Weather* getWeather() { return &mWeatherSettings[mCurrentWeather]; } int getWeatherID() const { return mCurrentWeather; } diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index e225819c54..4c1d63bc04 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1875,6 +1875,11 @@ namespace MWWorld return ESM::Cell::sDefaultWorldspaceId; } + std::vector World::getAllWeather() const + { + return mWeatherManager->getAllWeather(); + } + MWWorld::Weather* World::getCurrentWeather() const { return mWeatherManager->getWeather(); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 962cbfb797..b922d4b250 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -318,6 +318,8 @@ namespace MWWorld void changeWeather(const ESM::RefId& region, const std::string name) override; + std::vector getAllWeather() const override; + MWWorld::Weather* getCurrentWeather() const override; MWWorld::Weather* getNextWeather() const override; From 6c8c013b47e58af53510cf7fe1c140e11d967cce Mon Sep 17 00:00:00 2001 From: Sebastian Fieber Date: Sun, 26 Jan 2025 23:19:48 +0100 Subject: [PATCH 4/6] changeWeather(string,weather) instead of changeWeather(string, string) --- apps/openmw/mwbase/world.hpp | 2 -- apps/openmw/mwlua/weatherbindings.cpp | 6 +++--- apps/openmw/mwworld/weather.cpp | 22 ---------------------- apps/openmw/mwworld/weather.hpp | 7 ------- apps/openmw/mwworld/worldimp.cpp | 5 ----- apps/openmw/mwworld/worldimp.hpp | 2 -- 6 files changed, 3 insertions(+), 41 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 7cadc444b9..ece32b3e10 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -217,8 +217,6 @@ namespace MWBase virtual void changeWeather(const ESM::RefId& region, const unsigned int id) = 0; - virtual void changeWeather(const ESM::RefId& region, const std::string name) = 0; - virtual std::vector getAllWeather() const = 0; virtual MWWorld::Weather* getCurrentWeather() const = 0; diff --git a/apps/openmw/mwlua/weatherbindings.cpp b/apps/openmw/mwlua/weatherbindings.cpp index d830782bf4..5c2d653504 100644 --- a/apps/openmw/mwlua/weatherbindings.cpp +++ b/apps/openmw/mwlua/weatherbindings.cpp @@ -61,18 +61,18 @@ namespace MWLua api["getCurrentWindSpeed"] = []() { return MWBase::Environment::get().getWorld()->getWindSpeed(); }; api["getCurrentStormDirection"] = []() { return MWBase::Environment::get().getWorld()->getStormDirection(); }; - api["changeWeather"] = [](std::string_view regionId, std::string_view weatherName) { + api["changeWeather"] = [](std::string_view regionId, const MWWorld::Weather& weather) { ESM::RefId region = ESM::RefId::stringRefId(regionId); const ESM::Region* reg = MWBase::Environment::get().getESMStore()->get().search(region); if (reg) - MWBase::Environment::get().getWorld()->changeWeather(region, std::string(weatherName)); + MWBase::Environment::get().getWorld()->changeWeather(region, weather.mId); else throw std::runtime_error("Region not found"); }; api["getAllWeather"] = [context]() { sol::table allWeather(context.sol(), sol::create); - for (const auto &weather : MWBase::Environment::get().getWorld()->getAllWeather()) + for (const auto& weather : MWBase::Environment::get().getWorld()->getAllWeather()) allWeather.add(weather); return allWeather; }; diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 68425dad54..3eadcfb246 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -605,28 +605,6 @@ namespace MWWorld stopSounds(); } - void WeatherManager::changeWeather(const ESM::RefId& regionID, const std::string weatherName) - { - int weatherID = -1; - for (const auto& weather : mWeatherSettings) - { - if (weather.mName == weatherName) - { - weatherID = weather.mId; - } - } - - if (weatherID < mWeatherSettings.size() && weatherID > -1) - { - auto it = mRegions.find(regionID); - if (it != mRegions.end()) - { - it->second.setWeather(weatherID); - regionalWeatherChanged(it->first, it->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: diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index 9b4325445c..424b5e7956 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -291,13 +291,6 @@ namespace MWWorld * @param ID of the weather setting to shift to */ void changeWeather(const ESM::RefId& regionID, const unsigned int weatherID); - - /** - * Change the weather in the specified region by name of the weather - * @param region that should be changed - * @param name of the weather setting to shift to - */ - void changeWeather(const ESM::RefId& regionID, const std::string weatherName); void modRegion(const ESM::RefId& regionID, const std::vector& chances); void playerTeleported(const ESM::RefId& playerRegion, bool isExterior); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 4c1d63bc04..1a350c8001 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1905,11 +1905,6 @@ namespace MWWorld mWeatherManager->changeWeather(region, id); } - void World::changeWeather(const ESM::RefId& region, const std::string name) - { - mWeatherManager->changeWeather(region, name); - } - void World::modRegion(const ESM::RefId& regionid, const std::vector& chances) { mWeatherManager->modRegion(regionid, chances); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index b922d4b250..65c7f80c92 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -316,8 +316,6 @@ namespace MWWorld void changeWeather(const ESM::RefId& region, const unsigned int id) override; - void changeWeather(const ESM::RefId& region, const std::string name) override; - std::vector getAllWeather() const override; MWWorld::Weather* getCurrentWeather() const override; From ef687fb3ebee8c4ad6cec70cb4dc571153abfbca Mon Sep 17 00:00:00 2001 From: Sebastian Fieber Date: Sun, 26 Jan 2025 23:33:04 +0100 Subject: [PATCH 5/6] optional next --- apps/openmw/mwlua/weatherbindings.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwlua/weatherbindings.cpp b/apps/openmw/mwlua/weatherbindings.cpp index 5c2d653504..80919de770 100644 --- a/apps/openmw/mwlua/weatherbindings.cpp +++ b/apps/openmw/mwlua/weatherbindings.cpp @@ -52,7 +52,12 @@ namespace MWLua = sol::readonly_property([](const MWWorld::Weather& w) { return w.mDL.FogOffset; }); api["getCurrent"] = []() { return *MWBase::Environment::get().getWorld()->getCurrentWeather(); }; - api["getNext"] = []() { return *MWBase::Environment::get().getWorld()->getNextWeather(); }; + api["getNext"] = []() -> sol::optional { + auto next = MWBase::Environment::get().getWorld()->getNextWeather(); + if (next == nullptr) + return sol::nullopt; + return *next; + }; api["getTransition"] = []() { return MWBase::Environment::get().getWorld()->getWeatherTransition(); }; // TODO these return values that already take weather transition into account - maybe good to have? From 2283cd5adb9a1430949818949a8396eca7dbdfab Mon Sep 17 00:00:00 2001 From: Sebastian Fieber Date: Thu, 30 Jan 2025 22:39:07 +0100 Subject: [PATCH 6/6] introduce refid to weather type --- apps/openmw/mwdialogue/filter.cpp | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 4 ++-- apps/openmw/mwscript/skyextensions.cpp | 2 +- apps/openmw/mwworld/weather.cpp | 8 +++++--- apps/openmw/mwworld/weather.hpp | 5 +++-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwdialogue/filter.cpp b/apps/openmw/mwdialogue/filter.cpp index d194eeb1a0..076c6ec952 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()->mId; + return MWBase::Environment::get().getWorld()->getCurrentWeather()->mScriptId; case ESM::DialogueCondition::Function_Reputation: diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index c16d251409..76c9cc60bf 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()->mId); - stateUpdater->setNextWeatherId(world->getNextWeather() ? world->getNextWeather()->mId : -1); + stateUpdater->setWeatherId(world->getCurrentWeather()->mScriptId); + stateUpdater->setNextWeatherId(world->getNextWeather() ? world->getNextWeather()->mScriptId : -1); stateUpdater->setWeatherTransition(world->getWeatherTransition()); stateUpdater->setWindSpeed(world->getWindSpeed()); stateUpdater->setSkyColor(mSky->getSkyColor()); diff --git a/apps/openmw/mwscript/skyextensions.cpp b/apps/openmw/mwscript/skyextensions.cpp index 260cc8689d..67ada52503 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()->mId); + runtime.push(MWBase::Environment::get().getWorld()->getCurrentWeather()->mScriptId); } }; diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 3eadcfb246..c22545766e 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,10 @@ namespace MWWorld return direction; } - Weather::Weather(int id, const std::string& name, float stormWindSpeed, float rainSpeed, float dlFactor, + 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(id) , mName(name) , mCloudTexture(Fallback::Map::getString("Weather_" + name + "_Cloud_Texture")) , mSkyColor(Fallback::Map::getColour("Weather_" + name + "_Sky_Sunrise_Color"), @@ -982,8 +984,8 @@ 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(mWeatherSettings.size(), 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 424b5e7956..599c820bdb 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -119,10 +119,11 @@ namespace MWWorld public: static osg::Vec3f defaultDirection(); - Weather(const int id, const std::string& name, float stormWindSpeed, float rainSpeed, float dlFactor, + Weather(const ESM::RefId id, const int scriptId, const std::string& name, float stormWindSpeed, float rainSpeed, float dlFactor, float dlOffset, const std::string& particleEffect); - int mId; + ESM::RefId mId; + int mScriptId; std::string mName; std::string mCloudTexture;