Jump to content

[Lua Help] Waiting and Busy Waiting - how do i "delay" calls?


Recommended Posts

I'm trying to make a series of locomotor calls to make the player deploy a bunch of prefabs in a nice, long row, but there does not appear to be any way to "sleep" or "wait" in LUA.  Here is an example of what my script would look like if there was a "Sleep" function:

for k, v in pairs(actionlist) doaction = actionlist[k].actiondestination = actionlist[k].destinationplayer.components.locomotor:GoToPoint(destination, action, true)----------repeat   SLEEP(0.250) --sleep for 250msuntil (player.sg:HasStateTag("idle"))end

Without the delay created by that sleep, the entire code executes as fast as the CPU can run it.  The character deploys all the wall prefabs from the actionlist simultaneously, then walks to the final destination coordinate.  What I want the player to do is loco to the first coordinate, deploy a prefab, then proceed to the next one.

Link to comment
Share on other sites

Search for DoTaskInTime. The function definition is in scripts/entityscript.lua.

 

Thank you so much! I've been looking all over the scripts for a starting point.  This also helped me to find the sleep function, which is in Scheduler.lua.  I was very curious about Klei was implementing delays.

function EntityScript:DoTaskInTime(time, fn, ...)	--print ("DO TASK IN TIME", time, self)    if not self.pendingtasks then		self.pendingtasks = {}    end        local per = scheduler:ExecuteInTime(time, fn, self.GUID, self, ...)    self.pendingtasks[per] = true    per.onfinish = task_finish -- function() if self and self.pendingtasks then self.pendingtasks[per] = nil end end    return perend 

 

function Sleep(time)    local desttick = math.ceil((GetTime() + time)/GetTickTime())	if GetTick() < desttick then        coroutine.yield(SLEEP, desttick)    else        coroutine.yield()    endend

 

[spoilers contain code for anyone else who is curious]

Link to comment
Share on other sites

Thank you so much! I've been looking all over the scripts for a starting point.  This also helped me to find the sleep function, which is in Scheduler.lua.  I was very curious about Klei was implementing delays.

function EntityScript:DoTaskInTime(time, fn, ...)	--print ("DO TASK IN TIME", time, self)    if not self.pendingtasks then		self.pendingtasks = {}    end        local per = scheduler:ExecuteInTime(time, fn, self.GUID, self, ...)    self.pendingtasks[per] = true    per.onfinish = task_finish -- function() if self and self.pendingtasks then self.pendingtasks[per] = nil end end    return perend 

 

function Sleep(time)    local desttick = math.ceil((GetTime() + time)/GetTickTime())	if GetTick() < desttick then        coroutine.yield(SLEEP, desttick)    else        coroutine.yield()    endend

 

[spoilers contain code for anyone else who is curious]

Nice! I didn't know about Sleep. That's much closer to what you're looking for originally. Another option would be to see if there's an event that is fired when you go idle (or create your own event) to finish up doing stuff without having a sleep loop. A sloop?

Link to comment
Share on other sites

I've been trying to use DoTaskInTime(time, fn, ...) with various values for time and nothing seems to have any impact on the delay.  I would love to just use the Sleep() function directly, but it needs to be used "from within a thread". I don't yet understand how to thread.

EntityScript:DoTaskInTime(100000, print("tasking time of 100000"))EntityScript:DoTaskInTime(1, print("tasking time of 1"))

Both of those print statements execute immediately, without any delay.

 

 

[edit:]

 I searched the forums using google site search before I made the first post in this topic.  I've looked so many times without finding anything, but just a moment ago I found this topic:

 

http://forums.kleientertainment.com/topic/33035-lua-sleep-function/

Link to comment
Share on other sites

There are a few things I can see with wrong with the DoTaskInTime lines. First, the function should be run with the context of an entity. Second, the 2nd argument needs to be a function that takes an entity as the first argument.

AddPostInit("spear", function(firstInst)    firstInst.components.weapon:SetOnAttack(function(secondInst, attacker, target)        secondInst:DoTaskInTime(10, function(thirdInst)            thirdInst.owner.components.inventory:RemoveItem(thirdInst)        end)    end)end)
This will set a ten second timer when you attack with a spear. When that ten seconds is up, you will drop the spear.

I'll definitely have to look at that thread to learn more about Threads and Sleeping!

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...