Okay, one more before I get down to stuff that's specific to the game I'm writing (I think). I promise I'll stop spamming the file uploads section now. ;P ...for at least a week, anyway.
I wrote an event scheduling lib today using my ClassBuilder. (The zip also contains the latest version of ClassBuilder.pl, which has macros that allow easy type checking at runtime and can translate from type ID numbers into class names to give easy-to-read error messages...see the StringCmp() function in string.dma if you're interested in using them, and can run Perl scripts.)
Events can be single-use (with a time interval specifying how many ticks in the future the event will occur, after which they will delete themselves), recurring (with a time interval specifying how many ticks to wait before triggering the event again) or conditional (where you can set a function to be called to see whether the event should be triggered or not.)
When an event is triggered, it calls a specified function and uses a global variable to pass a single integer into the event function. I've been using it as a pointer to a DMA-based object that holds whatever data I need. If you just want to pass plain integers around, use the SimpleEvent class that is also included - it won't try to interpret your data as a pointer and use MemFree() on it when the event is deleted. Otherwise the SimpleEventSetup* functions work the same as the EventSetup* functions.
Events can be cancelled at any time either by using a pointer to the Event object (which is returned by the constructors...you can choose to catch the pointer or not, since all the essential work is done by the constructor) or by using the name of the event function you want to end. Using the name will cancel any events that are currently using that function.
Events can be paused and resumed with no ill effects. Like this:
// Set up an event to occur in 10 seconds
EventSetupOnce(1000, 'DoSomething', 0);
Wait(500); // Wait for 5 seconds
EventPause(); // Pause all events
Wait(6000); // Wait for a full minute
EventUnpause(); // The event will occur 5 seconds from now.
This works, too:
EventPause(); // Pause the events
EventSetupOnce(50, 'DoSomething', 0); // Set an event for .5 seconds after unpause
// do lots of stuff
EventUnpause(); // In .5 seconds the event will activate
The included system.vc has examples for all three types of events. Just unzip the archive over a fresh copy of the V3 engine.
Get it
right here.
* edit *
Urk. Just realized that some of my comments in system.vc are lying. They say that we're not unpausing the events until the map transition completes, but I found that I was being overly cautious in that and changed it to unpause just before the map transition starts. I just forgot to change the comments.