1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-30 07:15:34 +00:00

Add Lua timers

This commit is contained in:
Petr Mikheev 2021-03-12 18:29:51 +01:00
parent 3d7e306064
commit f2d0a702e9
7 changed files with 97 additions and 1 deletions

View file

@ -57,7 +57,7 @@ add_openmw_dir (mwscript
add_openmw_dir (mwlua
luamanagerimp localscripts object worldview luabindings userdataserializer
objectbindings
objectbindings asyncbindings
)
add_openmw_dir (mwsound

View file

@ -0,0 +1,55 @@
#include "luabindings.hpp"
namespace sol
{
template <>
struct is_automagical<MWLua::AsyncPackageId> : std::false_type {};
}
namespace MWLua
{
struct TimerCallback
{
AsyncPackageId mAsyncId;
std::string mName;
};
sol::function getAsyncPackageInitializer(const Context& context)
{
sol::usertype<AsyncPackageId> api = context.mLua->sol().new_usertype<AsyncPackageId>("AsyncPackage");
api["registerTimerCallback"] = [](const AsyncPackageId& asyncId, std::string_view name, sol::function callback)
{
asyncId.mContainer->registerTimerCallback(asyncId.mScript, name, std::move(callback));
return TimerCallback{asyncId, std::string(name)};
};
api["newTimerInSeconds"] = [world=context.mWorldView](const AsyncPackageId&, double delay,
const TimerCallback& callback, sol::object callbackArg)
{
callback.mAsyncId.mContainer->setupSerializableTimer(
false, world->getGameTimeInSeconds() + delay, callback.mAsyncId.mScript, callback.mName, std::move(callbackArg));
};
api["newTimerInHours"] = [world=context.mWorldView](const AsyncPackageId&, double delay,
const TimerCallback& callback, sol::object callbackArg)
{
callback.mAsyncId.mContainer->setupSerializableTimer(
true, world->getGameTimeInHours() + delay, callback.mAsyncId.mScript, callback.mName, std::move(callbackArg));
};
api["newUnsavableTimerInSeconds"] = [world=context.mWorldView](const AsyncPackageId& asyncId, double delay, sol::function callback)
{
asyncId.mContainer->setupUnsavableTimer(false, world->getGameTimeInSeconds() + delay, asyncId.mScript, std::move(callback));
};
api["newUnsavableTimerInHours"] = [world=context.mWorldView](const AsyncPackageId& asyncId, double delay, sol::function callback)
{
asyncId.mContainer->setupUnsavableTimer(true, world->getGameTimeInHours() + delay, asyncId.mScript, std::move(callback));
};
auto initializer = [](sol::table hiddenData)
{
LuaUtil::ScriptsContainer::ScriptId id = hiddenData[LuaUtil::ScriptsContainer::ScriptId::KEY];
return AsyncPackageId{id.mContainer, id.mPath};
};
return sol::make_object(context.mLua->sol(), initializer);
}
}

View file

@ -15,6 +15,8 @@ namespace MWLua
{
context.mGlobalEventQueue->push_back({std::move(eventName), LuaUtil::serialize(eventData, context.mSerializer)});
};
api["getGameTimeInSeconds"] = [world=context.mWorldView]() { return world->getGameTimeInSeconds(); };
api["getGameTimeInHours"] = [world=context.mWorldView]() { return world->getGameTimeInHours(); };
return context.mLua->makeReadOnly(api);
}

View file

@ -3,6 +3,7 @@
#include <components/lua/luastate.hpp>
#include <components/lua/serialization.hpp>
#include <components/lua/scriptscontainer.hpp>
#include "eventqueue.hpp"
#include "object.hpp"
@ -30,6 +31,15 @@ namespace MWLua
void initObjectBindingsForLocalScripts(const Context&);
void initObjectBindingsForGlobalScripts(const Context&);
// Implemented in asyncbindings.cpp
struct AsyncPackageId
{
// TODO: add ObjectId mLocalObject;
LuaUtil::ScriptsContainer* mContainer;
std::string mScript;
};
sol::function getAsyncPackageInitializer(const Context&);
// openmw.self package is implemented in localscripts.cpp
}

View file

@ -34,6 +34,7 @@ namespace MWLua
initObjectBindingsForLocalScripts(localContext);
LocalScripts::initializeSelfPackage(localContext);
mLua.addCommonPackage("openmw.async", getAsyncPackageInitializer(context));
mLua.addCommonPackage("openmw.util", LuaUtil::initUtilPackage(mLua.sol()));
mLua.addCommonPackage("openmw.core", initCorePackage(context));
mGlobalScripts.addPackage("openmw.world", initWorldPackage(context));
@ -62,6 +63,16 @@ namespace MWLua
mGlobalEvents = std::vector<GlobalEvent>();
mLocalEvents = std::vector<LocalEvent>();
{ // Update time and process timers
double seconds = mWorldView.getGameTimeInSeconds() + dt;
mWorldView.setGameTimeInSeconds(seconds);
double hours = mWorldView.getGameTimeInHours();
mGlobalScripts.processTimers(seconds, hours);
for (LocalScripts* scripts : mActiveLocalScripts)
scripts->processTimers(seconds, hours);
}
for (GlobalEvent& e : globalEvents)
mGlobalScripts.receiveEvent(e.eventName, e.eventData);
for (LocalEvent& e : localEvents)

View file

@ -1,6 +1,7 @@
#include "worldview.hpp"
#include "../mwworld/class.hpp"
#include "../mwworld/timestamp.hpp"
namespace MWLua
{
@ -35,6 +36,13 @@ namespace MWLua
removeFromGroup(mItemsInScene, ptr);
}
double WorldView::getGameTimeInHours() const
{
MWBase::World* world = MWBase::Environment::get().getWorld();
MWWorld::TimeStamp timeStamp = world->getTimeStamp();
return static_cast<double>(timeStamp.getDay()) * 24 + timeStamp.getHour();
}
void WorldView::ObjectGroup::updateList()
{
if (mChanged)

View file

@ -13,6 +13,14 @@ namespace MWLua
void update(); // Should be called every frame.
void clear(); // Should be called every time before starting or loading a new game.
// Returns the number of seconds passed from the beginning of the game.
double getGameTimeInSeconds() const { return mGameSeconds; }
void setGameTimeInSeconds(double t) { mGameSeconds = t; }
// Returns the number of game hours passed from the beginning of the game.
// Note that the number of seconds in a game hour is not fixed.
double getGameTimeInHours() const;
ObjectIdList getActorsInScene() const { return mActorsInScene.mList; }
ObjectIdList getItemsInScene() const { return mItemsInScene.mList; }
@ -40,6 +48,8 @@ namespace MWLua
ObjectRegistry mObjectRegistry;
ObjectGroup mActorsInScene;
ObjectGroup mItemsInScene;
double mGameSeconds = 0;
};
}