0 votes
by (160 points)
edited by

I want to execute a function from a timer after a certain amount of in-game time has passed, to do things like enable and disable status effects, trigger events, etc., using a unified system.

I have an array of timer objects which look something like this:

{ time: 10, func: "exampleFunction", args: [foo, bar] }

This function is called from the main time function (a macro named <<time>>) and progresses all the timers:

function timers(forward) {
    "use strict";
    
    let timers = State.getVar("$timers")
    
    for (let i = 0; i < timers.length; i++) {
        timers[i].time = timers[i].time - forward
        
        if (timers[i].time <= 0) {
            executeTimer(timers[i])
            timers.deleteAt(i)
        }
    }
    
    State.setVar("$timers", timers);
}

function executeTimer(timer) {
    let func = timer.func
    let args = timer.args
    
    return window[func](args);
}

I want the code to execute exampleFunction(foo, bar) when the time property reaches 0. It works until the actual execution, where I get this error message:

Error: cannot execute macro <<time>>: window[func] is not a function

What am I doing wrong? Is there a better way to do this?

1 Answer

+1 vote
by (44.7k points)
selected by
 
Best answer

After I changed the last executeTimer() line to:

	return window[func].apply(this, args);

The code worked fine for me when I had exampleFunction(foo, bar) set up like this:

window.exampleFunction = function (foo, bar) {
	alert("Foo = " + foo + "\nBar = " + bar);
	return true;
};

Hope that helps!  :-)

by (160 points)
Thank you, that worked perfectly!

(Also, an aside for anybody coming to this page in the future, the timer code above doesn't deal with simultaneously ending timers well. Use an array of id properties and do the execution and deletion outside the timer loop.)
...