Join us in Outworldz at www.outworldz.com:9000 or follow us:

Search dozens of selected web sites for OpenSim and LSL script

New! Script Meta-Search will search thousands of scripts here and at other sites for LSL or Opensim scripts.
Loading

Want to add a script or a project? Upload it and a half million people will see it and your name here this year.

Home   Show All
Category: Contributor: Creator
Clock THWatch_  

THWatch_

THWatch 0.lsl

Category: Clock
By : Trimming Hedges
Created: 2010-01-10 Edited: 2010-01-10
Worlds: Second Life

the Zip file

Download all files for THWatch_
Contents are in zip format, with .LSL (text) source code and LSLEdit (text + Solution) formats.
Get file # 1. THWatch__1.lsl
1
2
3 // THWatch, version 0.32, written 12/30/03 by Trimming Hedges. You're welcome to use this code as you wish. If you find it
4 // useful, I'd appreciate a donation. I stole a couple of code snippets, primarily the argument-parsing stuff
5 // (search for 'preamble') from another watch script. There's no record of the author or I would credit them. I'm not really
6 // a programmer (as will probably be obvious from the code :) ), and this is my first real script, so if you find bugs or have
7 // suggestions, I'm eager to hear them.
8
9 // This code is released under the Attribution-ShareAlike Creative Commons license. A summary is at:
10 // http://creativecommons.org/licenses/by-sa/1.0/. Basically: if you incorporate my code, you must credit me and you must
11 // release that code freely. If you make a super-cool watch and put this code in it, you are welcome to sell it for any
12 // amount you can get for it, but you cannot lock the user's ability to see, modify, or copy this code.
13 // If you want to lock your object and can do so while still leaving this code free, that's fine.
14
15 // WARNING: this script is VERY close to the heap limit, which seems to be about 8k. There's probably about 10 BYTES left.
16 // If you want to add ANYTHING to this, you're going to have to take something else out.
17
18 // revision history: 0.30 released 12/31/2003. Most recent change: Attempt to avoid double listens by checking to see if listentrack
19 // variable is set before starting a listen, and clearning listentrack variable when clearing a listen. Should avoid an occasional bug
20 // I've seen.
21
22
23 // DEFAULTS SECTION:
24 // User-settable defaults: you can change all of these with 'say' commands, but if you get tired of that, change the defaults here.
25
26
27 integer hour24 = 0; // 0 is 12-hour (AM/PM), 1 is 24-hour.
28 integer offset = 0; // 3 = eastern, 8 = roughly UTC (depends on Daylight Savings), Sydney=18, Hawaii=-2
29 integer alarmwarnmax = 3; // how many times the alarm should alert you before shutting off
30 integer output = 1; // 0=tell via dialog, 1=instant message, 2=whisper, 2=say, 3=shout
31 integer playsound = 1; // whether or not to make sound
32 integer updatefrequency = 1; // how often, in seconds, the watch checks the alarm and timer. If you use the timer, you probably want 1
33
34 // Other global variables, computed by the watch. If you change these without understanding how the watch works internally,
35 // you will probably break it.
36
37 integer alarmset = 0;
38 integer alarmmintime = 0;
39 integer alarmmaxtime = 0;
40 integer alarmwarnings = 0;
41 integer timerstop = 0;
42 integer timerset = 0;
43 integer stopwatchstart=0;
44 integer stopwatchon=0;
45 integer listentrack=0;
46 string version = "0.32";
47 key owner;
48
49 integer secondsin24hours = 86400;
50
51 // Code starts
52
53 telluser (string outmessage)
54 {
55 if(output == 0)
56 llDialog(owner, outmessage, [], 23882102 );
57 if(output == 1)
58 llInstantMessage(owner, outmessage);
59 if(output == 2)
60 llWhisper(0,outmessage);
61 if(output == 3)
62 llSay(0,outmessage);
63 if(output == 4)
64 llShout(0,outmessage);
65 }
66
67 do_help (key id)
68 {
69 llGiveInventory(id,"THWatchbasichelp");
70 }
71
72 do_morehelp(key id)
73 {
74 llGiveInventory(id,"THWatchadvancedhelp");
75 }
76
77 integer localseconds (integer lindenseconds)
78 {
79 integer localseconds = lindenseconds + (offset * 3600); // add or subtract 3600 seconds per hour of offset
80
81 if( localseconds < 0)
82 localseconds = localseconds + secondsin24hours;
83 localseconds = localseconds % secondsin24hours; // masks times greater than 1 day; modulo result can't exceed 86399, 1 second before midnight
84 return localseconds;
85 }
86 integer lindenseconds (integer localseconds)
87 {
88 integer lindenseconds = localseconds - (offset * 3600); //subtract or add 3600 seconds per hour of offset
89 if(lindenseconds < 0)
90 lindenseconds = lindenseconds + secondsin24hours;
91 lindenseconds = lindenseconds % secondsin24hours; // modulo division prevents values greater than secondsin24hours
92 return lindenseconds;
93 }
94
95 integer stringtoseconds (string timestring)
96 {
97 list hoursminutes = llParseString2List(timestring, [ ":" ], [] );
98 integer hour = llList2Integer(hoursminutes,0);
99 integer minutes = llList2Integer(hoursminutes,1);
100 return ( (hour * 3600) + (minutes * 60) );
101 }
102
103 string secondstostring (integer time)
104 // this function takes a number of seconds and converts it into a human-readable string.
105 // It returns a null string if it gets greater than 24 hours' worth of seconds, or if it gets less than zero.
106 // It reads the global veriable hour24 to know how to format the string
107
108 {
109 integer hours = 0;
110 integer minutes = 0;
111 integer seconds = 0;
112 string hourstring = "";
113 string minutestring = "";
114 string secondstring="";
115 string ampm="";
116
117 if( (time > secondsin24hours) || (time < 0) ) // invalid value, return empty string
118 return "";
119
120 hours = time / 3600; // 3600 seconds in an hour
121 time = time % 3600; // get remainder, anything less than 3600
122
123 minutes = time / 60; // 60 seconds in a minute
124 time = time % 60; // get remainder, anything less than 60
125
126 seconds = time; // all we have left are seconds
127
128
129 if(minutes < 10) // pad output string for readability
130 minutestring = "0"+(string)minutes;
131 else
132 minutestring = (string)minutes;
133
134 if(seconds < 10)
135 secondstring = "0"+(string)seconds;
136 else
137 secondstring = (string)seconds;
138
139 // determine whether we're in 24-hour mode
140
141 if(hour24 != 1)
142 {
143 if(hours < 12)
144 ampm = " AM";
145 else
146 ampm = " PM";
147
148 if(hours > 12) // can't combine these into 1 if statement, because hours=12 is PM but shouldn't have 12 subtracted
149 {
150 hours = hours - 12;
151 } else if(hours == 0) // it's 12AM
152 {
153 hours = 12;
154 }
155 } else { // it is a 24 hour clock, skip all that crap
156 ampm = "";
157 }
158
159 hourstring = (string)hours; // doesn't need padding, 9:03 looks better than 09:03
160
161 return hourstring + ":"+minutestring+":"+secondstring + ampm;
162 }
163
164 showtime()
165 {
167
168 time = localseconds (time);
169
170 if(offset == 0)
171 {
172 telluser ("Linden time is " + secondstostring(time) + ".");
173 } else {
174 telluser ("Your local time is " + secondstostring(time) + ".");
175 }
176 }
177
178 alarmfunctions (list parsed) // I use braces around single statement blocks here for readability, since they're fairly long commands.
179 {
180 string alarmcommand = llList2String(parsed,2);
181 if(alarmcommand == "")
182 {
183 if(alarmset == 0)
184 {
185 telluser ("Alarm isn't set.");
186 return;
187 }
188 if(offset != 0)
189 {
190 telluser ("Alarm set for " + secondstostring(localseconds(alarmmintime)) + ", your local time.");
191 } else
192 {
193 telluser ("Alarm set for " + secondstostring(alarmmintime) + ", Linden Standard Time.");
194 }
195 } else if( (alarmcommand == "warning") || (alarmcommand == "warnings") )
196 {
197 string alarmwarnings = llList2String(parsed,3);
198 if( (integer)alarmwarnings == 0) // if they pass in something non-numeric or blank
199 {
200 telluser ("Alarm warnings now " + (string)alarmwarnmax);
201 return;
202 }
203 if( ( (integer)alarmwarnings < 1 ) || ( (integer)alarmwarnings > 60 ) )
204 {
205 telluser ("Warnings must be between 1 and 60, inclusive");
206 return;
207 } else
208 {
209 alarmwarnmax = (integer)alarmwarnings;
210 telluser ("Warnings now set to " + alarmwarnings);
211 }
212 }
213 else if(alarmcommand == "off")
214 {
215 alarmset = 0; // alarm turns off!
216 alarmmintime = 0;
217 alarmmaxtime = 0;
218 telluser ("Alarm disabled.");
219 }
220 else // we assume user is setting time... original code used 'set' but everyone including me kept getting confused.
221 // this is the single most complex function, as it has to deal with many different input and output possibilities
222 {
223 // old syntax was alarm time set, new syntax is alarm time XX:YY, move arguments down by one if arg2 is 'set'
224 string alarmtimestring = llList2String(parsed,2); // this is the same argument as timecommand, so they're identical values
225 string argument3 = llList2String(parsed,3); // this is a bit tough; user could say 5:00 pm lst, or 5:00 pm, or 5:00 lst
226 string argument4 = llList2String(parsed,4);
227 string argument5 = llList2String(parsed,5);
228 if(alarmtimestring == "set") // old syntax was alarm time set XX:YY, new one is alarm time XX:YY... if there is a set,
229 // slide all variables down by one
230 {
231 alarmtimestring = argument3;
232 argument3 = argument4;
233 argument4 = argument5;
234 }
235 list alarmtimeparsed = llParseString2List(alarmtimestring, [ ":" ],[]);
236 integer alarmhour = llList2Integer(alarmtimeparsed,0);
237 integer alarmminute = llList2Integer(alarmtimeparsed,1);
238
239 if(alarmhour > 12)
240 {
241 telluser ("Hour greater than 12. Ignoring AM or PM.");
242 } else
243 {
244 if(argument3 == "pm")
245 {
246 if(alarmhour < 12) // fortunately, 12 pm is just 12, it's only 1-11 pm we need to worry about
247 {
248 alarmhour = alarmhour + 12;
249 }
250 }
251 if(argument3 == "am") // have to check for 12 am
252 {
253 if(alarmhour == 12)
254 {
255 alarmhour = 0; // 12 am is 0 hours
256 }
257 }
258 }
259
260 integer alarmtimeseconds = (alarmhour * 3600 ) + (alarmminute * 60);
261 if(alarmtimeseconds < 0) // user is being stupid
262 {
263 telluser ("Can't set alarms for negative time values.");
264 return;
265 }
266 alarmtimeseconds = alarmtimeseconds % secondsin24hours; // just in case user is being an idiot, prevent >24 hour times
267
268 if((argument3 == "lst") || (argument4 == "lst") || (offset == 0)) // user said 'lst', or offset is 0, so the time was specified as lindentime
269 {
270 alarmmintime = alarmtimeseconds;
271 alarmmaxtime = alarmtimeseconds + 60; // 1 minute later
272 alarmset = 1; // alarm turns on!
273 telluser ("Alarm set for " + secondstostring(alarmtimeseconds) + " Linden Standard Time.");
274 } else // user didn't say 'lst' and offset is nonzero, so he/she is specifying local time
275 {
276 alarmmintime = lindenseconds (alarmtimeseconds); // we set the actual alarm in lindenseconds, even though we display localtime
277 alarmmaxtime = alarmmintime + 60;
278 alarmset = 1; // alarm turns on!
279 telluser ("Alarm set for " + secondstostring(alarmtimeseconds) + ", your local time.");
280 }
281 }
282 }
283
284 outputfunctions (list parsed)
285 {
286 string outputsetting = llList2String(parsed,2);
287
288 if(outputsetting == "dialog")
289 {
290 output = 0;
291 } else if(outputsetting == "message")
292 {
293 output = 1;
294 } else if(outputsetting == "whisper")
295 {
296 output = 2;
297 } else if(outputsetting == "say")
298 {
299 output = 3;
300 } else if(outputsetting == "shout")
301 {
302 output = 4;
303 } else {
304 telluser ("Has to be dialog, message, whisper, say, or shout.");
305 }
306 telluser ("Watch output is like this.");
307 return;
308 }
309
310 modefunctions (list parsed)
311 {
312 string newmode = llList2String(parsed,2);
313
314 if(newmode == "12")
315 {
316 hour24 = 0;
317 telluser ("Watch set to 12-hour mode.");
318 } else if(newmode == "24")
319 {
320 hour24 = 1;
321 telluser ("Watch set to 24-hour mode.");
322 } else if(newmode =="")
323 {
324 if(hour24 == 1)
325 {
326 telluser ("Watch is in 24-hour mode.");
327 } else {
328 telluser ("Watch is in 12-hour mode.");
329 }
330 } else {
331 telluser ("You can only set 12- or 24-hour mode.");
332 }
333 return;
334 }
335
336 zonefunctions (list parsed)
337 {
338
339 if(llList2String(parsed, 2) != "") // any argument given
340 {
341 integer newzone = (integer)llList2String(parsed,2);
342 if((newzone < -24) || (newzone > 24))
343 {
344 telluser ("Zone has to be between -24 and +24, inclusive.");
345 return;
346 }
347 offset = newzone;
348 telluser ("Time zone offset changed to " + (string)offset);
349 } else // no argument given, just tell current setting
350 {
351 telluser ("Current time zone is " + (string)offset);
352 }
353 }
354
355 stopwatchfunctions (list parsed)
356 {
357 integer elapsed;
358 if(stopwatchon == 0)
359 {
360 telluser ("Starting stopwatch.");
361 stopwatchstart = (integer)llGetWallclock();
362 stopwatchon = 1;
363 } else
364 {
365 telluser ("Stopping stopwatch.");
366 elapsed = (integer)llGetWallclock() - stopwatchstart;
367 if(elapsed < 0)
368 {
369 elapsed = secondsin24hours - elapsed;
370 }
371 telluser ("Stopwatch stopped after " + (string)elapsed + " seconds.");
372 stopwatchon = 0;
373 stopwatchstart = 0;
374 }
375 }
376 timerfunctions (list parsed)
377 {
378 integer timercount = (integer)llList2String(parsed,2);
379 if(timercount == 0)
380 {
381 telluser ("Disabling timer");
382 timerset = 0;
383 timerstop = 0;
384 }
385 if(timercount > 0)
386 {
387 timerstop = (integer)llGetWallclock() + timercount;
388 if( timerstop < secondsin24hours)
389 {
390 timerset = 1;
391 telluser ("Timer set! Counting " + (string)timercount + " seconds.");
392 } else
393 {
394 telluser ("Can't set timer across midnight boundary LST.");
395 }
396 }
397 return;
398 }
399
400 soundfunctions (list parsed)
401 {
402 string onoroff = llList2String(parsed,2);
403 if(onoroff == "on")
404 {
405 playsound = 1;
406 } else if(onoroff == "off")
407 {
408 playsound = 0;
409 }
410 if(playsound)
411 {
412 telluser ("Sound output is on.");
413 } else {
414 telluser ("Sound output is off.");
415 }
416 }
417 do_alarm()
418 {
419 if(playsound)
420 llPlaySound("alarmbeep",0.50);
421 telluser ("Alarm going off! It was set for " + secondstostring(localseconds(alarmmintime)));
422 alarmwarnings = alarmwarnings + 1;
423 if(alarmwarnings >= alarmwarnmax)
424 {
425 alarmset = 0;
426 alarmwarnings = 0;
427 }
428 }
429
430
431 do_timerexpire()
432 {
433 timerset = 0;
434 timerstop = 0;
435 if(playsound)
436 llPlaySound("timerbeep",1.0);
437 telluser ("Time's up!");
438 }
439
440 init ()
441 {
442 owner = llGetOwner();
443 telluser("THWatch " + version+". Say 'time help' or 'time morehelp' for basic or advanced help.");
444 if(listentrack == 0)
445 {
446 llSetTimerEvent(updatefrequency);
447 listentrack=llListen(0, "", owner, "");
448 }
449 }
450 die ()
451 {
452 llSetTimerEvent(0.0);
453 llListenRemove(listentrack);
454 listentrack = 0;
455 }
456
457
458 default
459 {
461 {
462
463 }
464 attach (key attached)
465 {
466 if(attached != NULL_KEY) //object has been attached
467 init();
468 else //object is being detached
469 die();
470 }
471
472 timer () // because this code runs constantly, it needs to be VERY lightweight. This code does almost nothing unless an alarm or timer is set.
473
474 {
475 if((alarmset == 0) && (timerset == 0))
476 return;
477
478 // ok, either alarm or timer is set
480 if((alarmset != 0) && (now >= alarmmintime) && (now <= alarmmaxtime))
481 {
482 do_alarm();
483 }
484 if((timerset != 0) && (now >= timerstop))
485 {
486 do_timerexpire();
487 }
488 }
489
490 listen (integer channel, string name, key id, string message)
491 {
492 message = llToLower(message);
493 string preamble = llGetSubString(message,0,3);
494 if(preamble != "time")
495 return;
496 list parsed = llParseString2List(message, [ " " ], []);
497 string command = llList2String(parsed,1);
498
499 if(command == "")
500 {
501 showtime();
502 }
503 else if(command == "help")
504 {
505 do_help(id);
506 }
507 else if(command == "morehelp")
508 {
509 do_morehelp(id);
510 }
511 else if(command == "alarm")
512 {
513 alarmfunctions(parsed);
514 }
515 else if(command == "output")
516 {
517 outputfunctions(parsed);
518 }
519 else if(command == "mode")
520 {
521 modefunctions(parsed);
522 }
523 else if(command == "zone")
524 {
525 zonefunctions(parsed);
526 }
527 else if(command == "stopwatch")
528 {
529 stopwatchfunctions(parsed);
530 }
531 else if(command == "timer")
532 {
533 timerfunctions(parsed);
534 }
535 else if(command == "sound")
536 {
537 soundfunctions (parsed);
538 }
539 }
540 }
541 // END //

Back to the Best Free Tools in Second Life and OpenSim.