you can use jKos' LoG framework timers module, quite complete, which is an extended lua wrapper for Grimrock native timers.
otherwise, if you want a pure lua solution here's what we use in the ORRR2 as a global time system (complete sources will be coming up 2 weeks after initial release, which should happen next week):
Code: Select all
-- =======================================================
-- TIME
-- =======================================================
lastFrameTime = 0;
dt = 0;
coroutinesTable = {};
function updateDt()
local t = getStatistic("play_time");
dt = t - lastFrameTime;
lastFrameTime = t;
end
function waitForSeconds(delay, funct, args, id)
coroutinesTable[#coroutinesTable+1] = {delay, funct, args, false, 0, id};
end
function startCoroutine(delay, funct, args, id)
table.insert(coroutinesTable, {delay, funct, args, true, 0, id});
end
function stopCoroutine(id)
--print("stopCoroutine start", id)
for i = #coroutinesTable, 1, -1 do
local tId = coroutinesTable[i][6];
if tId and tId == id then
table.remove(coroutinesTable, i);
end
end
--print("stopCoroutine end", id)
end
cTable = {};
function update()
updateDt();
if #coroutinesTable == 0 then return; end
for i = #coroutinesTable, 1, -1 do
cTable = coroutinesTable[i];
if cTable then
cTable[5] = cTable[5] + dt;
if cTable[5] > cTable[1] then
local result;
if cTable[3] then
result = cTable[2](unpack(cTable[3]));
else
result = cTable[2]();
end
if result == false or not(cTable[4]) then
table.remove(coroutinesTable, i);
else
cTable[5] = 0;
end
end
end
end
end
put that into whatever script entity you want, like luaTime for example, send a call from the party onDrawGui hook to luaTime.updateDt().
Syntax is modeled after Unity3D:
use luaTime.waitForSeconds(delay, function, [args], [id]) to execute a function in n seconds delay. args is optional, it's the arguments to send to the funtion if it needs some, packed in a table (don't send game entities => serialization crashes). id is optional too, you can give the function call an id and use stopCoroutine(id) to stop the execution before it does.
startCoroutine has the same syntax, but the function will execute every n seconds forever, until you either return false from the function, or call stopCoroutine.
Ex usage from the orrr2, two coroutines to check achievements every 5s or manage monster respawning every 15 minutes:
Code: Select all
startCoroutine(5, function()
orrrManager.checkSecretsAchievements()
end);
startCoroutine(900, function()
crowSpawner.respawn()
end);
advantage is that this is always spot on in terms of time no matter where the party is, vs editor timers which slow down when not on the same level
example of a delayed call. here it`s for a secret you need to stand 10s on a particular square. the hidden pressure plate is connected on activate to startTimer and on deactivate to stopTimer (in the mod, the time functions reside in our orrrManager script:
Code: Select all
function startTimer()
orrrManager.waitForSeconds(10,
function()
temple_secret_door_4:open();
secret_3:activate();
teleporter_21:activate();
timer_3:activate();
end,
{},
"timerSecret")
end
function stopTimer()
orrrManager.stopCoroutine("timerSecret");
end
here, hope this gives you some ideas about how it can be done.