Require cell arguments for Lua weather functions

This commit is contained in:
Evil Eye 2025-08-15 13:17:17 +02:00
parent ac2627a7b7
commit ead19d099a
6 changed files with 73 additions and 24 deletions

View File

@ -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 92)
set(OPENMW_LUA_API_REVISION 93)
set(OPENMW_POSTPROCESSING_API_REVISION 3)
set(OPENMW_VERSION_COMMITHASH "")

View File

@ -404,7 +404,7 @@ namespace MWBase
///< Apply a health difference to any actors colliding with \a object.
/// To hurt actors, healthPerSecond should be a positive value. For a negative value, actors will be healed.
virtual float getWindSpeed() = 0;
virtual float getWindSpeed() const = 0;
virtual void getContainersOwnedBy(const MWWorld::ConstPtr& npc, std::vector<MWWorld::Ptr>& out) = 0;
///< get all containers in active cells owned by this Npc

View File

@ -1,5 +1,7 @@
#include "weatherbindings.hpp"
#include <type_traits>
#include <osg/Vec4f>
#include <components/esm3/loadregn.hpp>
@ -10,10 +12,13 @@
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/cellstore.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/scene.hpp"
#include "../mwworld/weather.hpp"
#include "context.hpp"
#include "object.hpp"
namespace
{
@ -35,6 +40,43 @@ namespace
{
return Misc::Color(color.r(), color.g(), color.b(), color.a());
}
template <class Cell>
bool hasWeather(const Cell& cell)
{
if (!cell.mStore->isQuasiExterior() && !cell.mStore->isExterior())
return false;
return MWBase::Environment::get().getWorldScene()->isCellActive(*cell.mStore);
}
template <class Getter>
auto overloadForActiveCell(const Getter&& getter)
{
using Result = std::invoke_result_t<Getter>;
return sol::overload(
[=](const MWLua::GCell& cell) -> Result {
if (!hasWeather(cell))
return Result{};
return getter();
},
[=](const MWLua::LCell& cell) -> Result {
if (!hasWeather(cell))
return Result{};
return getter();
});
}
template <class T>
using WeatherGetter = T (MWBase::World::*)() const;
template <class T>
auto overloadWeatherGetter(WeatherGetter<T> getter)
{
return overloadForActiveCell([=]() -> std::optional<T> {
const MWBase::World& world = *MWBase::Environment::get().getWorld();
return (world.*getter)();
});
}
}
namespace MWLua
@ -140,12 +182,6 @@ namespace MWLua
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"]
= []() -> const MWWorld::Weather* { 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);
@ -169,18 +205,23 @@ namespace MWLua
// Provide access to the store.
api["records"] = WeatherStore{};
api["getCurrentSunLightDirection"] = []() {
api["getCurrent"] = overloadForActiveCell(
[]() -> const MWWorld::Weather* { return &MWBase::Environment::get().getWorld()->getCurrentWeather(); });
api["getNext"] = overloadForActiveCell(
[]() -> const MWWorld::Weather* { return MWBase::Environment::get().getWorld()->getNextWeather(); });
api["getTransition"] = overloadWeatherGetter(&MWBase::World::getWeatherTransition);
api["getCurrentSunLightDirection"] = overloadForActiveCell([]() -> std::optional<osg::Vec4f> {
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(); };
});
api["getCurrentSunVisibility"] = overloadWeatherGetter(&MWBase::World::getSunVisibility);
api["getCurrentSunPercentage"] = overloadWeatherGetter(&MWBase::World::getSunPercentage);
api["getCurrentWindSpeed"] = overloadWeatherGetter(&MWBase::World::getWindSpeed);
api["getCurrentStormDirection"] = overloadWeatherGetter(&MWBase::World::getStormDirection);
return LuaUtil::makeReadOnly(api);
}

View File

@ -2546,7 +2546,7 @@ namespace MWWorld
}
}
float World::getWindSpeed()
float World::getWindSpeed() const
{
if (isCellExterior() || isCellQuasiExterior())
return mWeatherManager->getWindSpeed();

View File

@ -497,7 +497,7 @@ namespace MWWorld
///< Apply a health difference to any actors colliding with \a object.
/// To hurt actors, healthPerSecond should be a positive value. For a negative value, actors will be healed.
float getWindSpeed() override;
float getWindSpeed() const override;
void getContainersOwnedBy(const MWWorld::ConstPtr& npc, std::vector<MWWorld::Ptr>& out) override;
///< get all containers in active cells owned by this Npc

View File

@ -243,7 +243,7 @@
-- Can be used to move objects from an inventory or a container to the world.
-- @function [parent=#GameObject] teleport
-- @param self
-- @param #any cellOrName A cell to define the destination worldspace; can be either #Cell, or cell name, or an empty string (empty string means the default exterior worldspace).
-- @param #any cellOrName A cell to define the destination worldspace; can be either @{#Cell}, or cell name, or an empty string (empty string means the default exterior worldspace).
-- If the worldspace has multiple cells (i.e. an exterior), the destination cell is calculated using `position`.
-- @param openmw.util#Vector3 position New position.
-- @param #TeleportOptions options (optional) Either table @{#TeleportOptions} or @{openmw.util#Transform} rotation.
@ -1250,17 +1250,20 @@
---
-- Get the current weather
-- @function [parent=#Weather] getCurrent
-- @return #WeatherData
-- @param #Cell The cell to get the current weather for
-- @return #WeatherData or nil if the cell is inactive or has no weather
---
-- Get the next weather if any
-- @function [parent=#Weather] getNext
-- @param #Cell The cell to get the next weather for
-- @return #any can be nil
---
-- Get current weather transition value
-- @function [parent=#Weather] getTransition
-- @return #number
-- @param #Cell The cell to get the transition value for
-- @return #number or nil if the cell is inactive or has no weather
---
-- Change the weather
@ -1271,27 +1274,32 @@
---
-- Get the current direction of the light of the sun.
-- @function [parent=#Weather] getCurrentSunLightDirection
-- @return openmw.util#Vector4
-- @param #Cell The cell to get the sun direction for
-- @return openmw.util#Vector4 or nil if the cell is inactive or has no weather
---
-- Get the current sun visibility taking weather transition into account.
-- @function [parent=#Weather] getCurrentSunVisibility
-- @return #number
-- @param #Cell The cell to get the sun visibility for
-- @return #number or nil if the cell is inactive or has no weather
---
-- Get the current sun percentage taking weather transition into account.
-- @function [parent=#Weather] getCurrentSunPercentage
-- @return #number
-- @param #Cell The cell to get the sun percentage for
-- @return #number or nil if the cell is inactive or has no weather
---
-- Get the current wind speed taking weather transition into account.
-- @function [parent=#Weather] getCurrentWindSpeed
-- @return #number
-- @param #Cell The cell to get the wind speed for
-- @return #number or nil if the cell is inactive or has no weather
---
-- Get the current storm direction taking weather transition into account.
-- @function [parent=#Weather] getCurrentStormDirection
-- @return openmw.util#Vector3
-- @param #Cell The cell to get the storm direction for
-- @return openmw.util#Vector3 or nil if the cell is inactive or has no weather
---
-- Weather data