User:Kimm Paulino/Scripts1: Difference between revisions
Kimm Paulino (talk | contribs) →(soon): Added example multiple-notecard reader template |
Kimm Paulino (talk | contribs) No edit summary |
||
| Line 334: | Line 334: | ||
llResetScript(); | llResetScript(); | ||
} | } | ||
} | |||
} | |||
</lsl> | |||
== Alarm Script == | |||
<lsl> | |||
// Simple script to trigger at a certain time and perform a function, | |||
// in the default case send an IM to the specified avatar | |||
// | |||
// Notes | |||
// Can specify a time in GMT (ie no seasonal changes) or SLT | |||
// Uses 24 hour times | |||
// Can include touch control if required | |||
// Sends the specified message to the specified UUID | |||
// | |||
// If you want it to do something else, code it in the alarm() function | |||
// | |||
// Kimm Paulino | |||
// Oct 2012 | |||
// http://kimmscripts.wordpress.com/ | |||
integer gHour = 7; // 24 hour clock | |||
integer gMin = 30; | |||
integer gSec = 0; | |||
integer gGMT = TRUE; // GMT or SL time | |||
integer gTouchControl = TRUE; | |||
string gMsg = "Wake up!"; | |||
key gAv = "00000000-0000-0000-0000-000000000000"; | |||
integer gArmed; | |||
setAlarm () | |||
{ | |||
// set a timer event for destination time - current time | |||
float desttime = (float)(gHour*60*60 + gMin*60 + gSec); | |||
// This is the number of seconds since midnight | |||
// so the required setting until the destination time | |||
// will depend on if the time is in the past or not. | |||
// If we happen to get lucky and | |||
float nowtime = llGetWallclock (); | |||
if (gGMT) | |||
{ | |||
nowtime = llGetGMTclock (); | |||
} | |||
if (nowtime >= desttime) | |||
{ | |||
// Need to add 24 hours before subtracting | |||
desttime = desttime + 24.0*60.0*60.0; | |||
llOwnerSay ("Dest: " + (string)desttime + " Now: " + (string)nowtime); | |||
llSetTimerEvent (desttime - nowtime); | |||
} | |||
else | |||
{ | |||
llOwnerSay ("Dest: " + (string)desttime + " Now: " + (string)nowtime); | |||
llSetTimerEvent (desttime - nowtime); | |||
} | |||
} | |||
disableAlarm() | |||
{ | |||
llSetTimerEvent (0.0); | |||
} | |||
// This is what happens on the alarm | |||
alarm () | |||
{ | |||
//llOwnerSay ("Alarm"); | |||
llInstantMessage (gAv, gMsg); | |||
} | |||
default | |||
{ | |||
state_entry() | |||
{ | |||
string zone = " SLT"; | |||
if (gGMT) | |||
{ | |||
zone = " GMT"; | |||
} | |||
llOwnerSay ("Alarm set for " + (string)gHour + " h " + (string)gMin + " m" + (string)gSec + " s " + zone); | |||
gArmed = TRUE; | |||
setAlarm(); | |||
} | |||
touch_start (integer num_detected) | |||
{ | |||
if (gTouchControl) | |||
{ | |||
if (gArmed) | |||
{ | |||
gArmed = FALSE; | |||
disableAlarm(); | |||
} | |||
else | |||
{ | |||
gArmed = TRUE; | |||
setAlarm(); | |||
} | |||
} | |||
} | |||
timer () | |||
{ | |||
alarm(); | |||
// Reset alarm each time, to allow for any drift in time | |||
setAlarm(); | |||
} | } | ||
} | } | ||
</lsl> | </lsl> | ||
Revision as of 12:26, 22 October 2012
Rez and Sense
<lsl> // Rezzer that will only rez an object (from inventory) if it // can't detect the specified number of objects in the region nearby already. // // Note: Sensing is limitd to a maximum of 96m in all directions. If the // objects pass out of that range, this won't find them. // // Always looks for (and rezzes) the first object found in inventory. // NB: This must have copy permissions if you want to rez it more than once! // // Kimm Paulino, July 2012
integer MAX_REZZED_OBJECTS = 5; vector REZ_POSITION = <1.0, 0.0, 0.0>; // Relative to the rezzing prim, must be less than 10m away vector REZ_ROTATION = <0.0, 0.0, 0.0>; // In degrees
string gObjectName;
rezObject () {
llRezObject (gObjectName, llGetPos() + REZ_POSITION, ZERO_VECTOR, llEuler2Rot (REZ_ROTATION * DEG_TO_RAD), 0);
}
default {
on_rez (integer start_param)
{
llResetScript();
}
state_entry ()
{
gObjectName = llGetInventoryName (INVENTORY_OBJECT, 0);
if (gObjectName == "")
{
llOwnerSay ("Note to owner: No objects found in this prims inventory");
}
}
touch_start (integer num_detected)
{
if (gObjectName != "")
{
// Trigger a single sensor event for the full range/arc looking for any non-avatar
// objects with the same name as our rezzing object.
llSensor (gObjectName, NULL_KEY, (ACTIVE|PASSIVE), 96.0, PI);
}
}
sensor (integer num_detected)
{
if (num_detected < MAX_REZZED_OBJECTS)
{
rezObject();
}
else
{
llOwnerSay ("Max Objects detected ...");
// Nothing to do
}
}
no_sensor ()
{
// None found, so ok to rez one
rezObject();
}
changed (integer change)
{
if (change & CHANGED_INVENTORY)
{
llResetScript();
}
}
} </lsl>
Derez After Sitting
<lsl> // This will kill the prim it is in, the specified time after someone // sits on the prim. It will unsit them before derezzing. // // Note: This only works when the prim has a sittarget defined. // But this script does not have to be the thing setting it, // if the sit target is set to <0.0,0.0,0.0> in this script, // then no call to llSitTarget is made - so another script // can do it instead. // // It can optionally derez on unsit too - i.e. when they get up // or derez a defined time after they unsit. // // Note: It doesn't unsit any other avatars sitting on other // prims prior to derezzing, but derezzing will unsit them anyway! // // It will also (optionally) automatically derez itself after a specified // time if noone sits down on it. // // Kimm Paulino, July 2012
// TRUE if want to immediately auto derez when av gets up. // (overrides DEREZ_AFTER_UNSIT_TIMEOUT) integer DEREZ_ON_UNSIT = FALSE;
// Time to derez if noone sits down // (in seconds - 0.0 to disable) float DEREZ_TIMEOUT = 60.0;
// Once an av sits down, this timer starts // and will derez when it times out. // (in seconds - 0.0 to disable) float DEREZ_AFTER_SIT_TIMEOUT = 30.0;
// Once an av gets up, this timer starts // and will derez when it times out. // (in seconds - 0.0 to disable) float DEREZ_AFTER_UNSIT_TIMEOUT = 0.0;
// Position of the sittarget vector SIT_VECTOR = <0.0, 0.0, 0.5>; // In metres - ZERO_VECTOR to disable vector SIT_ROTATION = <0.0, 0.0, 0.0>; // In degrees
key gAvUuid; integer gSitting = FALSE;
default {
on_rez (integer start_param)
{
llResetScript();
}
state_entry()
{
if (SIT_VECTOR != ZERO_VECTOR)
{
llSitTarget (SIT_VECTOR, llEuler2Rot (SIT_ROTATION * DEG_TO_RAD));
}
llSetTimerEvent (DEREZ_TIMEOUT);
}
timer ()
{
if (gAvUuid)
{
llUnSit (gAvUuid);
}
llSetTimerEvent (0.0);
llDie();
}
changed (integer change)
{
// When someone sits on an object, the av is considered to be
// a linked-in child prim, so the link number changes
if (change & CHANGED_LINK)
{
gAvUuid = llAvatarOnSitTarget();
if (gAvUuid)
{
// Avatar has just sat down
gSitting = TRUE;
llSetTimerEvent (DEREZ_AFTER_SIT_TIMEOUT);
}
else if (gSitting)
{
// Assume av just got up - it was sitting and now isn't ...
gSitting = FALSE;
if (DEREZ_ON_UNSIT)
{
// Want to derez straight away
llDie();
}
llSetTimerEvent (DEREZ_AFTER_UNSIT_TIMEOUT);
}
else
{
// Could be unlinking going on
// or maybe there is another sit target in a linked prim
// that someone has just sat on or vacated
}
}
}
} </lsl>
Timer Action Template
<lsl> // Basic timer-driven state changing script. // NB: Does not use the LSL ability to define // states, but uses a counter to manage a simple // incrementing state machine. // // Every time interval, it will change its record of state // and you can add code to do something, then it will move // to the next state. // // To add more things, just add more // else if (gState == 4) // { // // and the next // } // statements in the appropriate place. // // If you want the timer interval to be different for different // states, then you could add more llSetTimerEvent() calls // in each state to set the timer for the next one. // // Kimm Paulino // Sept 2012
// Timer interval in seconds float TIMER_INTERVAL = 5.0;
integer gState;
default {
on_rez (integer start_param)
{
llResetScript();
}
state_entry ()
{
gState = 0;
llSetTimerEvent (TIMER_INTERVAL);
}
timer ()
{
gState ++;
if (gState == 1)
{
// Do the first thing here
}
else if (gState == 2)
{
// After the timer interval this is next
}
else if (gState == 3)
{
// and the next
}
// add more else if () statements here
else
{
// Once all states are complete, reset the counter ready for the next time
gState = 0;
}
}
} </lsl>
Multiple Notecard Reading Template
<lsl> // Example showing multiple notecard reading. // // Kimm Paulino, Oct 2012
key gNCQueryId; integer gNCLine; integer gNCNumber; string gNCName;
default {
on_rez (integer start_param)
{
llResetScript();
}
state_entry ()
{
gNCNumber = 0;
gNCLine = 0;
gNCName = llGetInventoryName (INVENTORY_NOTECARD, gNCNumber);
if (gNCName != "")
{
llOwnerSay ("=== Reading notecard " + gNCName + " (" + (string)gNCNumber + ")");
gNCQueryId = llGetNotecardLine (gNCName, gNCLine);
}
}
dataserver (key query_id, string data)
{
if (query_id != gNCQueryId)
{
// Not for us
return;
}
// Note: If the notecard contains embedded objects (like scripts, landmarks, etc)
// then EOF is returned - so this will move onto the next one as if the notecard
// was empty.
if (data == EOF)
{
// Move to the next notecard
gNCNumber++;
gNCLine = 0;
gNCName = llGetInventoryName (INVENTORY_NOTECARD, gNCNumber);
if (gNCName != "")
{
llOwnerSay ("=== Reading notecard " + gNCName + " (" + (string)gNCNumber + ")");
gNCQueryId = llGetNotecardLine (gNCName, gNCLine);
}
else
{
llOwnerSay ("=== Complete");
}
// Wait for the next line to be read
return;
}
// Do something with the notecard line
// Note: Only get first 255 characters of each line
llOwnerSay (data);
// and read the next line
gNCLine++;
gNCQueryId = llGetNotecardLine(gNCName, gNCLine);
}
changed (integer change)
{
if (change & CHANGED_INVENTORY)
{
llResetScript();
}
}
} </lsl>
Alarm Script
<lsl> // Simple script to trigger at a certain time and perform a function, // in the default case send an IM to the specified avatar // // Notes // Can specify a time in GMT (ie no seasonal changes) or SLT // Uses 24 hour times // Can include touch control if required // Sends the specified message to the specified UUID // // If you want it to do something else, code it in the alarm() function // // Kimm Paulino // Oct 2012 // http://kimmscripts.wordpress.com/
integer gHour = 7; // 24 hour clock integer gMin = 30; integer gSec = 0; integer gGMT = TRUE; // GMT or SL time integer gTouchControl = TRUE; string gMsg = "Wake up!"; key gAv = "00000000-0000-0000-0000-000000000000";
integer gArmed;
setAlarm () {
// set a timer event for destination time - current time float desttime = (float)(gHour*60*60 + gMin*60 + gSec);
// This is the number of seconds since midnight
// so the required setting until the destination time
// will depend on if the time is in the past or not.
// If we happen to get lucky and
float nowtime = llGetWallclock ();
if (gGMT)
{
nowtime = llGetGMTclock ();
}
if (nowtime >= desttime)
{
// Need to add 24 hours before subtracting
desttime = desttime + 24.0*60.0*60.0;
llOwnerSay ("Dest: " + (string)desttime + " Now: " + (string)nowtime);
llSetTimerEvent (desttime - nowtime);
}
else
{
llOwnerSay ("Dest: " + (string)desttime + " Now: " + (string)nowtime);
llSetTimerEvent (desttime - nowtime);
}
}
disableAlarm() {
llSetTimerEvent (0.0);
}
// This is what happens on the alarm alarm () {
//llOwnerSay ("Alarm");
llInstantMessage (gAv, gMsg);
}
default {
state_entry()
{
string zone = " SLT";
if (gGMT)
{
zone = " GMT";
}
llOwnerSay ("Alarm set for " + (string)gHour + " h " + (string)gMin + " m" + (string)gSec + " s " + zone);
gArmed = TRUE;
setAlarm();
}
touch_start (integer num_detected)
{
if (gTouchControl)
{
if (gArmed)
{
gArmed = FALSE;
disableAlarm();
}
else
{
gArmed = TRUE;
setAlarm();
}
}
}
timer ()
{
alarm();
// Reset alarm each time, to allow for any drift in time
setAlarm();
}
} </lsl>