Difference between revisions of "User:Kimm Paulino/Scripts1"
Kimm Paulino (talk | contribs) |
Kireji Haiku (talk | contribs) m (a few minor readability improvements) |
||
Line 15: | Line 15: | ||
integer MAX_REZZED_OBJECTS = 5; | 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_POSITION = <1.0, 0.0, 0.0>; // Relative to the rezzing prim, must be less than 10m away | ||
vector REZ_ROTATION = | vector REZ_ROTATION = ZERO_VECTOR; // In degrees | ||
string | string objectName; | ||
rezObject () | rezObject () | ||
{ | { | ||
llRezObject (gObjectName, | vector currentPosition = llGetPos(); | ||
llRezObject (gObjectName, currentPosition + REZ_POSITION, ZERO_VECTOR, llEuler2Rot (REZ_ROTATION * DEG_TO_RAD), 0); | |||
} | } | ||
Line 30: | Line 32: | ||
llResetScript(); | llResetScript(); | ||
} | } | ||
changed (integer change) | |||
{ | |||
if (change & CHANGED_INVENTORY) | |||
{ | |||
llResetScript(); | |||
} | |||
} | |||
state_entry () | state_entry () | ||
{ | { | ||
objectName = llGetInventoryName (INVENTORY_OBJECT, 0); | |||
if ( | |||
if (objectName == "") | |||
{ | { | ||
llOwnerSay ("Note to owner: No objects found in this prims inventory"); | llOwnerSay ("Note to owner: No objects found in this prims inventory"); | ||
} | } | ||
} | } | ||
touch_start (integer num_detected) | touch_start (integer num_detected) | ||
{ | { | ||
if (gObjectName != "") | 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); | llSensor (gObjectName, NULL_KEY, (ACTIVE|PASSIVE), 96.0, PI); | ||
} | } | ||
} | } | ||
sensor (integer num_detected) | sensor (integer num_detected) | ||
{ | { | ||
Line 58: | Line 70: | ||
else | else | ||
{ | { | ||
// Nothing to do | |||
llOwnerSay ("Max Objects detected ..."); | llOwnerSay ("Max Objects detected ..."); | ||
} | } | ||
} | } | ||
no_sensor () | no_sensor () | ||
{ | { | ||
// None found, so ok to rez one | // None found, so ok to rez one | ||
rezObject(); | rezObject(); | ||
} | } | ||
} | } | ||
Line 122: | Line 127: | ||
// Position of the sittarget | // Position of the sittarget | ||
vector SIT_VECTOR = <0.0, 0.0, 0.5>; // In metres - ZERO_VECTOR to disable | vector SIT_VECTOR = <0.0, 0.0, 0.5>; // In metres - ZERO_VECTOR to disable | ||
vector SIT_ROTATION = | vector SIT_ROTATION = ZERO_VECTOR; // In degrees | ||
key avatarOnSitTarget; | |||
integer isSitting = FALSE; | |||
default | default | ||
{ | { | ||
Line 134: | Line 139: | ||
} | } | ||
changed (integer change) | 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) | if (change & CHANGED_LINK) | ||
{ | { | ||
avatarOnSitTarget = llAvatarOnSitTarget(); | |||
if ( | if (avatarOnSitTarget) | ||
{ | { | ||
// Avatar has just sat down | |||
llSetTimerEvent (DEREZ_AFTER_SIT_TIMEOUT); | isSitting = TRUE; | ||
llSetTimerEvent(DEREZ_AFTER_SIT_TIMEOUT); | |||
} | } | ||
else if ( | else if (isSitting) | ||
{ | { | ||
// Assume av just got up - it was sitting and now isn't ... | |||
isSitting = FALSE; | |||
if (DEREZ_ON_UNSIT) | if (DEREZ_ON_UNSIT) | ||
{ | { | ||
// Want to derez straight away | |||
llDie(); | llDie(); | ||
} | } | ||
llSetTimerEvent (DEREZ_AFTER_UNSIT_TIMEOUT); | llSetTimerEvent(DEREZ_AFTER_UNSIT_TIMEOUT); | ||
} | } | ||
else | else | ||
Line 184: | Line 172: | ||
} | } | ||
} | } | ||
} | |||
state_entry() | |||
{ | |||
if (SIT_VECTOR != ZERO_VECTOR) | |||
{ | |||
llSitTarget(SIT_VECTOR, llEuler2Rot(SIT_ROTATION * DEG_TO_RAD)); | |||
} | |||
llSetTimerEvent(DEREZ_TIMEOUT); | |||
} | |||
timer () | |||
{ | |||
if (avatarOnSitTarget) | |||
{ | |||
llUnSit(avatarOnSitTarget); | |||
} | |||
llSetTimerEvent((float)FALSE);// disable timer | |||
llDie(); | |||
} | } | ||
} | } | ||
Line 191: | Line 200: | ||
<lsl> | <lsl> | ||
// Basic timer-driven state changing script. | // Basic timer-driven state changing script. | ||
// NB: Does not use the LSL ability to define | // NB: Does not use the LSL ability to define | ||
// states, but uses a counter to manage a simple | // states, but uses a counter to manage a simple | ||
// incrementing state machine. | // 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 ( | // else if (currentState == 4) | ||
// { | // { | ||
// // and the next | // // and the next | ||
// } | // } | ||
// | // statements in the appropriate place. | ||
// | // | ||
// If you want the timer interval to be different for different | // If you want the timer interval to be different for different | ||
// states, then you could add more llSetTimerEvent() calls | // states, then you could add more llSetTimerEvent() calls | ||
// in each state to set the timer for the next one. | // in each state to set the timer for the next one. | ||
// | // | ||
// Kimm Paulino | // Kimm Paulino | ||
// Sept 2012 | // Sept 2012 | ||
// Timer interval in seconds | // Timer interval in seconds | ||
float TIMER_INTERVAL = 5.0; | float TIMER_INTERVAL = 5.0; | ||
integer | integer currentState; | ||
default | default | ||
Line 225: | Line 234: | ||
llResetScript(); | llResetScript(); | ||
} | } | ||
state_entry () | state_entry () | ||
{ | { | ||
currentState = 0; | |||
llSetTimerEvent (TIMER_INTERVAL); | llSetTimerEvent (TIMER_INTERVAL); | ||
} | } | ||
timer () | timer () | ||
{ | { | ||
++currentState;// ++index is faster than index++ | |||
if ( | |||
if (currentState == 1) | |||
{ | { | ||
// Do the first thing here | // Do the first thing here | ||
} | } | ||
else if ( | else if (currentState == 2) | ||
{ | { | ||
// After the timer interval this is next | // After the timer interval this is next | ||
} | } | ||
else if ( | else if (currentState == 3) | ||
{ | { | ||
// and the next | // and the next | ||
Line 251: | Line 262: | ||
{ | { | ||
// Once all states are complete, reset the counter ready for the next time | // Once all states are complete, reset the counter ready for the next time | ||
currentState = 0; | |||
} | } | ||
} | } | ||
Line 264: | Line 275: | ||
// Kimm Paulino, Oct 2012 | // Kimm Paulino, Oct 2012 | ||
key | key notecardQueryId; | ||
integer | integer notecardLine; | ||
integer | integer notecardNumber; | ||
string | string notecardName; | ||
default | default | ||
Line 275: | Line 286: | ||
llResetScript(); | llResetScript(); | ||
} | } | ||
changed (integer change) | |||
{ | |||
if (change & CHANGED_INVENTORY) | |||
{ | |||
llResetScript(); | |||
} | |||
} | |||
state_entry () | state_entry () | ||
{ | { | ||
notecardNumber = 0; | |||
notecardLine = 0; | |||
if ( | notecardName = llGetInventoryName(INVENTORY_NOTECARD, notecardNumber); | ||
if (notecardName != "") | |||
{ | { | ||
llOwnerSay ("=== Reading notecard " + | llOwnerSay("=== Reading notecard '" + notecardName + "' (" + (string)notecardNumber + ")"); | ||
notecardQueryId = llGetNotecardLine(notecardName, notecardLine); | |||
} | } | ||
} | } | ||
dataserver (key query_id, string data) | dataserver (key query_id, string data) | ||
{ | { | ||
if (query_id != | if (query_id != notecardQueryId) | ||
{ | { | ||
// Not for us | |||
return; | return; | ||
} | } | ||
Line 302: | Line 322: | ||
{ | { | ||
// Move to the next notecard | // Move to the next notecard | ||
++notecardNumber; | |||
notecardLine = 0; | |||
if ( | notecardName = llGetInventoryName(INVENTORY_NOTECARD, notecardNumber); | ||
if (notecardName != "") | |||
{ | { | ||
llOwnerSay ("=== Reading notecard " + | llOwnerSay("=== Reading notecard '" + notecardName + "' (" + (string)notecardNumber + ")"); | ||
notecardQueryId = llGetNotecardLine(notecardName, notecardLine); | |||
} | } | ||
else | else | ||
Line 322: | Line 343: | ||
// Note: Only get first 255 characters of each line | // Note: Only get first 255 characters of each line | ||
llOwnerSay (data); | llOwnerSay (data); | ||
// and read the next line | // and read the next line | ||
++notecardLine; | |||
notecardQueryId = llGetNotecardLine(notecardName, notecardLine); | |||
} | } | ||
} | } | ||
Line 348: | Line 361: | ||
// Uses 24 hour times | // Uses 24 hour times | ||
// Can include touch control if required | // Can include touch control if required | ||
// Sends the specified message to the specified UUID | // Sends the specified message to the specified UUID | ||
// | // | ||
// If you want it to do something else, code it in the alarm() function | // If you want it to do something else, code it in the alarm() function | ||
Line 359: | Line 372: | ||
integer gMin = 30; | integer gMin = 30; | ||
integer gSec = 0; | integer gSec = 0; | ||
integer | integer isGMTnotSL = TRUE; // GMT or SL time | ||
integer gTouchControl = TRUE; | integer gTouchControl = TRUE; | ||
string | string alarmMessage = "Wake up!"; | ||
key | |||
// NULL_KEY has the key value "00000000-0000-0000-0000-000000000000" | |||
key avatarToBeAlarmed = NULL_KEY; | |||
integer | integer alarmIsArmed; | ||
setAlarm () | setAlarm () | ||
Line 374: | Line 389: | ||
// so the required setting until the destination time | // so the required setting until the destination time | ||
// will depend on if the time is in the past or not. | // will depend on if the time is in the past or not. | ||
// If we happen to get lucky and | // If we happen to get lucky and | ||
float nowtime = llGetWallclock (); | float nowtime = llGetWallclock(); | ||
if ( | if (isGMTnotSL) | ||
{ | { | ||
nowtime = llGetGMTclock (); | nowtime = llGetGMTclock(); | ||
} | } | ||
if (nowtime >= desttime) | if (nowtime >= desttime) | ||
{ | { | ||
// Need to add 24 hours before subtracting | // Need to add 24 hours before subtracting | ||
desttime = desttime + 24.0*60.0*60.0; | desttime = desttime + 24.0*60.0*60.0; | ||
llOwnerSay ("Dest: " + (string)desttime + " Now: " + (string)nowtime); | llOwnerSay("Dest: " + (string)desttime + " Now: " + (string)nowtime); | ||
llSetTimerEvent (desttime - nowtime); | llSetTimerEvent(desttime - nowtime); | ||
} | } | ||
else | else | ||
{ | { | ||
llOwnerSay ("Dest: " + (string)desttime + " Now: " + (string)nowtime); | llOwnerSay("Dest: " + (string)desttime + " Now: " + (string)nowtime); | ||
llSetTimerEvent (desttime - nowtime); | llSetTimerEvent(desttime - nowtime); | ||
} | } | ||
} | } | ||
Line 397: | Line 412: | ||
disableAlarm() | disableAlarm() | ||
{ | { | ||
llSetTimerEvent ( | llSetTimerEvent((float)FALSE); | ||
} | } | ||
Line 403: | Line 418: | ||
alarm () | alarm () | ||
{ | { | ||
//llOwnerSay ("Alarm"); | //llOwnerSay("Alarm"); | ||
llInstantMessage ( | llInstantMessage(avatarToBeAlarmed, alarmMessage); | ||
} | } | ||
Line 412: | Line 427: | ||
{ | { | ||
string zone = " SLT"; | string zone = " SLT"; | ||
if ( | if (isGMTnotSL) | ||
{ | { | ||
zone = " GMT"; | zone = " GMT"; | ||
} | } | ||
llOwnerSay ("Alarm set for " + (string)gHour + " h " + (string)gMin + " m" + (string)gSec + " s " + zone); | llOwnerSay("Alarm set for " + (string)gHour + " h " + (string)gMin + " m" + (string)gSec + " s " + zone); | ||
alarmIsArmed = TRUE; | |||
setAlarm(); | setAlarm(); | ||
} | } | ||
touch_start (integer num_detected) | touch_start (integer num_detected) | ||
{ | { | ||
if (gTouchControl) | if (gTouchControl) | ||
{ | { | ||
if ( | if (alarmIsArmed) | ||
{ | { | ||
alarmIsArmed = FALSE; | |||
disableAlarm(); | disableAlarm(); | ||
} | } | ||
else | else | ||
{ | { | ||
alarmIsArmed = TRUE; | |||
setAlarm(); | setAlarm(); | ||
} | } | ||
} | } | ||
} | } | ||
timer () | timer () | ||
{ | { | ||
alarm(); | alarm(); | ||
// Reset alarm each time, to allow for any drift in time | |||
setAlarm(); | setAlarm(); | ||
} | } | ||
} | } | ||
</lsl> | </lsl> |
Revision as of 14:12, 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 = ZERO_VECTOR; // In degrees
string objectName;
rezObject () {
vector currentPosition = llGetPos();
llRezObject (gObjectName, currentPosition + REZ_POSITION, ZERO_VECTOR, llEuler2Rot (REZ_ROTATION * DEG_TO_RAD), 0);
}
default {
on_rez (integer start_param) { llResetScript(); }
changed (integer change) { if (change & CHANGED_INVENTORY) { llResetScript(); } }
state_entry () { objectName = llGetInventoryName (INVENTORY_OBJECT, 0);
if (objectName == "") { 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 { // Nothing to do
llOwnerSay ("Max Objects detected ..."); } }
no_sensor () { // None found, so ok to rez one rezObject(); }
} </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 = ZERO_VECTOR; // In degrees
key avatarOnSitTarget; integer isSitting = FALSE;
default {
on_rez (integer start_param) { llResetScript(); }
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) { avatarOnSitTarget = llAvatarOnSitTarget(); if (avatarOnSitTarget) { // Avatar has just sat down
isSitting = TRUE; llSetTimerEvent(DEREZ_AFTER_SIT_TIMEOUT); } else if (isSitting) { // Assume av just got up - it was sitting and now isn't ... isSitting = 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 } } }
state_entry() { if (SIT_VECTOR != ZERO_VECTOR) { llSitTarget(SIT_VECTOR, llEuler2Rot(SIT_ROTATION * DEG_TO_RAD)); }
llSetTimerEvent(DEREZ_TIMEOUT); }
timer () { if (avatarOnSitTarget) { llUnSit(avatarOnSitTarget); }
llSetTimerEvent((float)FALSE);// disable timer llDie(); }
} </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 (currentState == 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 currentState;
default {
on_rez (integer start_param) { llResetScript(); }
state_entry () { currentState = 0;
llSetTimerEvent (TIMER_INTERVAL); }
timer () { ++currentState;// ++index is faster than index++
if (currentState == 1) { // Do the first thing here } else if (currentState == 2) { // After the timer interval this is next } else if (currentState == 3) { // and the next } // add more else if () statements here else { // Once all states are complete, reset the counter ready for the next time currentState = 0; } }
} </lsl>
Multiple Notecard Reading Template
<lsl> // Example showing multiple notecard reading. // // Kimm Paulino, Oct 2012
key notecardQueryId; integer notecardLine; integer notecardNumber; string notecardName;
default {
on_rez (integer start_param) { llResetScript(); }
changed (integer change) { if (change & CHANGED_INVENTORY) { llResetScript(); } }
state_entry () { notecardNumber = 0; notecardLine = 0;
notecardName = llGetInventoryName(INVENTORY_NOTECARD, notecardNumber); if (notecardName != "") { llOwnerSay("=== Reading notecard '" + notecardName + "' (" + (string)notecardNumber + ")"); notecardQueryId = llGetNotecardLine(notecardName, notecardLine); } }
dataserver (key query_id, string data) { if (query_id != notecardQueryId) { // 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 ++notecardNumber; notecardLine = 0;
notecardName = llGetInventoryName(INVENTORY_NOTECARD, notecardNumber); if (notecardName != "") { llOwnerSay("=== Reading notecard '" + notecardName + "' (" + (string)notecardNumber + ")"); notecardQueryId = llGetNotecardLine(notecardName, notecardLine); } 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 ++notecardLine; notecardQueryId = llGetNotecardLine(notecardName, notecardLine); }
} </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 isGMTnotSL = TRUE; // GMT or SL time integer gTouchControl = TRUE; string alarmMessage = "Wake up!";
// NULL_KEY has the key value "00000000-0000-0000-0000-000000000000" key avatarToBeAlarmed = NULL_KEY;
integer alarmIsArmed;
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 (isGMTnotSL) { 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((float)FALSE);
}
// This is what happens on the alarm alarm () {
//llOwnerSay("Alarm"); llInstantMessage(avatarToBeAlarmed, alarmMessage);
}
default {
state_entry() { string zone = " SLT"; if (isGMTnotSL) { zone = " GMT"; } llOwnerSay("Alarm set for " + (string)gHour + " h " + (string)gMin + " m" + (string)gSec + " s " + zone); alarmIsArmed = TRUE; setAlarm(); }
touch_start (integer num_detected) { if (gTouchControl) { if (alarmIsArmed) { alarmIsArmed = FALSE; disableAlarm(); } else { alarmIsArmed = TRUE; setAlarm(); } } }
timer () { alarm();
// Reset alarm each time, to allow for any drift in time setAlarm(); }
} </lsl>