ТАЙМЕРЫ от BMD
Код:
--[[
-- A timer running every second that starts immediately on the next frame, respects pauses
Timers:CreateTimer(function()
print ("Hello. I'm running immediately and then every second thereafter.")
return 1.0
end
)
-- A timer running every second that starts 5 seconds in the future, respects pauses
Timers:CreateTimer(5, function()
print ("Hello. I'm running 5 seconds after you called me and then every second thereafter.")
return 1.0
end
)
-- 10 second delayed, run once using gametime (respect pauses)
Timers:CreateTimer({
endTime = 10, -- when this timer should first execute, you can omit this if you want it to run first on the next frame
callback = function()
print ("Hello. I'm running 10 seconds after when I was started.")
end
})
-- 10 second delayed, run once regardless of pauses
Timers:CreateTimer({
useGameTime = false,
endTime = 10, -- when this timer should first execute, you can omit this if you want it to run first on the next frame
callback = function()
print ("Hello. I'm running 10 seconds after I was started even if someone paused the game.")
end
})
-- A timer running every second that starts after 2 minutes regardless of pauses
Timers:CreateTimer("uniqueTimerString3", {
useGameTime = false,
endTime = 120,
callback = function()
print ("Hello. I'm running after 2 minutes and then every second thereafter.")
return 1
end
})
-- A timer using the old style to repeat every second starting 5 seconds ahead
Timers:CreateTimer("uniqueTimerString3", {
useOldStyle = true,
endTime = GameRules:GetGameTime() + 5,
callback = function()
print ("Hello. I'm running after 5 seconds and then every second thereafter.")
return GameRules:GetGameTime() + 1
end
})
]]
TIMERS_THINK = 0.01
if Timers == nil then
print ( '[Timers] creating Timers' )
Timers = {}
Timers.__index = Timers
end
function Timers:new( o )
o = o or {}
setmetatable( o, Timers )
return o
end
function Timers:start()
Timers = self
self.timers = {}
local ent = Entities:CreateByClassname("info_target") -- Entities:FindByClassname(nil, 'CWorld')
ent:SetThink("Think", self, "timers", TIMERS_THINK)
end
function Timers:Think()
if GameRules:State_Get() >= DOTA_GAMERULES_STATE_POST_GAME then
return
end
-- Track game time, since the dt passed in to think is actually wall-clock time not simulation time.
local now = GameRules:GetGameTime()
-- Process timers
for k,v in pairs(Timers.timers) do
local bUseGameTime = true
if v.useGameTime ~= nil and v.useGameTime == false then
bUseGameTime = false
end
local bOldStyle = false
if v.useOldStyle ~= nil and v.useOldStyle == true then
bOldStyle = true
end
local now = GameRules:GetGameTime()
if not bUseGameTime then
now = Time()
end
if v.endTime == nil then
v.endTime = now
end
-- Check if the timer has finished
if now >= v.endTime then
-- Remove from timers list
Timers.timers[k] = nil
-- Run the callback
local status, nextCall = pcall(v.callback, GameRules:GetGameModeEntity(), v)
-- Make sure it worked
if status then
-- Check if it needs to loop
if nextCall then
-- Change its end time
if bOldStyle then
v.endTime = v.endTime + nextCall - now
else
v.endTime = v.endTime + nextCall
end
Timers.timers[k] = v
end
-- Update timer data
--self:UpdateTimerData()
else
-- Nope, handle the error
Timers:HandleEventError('Timer', k, nextCall)
end
end
end
return TIMERS_THINK
end
function Timers:HandleEventError(name, event, err)
print(err)
-- Ensure we have data
name = tostring(name or 'unknown')
event = tostring(event or 'unknown')
err = tostring(err or 'unknown')
-- Tell everyone there was an error
--Say(nil, name .. ' threw an error on event '..event, false)
--Say(nil, err, false)
-- Prevent loop arounds
if not self.errorHandled then
-- Store that we handled an error
self.errorHandled = true
end
end
function Timers:CreateTimer(name, args)
if type(name) == "function" then
args = {callback = name}
name = DoUniqueString("timer")
elseif type(name) == "table" then
args = name
name = DoUniqueString("timer")
elseif type(name) == "number" then
args = {endTime = name, callback = args}
name = DoUniqueString("timer")
end
if not args.callback then
print("Invalid timer created: "..name)
return
end
local now = GameRules:GetGameTime()
if args.useGameTime ~= nil and args.useGameTime == false then
now = Time()
end
if args.endTime == nil then
args.endTime = now
elseif args.useOldStyle == nil or args.useOldStyle == false then
args.endTime = now + args.endTime
end
Timers.timers[name] = args
return name
end
function Timers:RemoveTimer(name)
Timers.timers[name] = nil
end
function Timers:RemoveTimers(killAll)
local timers = {}
if not killAll then
for k,v in pairs(Timers.timers) do
if v.persist then
timers[k] = v
end
end
end
Timers.timers = timers
end
Timers:start()
Первое, что бросается в глаза - куча примеров (типа вместо документации). Их действительно куча, и даже немного сбивают столку: какой юзать, а чем этот отличается от другого и т. д. Сама "библиотека" представляет из себя набор функций, которые можно использовать вызвав и передав нужные параметры. Как стандартный print('текст').
Но если стандартный принт подключен в стандартной Луа, то таймеры написал чувак с ником BMD (гамбургер) и чтобы использовать таймеры нужно их подключить вручную, или просто закинуть все содержимое в файл, где собираемся использовать, но это быдлокод.
Итак подключаем:
[list type=decimal]
[li]Скачиваем луа файл по ссылке выше. [/li]
[li]Кидаем в папку с скриптами (там, где аддон_гейм_мод.луа)[/li]
[li]В аддоне_гейм_луа подключаем: require('имя_файла_без_расширения') т.е. timers.lua будет как 'timers'. Подключать нужно выше места, где будем юзать таймеры, что логично. Например в init функции[/li]
[li]Создать таймер.[/li]
[/list]
Я, лично, использовал два типа таймеров: который выполняется раз в "n" сек, и второй - ждет "m" сек и начинает выполнятся раз в "n" сек. таймер как Thinker, но лучше, да и вызывать можно где угодно, а не только в инит. Чтобы остановить(удалить) таймер передаем return nil
Первый тип
Timers:CreateTimer(function()--действия
return 1.0 -- 1.0 Время следующего запуска в сек, nil - остановиться.
end )
Второй тип
Timers:CreateTimer(5, function() -- Такой же как и первый, но ждет 5 сек перед первым запуском.--действия
return 1.0 -- 1.0 Время следующего запуска в сек, nil - остановиться.
end )
Обычно в блоке "действия" добавляют проверку на успешность выполнения какой-либо цели, и в случае успеха return nill Время можно задавать в дробных: return 0.5 Есть другие типы таймеров, например: игнорирующие паузы или наоборот ожидающие вместе с паузами и .т.д.
Сам файл (возможно будет обновляться)
Последнее редактирование модератором: