Stop+Watch

code // Purpose // -- //  This is a basic example of how you can create a stopwatch. //

// Requirements // -- //  A single prim is all that is necessary for this example.

// Usage // -- //  Touch the object to toggle the timer off/on // type "reset" to reset the timer. Not case-sensitive.

// GLOBAL VARIABLES // --

integer g_Seconds  = 0;        //  Globaly store the Seconds integer g_Minutes  = 0;        //  Globaly store the Minutes integer g_Hours    = 0;        //  Globaly store the Hours integer g_Ticking  = FALSE;    //  Toggles the timer off/on vector g_TextColor = <1,1,1>;  //  Text color for the timer. <1,1,1> = White

// FUNCTIONS // --

// This is a simple function to zero pad the numbers 2 spaces to make // the timer look more authentic. It takes an integer as an argument // and outputs a string. string zero_pad(integer number) {   if(number < 10) return "0" + (string)number; return (string)number; }

// EVENTS // --

default {   state_entry {       //  --        //  This is the entry-point of the script. After a script // has been saved or reset, this event will fire off first // --

// We call llSetText first to reset the text above the object // back to 00:00:00 time. llSetText("00:00:00", g_TextColor, TRUE);

// Set up a listener so that we can reset the timer by typing // "reset". This particular listener will listen to any chat // typed by anyone (or any object) llListen(0, "", "", "");

// Finally, we set up a timer that will repeat itself every // g_Ticking seconds. Since g_Ticking could only ever possibly // equal 0 or 1, we can use this to our advantage in optimizing. // This particular example is not necessary, but can have a        //  dramatic impact on larger scripts. Note that setting a timer // to 0 (False) will indeed turn off the timer. llSetTimerEvent(g_Ticking); }

touch_start(integer num_detected) {       //  If someone touches the object, it will toggle the timer off/on

// We can avoid using if/else statements here because of the // nature of our timer. Using an exclamation in front of the // variable "flips" the bits. In this case, our variable is either // only ever TRUE (1) or FALSE(0). Since we need the timer to       //  tick each second, this becomes a nice optimization method. g_Ticking = !g_Ticking; llSetTimerEvent(g_Ticking);

}

listen(integer channel, string name, key id, string message) {       //  This event is fired off whenever anyone chats around the object // and a proper listener is set up, such as in state_entry

// We take the message and make it all lowercase so that the word // "reset" is not case-sensitive message = llToLower(message); if(message == "reset") {           //  The filter determined that the word "reset" was typed. So           //  we need to reset everything back to 0, and turn the timer off g_Ticking = FALSE; llSetTimerEvent(0); llSetText("00:00:00", g_TextColor, TRUE); g_Seconds = 0; g_Minutes = 0; g_Hours; }   }

timer {       //  This event fires off each second because the integer 1 is being // passed as the argument for seconds in llSetTimerEvent(float seconds)

// Incriment the global Seconds variable by 1 g_Seconds++;

// If seconds are at 60, then we've just made a minute if(g_Seconds >= 60) {           //  So we increment the global minutes by 1, and reset the seconds. g_Minutes++; g_Seconds = 0;

// If the minutes are at 60, then we've just made an hour if(g_Minutes >= 60) {               //  Increment the global hours by 1, and reset the minutes. g_Hours++; g_Minutes = 0; }       }

// Display everything above the object. Notice the use of the zero_pad // function that we created earlier to make the timer look better. llSetText(zero_pad(g_Hours) + ":" + zero_pad(g_Minutes) + ":" + zero_pad(g_Seconds), g_TextColor, TRUE); } }

code