Difference between revisions of "User:Kimm Paulino/Scripts1"

From Second Life Wiki
Jump to navigation Jump to search
(Added template timer script (written to illustrate adding timer code to a script for someone))
(→‎(soon): Added example multiple-notecard reader template)
Line 257: Line 257:
</lsl>
</lsl>


== (soon) ==
== 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>

Revision as of 14:50, 4 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>