Don't click here unless you want to be banned.

LSL Wiki : LibraryDualTimers

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are ia360925.us.archive.org
I get the question a lot: "How do I run 2 timers at the same time?".

The short answer is "You don't". There are in fact 3 ways to do it:
1) Start a timer running in a remote script and have it communicate back with linked messages.
2) If you have 2 timers with a "greatest common factor", run the script for that time and use counters/switches.
3) Use a repeating sensor that's looking for something that doesn't exist.

#1 is relatively straight forward to set up, and is also the least efficient method in terms of both complexity an execution time, but is a more "pure" solution.

for #2. You can do something like the following:
//Dual Timer Triggers by Redux
//This only works with integer timers.  This can be done with float timers as well, but you would need a GCF with a decimal
//This could be more efficient if you calculated the greatest common factor and set the timer for that.

integer timerCounter = 0;  //a place holder
integer shorterTimer = 3;  //the number of seconds to wait until triggering the first (shorter) timer
integer longerTimer = 7; //the number of seconds to wait until triggering the second (longer) timer
integer bestTime; //optimized timer
default
{
    state_entry()
    {
        //finds the largest number that both are divisible by for the timer
        bestTime = longerTimer / 2;
        while( (shorterTimer % bestTime) || (longerTimer % bestTime))
        {
            --bestTime;
        }

        llSetTimerEvent(bestTime);
    }
    
    timer()
    {
      ++timerCounter;
      
      if(!(timerCounter * bestTime % shorterTimer))
      {
         llOwnerSay("Shorter Timer trigger");
      }
      if(!(timerCounter * bestTime % longerTimer))
      {
         llOwnerSay("Trigger Timer 2");   
      }
    }
}

IMPORTANT NOTE: This script will trigger erratically ONCE after about 4,000 years have passed, when the integer maxes out at 2 billion and resets to negative 2 billion. If this concerns you, you can add the following to the if statement in the timer():
if(!(timerCounter * bestTime % (shorterTimer * longerTimer)))
{
   counter = 0;
}

For the third method, if you have 2 non-integer timers that you cant easily resolve to a greatest common factor, you can use a sensor repeat as a second timer. This also can make it easier to keep track of your timers, and is more pleasing to the eye (albeit WAY laggier, and sort of a hack, still better than the linked messages). This assumes you wont be needing sensors in this state.

//sensor repeat dual timer hack by Redux
float timer1 = 1.79; //some period of time for timer1
float timer2 = 4.33; //some period of time for timer2
key nonExistentPrim = "04662fa1-4a6b-2193-06c9-b52564609606"; //the key of a prim I just deleted.

default
{
    state_entry()
    {
        llSetTimerEvent(timer1);
        llSensorRepeat("", nonExistentPrim, AGENT, 1, 1, timer2);
    }

    timer()
    {
        llOwnerSay("Timer 1");   
    }
    
    no_sensor()
    {
        llOwnerSay("Timer 2");   
    }
}

These can probably be optimized further, but are a good starting point.
There is no comment on this page. [Display comments/form]