1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-14 01:19:59 +00:00

Merge branch 'lua_weather_bindings' into 'master'

Draft: lua - add weatherbindings to world

See merge request OpenMW/openmw!4526
This commit is contained in:
Sebastian Fieber 2025-03-11 16:28:39 +00:00
commit 6b5077661b
12 changed files with 153 additions and 21 deletions

View File

@ -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

View File

@ -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 std::vector<MWWorld::Weather> getAllWeather() const = 0;
virtual int getNextWeather() const = 0;
virtual MWWorld::Weather* getCurrentWeather() const = 0;
virtual MWWorld::Weather* getNextWeather() const = 0;
virtual float getWeatherTransition() const = 0;

View File

@ -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()->mScriptId;
case ESM::DialogueCondition::Function_Reputation:

View File

@ -0,0 +1,87 @@
#include "weatherbindings.hpp"
#include <components/esm3/loadregn.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/weather.hpp"
namespace MWLua
{
sol::table initWeatherBindings(const Context& context)
{
sol::state_view lua = context.sol();
sol::table api(lua, sol::create);
auto weatherT = lua.new_usertype<MWWorld::Weather>("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["getCurrent"] = []() { return *MWBase::Environment::get().getWorld()->getCurrentWeather(); };
api["getNext"] = []() -> sol::optional<MWWorld::Weather> {
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?
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, const MWWorld::Weather& weather) {
ESM::RefId region = ESM::RefId::stringRefId(regionId);
const ESM::Region* reg = MWBase::Environment::get().getESMStore()->get<ESM::Region>().search(region);
if (reg)
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())
allWeather.add(weather);
return allWeather;
};
return LuaUtil::makeReadOnly(api);
}
}

View File

@ -0,0 +1,15 @@
#ifndef MWLUA_WEATHERBINDINGS_H
#define MWLUA_WEATHERBINDINGS_H
#include <sol/forward.hpp>
#include "context.hpp"
namespace MWLua
{
sol::table initWeatherBindings(const Context&);
}
#endif // MWLUA_WEATHERBINDINGS_H

View File

@ -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() };

View File

@ -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()->mScriptId);
stateUpdater->setNextWeatherId(world->getNextWeather() ? world->getNextWeather()->mScriptId : -1);
stateUpdater->setWeatherTransition(world->getWeatherTransition());
stateUpdater->setWindSpeed(world->getWindSpeed());
stateUpdater->setSkyColor(mSky->getSkyColor());

View File

@ -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()->mScriptId);
}
};

View File

@ -1,5 +1,6 @@
#include "weather.hpp"
#include <components/esm/stringrefid.hpp>
#include <components/settings/values.hpp>
#include <components/misc/rng.hpp>
@ -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(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"),
@ -980,8 +984,8 @@ namespace MWWorld
const std::string& name, float dlFactor, float dlOffset, const std::string& particleEffect)
{
static const float fStromWindSpeed = mStore.get<ESM::GameSetting>().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);
}

View File

@ -119,9 +119,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
@ -284,7 +287,7 @@ 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
*/
@ -311,8 +314,19 @@ namespace MWWorld
void advanceTime(double hours, bool incremental);
std::vector<Weather> getAllWeather() { return mWeatherSettings; }
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; }

View File

@ -1875,14 +1875,19 @@ namespace MWWorld
return ESM::Cell::sDefaultWorldspaceId;
}
int World::getCurrentWeather() const
std::vector<MWWorld::Weather> World::getAllWeather() const
{
return mWeatherManager->getWeatherID();
return mWeatherManager->getAllWeather();
}
int World::getNextWeather() const
MWWorld::Weather* World::getCurrentWeather() const
{
return mWeatherManager->getNextWeatherID();
return mWeatherManager->getWeather();
}
MWWorld::Weather* World::getNextWeather() const
{
return mWeatherManager->getNextWeather();
}
float World::getWeatherTransition() const

View File

@ -316,9 +316,11 @@ namespace MWWorld
void changeWeather(const ESM::RefId& region, const unsigned int id) override;
int getCurrentWeather() const override;
std::vector<MWWorld::Weather> getAllWeather() const override;
int getNextWeather() const override;
MWWorld::Weather* getCurrentWeather() const override;
MWWorld::Weather* getNextWeather() const override;
float getWeatherTransition() const override;