diff --git a/apps/openmw/mwlua/animationbindings.cpp b/apps/openmw/mwlua/animationbindings.cpp index 22ebd7e33a..2f6f60ea3e 100644 --- a/apps/openmw/mwlua/animationbindings.cpp +++ b/apps/openmw/mwlua/animationbindings.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -99,6 +100,8 @@ namespace MWLua sol::table initAnimationPackage(const Context& context) { + using FiniteFloat = Misc::FiniteFloat; + auto view = context.sol(); auto mechanics = MWBase::Environment::get().getMechanicsManager(); auto world = MWBase::Environment::get().getWorld(); @@ -197,7 +200,7 @@ namespace MWLua return speed; return sol::nullopt; }; - api["setSpeed"] = [](const sol::object& object, std::string groupname, float speed) { + api["setSpeed"] = [](const sol::object& object, std::string groupname, const FiniteFloat speed) { getMutableAnimationOrThrow(ObjectVariant(object))->adjustSpeedMult(groupname, speed); }; api["getActiveGroup"] = [](const sol::object& object, MWRender::BoneGroup boneGroup) -> std::string_view { diff --git a/apps/openmw/mwlua/worldbindings.cpp b/apps/openmw/mwlua/worldbindings.cpp index ac7bd307cf..c960c4e9e4 100644 --- a/apps/openmw/mwlua/worldbindings.cpp +++ b/apps/openmw/mwlua/worldbindings.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/statemanager.hpp" @@ -56,10 +57,12 @@ namespace MWLua static void addWorldTimeBindings(sol::table& api, const Context& context) { + using FiniteFloat = Misc::FiniteFloat; + MWWorld::DateTimeManager* timeManager = MWBase::Environment::get().getWorld()->getTimeManager(); - api["setGameTimeScale"] = [timeManager](double scale) { timeManager->setGameTimeScale(scale); }; - api["setSimulationTimeScale"] = [context, timeManager](float scale) { + api["setGameTimeScale"] = [timeManager](const FiniteFloat scale) { timeManager->setGameTimeScale(scale); }; + api["setSimulationTimeScale"] = [context, timeManager](const FiniteFloat scale) { context.mLuaManager->addAction([scale, timeManager] { timeManager->setSimulationTimeScale(scale); }); }; diff --git a/components/misc/finitenumbers.hpp b/components/misc/finitenumbers.hpp index 3d166ee26d..7d27987c5f 100644 --- a/components/misc/finitenumbers.hpp +++ b/components/misc/finitenumbers.hpp @@ -8,6 +8,18 @@ namespace Misc { + struct FiniteDouble + { + double mValue; + FiniteDouble(double v) + { + if (!std::isfinite(v)) + throw std::invalid_argument("Value must be a finite number"); + mValue = v; + } + operator double() const { return mValue; } + }; + struct FiniteFloat { float mValue; @@ -23,8 +35,25 @@ namespace Misc namespace sol { + using FiniteDouble = Misc::FiniteDouble; using FiniteFloat = Misc::FiniteFloat; + template + bool sol_lua_check( + sol::types, lua_State* L, int index, Handler&& handler, sol::stack::record& tracking) + { + bool success = sol::stack::check(L, lua_absindex(L, index), handler); + tracking.use(1); + return success; + } + + static FiniteDouble sol_lua_get(sol::types, lua_State* L, int index, sol::stack::record& tracking) + { + double val = sol::stack::get(L, lua_absindex(L, index)); + tracking.use(1); + return FiniteDouble(val); + } + template bool sol_lua_check( sol::types, lua_State* L, int index, Handler&& handler, sol::stack::record& tracking)