2022-07-29 21:12:54 +01:00
-----
--- Basic timer - after a specified number of seconds, the specified thing happens.
-- Usage:
2022-07-29 21:14:56 +01:00
-- local Timer = require("Timer")
2022-07-29 21:12:54 +01:00
--
-- LevelFuncs.FinishTimer = function(healthWhenStarted, victoryMessage)
-- DoSomething(healthWhenStarted, victoryMessage)
-- end
--
-- LevelFuncs.TriggerTimer = function(obj)
2022-08-01 20:41:06 +01:00
-- local myTimer = Timer.Create("my_timer", 5.0, false, true, "FinishTimer", Lara:GetHP(), "Well done!")
2022-07-29 21:12:54 +01:00
-- myTimer:Start()
-- end
--
2022-07-29 21:14:56 +01:00
-- LevelFuncs.OnControlPhase = function(dt)
-- Timer.UpdateAll(dt)
-- end
--
2022-07-29 21:12:54 +01:00
-- @luautil Timer
2022-07-28 22:18:20 +01:00
LevelVars.__TEN_timer = { timers = { } }
2022-07-29 21:12:54 +01:00
local Timer
2022-08-01 20:41:06 +01:00
local unpausedColor = Color ( 255 , 255 , 255 )
local pausedColor = Color ( 255 , 255 , 0 )
local str = TEN.Strings . DisplayString ( " TIMER " , 0 , 0 , unpausedColor , false , { TEN.Strings . DisplayStringOption.CENTER , TEN.Strings . DisplayStringOption.SHADOW } )
2022-07-28 22:18:20 +01:00
Timer = {
2022-07-29 21:12:54 +01:00
--- Create (but do not start) a new timer.
-- @string name A label to give this timer; used to retrieve the timer later
-- @number totalTime The duration of the timer, in seconds
-- @bool loop if true, the timer will start again immediately after the time has elapsed
2022-08-01 20:41:06 +01:00
-- @bool showString if true, the remaining time, rounded up, will show at the bottom of the screen. __At any given time, only one timer can show its remaining time__.
2022-07-29 21:12:54 +01:00
-- @string func The name of the LevelFunc member to call when the time is up
-- @param funcArgs the arguments with which the above function will be called
-- @return The timer in its paused state
2022-08-01 20:41:06 +01:00
Create = function ( name , totalTime , loop , showString , func , ... )
2022-07-28 22:18:20 +01:00
local obj = { }
local mt = { }
mt.__index = Timer
setmetatable ( obj , mt )
obj.name = name
LevelVars.__TEN_timer . timers [ name ] = { }
local thisTimer = LevelVars.__TEN_timer . timers [ name ]
thisTimer.name = name
2022-08-01 20:41:06 +01:00
thisTimer.showString = showString
2022-07-28 22:18:20 +01:00
thisTimer.totalTime = totalTime
thisTimer.remainingTime = totalTime
2022-08-01 20:41:06 +01:00
thisTimer.func = func
2022-07-28 22:18:20 +01:00
thisTimer.funcArgs = { ... }
thisTimer.loop = loop
thisTimer.active = false
2022-08-01 20:41:06 +01:00
thisTimer.paused = true
2022-07-28 22:18:20 +01:00
return obj
end ;
2022-07-29 21:12:54 +01:00
--- Get a timer by its name.
-- @string name The label that was given to the timer when it was created
-- @return The timer
2022-07-28 22:18:20 +01:00
Get = function ( name )
if LevelVars.__TEN_timer . timers [ name ] then
local obj = { }
local mt = { }
mt.__index = Timer
setmetatable ( obj , mt )
obj.name = name
return obj
end
return nil
end ,
2022-07-29 21:12:54 +01:00
--- Give the timer a new function and args
-- @param t the timer in question
-- @string func The name of the LevelFunc member to call when the time is up
-- @param funcArgs the arguments with which the above function will be called
SetFunction = function ( t , func , ... )
local thisTimer = LevelVars.__TEN_timer . timers [ t.name ]
thisTimer.func = func
thisTimer.funcArgs = { ... }
end ,
2022-08-01 20:41:06 +01:00
--- Begin or unpause a timer. If showing the remaining time on-screen, its color will be set to white.
2022-07-29 21:12:54 +01:00
-- @param t the timer in question
Start = function ( t )
local thisTimer = LevelVars.__TEN_timer . timers [ t.name ]
if not thisTimer.active then
thisTimer.active = true
end
2022-08-01 20:41:06 +01:00
LevelVars.__TEN_timer . timers [ t.name ] . paused = false
if thisTimer.showString then
str : SetColor ( unpausedColor )
end
2022-07-29 21:12:54 +01:00
end ;
2022-08-01 20:41:06 +01:00
--- Pause the timer. If showing the remaining time on-screen, its color will be set to yellow.
2022-07-29 21:12:54 +01:00
-- @param t the timer in question
2022-07-28 22:18:20 +01:00
Pause = function ( t )
2022-08-01 20:41:06 +01:00
local thisTimer = LevelVars.__TEN_timer . timers [ t.name ]
thisTimer.paused = true
if thisTimer.showString then
str : SetColor ( pausedColor )
end
2022-07-28 22:18:20 +01:00
end ,
2022-08-01 20:41:06 +01:00
--- Stop the timer.
-- @param t the timer in question
Stop = function ( t )
LevelVars.__TEN_timer . timers [ t.name ] . active = false
end ,
--- Get the remaining time for a timer.
2022-07-29 21:12:54 +01:00
-- @param t the timer in question
-- @return the time in seconds remaining on the clock
2022-07-28 22:18:20 +01:00
GetRemainingTime = function ( t )
return LevelVars.__TEN_timer . timers [ t.name ] . remainingTime
end ,
2022-07-29 21:12:54 +01:00
--- Set the remaining time for a timer
-- @param t the timer in question
-- @number remainingTime the new time remaining for the timer
2022-07-28 22:18:20 +01:00
SetRemainingTime = function ( t , remainingTime )
LevelVars.__TEN_timer . timers [ t.name ] . remainingTime = remainingTime
end ,
2022-08-01 20:41:06 +01:00
--- Get the total time for a timer.
2022-07-29 21:12:54 +01:00
-- This is the amount of time the timer will start with, as well as when starting a new loop
-- @param t the timer in question
-- @return the timer's total time
2022-07-28 22:18:20 +01:00
GetTotalTime = function ( t )
return LevelVars.__TEN_timer . timers [ t.name ] . totalTime
end ,
2022-07-29 21:12:54 +01:00
--- Set the total time for a timer
-- @param t the timer in question
-- @number totalTime timer's new total time
2022-07-28 22:18:20 +01:00
SetTotalTime = function ( t , totalTime )
LevelVars.__TEN_timer . timers [ t.name ] . totalTime = totalTime
end ,
2022-07-29 21:12:54 +01:00
--- Set whether or not the timer loops
-- @param t the timer in question
-- @bool looping whether or not the timer loops
2022-07-28 22:18:20 +01:00
SetLooping = function ( t , looping )
LevelVars.__TEN_timer . timers [ t.name ] . loop = looping
end ,
2022-07-29 21:12:54 +01:00
--- Update all active timers.
-- Should be called in LevelFuncs.OnControlPhase
-- @number dt The time in seconds since the last frame
2022-07-28 22:18:20 +01:00
UpdateAll = function ( dt )
2022-08-01 20:41:06 +01:00
for _ , t in pairs ( LevelVars.__TEN_timer . timers ) do
2022-07-28 22:18:20 +01:00
Timer.Update ( t , dt )
end
end ;
Update = function ( t , dt )
if t.active then
2022-08-01 20:41:06 +01:00
if not t.paused then
t.remainingTime = t.remainingTime - dt
2022-07-28 22:18:20 +01:00
2022-08-01 20:41:06 +01:00
if t.remainingTime <= 0 then
LevelFuncs [ t.func ] ( table.unpack ( t.funcArgs ) )
2022-07-29 21:12:54 +01:00
2022-08-01 20:41:06 +01:00
if not t.loop then
t.active = false
else
t.remainingTime = t.remainingTime + t.totalTime
end
2022-07-28 22:18:20 +01:00
end
2022-08-01 20:41:06 +01:00
end
2022-07-29 21:12:54 +01:00
2022-08-01 20:41:06 +01:00
if t.showString then
TEN.Strings . HideString ( str )
str : SetKey ( tostring ( math.ceil ( t.remainingTime ) ) )
local myX , myY = PercentToScreen ( 50 , 90 )
str : SetPosition ( myX , myY )
TEN.Strings . ShowString ( str , 1 )
2022-07-28 22:18:20 +01:00
end
2022-08-01 20:41:06 +01:00
2022-07-28 22:18:20 +01:00
end
end ;
}
return Timer