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:
parent
3d7e306064
commit
f2d0a702e9
7 changed files with 97 additions and 1 deletions
|
@ -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
|
||||
|
|
55
apps/openmw/mwlua/asyncbindings.cpp
Normal file
55
apps/openmw/mwlua/asyncbindings.cpp
Normal 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue