Page 1 of 1

Delay script

Posted: Sun Jan 06, 2013 3:54 am
by Shane
Hi folks,

First post here, hello you you all.

I've been doing some scripting on a custom dungeon and as part of it I needed a delay. As I couldn't find a way to do it within the existing tools I wrote this simple delay script. I thought I would share it here in case it is useful.

This delay script calls a specific function after a specified period of time (in seconds). I named it "delay". The limitation of this delay script is that it will not return you to the function that called the delay (I tried to work on that, but as I couldn't use the debug.getinfo trackback I couldn't do it).

I've only been programming lua since tuesday when i first opened the editor (and I am not an IT pro), so if any of the experts on here can see a more efficient way of doing it, or know how to trackback to calling function without using debug tools, please don't hesitate to speak up!

Syntax for calling the delay:

delay.length(<seconds>,"<script to call after delay>","<function to call after delay>")

e.g. delay.length(20,"script1","function1")

(the script and function name must be in "" marks - if you call the script something other than delay the call will be different and need to be changed)

Script code:

Code: Select all

function length(delay_length,target_script,target_function)

	local dl = delay_length
	local ts = target_script
	local tf = target_function

	if findEntity("delay_unique_number") == nil
	then
		spawn("counter", party.level,0,0,0,"delay_unique_number")
			:setValue(1)
	else
		delay_unique_number:increment()
	end

	local timername = ("timer_counter_" .. delay_unique_number:getValue())
	spawn("timer",party.level,0,0,0,timername)
		:addConnector("activate", ts, tf)
		:addConnector("activate", timername, "destroy")
		:setTimerInterval(dl)
		:activate()

end
Regards,

Shane

Re: Delay script

Posted: Sun Jan 06, 2013 5:06 am
by Komag
Hmm, so this is a general script you stick in the dungeon and then forever after that you use this code whenever you want delays? I've always just set up new unique timers for each individual situation, which is all this does anyway I suppose, but I see how some people might really like a framework like this.

I'm not sure if the other framework guys have any delay system already, maybe you could compare notes?

Re: Delay script

Posted: Sun Jan 06, 2013 8:00 am
by dasarby
i kinda like it. It removes the complexity of generating a timer, and provides a "do this callback after N seconds" type functionality that is very common in other scripting languages.

The counter seems like an unnecessary complication though. The reason to use a counter would be if you wanted people to be able to add triggers to the counter. Otherwise, just use a script level variable:

Code: Select all

timer_count = 0 

function length(delay_length,target_script,target_function)

   local dl = delay_length
   local ts = target_script
   local tf = target_function

   timer_count = timer_count + 1

   local timername = ("timer_counter_" .. timer_count)
   spawn("timer",party.level,0,0,0,timername)
      :addConnector("activate", ts, tf)
      :addConnector("activate", timername, "destroy")
      :setTimerInterval(dl)
      :activate()

end

Re: Delay script

Posted: Sun Jan 06, 2013 2:46 pm
by Komag
Ah yes, I rarely use counters anymore, almost always script variables, although once in a while a counter is easier to set up

Re: Delay script

Posted: Sun Jan 06, 2013 10:07 pm
by Diarmuid
Hi there, yes I have a delay implemented (thank god or exsp would have never seen the light...).

I see two problems with your delay: it's not constant if party changes level, and you cannot pass arguments to the function. Here's what I use, which is powered by LoG framework. As you can see, I also have a cancelDelay function I can call to stop execution of the function before the time's up:

Code: Select all

function delay(delay, funct, args)
	local delayId = randomTimerId("delay")
	local delayTimer = timers:create(delayId)
	delayTimer:setTimerInterval(delay)
	delayTimer:addCallback(funct,args)
	delayTimer:setTickLimit(1,true)
	delayTimer:activate()
	return delayId
end

function cancelDelay(delayId)
	local delayTimer = timers:find(delayId)
	delayTimer:deactivate()
	delayTimer:destroy()
end

function randomTimerId(prefix)
	local numId = math.random(10000,99999)
	while timers:find(prefix.."."..numId) do
		numId = math.random(10000,99999)
	end
	return prefix.."."..numId
end
Example call:

Code: Select all

local a = "Hello "
local b = "World!"
delay(2,
	function(self, a, b)
		print(a..b)
	end,
	{a, b}
)
EDIT: And another code with the cancel delay, you have to keep the unique delayId returned by the delay function:

Code: Select all

local a = "Hello "
local b = "World!"
delayId = delay(5,
	function(self, a, b)
		print(a..b)
	end,
	{a, b}
)

-- Somewhere else:

if [...] then
	cancelDelay(delayId)
end
EDIT2: Forgot randomTimerId() code.

Re: Delay script

Posted: Sun Jan 06, 2013 10:55 pm
by Shane
Hi guys,

Thanks for the comments. Diarmuid, I see your point about changing level, my implementation would only really work for short duration stuff where you wouldn't be likely to change levels.

How does the add Callback thing work, and what can be done with it? Doe sit mean you can craft a bespoke function to trigger on that delay alone? If so, can it also be used to refer to another existing function? Sorry if it's a dumb question, but I googled the callback thing and didn't understand it.

Regards,

Shane

Re: Delay script

Posted: Sun Jan 06, 2013 11:40 pm
by Diarmuid
I realized the script I posted above is not level-constant either because I didn't need it, but you can add an argument to trigger delayTimer:setConstant(). For all info about the extended timers, check the docs on jKos's google homepage (search the forum for LoG framework or scripting cheat sheet).

The callback is a function executed everytime the timer ticks.

EDIT: Here's the link: https://sites.google.com/site/jkosgrimrock2/home

Re: Delay script

Posted: Mon Jan 07, 2013 11:30 pm
by Shane
Thanks!


Shane