Dota 2 Workshop Tools/Scripting/ThinkerFunctions: Difference between revisions
Jump to navigation
Jump to search
Warning:
(reorganized the page and added some details) |
mNo edit summary |
||
(8 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
{{ | {{lang|Dota 2 Workshop Tools/Scripting/ThinkerFunctions}} | ||
| | |||
}} | {{Dota 2Tools topicons}} | ||
The <code>SetThink</code> function can be used to | The <code>SetThink</code> function can be used to | ||
Line 9: | Line 9: | ||
Passing a function to <code>SetThink</code> is called "registering a [[Think|think]] function". It is possible to have multiple think functions running on an entity at the same time, but this does require the think functions to be named so as not to overlap. | Passing a function to <code>SetThink</code> is called "registering a [[Think|think]] function". It is possible to have multiple think functions running on an entity at the same time, but this does require the think functions to be named so as not to overlap. | ||
{{ | {{warning|<code>SetThink</code> does not respect game pauses. You can use the [https://github.com/bmddota/barebones/blob/source2/game/dota_addons/barebones/scripts/vscripts/libraries/timers.lua Timer library by BMD] to create think functions that respect game pauses.}} | ||
== Signature == | == Signature == | ||
Line 39: | Line 39: | ||
* Returning a number sets the next think time. | * Returning a number sets the next think time. | ||
* Returning <code>nil</code> will unregister the thinker and stop it. | * Returning <code>nil</code> will unregister the thinker and stop it. | ||
== Examples == | |||
=== Example 1 === | |||
Print a message to the console every 5 seconds: | |||
<table> | |||
<tr><th>Class method</th><th>Ordinary function</th></tr> | |||
<tr> | |||
<td valign="top"> | |||
<source lang="lua"> | |||
-- scripts/vscripts/addon_game_mode.lua | |||
if CustomGameMode == nil then | |||
CustomGameMode = class({}) | |||
end | |||
function CustomGameMode:PrintHello () | |||
print("Hello world!") | |||
return 5 | |||
end | |||
function CustomGameMode:InitGameMode () | |||
GameRules:GetGameModeEntity():SetThink("PrintHello", self) | |||
end | |||
function Activate () | |||
GameRules.CustomAddon = CustomGameMode() | |||
GameRules.CustomAddon:InitGameMode() | |||
end | |||
</source> | |||
</td> | |||
<td valign="top"> | |||
<source lang="lua"> | |||
-- scripts/vscripts/addon_game_mode.lua | |||
function PrintHello () | |||
print("Hello world!") | |||
return 5 | |||
end | |||
function Activate () | |||
GameRules:GetGameModeEntity():SetThink(PrintHello) | |||
end | |||
</source> | |||
</td> | |||
</tr> | |||
</table> | |||
=== Example 2 === | |||
Print a message to the console 15 seconds after <code>Activate</code> is called: | |||
<table> | |||
<tr><th>Class method</th><th>Ordinary function</th></tr> | |||
<tr> | |||
<td valign="top"> | |||
<source lang="lua"> | |||
-- scripts/vscripts/addon_game_mode.lua | |||
if CustomGameMode == nil then | |||
CustomGameMode = class({}) | |||
end | |||
function CustomGameMode:PrintHello () | |||
print("Hello world!") | |||
return nil | |||
end | |||
function CustomGameMode:InitGameMode () | |||
GameRules:GetGameModeEntity():SetThink("PrintHello", self, 15) | |||
end | |||
function Activate () | |||
GameRules.CustomAddon = CustomGameMode() | |||
GameRules.CustomAddon:InitGameMode() | |||
end | |||
</source> | |||
</td> | |||
<td valign="top"> | |||
<source lang="lua"> | |||
-- scripts/vscripts/addon_game_mode.lua | |||
function PrintHello () | |||
print("Hello world!") | |||
return nil | |||
end | |||
function Activate () | |||
GameRules:GetGameModeEntity():SetThink(PrintHello, 15) | |||
end | |||
</source> | |||
</td> | |||
</tr> | |||
</table> | |||
=== Example 3 === | |||
Count down from 25 when <code>Activate</code> is called while respecting pauses: | |||
<source lang="lua"> | |||
-- scripts/vscripts/addon_game_mode.lua | |||
local COUNT_DOWN_FROM = 25 | |||
function round (num) | |||
return math.floor(num + 0.5) | |||
end | |||
function Activate () | |||
local endTime = round(GameRules:GetGameTime() + COUNT_DOWN_FROM) | |||
GameRules:GetGameModeEntity():SetThink(function () | |||
local delta = round(endTime - GameRules:GetGameTime()) | |||
if delta > 0 then | |||
print(tostring(delta)) | |||
return 1 | |||
end | |||
end) | |||
end | |||
</source> | |||
=== Example 4 === | |||
Force player 0 to pick a random hero when the game starts: | |||
<source lang="lua"> | |||
-- scripts/vscripts/addon_game_mode.lua | |||
function RandomHeroThink () | |||
local player0 = PlayerResource:GetPlayer(0) | |||
if player0 then | |||
PlayerResource:SetHasRepicked(0) | |||
player0:MakeRandomHeroSelection() | |||
else | |||
return 0.5 | |||
end | |||
end | |||
function Activate () | |||
GameRules:GetGameModeEntity():SetThink(RandomHeroThink, "RAND") | |||
end | |||
</source> | |||
{{shortpagetitle}} | {{shortpagetitle}} | ||
[[Category:Dota 2 Workshop Tools]] | [[Category:Dota 2 Workshop Tools]] |
Latest revision as of 09:24, 25 November 2022
The SetThink
function can be used to
- run a function every x seconds,
- schedule a function to be run x seconds from now.
Passing a function to SetThink
is called "registering a think function". It is possible to have multiple think functions running on an entity at the same time, but this does require the think functions to be named so as not to overlap.

SetThink
does not respect game pauses. You can use the Timer library by BMD to create think functions that respect game pauses.Signature
SetThink
is a method on the CBaseEntity
class. It can be used in two ways:
void SetThink(function thinkFn, string thinkName, float initialDelay)
thinkFn
- The function that you want to run.
The other two arguments are optional:
thinkName
- The name of the think slot. Use this if you want to register multiple thinkers on the same entity.
initialDelay
- Delay in seconds before the thinker should start.
void SetThink(string thinkFnName, table context, string thinkName, float initialDelay)
thinkFnName
- The name of the function you want to run.
context
- A table/object. The function that will be registered is
context[thinkFnName]
. In other words,SetThink
uses the first argument as an index into the second argument. thinkName
,initialDelay
- These are optional. Their descriptions are as above.
Your function should return a number or nil
:
- Returning a number sets the next think time.
- Returning
nil
will unregister the thinker and stop it.
Examples
Example 1
Print a message to the console every 5 seconds:
Class method | Ordinary function |
---|---|
-- scripts/vscripts/addon_game_mode.lua
if CustomGameMode == nil then
CustomGameMode = class({})
end
function CustomGameMode:PrintHello ()
print("Hello world!")
return 5
end
function CustomGameMode:InitGameMode ()
GameRules:GetGameModeEntity():SetThink("PrintHello", self)
end
function Activate ()
GameRules.CustomAddon = CustomGameMode()
GameRules.CustomAddon:InitGameMode()
end
|
-- scripts/vscripts/addon_game_mode.lua
function PrintHello ()
print("Hello world!")
return 5
end
function Activate ()
GameRules:GetGameModeEntity():SetThink(PrintHello)
end
|
Example 2
Print a message to the console 15 seconds after Activate
is called:
Class method | Ordinary function |
---|---|
-- scripts/vscripts/addon_game_mode.lua
if CustomGameMode == nil then
CustomGameMode = class({})
end
function CustomGameMode:PrintHello ()
print("Hello world!")
return nil
end
function CustomGameMode:InitGameMode ()
GameRules:GetGameModeEntity():SetThink("PrintHello", self, 15)
end
function Activate ()
GameRules.CustomAddon = CustomGameMode()
GameRules.CustomAddon:InitGameMode()
end
|
-- scripts/vscripts/addon_game_mode.lua
function PrintHello ()
print("Hello world!")
return nil
end
function Activate ()
GameRules:GetGameModeEntity():SetThink(PrintHello, 15)
end
|
Example 3
Count down from 25 when Activate
is called while respecting pauses:
-- scripts/vscripts/addon_game_mode.lua
local COUNT_DOWN_FROM = 25
function round (num)
return math.floor(num + 0.5)
end
function Activate ()
local endTime = round(GameRules:GetGameTime() + COUNT_DOWN_FROM)
GameRules:GetGameModeEntity():SetThink(function ()
local delta = round(endTime - GameRules:GetGameTime())
if delta > 0 then
print(tostring(delta))
return 1
end
end)
end
Example 4
Force player 0 to pick a random hero when the game starts:
-- scripts/vscripts/addon_game_mode.lua
function RandomHeroThink ()
local player0 = PlayerResource:GetPlayer(0)
if player0 then
PlayerResource:SetHasRepicked(0)
player0:MakeRandomHeroSelection()
else
return 0.5
end
end
function Activate ()
GameRules:GetGameModeEntity():SetThink(RandomHeroThink, "RAND")
end