TimerComponents track "real" time elapsed on the level, which does not correspond to time of day at all. Time of day changes when the party moves, turns, and rests, rather than with real time. Here's one way you could track elapsed time of day. Add these components to the party object:
Code: Select all
{
class = "Timer",
name = "daytimer",
timerInterval = 0.001,
onActivate = function(self)
self.go.dayscript.update()
end,
},
{
class = "Script",
name = "dayscript",
source = [[-- NOTE: This will not correctly track GameMode.advanceTime() with units of 1.0 or greater, and will treat GameMode.setTimeOfDay() as advancing time. This isn't really avoidable without overwriting those functions, which would be gross. Instead we provide our own that you can use in place of these which will be tracked correctly.
last = 0
connectors = {}
function update()
-- track wrapping
local elapsed = math.min(math.abs(GameMode.getTimeOfDay() - last),GameMode.getTimeOfDay())
last = GameMode.getTimeOfDay()
updateConnectors(elapsed)
end
function addDayConnector(time,target,action)
if not type(time) == "number" then
print(string.format("err: invalid argument 1 to addDayConnector (number expected, got %s",type(time)))
return false
end
if not type(target) == "string" then
print(string.format("err: invalid argument 2 to addDayConnector (string expected, got %s",type(target)))
return false
end
if not type(action) == "string" then
print(string.format("err: invalid argument 3 to addDayConnector (string expected, got %s",type(action)))
return false
end
table.insert(connectors,{t=time,targ=target,act=action})
return true
end
-- Like GameMode.setTimeOfDay(), but don't elapse any time for the purposes of this script.
function setTimeOfDay(time)
GameMode.setTimeOfDay(time)
last = time%2
end
-- Like GameMode.advanceTime(), but elapse the appopriate amount of time in this script, even if the value is over 1.
function advanceTime(amt)
GameMode.advanceTime(amt)
updateConnectors(amt)
last = GameMode.getTimeOfDay()
end
function updateConnectors(elapsed)
for index,c in ipairs(connectors) do
c.t = c.t-elapsed
if c.t <= 0 then
local e = findEntity(c.targ)
if e and e.controller then
if e.controller[c.act] then
e.controller[c.act](e.controller)
else
print(string.format("warning: invalid day connector action %s on entity %s",c.act,c.targ))
end
else
print(string.format("warning: invalid day connector target %s",c.targ))
end
table.remove(connectors,index)
end
end
end]],
},
(dont have the time to test at the moment, so there may be some typos)
Then to trigger an event after some amount of elapsed time, you'd make a call like this (it acts like a connector, except the first parameter is the amount of day time to trigger it after; 2 is one day):
Code: Select all
party.dayscript.addDayConnector(2,"dungeon_portcullis_1","open")
Remember to replace any calls to GameMode.setTimeOfDay() or GameMode.advanceTime() with party.dayscript.setTimeOfDay() or party.dayscript.advanceTime().
Attaching a TimerComponent to the party object is the easiest and almost certainly the best way to track elapsed realtime or call something on every frame. The party object is certain to update every frame, since it will always be on the party's level. TimerComponents trigger a maximum of once per frame, which is very convenient (it's why we can use a 1ms interval and not care). The common thought of using an onDrawGui hook is not so good since that hook is not called while the party is free-looking, viewing the map, etc...
edit: fixed one of those typos