mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-09-08 11:51:23 -04:00
Merge branch 'lua_weather_bindings' into 'master'
lua - add weatherbindings to openmw.core (#6976) See merge request OpenMW/openmw!4526
This commit is contained in:
commit
9f10269ecc
@ -82,7 +82,7 @@ message(STATUS "Configuring OpenMW...")
|
|||||||
set(OPENMW_VERSION_MAJOR 0)
|
set(OPENMW_VERSION_MAJOR 0)
|
||||||
set(OPENMW_VERSION_MINOR 50)
|
set(OPENMW_VERSION_MINOR 50)
|
||||||
set(OPENMW_VERSION_RELEASE 0)
|
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_POSTPROCESSING_API_REVISION 3)
|
||||||
|
|
||||||
set(OPENMW_VERSION_COMMITHASH "")
|
set(OPENMW_VERSION_COMMITHASH "")
|
||||||
|
@ -63,7 +63,7 @@ add_openmw_dir (mwlua
|
|||||||
context menuscripts globalscripts localscripts playerscripts luabindings objectbindings cellbindings coremwscriptbindings
|
context menuscripts globalscripts localscripts playerscripts luabindings objectbindings cellbindings coremwscriptbindings
|
||||||
mwscriptbindings camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings dialoguebindings
|
mwscriptbindings camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings dialoguebindings
|
||||||
postprocessingbindings stats recordstore debugbindings corebindings worldbindings worker landbindings magicbindings factionbindings
|
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/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/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
|
types/potion types/ingredient types/misc types/repair types/armor types/light types/static
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
class Vec3f;
|
class Vec3f;
|
||||||
|
class Vec4f;
|
||||||
class Matrixf;
|
class Matrixf;
|
||||||
class Quat;
|
class Quat;
|
||||||
class Image;
|
class Image;
|
||||||
@ -93,6 +94,7 @@ namespace MWWorld
|
|||||||
class RefData;
|
class RefData;
|
||||||
class Cell;
|
class Cell;
|
||||||
class DateTimeManager;
|
class DateTimeManager;
|
||||||
|
class Weather;
|
||||||
|
|
||||||
typedef std::vector<std::pair<MWWorld::Ptr, MWMechanics::Movement>> PtrMovementList;
|
typedef std::vector<std::pair<MWWorld::Ptr, MWMechanics::Movement>> PtrMovementList;
|
||||||
}
|
}
|
||||||
@ -216,9 +218,21 @@ namespace MWBase
|
|||||||
|
|
||||||
virtual void changeWeather(const ESM::RefId& region, const unsigned int id) = 0;
|
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<MWWorld::Weather>& 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;
|
virtual float getWeatherTransition() const = 0;
|
||||||
|
|
||||||
@ -478,6 +492,7 @@ namespace MWBase
|
|||||||
// Allow NPCs to use torches?
|
// Allow NPCs to use torches?
|
||||||
virtual bool useTorches() const = 0;
|
virtual bool useTorches() const = 0;
|
||||||
|
|
||||||
|
virtual const osg::Vec4f& getSunLightPosition() const = 0;
|
||||||
virtual float getSunVisibility() const = 0;
|
virtual float getSunVisibility() const = 0;
|
||||||
virtual float getSunPercentage() const = 0;
|
virtual float getSunPercentage() const = 0;
|
||||||
|
|
||||||
|
@ -501,7 +501,7 @@ int MWDialogue::Filter::getSelectStructInteger(const SelectWrapper& select) cons
|
|||||||
|
|
||||||
case ESM::DialogueCondition::Function_Weather:
|
case ESM::DialogueCondition::Function_Weather:
|
||||||
|
|
||||||
return MWBase::Environment::get().getWorld()->getCurrentWeather();
|
return MWBase::Environment::get().getWorld()->getCurrentWeatherScriptId();
|
||||||
|
|
||||||
case ESM::DialogueCondition::Function_Reputation:
|
case ESM::DialogueCondition::Function_Reputation:
|
||||||
if (!mActor.getClass().isNpc())
|
if (!mActor.getClass().isNpc())
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "magicbindings.hpp"
|
#include "magicbindings.hpp"
|
||||||
#include "soundbindings.hpp"
|
#include "soundbindings.hpp"
|
||||||
#include "stats.hpp"
|
#include "stats.hpp"
|
||||||
|
#include "weatherbindings.hpp"
|
||||||
|
|
||||||
namespace MWLua
|
namespace MWLua
|
||||||
{
|
{
|
||||||
@ -104,6 +105,9 @@ namespace MWLua
|
|||||||
|
|
||||||
api["land"] = context.cachePackage("openmw_core_land", [context]() { return initCoreLandBindings(context); });
|
api["land"] = context.cachePackage("openmw_core_land", [context]() { return initCoreLandBindings(context); });
|
||||||
|
|
||||||
|
api["weather"]
|
||||||
|
= context.cachePackage("openmw_core_weather", [context]() { return initCoreWeatherBindings(context); });
|
||||||
|
|
||||||
api["factions"]
|
api["factions"]
|
||||||
= context.cachePackage("openmw_core_factions", [context]() { return initCoreFactionBindings(context); });
|
= context.cachePackage("openmw_core_factions", [context]() { return initCoreFactionBindings(context); });
|
||||||
api["dialogue"]
|
api["dialogue"]
|
||||||
|
185
apps/openmw/mwlua/weatherbindings.cpp
Normal file
185
apps/openmw/mwlua/weatherbindings.cpp
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
#include "weatherbindings.hpp"
|
||||||
|
|
||||||
|
#include <osg/Vec4f>
|
||||||
|
|
||||||
|
#include <components/esm3/loadregn.hpp>
|
||||||
|
#include <components/lua/util.hpp>
|
||||||
|
#include <components/misc/color.hpp>
|
||||||
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
|
#include <components/resource/resourcesystem.hpp>
|
||||||
|
|
||||||
|
#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<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([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<std::string> {
|
||||||
|
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<std::string> {
|
||||||
|
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<ESM::Region>().find(region);
|
||||||
|
MWBase::Environment::get().getWorld()->changeWeather(region, weather.mId);
|
||||||
|
};
|
||||||
|
|
||||||
|
sol::usertype<WeatherStore> storeT = lua.new_usertype<WeatherStore>("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<sol::function>();
|
||||||
|
storeT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
14
apps/openmw/mwlua/weatherbindings.hpp
Normal file
14
apps/openmw/mwlua/weatherbindings.hpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#ifndef MWLUA_WEATHERBINDINGS_H
|
||||||
|
#define MWLUA_WEATHERBINDINGS_H
|
||||||
|
|
||||||
|
#include <sol/forward.hpp>
|
||||||
|
|
||||||
|
namespace MWLua
|
||||||
|
{
|
||||||
|
struct Context;
|
||||||
|
|
||||||
|
sol::table initCoreWeatherBindings(const Context&);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MWLUA_WEATHERBINDINGS_H
|
@ -943,8 +943,8 @@ namespace MWRender
|
|||||||
stateUpdater->setIsUnderwater(isUnderwater);
|
stateUpdater->setIsUnderwater(isUnderwater);
|
||||||
stateUpdater->setFogColor(fogColor);
|
stateUpdater->setFogColor(fogColor);
|
||||||
stateUpdater->setGameHour(world->getTimeStamp().getHour());
|
stateUpdater->setGameHour(world->getTimeStamp().getHour());
|
||||||
stateUpdater->setWeatherId(world->getCurrentWeather());
|
stateUpdater->setWeatherId(world->getCurrentWeatherScriptId());
|
||||||
stateUpdater->setNextWeatherId(world->getNextWeather());
|
stateUpdater->setNextWeatherId(world->getNextWeatherScriptId());
|
||||||
stateUpdater->setWeatherTransition(world->getWeatherTransition());
|
stateUpdater->setWeatherTransition(world->getWeatherTransition());
|
||||||
stateUpdater->setWindSpeed(world->getWindSpeed());
|
stateUpdater->setWindSpeed(world->getWindSpeed());
|
||||||
stateUpdater->setSkyColor(mSky->getSkyColor());
|
stateUpdater->setSkyColor(mSky->getSkyColor());
|
||||||
|
@ -139,6 +139,7 @@ namespace MWRender
|
|||||||
int skyGetSecundaPhase() const;
|
int skyGetSecundaPhase() const;
|
||||||
void skySetMoonColour(bool red);
|
void skySetMoonColour(bool red);
|
||||||
|
|
||||||
|
const osg::Vec4f& getSunLightPosition() const { return mSunLight->getPosition(); }
|
||||||
void setSunDirection(const osg::Vec3f& direction);
|
void setSunDirection(const osg::Vec3f& direction);
|
||||||
void setSunColour(const osg::Vec4f& diffuse, const osg::Vec4f& specular, float sunVis);
|
void setSunColour(const osg::Vec4f& diffuse, const osg::Vec4f& specular, float sunVis);
|
||||||
void setNight(bool isNight) { mNight = isNight; }
|
void setNight(bool isNight) { mNight = isNight; }
|
||||||
|
@ -71,7 +71,7 @@ namespace MWScript
|
|||||||
public:
|
public:
|
||||||
void execute(Interpreter::Runtime& runtime) override
|
void execute(Interpreter::Runtime& runtime) override
|
||||||
{
|
{
|
||||||
runtime.push(MWBase::Environment::get().getWorld()->getCurrentWeather());
|
runtime.push(MWBase::Environment::get().getWorld()->getCurrentWeatherScriptId());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "weather.hpp"
|
#include "weather.hpp"
|
||||||
|
|
||||||
|
#include <components/esm/stringrefid.hpp>
|
||||||
#include <components/settings/values.hpp>
|
#include <components/settings/values.hpp>
|
||||||
|
|
||||||
#include <components/misc/rng.hpp>
|
#include <components/misc/rng.hpp>
|
||||||
@ -141,9 +142,12 @@ namespace MWWorld
|
|||||||
return direction;
|
return direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
Weather::Weather(const std::string& name, float stormWindSpeed, float rainSpeed, float dlFactor, float dlOffset,
|
Weather::Weather(ESM::RefId id, int scriptId, const std::string& name, float stormWindSpeed, float rainSpeed,
|
||||||
const std::string& particleEffect)
|
float dlFactor, float dlOffset, const std::string& particleEffect)
|
||||||
: mCloudTexture(Fallback::Map::getString("Weather_" + name + "_Cloud_Texture"))
|
: mId(id)
|
||||||
|
, mScriptId(scriptId)
|
||||||
|
, mName(name)
|
||||||
|
, mCloudTexture(Fallback::Map::getString("Weather_" + name + "_Cloud_Texture"))
|
||||||
, mSkyColor(Fallback::Map::getColour("Weather_" + name + "_Sky_Sunrise_Color"),
|
, mSkyColor(Fallback::Map::getColour("Weather_" + name + "_Sky_Sunrise_Color"),
|
||||||
Fallback::Map::getColour("Weather_" + name + "_Sky_Day_Color"),
|
Fallback::Map::getColour("Weather_" + name + "_Sky_Day_Color"),
|
||||||
Fallback::Map::getColour("Weather_" + name + "_Sky_Sunset_Color"),
|
Fallback::Map::getColour("Weather_" + name + "_Sky_Sunset_Color"),
|
||||||
@ -676,6 +680,41 @@ namespace MWWorld
|
|||||||
stopSounds();
|
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)
|
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:
|
// 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)
|
const std::string& name, float dlFactor, float dlOffset, const std::string& particleEffect)
|
||||||
{
|
{
|
||||||
static const float fStromWindSpeed = mStore.get<ESM::GameSetting>().find("fStromWindSpeed")->mValue.getFloat();
|
static const float fStromWindSpeed = mStore.get<ESM::GameSetting>().find("fStromWindSpeed")->mValue.getFloat();
|
||||||
|
ESM::StringRefId id(name);
|
||||||
Weather weather(name, fStromWindSpeed, mRainSpeed, dlFactor, dlOffset, particleEffect);
|
Weather weather(
|
||||||
|
id, mWeatherSettings.size(), name, fStromWindSpeed, mRainSpeed, dlFactor, dlOffset, particleEffect);
|
||||||
|
|
||||||
mWeatherSettings.push_back(weather);
|
mWeatherSettings.push_back(weather);
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,11 @@ namespace MWWorld
|
|||||||
|
|
||||||
T getValue(const float gameHour, const TimeOfDaySettings& timeSettings, const std::string& prefix) const;
|
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:
|
private:
|
||||||
T mSunriseValue, mDayValue, mSunsetValue, mNightValue;
|
T mSunriseValue, mDayValue, mSunsetValue, mNightValue;
|
||||||
};
|
};
|
||||||
@ -119,9 +124,12 @@ namespace MWWorld
|
|||||||
public:
|
public:
|
||||||
static osg::Vec3f defaultDirection();
|
static osg::Vec3f defaultDirection();
|
||||||
|
|
||||||
Weather(const std::string& name, float stormWindSpeed, float rainSpeed, float dlFactor, float dlOffset,
|
Weather(const ESM::RefId id, const int scriptId, const std::string& name, float stormWindSpeed, float rainSpeed,
|
||||||
const std::string& particleEffect);
|
float dlFactor, float dlOffset, const std::string& particleEffect);
|
||||||
|
|
||||||
|
ESM::RefId mId;
|
||||||
|
int mScriptId;
|
||||||
|
std::string mName;
|
||||||
std::string mCloudTexture;
|
std::string mCloudTexture;
|
||||||
|
|
||||||
// Sky (atmosphere) color
|
// Sky (atmosphere) color
|
||||||
@ -289,11 +297,12 @@ namespace MWWorld
|
|||||||
~WeatherManager();
|
~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 region that should be changed
|
||||||
* @param ID of the weather setting to shift to
|
* @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 unsigned int weatherID);
|
||||||
|
void changeWeather(const ESM::RefId& regionID, const ESM::RefId& weatherID);
|
||||||
void modRegion(const ESM::RefId& regionID, const std::vector<uint8_t>& chances);
|
void modRegion(const ESM::RefId& regionID, const std::vector<uint8_t>& chances);
|
||||||
void playerTeleported(const ESM::RefId& playerRegion, bool isExterior);
|
void playerTeleported(const ESM::RefId& playerRegion, bool isExterior);
|
||||||
|
|
||||||
@ -316,8 +325,23 @@ namespace MWWorld
|
|||||||
|
|
||||||
void advanceTime(double hours, bool incremental);
|
void advanceTime(double hours, bool incremental);
|
||||||
|
|
||||||
|
const std::vector<Weather>& 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; }
|
int getWeatherID() const { return mCurrentWeather; }
|
||||||
|
|
||||||
|
const Weather* getNextWeather()
|
||||||
|
{
|
||||||
|
if (mNextWeather > -1)
|
||||||
|
return &mWeatherSettings[mNextWeather];
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
int getNextWeatherID() const { return mNextWeather; }
|
int getNextWeatherID() const { return mNextWeather; }
|
||||||
|
|
||||||
float getTransitionFactor() const { return mTransitionFactor; }
|
float getTransitionFactor() const { return mTransitionFactor; }
|
||||||
|
@ -1868,14 +1868,43 @@ namespace MWWorld
|
|||||||
return ESM::Cell::sDefaultWorldspaceId;
|
return ESM::Cell::sDefaultWorldspaceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
int World::getCurrentWeather() const
|
const std::vector<MWWorld::Weather>& 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
|
float World::getWeatherTransition() const
|
||||||
@ -1893,6 +1922,11 @@ namespace MWWorld
|
|||||||
mWeatherManager->changeWeather(region, id);
|
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<uint8_t>& chances)
|
void World::modRegion(const ESM::RefId& regionid, const std::vector<uint8_t>& chances)
|
||||||
{
|
{
|
||||||
mWeatherManager->modRegion(regionid, chances);
|
mWeatherManager->modRegion(regionid, chances);
|
||||||
@ -3133,6 +3167,11 @@ namespace MWWorld
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const osg::Vec4f& World::getSunLightPosition() const
|
||||||
|
{
|
||||||
|
return mRendering->getSunLightPosition();
|
||||||
|
}
|
||||||
|
|
||||||
float World::getSunVisibility() const
|
float World::getSunVisibility() const
|
||||||
{
|
{
|
||||||
return mWeatherManager->getSunVisibility();
|
return mWeatherManager->getSunVisibility();
|
||||||
|
@ -317,9 +317,16 @@ namespace MWWorld
|
|||||||
|
|
||||||
void changeWeather(const ESM::RefId& region, const unsigned int id) override;
|
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<MWWorld::Weather>& 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;
|
float getWeatherTransition() const override;
|
||||||
|
|
||||||
@ -573,6 +580,7 @@ namespace MWWorld
|
|||||||
// Allow NPCs to use torches?
|
// Allow NPCs to use torches?
|
||||||
bool useTorches() const override;
|
bool useTorches() const override;
|
||||||
|
|
||||||
|
const osg::Vec4f& getSunLightPosition() const override;
|
||||||
float getSunVisibility() const override;
|
float getSunVisibility() const override;
|
||||||
float getSunPercentage() const override;
|
float getSunPercentage() const override;
|
||||||
|
|
||||||
|
@ -1198,4 +1198,100 @@
|
|||||||
-- @field #string id MWScript id
|
-- @field #string id MWScript id
|
||||||
-- @field #string text MWScript content
|
-- @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
|
return nil
|
||||||
|
Loading…
x
Reference in New Issue
Block a user