Multiple Timers in a single script?
|
Senuka Harbinger
A-Life, one bit at a time
Join date: 24 Oct 2005
Posts: 491
|
11-28-2005 22:10
I'd really like to use up to 8 timers in a single script using the llSetTimerEvent as it would make firing a weapons loadout with up to 8 different speed weapons firing at once a hell of a lot easier to script. right now I'm stumped as I can only call the timer event once it seems.
|
Osgeld Barmy
Registered User
Join date: 22 Mar 2005
Posts: 3,336
|
11-28-2005 22:20
basic math, a global and some if staments in the timer event integer time = 30; integer function; default { touch start { llSetTimer(time); set function =1; } timer { if (function == 1) { llSetTimer(time); it ran for 30 seconds and this will add 30 more before next timer function = 0; } } this is just an example, otherwise totally useless 
|
Kala Bijoux
Material Squirrel
Join date: 16 Nov 2004
Posts: 112
|
11-28-2005 22:39
integer counter = 0; float tick = whatever;
default { state_entry() { llSetTimerEvent(tick); }
timer() { // Stuff that needs to be done every tick
if ((counter % 2) == 0) { // Stuff to be done every 2 ticks - this will fire when counter == 0, 2, 4, 6, ... }
if ((counter % 3) == 0) { // Stuff to be done every 3 ticks - this will fire on 0, 3, 6, 9, ... }
// ... and so on for other firing rates
// Finally, increment counter on each timer tick counter ++; // or counter = (counter + 1) % maxCounterValueWeCareAbout, if you don't want it to wrap around MAXINT } }
Or make 8 different 'clock' scripts, each running a different timer rate. When the timer fires, it sends a link message, with an integer value indicating which clock just fired. Then in a main handler script, use the received link message value to figure out which clock fired, and therefore decide which weapon to fire. That's another easy way to do this.
|
Senuka Harbinger
A-Life, one bit at a time
Join date: 24 Oct 2005
Posts: 491
|
11-28-2005 22:47
From: Kala Bijoux
Or make 8 different 'clock' scripts, each running a different timer rate. When the timer fires, it sends a link message, with an integer value indicating which clock just fired. Then in a main handler script, use the received link message value to figure out which clock fired, and therefore decide which weapon to fire. That's another easy way to do this.
stupid question that I probably won't need to worry about, but from my understanding of floating point mathematics, won't using a lot of numbers really close together (3 seconds, 2.5 seconds, 1 second, 1.5 second) potentially cause some timing error if something ends in a binary decimal that it has to cut off? [edit] I'm not quite getting the way the script you gave an example of is working, what I'd like to have ideally would be something that looks like this where the timer# are the various timers. [edit 2] were you reffering to that I should have 8 different scripts for each timer, each one listening for the appropriate timer delay, and then having it broatcast a "ready to fire" or "not ready to fire" message for the damage/gun controlling script? float timer1 = 0; float timer2 = 0; float timer3 = 0; float timer4 = 0; float timer5 = 0; float timer6 = 0; float timer7 = 0; float timer8 = 0;
default { state_entry() { } link_message(integer sender_num, integer num, string message, key id) { if (num ==401) { float timer1=(float) message; } if (num ==402) { float timer2 = (float) message; } ... //etc etc.
if (num == 408) { float timer8 = (float) message; } llSetTimerEvent1(timer1); llSetTimerEvent2(timer2); ... //etc etc. llSetTimerEvent8(timer8); }
timer1() { //do stuff }
timer2() { //do stuff }
... //etc etc.
timer8() { //do stuff }
}
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
11-29-2005 08:33
I'm assuming that the 401 through 408 are messages that tell the script that a certain weapon is armed and ready to fire? If so: integer gun1Armed = FALSE; integer gun2Armed = FALSE;
...
float tick = 0.5; // Minimum timer resolution, you only have one timer integer counter = 0; // Timer counter
integer gun1Multiplier = 2; // This is for the 1 sec timer integer gun2Multiplier = 3; // The 1.5 sec timer ... integer maxMultiplier = 20; // Let's say the slowest weapon has a 10 sec rate
default { state_entry() { llSetTimerEvent(tick); // Now you get a timer event every 0.5s no matter what }
link_message(integer sender_num, integer num, string message, key id) { if (num ==401) { gun1Armed = TRUE; } if (num ==402) { gun2Armed = TRUE; } ... //etc etc.
// And to turn off guns, you could use something like... if (num ==501) { gun1Armed = FALSE; } if (num ==502) { gun2Armed = FALSE; } }
// Remember, this timer event is now called every 0.5s
timer() { // Stuff that needs to be done every tick
if (((counter % gun1Multiplier) == 0) && (gun1Armed == TRUE)) { // We're on a gun1Multiplier tick (i.e. every 2nd tick, so 1s), // and gun 1 is armed - do stuff to fire gun 1 }
if (((counter % gun2Multiplier) == 0) && (gun2Armed == TRUE)) { // We're on a gun2Multiplier tick (i.e. every 3rd tick, so every 1.5s), // and gun 2 is armed - do stuff to fire gun 2 }
// ... and so on for other firing rates
// Finally, increment counter on each timer tick counter ++; // or counter = (counter + 1) % maxCounterValueWeCareAbout, if you don't want it to wrap around MAXINT } }
float tick = whatever;
default { state_entry() { llSetTimerEvent(tick); }
timer() { // Stuff that needs to be done every tick
if ((counter % 2) == 0) { // Stuff to be done every 2 ticks - this will fire when counter == 0, 2, 4, 6, ... }
if ((counter % 3) == 0) { // Stuff to be done every 3 ticks - this will fire on 0, 3, 6, 9, ... }
// ... and so on for other firing rates
// Finally, increment counter on each timer tick counter = (counter + 1) % maxMultiplier; } }
Hopefully that makes more sense. Basically, you use a single timer, at your finest/smallest resolution. The counter is a divider of sorts - it tells you which timer tick you're on. So if you want a 1s timer and a 1.5s timer, you can do that by setting a 0.5s timer, and doing stuff every 2nd tick for the 1s and every 3rd tick for the 2s. If you need a 1s timer and a 1.1s timer, you set a 0.1s timer, and do stuff on every 10th and 11th tick. Does that make more sense? 
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
11-29-2005 08:40
From: someone stupid question that I probably won't need to worry about, but from my understanding of floating point mathematics, won't using a lot of numbers really close together (3 seconds, 2.5 seconds, 1 second, 1.5 second) potentially cause some timing error if something ends in a binary decimal that it has to cut off?
Depends. Do you care if a 1.5s timer fires at 1.499999s instead? SL lag will almost guarantee that your timer events won't be received at exactly the right time anyway, even if you used larger enough timer values that floating point error wasn't a concern. Note that in the previous script, you aren't doing any floating point math. You use a single 0.5s timer, and then count up from there, using integer math. So your timing error will be whatever SL does in generating a timer event every 0.5s, not due to any floating point math errors. From: someone [edit 2] were you reffering to that I should have 8 different scripts for each timer, each one listening for the appropriate timer delay, and then having it broatcast a "ready to fire" or "not ready to fire" message for the damage/gun controlling script? Something like this: Script 1: // Timer 1 integer me = 1;
float tick = 1.0;
default { state_entry() { llSetTimerEvent(tick); }
timer() { // Tell the main script that I fired. Use 901, 902, ... as the indicator of timer link messages
llMessageLinked(LINK_SET, (900 + me), "", NULL_KEY); } }
Script 2: // Timer 2 integer me = 2;
float tick = 1.5;
default { state_entry() { llSetTimerEvent(tick); }
timer() { // Tell the main script that I fired. Use 901, 902, ... as the indicator of timer link messages
llMessageLinked(LINK_SET, (900 + me), "", NULL_KEY); } }
Main Script:
...
link_message(integer sender_num, integer num, string message, key id) { if (num ==401) { gun1Armed = TRUE; } if (num ==402) { gun2Armed = TRUE; } ... //etc etc.
// And to turn off guns, you could use something like... if (num ==501) { gun1Armed = FALSE; } if (num ==502) { gun2Armed = FALSE; }
...
// And to fire the guns... if (num ==901) { if (gun1Armed == TRUE) { // Gun 1 is armed and its timer just fired - do stuff } } if (num ==902) { if (gun2Armed == TRUE) { // Gun 2 is armed and its timer just fired - do stuff } } }
...
Again, I hope that makes more sense. 
|
Senuka Harbinger
A-Life, one bit at a time
Join date: 24 Oct 2005
Posts: 491
|
11-29-2005 09:25
From: Ziggy Puff Depends... Again, I hope that makes more sense.  ah, cleared things up a lot  thanks for the help
|