Difference between revisions of "User:Fred Gandt/Scripts"

From Second Life Wiki
Jump to navigation Jump to search
(Added scripts and notes.)
m (cleaning up headings)
 
(117 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{LSL Header}}
{{User:Fred Gandt/Template|content=


{{RightToc|right;}}
== Free Scripts ==
=== Basic Light Switch ===


== My contributions ==
Placed in the root of a [[LINK_SET|linked object]] this script will make the whole object active to touch. The light will always be emitted by the prim the script is in. So, if you have a 5 prim lamp, put this in the "bulb" prim and make that prim the root. If placed in a child prim of an object, only that prim will be ''clickable'' (unless there are other touch scripts in other prims of the object).


'''[[Project:Contribution Agreement| The legal stuff about contributing stuff here and about (worth reading).]]'''
<syntaxhighlight lang="lsl2">// V1 //


== Tuition ==
vector color = <1.0, 1.0, 1.0>; // R,G,B ( red, green, blue ) values.


'''[[User:Fred_Gandt/Tuition| Tuition scripts, notes, videos and screenshots etc.]]'''
float intensity = 1.0; // 0.0 to 1.0 ( 1.0 = full brightness )


== Basic Light Switch ==
float radius = 20.0; // 0.1 to 20.0 ( 20.0 = full sphere )


<lsl>// This script will cause the prim it is in to emit light.
float falloff = 0.01; // 0.01 to 2.0 ( 2.0 = least spread )
// If the prim (or object if the script is in the root of a link_set)
// is touched the light will turn off if on and on if off.
// The switching code can be used for many different actions.


integer on; // Global variable used to measure the condition 'on or off'.
/////////////////////////////////////////////////////////////////////////


vector color = <1.0,1.0,1.0>; // R,G,B (red, green, blue) values.
integer on; // Global variable used to measure the condition "on" or "off".


float intensity = 1.0; // 0.0 to 1.0 (1.0 = full brightness)
Switch() {
    // The switching function.
    on = !on; // Flip the boolean value of the integer "on".
    // Set the prim's light emitter on or off, dependant on the value of "on".
    llSetPrimitiveParams( [ PRIM_POINT_LIGHT, on, color, intensity, radius, falloff ] );
}
 
default {
    touch_end( integer nd ) { // If clicked,
        Switch(); // unconditionally call the switch to operate.
    }
}</syntaxhighlight>
 
=== Basic Alpha (transparency) SHOW/HIDE ===
 
<syntaxhighlight lang="lsl2">// V1 //
string command = "switch"; // Place the command to chat here. The same command will switch on and off.
integer channel = 1; // Place channel to use here ( must be positive if an avatar is chatting on it ).
 
//////////////////////////////////////////////////////////////////////////////////////////////////////
 
integer on; // Store the state of transparency.
Switch() {
    llSetLinkAlpha( LINK_SET, ( float )on, ALL_SIDES ); // This setting will turn a whole link_set transparent or visible.
    on = !on; // Flip the boolean value of the integer "on".
}
default {
    state_entry() {
        llListen( channel, "", "", command ); // This script is listening to everyone all the time.
        // llListen( channel, "", llGetOwner(), command ); // Delete the "//" at the beginning of this line...
                                                          // ...and add "//" at the beginning of the line above...
                                                          // ...to make This script listen to only the owner.
    } // Switching the listen off at times would be better to reduce lag. But when??
    touch_end( integer nd ) {
        // if ( llDetectedKey( 0 ) == llGetOwner() ) // Delete the "//" at the beginning of this line to make touches only respond to owner.
        Switch(); // Call the switching function.
    }
    listen( integer chan, string name, key id, string msg ) {
        Switch(); // Call the switching function.
    }
}</syntaxhighlight>
 
=== Basic Particle Candle Flame ON/OFF ===


float radius = 20.0; // 0.1 to 20.0 (20.0 = full sphere)
This script will make the prim it is in a small glowing sphere that sits at the center of the flame.


float falloff = 0.01; // 0.01 to 2.0 (2.0 = least spread)
<syntaxhighlight lang="lsl2">// V1 //


Switch() // The switching function. I made the switch function to facilitate easier editing.
integer on; // Establish "on" as a global variable so that we can remember whether or not the flame is on.
{
 
    on = (!on); // Flip the boolean value of the integer 'on'.
Flame( integer num ) {
    llSetPrimitiveParams([PRIM_POINT_LIGHT, on, color, intensity, radius, falloff]);
    // Do we or don't we make a flame? "num" is either TRUE or FALSE ( 1 or 0 ).
    if ( num ) {
        // Make the flame since the condition above was met.
        llParticleSystem( [ PSYS_PART_FLAGS, 275,
                            PSYS_SRC_PATTERN, 4,
                            PSYS_PART_START_ALPHA, 0.6,
                            PSYS_PART_END_ALPHA, 0.0,
                            PSYS_PART_START_COLOR, <1.0, 1.0, 0.3>,
                            PSYS_PART_END_COLOR, <0.8, 0.6, 0.6>,
                            PSYS_PART_START_SCALE, <0.04, 0.07, 0.0>,
                            PSYS_PART_END_SCALE, <0.04, 0.04, 0.0>,
                            PSYS_PART_MAX_AGE, 0.3,
                            PSYS_SRC_MAX_AGE, 0.0,
                            PSYS_SRC_ACCEL, <0.0, 0.0, 0.02>, // These are the parameters of the particle effect.
                            PSYS_SRC_ANGLE_BEGIN, 0.0,
                            PSYS_SRC_ANGLE_END, 0.0,
                            PSYS_SRC_BURST_PART_COUNT, 50,
                            PSYS_SRC_BURST_RATE, 0.07,
                            PSYS_SRC_BURST_RADIUS, 0.0,
                            PSYS_SRC_BURST_SPEED_MIN, 0.001,
                            PSYS_SRC_BURST_SPEED_MAX, 0.4,
                            PSYS_SRC_OMEGA, <0.0, 0.0, 0.0>,
                            PSYS_SRC_TARGET_KEY, ( key )"",
                            PSYS_SRC_TEXTURE, "" ]
                        );
        llSetPrimitiveParams( [ PRIM_POINT_LIGHT, TRUE, <1.0, 0.8, 0.3>, 0.5, 2.0, 1.9, // For extra effect we switch the light on too.
                                PRIM_COLOR, ALL_SIDES, <1.0, 1.0, 1.0>, 0.1, // And set the transparency to slightly visible,
                                PRIM_GLOW, ALL_SIDES, 0.1 ] // and the glow to slight.
                            );
    } else {
        // "num" was not 1 ( TRUE ) so we need to stop the effect or not start it.
        llParticleSystem( [] ); // Make no particles ( no flame ).
        llSetPrimitiveParams( [ PRIM_POINT_LIGHT, FALSE, ZERO_VECTOR, 0.0, 0.0, 0.0, // Switch the light off.
                                PRIM_COLOR, ALL_SIDES, <1.0, 1.0, 1.0>, 0.0, // And set the transparency to invisible,
                                PRIM_GLOW, ALL_SIDES, 0.0 ] // and the glow to zero.
                            );
    }
    on = num; // Establish the value of the global variable "on" as being equal to the task we just performed. This acts as our memory.
}
}


default
default { // Create a state for the code to run in.
{
    state_entry() {
     touch_end(integer nd)
        // These instructions will change the size, shape and texturing of the prim the script is in.
    {
        llSetPrimitiveParams( [ PRIM_TYPE, PRIM_TYPE_SPHERE, 0, <0.0, 1.0, 0.0>, 0.0, ZERO_VECTOR, <0.0, 1.0, 0.0>, // Make the prim a sphere.
         Switch(); // Unconditionally call the switch to operate.
                                PRIM_SIZE, <0.01, 0.01, 0.03>, // Make the prim the right size to act as the glowing center of the flame.
                                PRIM_TEXTURE, ALL_SIDES, TEXTURE_BLANK, ZERO_VECTOR, ZERO_VECTOR, 0.0 ] // Set the blank texture.
                            );
        // Make the candle flame ignite.
        Flame( TRUE ); // Flame( TRUE ); Is an order to run the code "Flame" with the integer value "TRUE" ( numerical value = 1 ).
    }
     touch_end( integer detected ) { // Detect if we have touched the candle.
         Flame( !on ); // We now order that the Flame() code is run with the integer value that is the opposite of what it already is.
        // "!on" = FALSE if on = TRUE and TRUE if on = FALSE. The "!" means "not".
     }
     }
}</lsl>
}</syntaxhighlight>


== Script that gives a set amount of L$ to whoever touches the object this script is in ==
=== Simple Timer Alarm ===


'''TAKE CARE WITH THIS ONE. IT WILL DEDUCT L$ FROM YOUR ACCOUNT ONCE YOU GRANT PERMISSIONS'''
Good for reminding you about sandbox returns etc. Ideally worn as a single prim HUD attachment.


'''I WAS ASKED TO MAKE IT THIS WAY. IT WAS DESIGNED TO BE REZZED FOR SHORT PERIODS OF TIME'''
<syntaxhighlight lang="lsl2">// V3 //


'''IF TOO MANY AGENTS USE IT THE MEMORY WILL RUN OUT AND IT WILL FAIL'''
string alarm = "5e1d5f52-e7ae-0194-a412-93a96f39ff6f"; // Name of the sound in the object inventory.
                                                      // Or the UUID of any sound.


<lsl>key owner; // Global variable to store the owner UUID (key)
float volume = 0.5; // Values between "0.0" and "1.0".


integer perms; // Global to store the condition of the request for permissions.
vector passive = <0.0, 0.0, 1.0>; // Color for prim when timer is off.


integer count; // Global counter.
vector active = <0.0, 1.0, 0.0>; // Color for prim when timer is running.


list visitors; // This stores the keys of all the agents who take the gift. They will be allowed only one gift.
vector alarmed = <1.0, 0.0, 0.0>; // Color for prim when alarm is sounding.


integer ammount = 1; // Change this figure to the required ammount to give away (e.g. 5). Then drop in your object.
integer on; // Used to store if the timer is running.


default
default {
{
     on_rez( integer param ) {
     on_rez(integer param)
         llResetScript();
    {
         llResetScript(); // Clear all lists and reset all variables. This action will also clear the permissions.
    }
    changed(integer change)
    {
        if(change & CHANGED_OWNER) // If the script or object changes ownership the script will not be able
        llResetScript();          // to deduct cash from the previous owners account.
    }
    state_entry()
    {
        owner = llGetOwner(); // Store the owners key.
        llRequestPermissions(owner, PERMISSION_DEBIT); // !! THIS MEANS IT WILL TAKE YOUR MONEY !!
     }
     }
     run_time_permissions(integer perm)
     state_entry() {
    {
         llStopSound();
         if(perm & PERMISSION_DEBIT) // Have we got the permissions we requested?
         llSetColor( passive, ALL_SIDES );
         perms = TRUE; // Store the result of success.
         llSetObjectName( "Alarm" );
        else
         llRequestPermissions(owner, PERMISSION_DEBIT); // If not we ask for them again.
     }
     }
     touch_end(integer nd)
     touch_end( integer nd ) {
    {
         if ( on ) {
         do // Loop through the detected touchers to cover the rare cases when
             llResetScript();
        { // more than one agent touches the object at the same time.
        } else {
             key toucher = llDetectedKey(count);
             float time = ( float )llGetObjectDesc() * 60; // Time established from the prim description.
             if(llListFindList(visitors, [toucher]) == -1) // Check if the agent has touched us before by searching the list for a match.
             if ( time < 1.0 ) {
             {
                 llOwnerSay( "The time is not set.\nPlease write the time into the object description and try again" );
                if(perms) // Check if we have permissions.
                return;
                 {
                    llGiveMoney(toucher, ammount); // Ker-ching!!
                    visitors += [toucher]; // That's all buster! NEXT!!
                }
             }
             }
            llSetColor( active, ALL_SIDES );
            llOwnerSay( "/me is set to sound in " + ( string )llRound( time / 60 ) + " minutes." );
            llSetTimerEvent( time );
            on = TRUE;
            llPreloadSound( alarm );
         }
         }
        while((++count) < nd); // Increment the counter and loop while it is less than the number of touchers detected.
        count = 0; // Reset the counter.
     }
     }
}</lsl>
    timer() {
        llSetTimerEvent( 0.0 );
        llLoopSound( alarm, volume );
        llSetColor( alarmed, ALL_SIDES );
    }
}</syntaxhighlight>


== Script to make the Mouselook button show at the bottom of your screen ==
=== Floating on Water (very beta) ===


<lsl>key owner;
This creates a movement sort of like a floating lantern. But '''it needs a lot of work''' before I will consider it even close to done.


default
<syntaxhighlight lang="lsl2">// V2 //
{
     state_entry()
float limit = 10.0; // This is the radius that the object is allowed to drift up to.
    {
                    // 20.0 would be a 40 meter circle.
         owner = llGetOwner();
         llRequestPermissions(owner, PERMISSION_TAKE_CONTROLS);
float offset = 0.0; // Use this float to offset the height of the object in relation to the water surface.
// The object will (when the offset is zero) float with its geometric center at the level of the water surface.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
float float_height;
vector home;
FloatAbout( vector pos ) {
    llSetTimerEvent( limit );
    @a;
    float num_x = llFrand( limit / 2 ) - ( limit / 4 );
    float num_y = llFrand( limit / 2 ) - ( limit / 4 );
    vector target = <( pos.x + num_x ), ( pos.y + num_y ), float_height>;
    if ( llVecDist( target, home ) <= limit ) {
        llMoveToTarget( target, limit * 1.5 );
    } else {
        jump a;
    }
}
default {
    on_rez( integer param ) {
        llResetScript();
    }
     state_entry() {
         float_height = llWater( ZERO_VECTOR ) + offset;
         llSetStatus( STATUS_ROTATE_X | STATUS_ROTATE_Y, FALSE );
        llSetStatus( STATUS_PHYSICS | STATUS_PHANTOM, TRUE );
        home = llGetPos();
        llSetTimerEvent( 0.1 );
     }
     }
     run_time_permissions(integer perm)
     timer() {
    {
         FloatAbout( llGetPos() );
         if(perm & PERMISSION_TAKE_CONTROLS) // Do we have the perms we asked for?
        llTakeControls(CONTROL_ML_LBUTTON, TRUE, FALSE); // This creates a button at the bottom of the screen
        else                    // that if pressed automatically zooms the camera of the owner into mouselook.
        llRequestPermissions(owner, PERMISSION_TAKE_CONTROLS);
     }
     }
     control(key id, integer this, integer that)
     touch_end( integer nd ) {
    {                       // Adding various conditions here can change the script behavior in many ways.
        if ( llDetectedKey( 0 ) == llGetOwner() ) {
        llOwnerSay("Click"); // Do stuff when clicking the left mouse button while in mouselook. Like for guns etc.
            FloatAbout( home = llGetPos() );
        }
     }
     }
}</lsl>
}</syntaxhighlight>
 
=== Visit Web Address Dialog ===


== Script that makes the object it is in float on water (like a marker buoy)==
If you have a website use something like this to direct people to it.


<lsl>float offset = 0.0; // Use this float to offset the height of the object in relation to the water surface.
<syntaxhighlight lang="lsl2">// V3 //
// The object will (when the offset is zero) float with its geometric center at the level of the water surface.
default // The offset is a measure of meters and/or parts thereof.
string URL_Loader_Message = "\nCopy FREE scripts from an SL wiki page"; // Message to show on dialog.
{
     state_entry() // Best to set the object in place with your edit tools and then add the script.
string URL_To_Visit = "https://wiki.secondlife.com/wiki/User:Fred_Gandt"; // URL to visit.
    {             // As the code runs it will lock the objects position and attempt to remain there.
         float float_height = (llWater(ZERO_VECTOR) + offset);  
string Floating_Text = "FREE SCRIPTS!!\n \nTouch to visit web site.\n \n(Official SL wiki)\n \n "; // Floating text.
        vector pos = llGetPos();
         llSetStatus(STATUS_PHYSICS, TRUE); // Make the object physical.
vector Float_Text_Color = <1.0, 1.0, 1.0>; // Color of floating text.
        llMoveToTarget(<pos.x, pos.y, float_height>, 0.5); // Have it maintain it's position.
         // Things get more complex if you wanna make a boat. But this is a place to start.
float Float_Text_Alpha = 1.0; // Transparency of floating text (1.0 is solid).
// FROM THIS POINT IT IS SCARY!! ARRGGGHHHH...!!! //
default {
     state_entry() {
         llSetText( Floating_Text, Float_Text_Color, Float_Text_Alpha );
    }
    touch_start( integer nd ) {
         while ( nd ) {
            llLoadURL( llDetectedKey( --nd ), URL_Loader_Message, URL_To_Visit );
         }
     }
     }
}</lsl>
}</syntaxhighlight>
 
=== AO Overriding Sit Script ===
 
<syntaxhighlight lang="lsl2">// V1 //
 
integer sit_target; // Used to store whether or not a sit target is applied.


== Very Basic Alpha (transparency) ON/OFF script ==
key sitter; // Used to store the UUID (key) of the avatar we are animating.


<lsl>integer on;
integer perm; // Used to store whether or not we have permissions we ask for.


key owner; // Store the owners UUID (key)
string anim_name = ""; // Used to store the name of the animation we have in the objects inventory.


string command = "switch"; // Place the command to chat here. The same command will switch on and off.
string sit_text = ""; // Add a word to replace the words "Sit Here" (in the pie menu) to show if right clicking to sit.


integer channel = 1; // Place channel to use here (must be a positive if an avatar is chatting on it).
vector pose_offset = <0.0,0.0,0.01>; // This must be a non zero value.
//  The X,Y,Z values denote by how much in meters or parts thereof the avatars pelvis is offset from the center of the prim.
// There can be an offset induced by the animation its self. If this is the case trial and error is the only way forward.


Switch(integer i)
vector pose_rotation = <0.0,0.0,0.0>; // This can be a zero value.
{
// The X,Y,Z values denote the rotation in degrees that the animation is rotated around the avatars pelvis.
    llSetLinkAlpha(LINK_SET, ((float)i), ALL_SIDES); // This setting will turn a whole link_set transparent or solid.
// There can be an offset induced by the animation its self. If this is the case trial and error is the only way forward.
}


default
default
{
{
    on_rez(integer param)
    {
        llResetScript(); // Clean the script when we rez the object.
    }
     state_entry()
     state_entry()
     {
     {
         owner = llGetOwner();
         if(sit_text != "") // If we have not set sit_text don't apply it.
         llListen(channel, "", owner, command); // This script is listening all the time.
        llSetSitText(sit_text);
    }   // Switching the listen off at times would be better to reduce lag. But when??
         if(anim_name == "") // If we have not named an anim (Such as the internal animations)...
     touch_end(integer nd)
        {
            // ...this will get the name of an animation in the prims inventory and store it.
            anim_name = llGetInventoryName(INVENTORY_ANIMATION, 0);
            if(anim_name == "") // If there is no animation in the inventory and we haven't named one...
            {
                llSitTarget(ZERO_VECTOR, ZERO_ROTATION); // Remove any stored sit target.
                llOwnerSay("There is no animation named or in my inventory. Please add an animation so I can work properly.");
                return; // Inform the owner and do nothing else.
            }
        } // If an animation exists either in inventory or by name...
        llSitTarget(pose_offset, llEuler2Rot(pose_rotation*DEG_TO_RAD)); // Set the sit target.
        sit_target = TRUE; // Remember that we are an active seat.
     }
    changed(integer change)
     {
     {
         on = (!on);
         if(change & CHANGED_LINK) // Sense that the object has an added link (may be an avatar).
         Switch(on); // Blah
        {
            if(sit_target)
            {
                sitter = llAvatarOnSitTarget(); // If it is an avatar store the UUID (key).
                if(sitter) // Check if the sitter is still sitting.
                llRequestPermissions(sitter, PERMISSION_TRIGGER_ANIMATION); // If sitting get permission to animate.
                else
                { // The sitter must have got up or something else changed.
                    if(perm)
                    {
                        llStopAnimation(anim_name); // Make sure the sit animation we play is stopped when the avatar stands.
                        llResetScript(); // Remove the permissions we had and clean the script.
                    }
                }
            }
        }
         if(change & CHANGED_INVENTORY)
        {
            llResetScript(); // If the animation is changed reset the script to get its name.
        }
     }
     }
     listen(integer chan, string name, key id, string msg)
     run_time_permissions(integer perms) // Use the permissions.
     {
     {
         on = (!on);
         if(perms & PERMISSION_TRIGGER_ANIMATION) // If we have the permissions we asked for.
        Switch(on); // Blah
        {
            perm = TRUE; // Remember that we have the permissions.
            if(sitter) // If the avatar is still sitting.
            {
                llStopAnimation("sit"); // Stop the default linden sit animation.
                llSleep(0.2); // Slow it down a bit. This gives time for the avatar animation list to be sit specific.
                integer count = 0;
                list anims = llGetAnimationList(sitter); // Get a list of animations the avatar is playing.
                integer length = llGetListLength(anims); // Get the length of that list.
                do
                {
                    string anim = llList2String(anims, count); // Pick the animation from the list of animations at index count.
                    if(anim != "")
                    llStopAnimation(anim); // Stop the animation.
                }
                while((++count) < length);
                llStartAnimation(anim_name); // Animate the sitting avatar using our inventory or named animation.
            }
        }
     }
     }
}</lsl>
}</syntaxhighlight>


== Scripts for multi prim drawers (2 scripts) ==
=== Region Stats as Graphical Floating Text ===


'''Could also be used for doors etc.'''
<syntaxhighlight lang="lsl2">// V3 //


<lsl>// INSTRUCTIONS FOR USE (there are two scripts that make up the set)
integer on = TRUE;


// Make your chest of drawers and link the whole set together with the body (any prim that doesn't move) of the chest as the root.
Switch()
 
{
// Name every prim used as a part of a drawer (include handles, drawer fronts, bases etc.) "drawer " plus a number.
    if(on)
 
    {
// All the prims of one drawer should now all be named the same. e.g. "drawer 1".
        llSetTimerEvent(0.0);
 
        llSetText("Click Me to Enable Region Stats Display\n \n ", <1.0, 1.0, 0.0>, 1.0);
// Name every drawer a different number. e.g. "drawer 1", "drawer 2" etc.
    }
 
    else
// With all the parts named correctly, edit the object so that all the drawers are closed.
    {
 
        llSetText("Gathering Region Stats...\n \n ", <1.0, 1.0, 0.0>, 1.0);
// At this point you might want to take a copy.
        llSetTimerEvent(2.5);
 
    }
// Be sure that no prims are named "drawer (something)" unless they are supposed to be (according to the above).
    on = (!on);
 
}
// Drop both the scripts (at the same time) into the root of the object.


// You will get further instructions in local chat. Follow them.</lsl><lsl>// This script needs to be named "Linkypooz".
DisplayStats()
 
vector open;
 
vector closed;
 
integer OPEN;
 
key owner;
 
integer my_response_num;
 
integer my_link_num;
 
Drawer()
{
{
     vector pos;
     integer count;
     if(OPEN)
     string d = "";
     pos = closed;
    string f = "";
    integer fps = (llRound((llGetRegionFPS() * 2.0) + 10.0) / 10);
    integer dilation = llRound((llGetRegionTimeDilation() * 10.0));
    integer combo = (dilation + fps);
    while((++count) < dilation)
    d += "||";
    count = 0;
    while((++count) < fps)
    f += "||";
    llSetText("The Region is  -  " + GetCondition((combo * 2)) +
              "\n \nNumber of Agents on Region  -  " + ((string)llGetRegionAgentCount()) +
              "\n \nRegion F.P.S.  -  " + f +
              "\nRegion Dilation  -  " + d, <1.0, ((((float)combo) / 2.0) / 10.0), 0.0>, 1.0);
}
string GetCondition(integer c) // Obviously you can change this wording if you like.
{                              // I just thought of "health" and went with it.
    if(c == 40)
    return "TRANSCENDENT";
    else if(c > 35)
    return "ATHLETIC";
    else if(c > 30)
    return "HEALTHY";
    else if(c > 25)
    return "AVERAGE";
    else if(c > 20)
    return "ILL";
    else if(c > 15)
     return "DYING";
    else if(c > 10)
    return "CRITICAL";
     else
     else
     pos = open;
     return "DEAD?";
    llSetPos(pos);
    OPEN = (!OPEN);
}
}
 
default
default
{
{
     state_entry()
     state_entry()
     {
     {
         owner = llGetOwner();
         Switch();
        closed = llGetLocalPos();
     }
     }
     touch_start(integer nd)
     touch_start(integer nd)
     {
     {
         if(llDetectedKey(0) == owner)
         Switch();
    }
    timer()
    {
        DisplayStats();
    }
}</syntaxhighlight>
 
=== Configurable Unpacker ===
 
<syntaxhighlight lang="lsl2">// V1 //
 
key owner;
string me;
integer open = FALSE;
list folder_contents;
string folder_name; // The folder name will establish from the description of the object this script is in.
// CHANGE ONLY THE SETTINGS BELOW //
integer give_this_script = TRUE; // Give this FREE script away with the other contents? Think about it....
integer allow_only_owner = FALSE; // Owner only or open to all?
integer self_delete = FALSE; // Self delete?
integer timed_deletion = FALSE; // Delete immediately after giving contents or hang around a bit?
float deletion_delay = 10.0; // Length of time to hang around in seconds (if timed_deletion is set TRUE)
string display_rez_text = ""; // Floating text on rez?
string localchat_rez_text = ""; // Chatted message on rez?
string ownerchat_rez_text = ""; // Chatted message only to owner on rez?
string display_deletion_text = ""; // Floating text before deletion?
string localchat_deletion_text = ""; // Chatted message before deletion?
string ownerchat_deletion_text = ""; // Chatted message only to owner before deletion?
vector rez_text_color = <1.0,1.0,1.0>; // Color of floating text if set to show on rez.
vector deletion_text_color = <1.0,1.0,1.0>; // Color of floating text if set to show before deletion.
float rez_text_alpha = 1.0; // Transparency of floating text if set to show on rez.
float deletion_text_alpha = 1.0; // Transparency of floating text if set to show before deletion.
// CHANGE ONLY THE SETTINGS ABOVE //
 
OnRezTextOptionsFunctionThingy(integer o)
{
    if(display_rez_text != "")
    llSetText(display_rez_text, rez_text_color, rez_text_alpha);
    if(localchat_rez_text != "")
    llSay(0, localchat_rez_text);
    if(ownerchat_rez_text != "")
    llOwnerSay(ownerchat_rez_text);
    if(!o)
    {
        integer count = 0;
        integer NOI = llGetInventoryNumber(INVENTORY_ALL);
        if(NOI)
         {
         {
             open = llGetLocalPos();
             folder_contents = [];
            llSetPos(closed);
            do
             state normal;
            {
                string name = llGetInventoryName(INVENTORY_ALL, count);
                if(name == me)
                {
                    if(give_this_script)
                    folder_contents += [name];
                }
                else
                folder_contents += [name];
             }
            while((++count) < NOI);
         }
         }
        folder_name = llGetObjectDesc();
     }
     }
}
}
state normal
default
{
{
     state_entry()
     on_rez(integer param)
     {
     {
         my_link_num = llGetLinkNumber();
         owner = llGetOwner();
         my_response_num = ((integer)llGetSubString(llGetLinkName(my_link_num), 7, -1));
         me = llGetScriptName();
         llOwnerSay(" is active!");
         OnRezTextOptionsFunctionThingy(FALSE);
     }
     }
     touch_start(integer nd)
     touch_start(integer nd)
     {
     {
         if(my_link_num == 1)
         if(!open)
         {
         {
             llRemoveInventory(llGetScriptName());
             integer give = FALSE;
            key toucher = llDetectedKey(0);
            if(allow_only_owner)
            {
                if(toucher == owner)
                give = TRUE;
            }
            else
            {
                give = TRUE;
            }
            if(give)
            {
                open = TRUE;
                llGiveInventoryList(toucher, folder_name, folder_contents);
            }
            if(open)
            {
                if(display_deletion_text != "")
                llSetText(display_deletion_text, deletion_text_color, deletion_text_alpha);
                if(localchat_deletion_text != "")
                llSay(0, localchat_deletion_text);
                if(ownerchat_deletion_text != "")
                llOwnerSay(ownerchat_deletion_text);
                if(self_delete)
                {
                    if(timed_deletion)
                    llSetTimerEvent(deletion_delay);
                    else
                    llDie();
                }
                else
                {
                    open = FALSE;
                    OnRezTextOptionsFunctionThingy(TRUE);
                }
            }
         }
         }
        llMessageLinked(LINK_SET, my_response_num, "", "");
     }
     }
     link_message(integer sender, integer num, string str, key id)
     timer()
     {
     {
         if(num == my_response_num)
         llDie();
        {
            Drawer();
        }
     }
     }
}</lsl><lsl>// This script can be called "cats ass" for all I care! lolz.
}</syntaxhighlight>


default
=== Random Item Giver ===
{
    state_entry()
    {
        integer count;
        integer links = llGetNumberOfPrims();
        do
        {
            string name = llGetLinkName(count);
            if(llGetSubString(name, 0, 5) == "drawer")
            {
                key link_key = llGetLinkKey(count);
                llGiveInventory(link_key, "Linkypooz");
            }
        }
        while((++count) < (links + 1));
        llOwnerSay("\n\nNow take the object to inventory and re-rez.
        \n\nSet all the prims so that all the drawers are closed.
        \n\nOpen an edit on the object.
        \n\nGo to the tools menu and at the bottom of the menu click \"Set Scripts Running in Selection\".
        \n\nEdit all the prims of the drawers from the closed position to the open position.
        \n\nWhen all the prims of the drawers are set open, touch each prim(you can do one prim at a time or all together, which ever you prefer).
        \n\nWhen the prim is touched it will automatically close.
        \n\nWhen all the prims of all the drawers are in the closed position the scripts are fully set up.
        \n\nThey will chat that they are active when ready.
        \n\nNow touch the root (or any other non drawer prim) and the script in it will self delete.
        \n\nThat's all!!");
        llRemoveInventory(llGetScriptName());
    }
}</lsl>


== Group Joiner that sets it's self to whatever group you are wearing as it is rezzed or created ==
'''IN ITS PRESENT STATE THIS SCRIPT SHOULD NOT BE USED TO GIVE ITEMS WITH NO COPY PERMISSIONS'''


<lsl>key group_key;
<syntaxhighlight lang="lsl2">// V2 //
   
   
Function()
integer NOI;
{
    group_key = llList2Key(llGetObjectDetails(llGetKey(), [OBJECT_GROUP]), 0);
    if(group_key != NULL_KEY)
    llHTTPRequest("http://world.secondlife.com/group/" + ((string)group_key), [], "");
    else
    {
        llSay(0, "Since you are not wearing a group tag I am not set to any group.
        \nWear a group tag and try again.
        \nThis script will self delete.");
        llRemoveInventory(llGetScriptName());
    }
}
   
   
default
default
Line 318: Line 583:
     state_entry()
     state_entry()
     {
     {
         Function();
         NOI = (llGetInventoryNumber(INVENTORY_ALL) - 1);
     }
     }
     on_rez(integer param)
     touch_start(integer nd)
    {
        Function();
    }
    http_response(key q, integer status, list metadata, string body)
     {
     {
         if(status == 200)
         while(nd && NOI)
        {
            integer name_start = (llSubStringIndex(body, "<title>") + 7);
            integer name_end = (llSubStringIndex(body, "</title>") - 1);
            integer tex_key_start = (llSubStringIndex(body, "imageid") + 18);
            integer tex_key_end = (tex_key_start + 35);
            string group_name = llGetSubString(body, name_start, name_end);
            llSetObjectName("Join " + group_name);
            key group_tex = llGetSubString(body, tex_key_start, tex_key_end);
            if(group_tex != NULL_KEY)
            llSetTexture(group_tex, ALL_SIDES);
            else
            llSetTexture(TEXTURE_BLANK, ALL_SIDES);
        }
        else
         {
         {
             llHTTPRequest("http://world.secondlife.com/group/" + ((string)group_key), [], "");
             string inv;
            while((inv = llGetInventoryName(INVENTORY_ALL, llRound(llFrand((float)NOI)))) == llGetScriptName());
            llGiveInventory(llDetectedKey(--nd), inv);
         }
         }
     }
     }
     touch_start(integer nd)
     changed(integer change)
     {
     {
         llSay(0, "/me by clicking this link\nsecondlife:///app/group/" + ((string)group_key) + "/about");
         if(change & (CHANGED_INVENTORY | CHANGED_OWNER))
        llResetScript();
     }
     }
}</lsl>
}</syntaxhighlight>


== Tip Jar with ability to pay a percentage to the founder of the group the object is set to ==
=== Programmable Song Player ===


'''Might be a bit buggy because I wrote it while 1/2 asleep. I'll check later.'''
Due the the 10 second limit on sounds we need to play whole songs as a sequence of clips. This does that.
* You can add up to 11 (inclusive) complete songs (however many sound files there are per song) and select which to play.
* If a song is playing you can select the next to play and a playlist is formed. The playlist can be added to at anytime during playback.
* The volume is adjustable at anytime, including during playback.
* Reads the song snippets from the sound files placed in the object inventory. They will be played in alphabetical/numerical order.
* Follow the instructions at the top of the script. Very little editing is needed.
** There is a chance that the memory will break if the playlist is made too long. V3 will include a measure against that but I have to sleep occasionally.


'''UNDER CERTAIN CONDITIONS (That you set and agree to) THIS SCRIPT WILL TAKE MONEY FROM YOUR ACCOUNT'''
<syntaxhighlight lang="lsl2">// V2 //
// This list is all you need to edit. List the names of the songs (each collection of sound files that makes one song)
// followed by the length of those sound clips (each song should contain clips of equal length)


<lsl>key owner;
// The list should be structured like so -


integer debit_perms = FALSE;
// list songs = ["First Song", 9.0, "Second Song", 9.65, "Third Song", 9.45];


integer pay_price = 0;
// The names of the songs must be identical to some part of the sound files used for that song like so -


list pay_buttons = [20, 50, 100, 250];
//// In the prim inventory (along with this script) -


integer percentage = 50; // Percentage to pay to the founder of the group the object is set to.
////// Box_Of_Rain_wav_1
////// Box_Of_Rain_wav_2
////// Box_Of_Rain_wav_3
////// Servant 1
////// Servant 2
////// Servant 3


key beneficiary;
//// In the script -


string default_message = "/me is very grateful for the generous contribution from ";
////// list songs = ["Box_Of_Rain", 9.2, "Servant", 9.8];


string beneficiary_message = "% of which has been paid to the founder of ";
// The script will play the clips in alpha/numerical order so name them wisely.


key group_key;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
////////////////////////////////////////////////ONLY EDIT BELOW HERE///////////////////////////////////////////////////////////////
string group_name;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
Function()
list songs = ["Box_Of_Rain", 9.2, "Servant", 9.8]; // YUP! EDIT THIS BIT ;-)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////ONLY EDIT ABOVE HERE///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
integer volume = 10;
integer lis_count;
integer playing;
integer busy;
integer part;
integer lis;
integer sl;
float delay;
list cancel = ["CANCEL"];
list playlist;
list waiting;
list song;
string vol_str = "Volume";
string song_str = "Songs";
string song_name;
list StrideOfList(list src, integer stride, integer start, integer end)
{
    list l = [];
    integer ll = llGetListLength(src);
    if(start < 0)start += ll;
    if(end < 0)end += ll;
    if(end < start) return llList2List(src, start, start);
    while(start <= end)
    {
        l += llList2List(src, start, start);
        start += stride;
    }
    return l;
}
list Volumes(integer vol)
{
    integer v = 0;
    list l = [];
    do
    {
        if(v != vol)
        l += [((string)v)];
    }
    while((++v) <= 10);
    return l;
}
PageOne(key k, integer c)
{
    llDialog(k, "\nAdjust the volume or select a song to play?", [vol_str, song_str] + cancel, c);
}
PlaySong(string n)
{
    song = [];
    integer c = -1;
    string name = "";
    do
    {
        if(llSubStringIndex((name = llGetInventoryName(INVENTORY_SOUND, (++c))), n) != -1)
        song += [name];
    }
    while(name);
    delay = llList2Float(songs, (llListFindList(songs, [n]) + 1));
    if((sl = llGetListLength(song)))
    {
        llPreloadSound(llList2String(song, (part = 0)));
        if(sl > 1)
        llPreloadSound(llList2String(song, 1));
        playing = FALSE;
        llSetTimerEvent(0.01);
    }
}
integer Chan()
{
    return llRound((llFrand(-5000000.0) + -500000.0));
}
float ScaleVol(integer v)
{
    return (v * 0.1);
}
Listen(integer c, key a)
{
    lis = llListen(c, "", a, "");
}
RemoveListen(integer b)
{
    llListenRemove(lis);
    lis_count = 0;
    if(b)
    busy = FALSE;
    lis = 0;
}
SetListenTimer(integer p)
{
{
     owner = llGetOwner();
     if(p)
     string owner_name = llKey2Name(owner);
     while(((++lis_count) * llRound(delay)) < 30);
    string object_name = (owner_name + "'s Money Box");
     else
     llSetObjectName(object_name);
     {
     llSetPayPrice(pay_price, pay_buttons);
        lis_count = 1;
    if(percentage)
        llSetTimerEvent(30.0);
     llRequestPermissions(owner, PERMISSION_DEBIT);
     }
}
}
 
integer CheckWaitingRoom(integer c)
{
    if(waiting)
    {
        key a = llList2Key(waiting, 0);
        if(!c)
        {
            RemoveListen(0);
            Listen((c = Chan()), a);
            SetListenTimer(playing);
        }
        PageOne(a, c);
        waiting = llDeleteSubList(waiting, 0, 0);
        return 1;
    }
    return 0;
}
default
default
{
{
     on_rez(integer param)
     on_rez(integer param)
     {
     {
         Function();
         llStopSound();
        llResetScript();
     }
     }
     state_entry()
     changed(integer change)
     {
     {
         Function();
         if(change & CHANGED_INVENTORY)
        llResetScript();
     }
     }
     run_time_permissions(integer perms)
     touch_start(integer nd)
     {
     {
         if(perms & PERMISSION_DEBIT)
         while(nd)
         {
         {
             debit_perms = TRUE;
             key agent = llDetectedKey(--nd);
            group_key = llList2Key(llGetObjectDetails(llGetKey(), [OBJECT_GROUP]), 0);
            if(!busy)
             if(group_key != NULL_KEY)
            {
            llHTTPRequest("http://world.secondlife.com/group/" + ((string)group_key), [], "");
                busy = TRUE;
                integer channel = Chan();
                SetListenTimer(playing);
                Listen(channel, agent);
                PageOne(agent, channel);
             }
            else
            {
                list a = [agent];
                if(llListFindList(waiting, a) == -1)
                waiting += a;
            }
         }
         }
        else
        llRequestPermissions(owner, PERMISSION_DEBIT);
     }
     }
     http_response(key q, integer status, list metadata, string body)
     listen(integer chan, string name, key id, string msg)
     {
     {
         if(status == 200)
         if(msg != llList2String(cancel, 0))
         {
         {
             integer name_start = (llSubStringIndex(body, "<title>") + 7);
             SetListenTimer(playing);
             integer name_end = (llSubStringIndex(body, "</title>") - 1);
            if(msg == vol_str)
            integer founder_key_start = (llSubStringIndex(body, "founderid") + 20);
            {
            integer founder_key_end = (founder_key_start + 35);
                llDialog(id, "\nChange the volume?\nThe current volume is set at \"" + ((string)volume) + "\"", cancel + Volumes(volume), chan);
             beneficiary = llGetSubString(body, founder_key_start, founder_key_end);
                return;
             group_name = llGetSubString(body, name_start, name_end);
            }
        }
            if(msg == song_str)
        else
             {
        {
                string current = "";
             llHTTPRequest("http://world.secondlife.com/group/" + ((string)group_key), [], "");
                if(playlist)
                {
                    current = "\n\nThe songs currently queued are\n\"" + llList2String(playlist, 0) + "\" (currently playing)";
                    if(llGetListLength(playlist) > 1)
                    current += "\n\"" + llDumpList2String(llList2List(playlist, 1, -1), "\"\n\"") + "\"";
                }
                llDialog(id, llGetSubString(("\nSelect a song to play?" + current), 0, 500), cancel + StrideOfList(songs, 2, 0, -1), chan);
                return;
             }
            if(llListFindList(Volumes(volume), [msg]) != -1)
             {
                llAdjustSoundVolume(ScaleVol((volume = ((integer)msg))));
                PageOne(id, chan);
                return;
            }
             if(llGetListLength((playlist += [msg])) == 1)
            PlaySong((song_name = msg));
         }
         }
        if(CheckWaitingRoom(chan))
        return;
        RemoveListen(1);
     }
     }
     money(key id, integer amount)
     timer()
     {
     {
        string message = "";
         if(playlist)
        integer dividend;
        string payer = llKey2Name(id);
         if(!percentage)
         {
         {
             message = (default_message + payer);
             if(!playing)
        }
            {
        else
                llSetTimerEvent(delay);
        {
                playing = TRUE;
             dividend = llFloor((((float)amount)/100.0) * ((float)percentage)); // I'm very tired and my eyes are sticky!
            }
             if(dividend)
             llPlaySound(llList2String(song, part), ScaleVol(volume));
             if((++part) == sl)
             {
             {
                 if(debit_perms)
                 if(llGetListLength(playlist) > 1)
                 {
                 {
                     message = (default_message + payer + ".\n" + ((string)percentage) + beneficiary_message + group_name);
                     song_name = llList2String((playlist = llDeleteSubList(playlist, 0, 0)), 0);
                     llGiveMoney(beneficiary, dividend);
                    llSleep(delay);
                     PlaySong(song_name);
                 }
                 }
                 else
                 else
                 {
                 {
                     message = (default_message + payer);
                     llSetTimerEvent(0.0);
                    song_name = "";
                    playing = FALSE;
                    playlist = [];
                 }
                 }
             }
             }
            else if(part == (sl - 1))
            llPreloadSound(llList2String(song, 0));
            else
            llPreloadSound(llList2String(song, (part + 1)));
        }
        if(lis && (!(--lis_count)))
        {
            if(!(CheckWaitingRoom(0)))
            RemoveListen(1);
         }
         }
        llSay(PUBLIC_CHANNEL, message);
     }
     }
}</lsl>
}</syntaxhighlight>


== Region Stats as floating text ==
=== Single Prim Double Doors ===


<lsl>string bar = "||";
Just drop the script into a fresh prim and it will become the doors.


string RFPS = "Region Frames per Second = ";
Can be made to allow only owner use by writing the word "owner" in the prim description.


string RTD = "Region Time Dilation = ";
<syntaxhighlight lang="lsl2">// V3 //


string GetCondition(integer d, integer f)
float auto_close = 10.0; // The time the door remains open before auto closing. Set to zero for no auto closure.
 
integer open;
OperateDoors()
{
{
    string s = "";
     if(!open)
     if(d >= 15 && f >= 15)
     {
     s = "GOOD";
        float f = 0.0;
    else if(d >= 10 && f >= 10)
        while((f += 0.01) <= 1.0)
    s = "POOR";
        llSetLinkPrimitiveParamsFast(LINK_THIS, [9, 0, 0, <0.375,0.875,0.0>, 0.95, ZERO_VECTOR, <f,1.0,0.0>, ZERO_VECTOR]);
    else if(d >= 5 && f >= 5)
     }
     s = "DIABOLICAL";
     else
     else
     s = "CRASHED?";
     {
     return s;
        float f = 1.0;
        while((f -= 0.01) >= -1.0)
        llSetLinkPrimitiveParamsFast(LINK_THIS, [9, 0, 0, <0.375,0.875,0.0>, 0.95, ZERO_VECTOR, <f,1.0,0.0>, ZERO_VECTOR]);
    }
    llSetTimerEvent(auto_close);
     open = (!open);
}
}
 
default
default
{
{
     on_rez(integer param)
     state_entry()
     {
     {
         llResetScript();
         vector pos = llGetPos();
        llSetLinkPrimitiveParamsFast(LINK_THIS, [9, 0, 0, <0.375,0.875,0.0>, 0.95, ZERO_VECTOR, <0.0,1.0,0.0>, ZERO_VECTOR,
                                                17, -1, TEXTURE_BLANK, <1.0,1.0,0.0>, ZERO_VECTOR, 0.0,
                                                6, <pos.x,pos.y,(pos.z - 0.25)>,
                                                18, -1, ZERO_VECTOR, 0.4,
                                                8, <PI,0.0,0.0,PI>,
                                                7, <3.0,5.0,0.01>]);
     }
     }
     state_entry()
     touch_start(integer nd)
     {
     {
         llSetTimerEvent(5.0);
         if(llToLower(llGetObjectDesc()) == "owner")
        {
            while(nd)
            {
                if(llDetectedKey(--nd) == llGetOwner())
                OperateDoors();
            }
        }
        else
        OperateDoors();
     }
     }
     timer()
     timer()
     {
     {
         integer count = 0;
         llSetTimerEvent(0.0);
        vector color;
         if(open)
        string d = "";
         OperateDoors();
        string f = "";
        string text = "";
        float dilation = (llGetRegionTimeDilation() * 10);
        float FPS = llGetRegionFPS();
        integer mathed_fps = (llRound(FPS*2)/10);
        integer mathed_dilation = llRound(dilation);
        do
        d += bar;
        while((++count) < mathed_dilation);
        count = 0;
        do
        f += bar;
        while((++count) < mathed_fps);
        color = <1.0, (dilation/10), 0.0>;
        text = ("All is - " + GetCondition((mathed_dilation * 2), (mathed_fps * 2)) + "\n");
         text += (RFPS + f + "\n" + RTD + d);
         llSetText(text, color, 1.0);
     }
     }
}</lsl>
}</syntaxhighlight>
 
== Configurable Unpacker ==
 
'''Untested (should work ok)'''


<lsl>key owner;
=== Give Only to Agents of an Age ===


integer open = FALSE;
Simple freebie giver that discriminates against old people. Use to allow only newer residents to grab your freebies.
*The measure of age isn't perfect but, the worst it will be off by is a day or so.
Load the prim up with stuff (of any type (set free scripts to "Not Running")) and the script will automatically read the contents and be ready to hand them out.


// CHANGE ONLY THE SETTINGS BELOW //
<syntaxhighlight lang="lsl2">// V1 //


string folder_name = ""; // Name of the folder
integer noobage = 30; // Age in days upto which an agent is considered eligible.


list folder_contents = ["First Inventory Item", "Second Inventory Item"]; // Each inventory item name. Each name in quotes and each separated by a comma.
string folder_name = "Folder"; // name of folder as it appears in the agents inventory.


integer allow_only_owner = FALSE; // TRUE to allow only the owner to unpack. FALSE to allow anyone.
///////////////////////////////////////////////////////////////////////////////////////


integer self_delete = FALSE; // TRUE to self delete after unpacking. FALSE to not self delete.
list inv = [];


integer timed_deletion = FALSE; // TRUE to set a delay before self deletion. FALSE to delete immediately after unpacking.
integer Inv = 0;


float deletion_delay = 10.0; // Time in seconds before the box deletes if it is set to self delete.
integer busy = 0;


string birth_text = ""; // Text to show before the item is touched (e.g. "Touch me to unpack"). If left as an empty string ("") no text will show.
list waiting = [];


string deletion_text = ""; // Text to show after the item is touched (e.g. "I have given you a folder"). If left as an empty string ("") no text will show.
key iq = NULL_KEY;


vector birth_text_color = <1.0,1.0,1.0>; // The color for the birth_text. Set < Red, Green, Blue > values each between 0.0 and 1.0
key Agent = NULL_KEY;


vector deletion_text_color = <1.0,1.0,1.0>; // The color for the deletion_text. Set < Red, Green, Blue > values each between 0.0 and 1.0
integer ThankYouForTheDays(string d)
{
    return llRound((((float)llGetSubString(d, 0, 3)) * 365.25) +
                  (((float)llGetSubString(d, 5, 6)) * 30.4375) +
                  ((float)llGetSubString(d, 8, 9)));
}


float birth_text_alpha = 1.0; // The transparency of the birth_text. Set between 0.0 and 1.0 (1.0 is solid)
integer Noob(string dob, string date)
 
{
float deletion_text_alpha = 1.0; // The transparency of the deletion_text. Set between 0.0 and 1.0 (1.0 is solid)
    if((ThankYouForTheDays(date) - ThankYouForTheDays(dob)) <= noobage)
 
    return 1;
// CHANGE ONLY THE SETTINGS ABOVE //
    return 0;
}


default
default
Line 552: Line 999:
     on_rez(integer param)
     on_rez(integer param)
     {
     {
         owner = llGetOwner();
         llResetScript();
         if(birth_text != "")
    }
    changed(integer change)
    {
         if(change & (CHANGED_OWNER | CHANGED_INVENTORY))
        llResetScript();
    }
    state_entry()
    {
        integer noi = llGetInventoryNumber(INVENTORY_ALL);
        string name;
        while(noi)
         {
         {
             llSetText(birth_text, birth_text_color, birth_text_alpha);
             if((name = llGetInventoryName(INVENTORY_ALL, (--noi))) != llGetScriptName())
            inv += [name];
         }
         }
        Inv = llGetListLength(inv);
     }
     }
     touch_start(integer nd)
     touch_start(integer nd)
     {
     {
         if(open)
         while(nd && Inv)
         {
         {
            open = FALSE;
             key agent = llDetectedKey(--nd);
             key toucher = llDetectedKey(0);
             if(!busy)
             if(allow_only_owner)
             {
             {
                 if(toucher == owner)
                 busy = TRUE;
                 {
                 iq = llRequestAgentData((Agent = agent), DATA_BORN);
                    llGiveInventoryList(toucher, folder_name, folder_contents);
                }
             }
             }
             else
             else
             {
             {
                 llGiveInventoryList(toucher, folder_name, folder_contents);
                 if(llListFindList(waiting, [agent]) == -1)
                waiting += [agent];
             }
             }
         }
         }
         if(self_delete)
    }
    dataserver(key q, string data)
    {
         if(q == iq)
         {
         {
             if(timed_deletion)
             if(Noob(data, llGetDate()))
            llGiveInventoryList(Agent, folder_name, inv);
            if(llGetListLength(waiting))
             {
             {
                 llSetTimerEvent(deletion_delay);
                 iq = llRequestAgentData((Agent = llList2Key(waiting, 0)), DATA_BORN);
                 if(deletion_text != "")
                 waiting = llDeleteSubList(waiting, 0, 0);
                {
                    llSetText(deletion_text, deletion_text_color, deletion_text_alpha);
                }
             }
             }
             else
             else
             {
             busy = FALSE;
                llDie();
            }
         }
         }
     }
     }
    timer()
}</syntaxhighlight>}}
    {
        llDie();
    }
}</lsl>

Latest revision as of 03:58, 21 March 2017

I get in-world very rarely these days. The knock-on effect of this, is that I am not in the best position to keep these scripts updated. Please message me in-world (forwarded to email) if you discover any bugs (that can't be simply fixed), and I'll do my best to find a solution.

My Contributions

If unsure about how to use these scripts

I have implemented a version number system to make it more obvious if a script is updated. The V# is a comment at the top of each script.

If you have any comments about the content of this page please post them HERE

All my scripts are written for compilation as MONO

More Scripts

Legal Stuff

The legal stuff about contributing to this wiki. (worth reading)

PJIRA Issue Tracker

The issues I have filed on the PJIRA

Tuition

Tuition scripts, notes, videos and screenshots etc. (hardly any content yet)

Free Scripts

Basic Light Switch

Placed in the root of a linked object this script will make the whole object active to touch. The light will always be emitted by the prim the script is in. So, if you have a 5 prim lamp, put this in the "bulb" prim and make that prim the root. If placed in a child prim of an object, only that prim will be clickable (unless there are other touch scripts in other prims of the object).

// V1 //

vector color = <1.0, 1.0, 1.0>; // R,G,B ( red, green, blue ) values.

float intensity = 1.0; // 0.0 to 1.0 ( 1.0 = full brightness )

float radius = 20.0; // 0.1 to 20.0 ( 20.0 = full sphere )

float falloff = 0.01; // 0.01 to 2.0 ( 2.0 = least spread )

/////////////////////////////////////////////////////////////////////////

integer on; // Global variable used to measure the condition "on" or "off".

Switch() {
    // The switching function.
    on = !on; // Flip the boolean value of the integer "on".
    // Set the prim's light emitter on or off, dependant on the value of "on".
    llSetPrimitiveParams( [ PRIM_POINT_LIGHT, on, color, intensity, radius, falloff ] );
}

default {
    touch_end( integer nd ) { // If clicked,
        Switch(); // unconditionally call the switch to operate.
    }
}

Basic Alpha (transparency) SHOW/HIDE

// V1 //
 
string command = "switch"; // Place the command to chat here. The same command will switch on and off.
 
integer channel = 1; // Place channel to use here ( must be positive if an avatar is chatting on it ).

//////////////////////////////////////////////////////////////////////////////////////////////////////

integer on; // Store the state of transparency.
 
Switch() {
    llSetLinkAlpha( LINK_SET, ( float )on, ALL_SIDES ); // This setting will turn a whole link_set transparent or visible.
    on = !on; // Flip the boolean value of the integer "on".
}
 
default {
    state_entry() {
        llListen( channel, "", "", command ); // This script is listening to everyone all the time.
        // llListen( channel, "", llGetOwner(), command ); // Delete the "//" at the beginning of this line...
                                                           // ...and add "//" at the beginning of the line above...
                                                           // ...to make This script listen to only the owner.
    } // Switching the listen off at times would be better to reduce lag. But when??
    touch_end( integer nd ) {
        // if ( llDetectedKey( 0 ) == llGetOwner() ) // Delete the "//" at the beginning of this line to make touches only respond to owner.
        Switch(); // Call the switching function.
    }
    listen( integer chan, string name, key id, string msg ) {
        Switch(); // Call the switching function.
    }
}

Basic Particle Candle Flame ON/OFF

This script will make the prim it is in a small glowing sphere that sits at the center of the flame.

// V1 //

integer on; // Establish "on" as a global variable so that we can remember whether or not the flame is on.

Flame( integer num ) {
    // Do we or don't we make a flame? "num" is either TRUE or FALSE ( 1 or 0 ).
    if ( num ) {
        // Make the flame since the condition above was met.
        llParticleSystem( [ PSYS_PART_FLAGS, 275,
                            PSYS_SRC_PATTERN, 4,
                            PSYS_PART_START_ALPHA, 0.6,
                            PSYS_PART_END_ALPHA, 0.0,
                            PSYS_PART_START_COLOR, <1.0, 1.0, 0.3>,
                            PSYS_PART_END_COLOR, <0.8, 0.6, 0.6>,
                            PSYS_PART_START_SCALE, <0.04, 0.07, 0.0>,
                            PSYS_PART_END_SCALE, <0.04, 0.04, 0.0>,
                            PSYS_PART_MAX_AGE, 0.3,
                            PSYS_SRC_MAX_AGE, 0.0,
                            PSYS_SRC_ACCEL, <0.0, 0.0, 0.02>, // These are the parameters of the particle effect.
                            PSYS_SRC_ANGLE_BEGIN, 0.0,
                            PSYS_SRC_ANGLE_END, 0.0,
                            PSYS_SRC_BURST_PART_COUNT, 50,
                            PSYS_SRC_BURST_RATE, 0.07,
                            PSYS_SRC_BURST_RADIUS, 0.0,
                            PSYS_SRC_BURST_SPEED_MIN, 0.001,
                            PSYS_SRC_BURST_SPEED_MAX, 0.4,
                            PSYS_SRC_OMEGA, <0.0, 0.0, 0.0>,
                            PSYS_SRC_TARGET_KEY, ( key )"",
                            PSYS_SRC_TEXTURE, "" ]
                        );
        llSetPrimitiveParams( [ PRIM_POINT_LIGHT, TRUE, <1.0, 0.8, 0.3>, 0.5, 2.0, 1.9, // For extra effect we switch the light on too.
                                PRIM_COLOR, ALL_SIDES, <1.0, 1.0, 1.0>, 0.1, // And set the transparency to slightly visible,
                                PRIM_GLOW, ALL_SIDES, 0.1 ] // and the glow to slight.
                            );
    } else {
        // "num" was not 1 ( TRUE ) so we need to stop the effect or not start it.
        llParticleSystem( [] ); // Make no particles ( no flame ).
        llSetPrimitiveParams( [ PRIM_POINT_LIGHT, FALSE, ZERO_VECTOR, 0.0, 0.0, 0.0, // Switch the light off.
                                PRIM_COLOR, ALL_SIDES, <1.0, 1.0, 1.0>, 0.0, // And set the transparency to invisible,
                                PRIM_GLOW, ALL_SIDES, 0.0 ] // and the glow to zero.
                            );
    }
    on = num; // Establish the value of the global variable "on" as being equal to the task we just performed. This acts as our memory.
}

default { // Create a state for the code to run in.
    state_entry() {
        // These instructions will change the size, shape and texturing of the prim the script is in.
        llSetPrimitiveParams( [ PRIM_TYPE, PRIM_TYPE_SPHERE, 0, <0.0, 1.0, 0.0>, 0.0, ZERO_VECTOR, <0.0, 1.0, 0.0>, // Make the prim a sphere.
                                PRIM_SIZE, <0.01, 0.01, 0.03>, // Make the prim the right size to act as the glowing center of the flame.
                                PRIM_TEXTURE, ALL_SIDES, TEXTURE_BLANK, ZERO_VECTOR, ZERO_VECTOR, 0.0 ] // Set the blank texture.
                            );
        // Make the candle flame ignite.
        Flame( TRUE ); // Flame( TRUE ); Is an order to run the code "Flame" with the integer value "TRUE" ( numerical value = 1 ).
    }
    touch_end( integer detected ) { // Detect if we have touched the candle.
        Flame( !on ); // We now order that the Flame() code is run with the integer value that is the opposite of what it already is.
        // "!on" = FALSE if on = TRUE and TRUE if on = FALSE. The "!" means "not".
    }
}

Simple Timer Alarm

Good for reminding you about sandbox returns etc. Ideally worn as a single prim HUD attachment.

// V3 //

string alarm = "5e1d5f52-e7ae-0194-a412-93a96f39ff6f"; // Name of the sound in the object inventory.
                                                       // Or the UUID of any sound.

float volume = 0.5; // Values between "0.0" and "1.0".

vector passive = <0.0, 0.0, 1.0>; // Color for prim when timer is off.

vector active = <0.0, 1.0, 0.0>; // Color for prim when timer is running.

vector alarmed = <1.0, 0.0, 0.0>; // Color for prim when alarm is sounding.

integer on; // Used to store if the timer is running.

default {
    on_rez( integer param ) {
        llResetScript();
    }
    state_entry() {
        llStopSound();
        llSetColor( passive, ALL_SIDES );
        llSetObjectName( "Alarm" );
    }
    touch_end( integer nd ) {
        if ( on ) {
            llResetScript();
        } else {
            float time = ( float )llGetObjectDesc() * 60; // Time established from the prim description.
            if ( time < 1.0 ) {
                llOwnerSay( "The time is not set.\nPlease write the time into the object description and try again" );
                return;
            }
            llSetColor( active, ALL_SIDES );
            llOwnerSay( "/me is set to sound in " + ( string )llRound( time / 60 ) + " minutes." );
            llSetTimerEvent( time );
            on = TRUE;
            llPreloadSound( alarm );
        }
    }
    timer() {
        llSetTimerEvent( 0.0 );
        llLoopSound( alarm, volume );
        llSetColor( alarmed, ALL_SIDES );
    }
}

Floating on Water (very beta)

This creates a movement sort of like a floating lantern. But it needs a lot of work before I will consider it even close to done.

// V2 //
 
float limit = 10.0; // This is the radius that the object is allowed to drift up to.
                    // 20.0 would be a 40 meter circle.
 
float offset = 0.0; // Use this float to offset the height of the object in relation to the water surface.
// The object will (when the offset is zero) float with its geometric center at the level of the water surface.
 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
float float_height;
 
vector home;
 
FloatAbout( vector pos ) {
    llSetTimerEvent( limit );
    @a;
    float num_x = llFrand( limit / 2 ) - ( limit / 4 );
    float num_y = llFrand( limit / 2 ) - ( limit / 4 );
    vector target = <( pos.x + num_x ), ( pos.y + num_y ), float_height>;
    if ( llVecDist( target, home ) <= limit ) {
        llMoveToTarget( target, limit * 1.5 );
    } else {
        jump a;
    }
}
 
default {
    on_rez( integer param ) {
        llResetScript();
    }
    state_entry() {
        float_height = llWater( ZERO_VECTOR ) + offset;
        llSetStatus( STATUS_ROTATE_X | STATUS_ROTATE_Y, FALSE );
        llSetStatus( STATUS_PHYSICS | STATUS_PHANTOM, TRUE );
        home = llGetPos();
        llSetTimerEvent( 0.1 );
    }
    timer() {
        FloatAbout( llGetPos() );
    }
    touch_end( integer nd ) {
        if ( llDetectedKey( 0 ) == llGetOwner() ) {
            FloatAbout( home = llGetPos() );
        }
    }
}

Visit Web Address Dialog

If you have a website use something like this to direct people to it.

// V3 //
 
string URL_Loader_Message = "\nCopy FREE scripts from an SL wiki page"; // Message to show on dialog.
 
string URL_To_Visit = "https://wiki.secondlife.com/wiki/User:Fred_Gandt"; // URL to visit.
 
string Floating_Text = "FREE SCRIPTS!!\n \nTouch to visit web site.\n \n(Official SL wiki)\n \n "; // Floating text.
 
vector Float_Text_Color = <1.0, 1.0, 1.0>; // Color of floating text.
 
float Float_Text_Alpha = 1.0; // Transparency of floating text (1.0 is solid).
 
// FROM THIS POINT IT IS SCARY!! ARRGGGHHHH...!!! //
 
default {
    state_entry() {
        llSetText( Floating_Text, Float_Text_Color, Float_Text_Alpha );
    }
    touch_start( integer nd ) {
        while ( nd ) {
            llLoadURL( llDetectedKey( --nd ), URL_Loader_Message, URL_To_Visit );
        }
    }
}

AO Overriding Sit Script

// V1 //

integer sit_target; // Used to store whether or not a sit target is applied.

key sitter; // Used to store the UUID (key) of the avatar we are animating.

integer perm; // Used to store whether or not we have permissions we ask for.

string anim_name = ""; // Used to store the name of the animation we have in the objects inventory.

string sit_text = ""; // Add a word to replace the words "Sit Here" (in the pie menu) to show if right clicking to sit.

vector pose_offset = <0.0,0.0,0.01>; // This must be a non zero value.
//  The X,Y,Z values denote by how much in meters or parts thereof the avatars pelvis is offset from the center of the prim.
// There can be an offset induced by the animation its self. If this is the case trial and error is the only way forward.

vector pose_rotation = <0.0,0.0,0.0>; // This can be a zero value.
// The X,Y,Z values denote the rotation in degrees that the animation is rotated around the avatars pelvis.
// There can be an offset induced by the animation its self. If this is the case trial and error is the only way forward.

default
{
    on_rez(integer param)
    {
        llResetScript(); // Clean the script when we rez the object.
    }
    state_entry()
    {
        if(sit_text != "") // If we have not set sit_text don't apply it.
        llSetSitText(sit_text);
        if(anim_name == "") // If we have not named an anim (Such as the internal animations)...
        {
            // ...this will get the name of an animation in the prims inventory and store it.
            anim_name = llGetInventoryName(INVENTORY_ANIMATION, 0);
            if(anim_name == "") // If there is no animation in the inventory and we haven't named one...
            {
                llSitTarget(ZERO_VECTOR, ZERO_ROTATION); // Remove any stored sit target.
                llOwnerSay("There is no animation named or in my inventory. Please add an animation so I can work properly.");
                return; // Inform the owner and do nothing else.
            }
        } // If an animation exists either in inventory or by name...
        llSitTarget(pose_offset, llEuler2Rot(pose_rotation*DEG_TO_RAD)); // Set the sit target.
        sit_target = TRUE; // Remember that we are an active seat.
    }
    changed(integer change)
    {
        if(change & CHANGED_LINK) // Sense that the object has an added link (may be an avatar).
        {
            if(sit_target)
            {
                sitter = llAvatarOnSitTarget(); // If it is an avatar store the UUID (key).
                if(sitter) // Check if the sitter is still sitting.
                llRequestPermissions(sitter, PERMISSION_TRIGGER_ANIMATION); // If sitting get permission to animate.
                else
                { // The sitter must have got up or something else changed.
                    if(perm)
                    {
                        llStopAnimation(anim_name); // Make sure the sit animation we play is stopped when the avatar stands.
                        llResetScript(); // Remove the permissions we had and clean the script.
                    }
                }
            }
        }
        if(change & CHANGED_INVENTORY)
        {
            llResetScript(); // If the animation is changed reset the script to get its name.
        }
    }
    run_time_permissions(integer perms) // Use the permissions.
    {
        if(perms & PERMISSION_TRIGGER_ANIMATION) // If we have the permissions we asked for.
        {
            perm = TRUE; // Remember that we have the permissions.
            if(sitter) // If the avatar is still sitting.
            {
                llStopAnimation("sit"); // Stop the default linden sit animation.
                llSleep(0.2); // Slow it down a bit. This gives time for the avatar animation list to be sit specific.
                integer count = 0;
                list anims = llGetAnimationList(sitter); // Get a list of animations the avatar is playing.
                integer length = llGetListLength(anims); // Get the length of that list.
                do
                {
                    string anim = llList2String(anims, count); // Pick the animation from the list of animations at index count.
                    if(anim != "")
                    llStopAnimation(anim); // Stop the animation.
                }
                while((++count) < length);
                llStartAnimation(anim_name); // Animate the sitting avatar using our inventory or named animation.
            }
        }
    }
}

Region Stats as Graphical Floating Text

// V3 //

integer on = TRUE;

Switch()
{
    if(on)
    {
        llSetTimerEvent(0.0);
        llSetText("Click Me to Enable Region Stats Display\n \n ", <1.0, 1.0, 0.0>, 1.0);
    }
    else
    {
        llSetText("Gathering Region Stats...\n \n ", <1.0, 1.0, 0.0>, 1.0);
        llSetTimerEvent(2.5);
    }
    on = (!on);
}

DisplayStats()
{
    integer count;
    string d = "";
    string f = "";
    integer fps = (llRound((llGetRegionFPS() * 2.0) + 10.0) / 10);
    integer dilation = llRound((llGetRegionTimeDilation() * 10.0));
    integer combo = (dilation + fps);
    while((++count) < dilation)
    d += "||";
    count = 0;
    while((++count) < fps)
    f += "||";
    llSetText("The Region is  -  " + GetCondition((combo * 2)) +
              "\n \nNumber of Agents on Region  -  " + ((string)llGetRegionAgentCount()) +
              "\n \nRegion F.P.S.  -  " + f +
              "\nRegion Dilation  -  " + d, <1.0, ((((float)combo) / 2.0) / 10.0), 0.0>, 1.0);
}
 
string GetCondition(integer c) // Obviously you can change this wording if you like.
{                              // I just thought of "health" and went with it.
    if(c == 40)
    return "TRANSCENDENT";
    else if(c > 35)
    return "ATHLETIC";
    else if(c > 30)
    return "HEALTHY";
    else if(c > 25)
    return "AVERAGE";
    else if(c > 20)
    return "ILL";
    else if(c > 15)
    return "DYING";
    else if(c > 10)
    return "CRITICAL";
    else
    return "DEAD?";
}
 
default
{
    state_entry()
    {
        Switch();
    }
    touch_start(integer nd)
    {
        Switch();
    }
    timer()
    {
        DisplayStats();
    }
}

Configurable Unpacker

// V1 //

key owner;
 
string me;
 
integer open = FALSE;
 
list folder_contents;
 
string folder_name; // The folder name will establish from the description of the object this script is in.
 
// CHANGE ONLY THE SETTINGS BELOW //
 
integer give_this_script = TRUE; // Give this FREE script away with the other contents? Think about it....
 
integer allow_only_owner = FALSE; // Owner only or open to all?
 
integer self_delete = FALSE; // Self delete?
 
integer timed_deletion = FALSE; // Delete immediately after giving contents or hang around a bit?
 
float deletion_delay = 10.0; // Length of time to hang around in seconds (if timed_deletion is set TRUE)
 
string display_rez_text = ""; // Floating text on rez?
 
string localchat_rez_text = ""; // Chatted message on rez?
 
string ownerchat_rez_text = ""; // Chatted message only to owner on rez?
 
string display_deletion_text = ""; // Floating text before deletion?
 
string localchat_deletion_text = ""; // Chatted message before deletion?
 
string ownerchat_deletion_text = ""; // Chatted message only to owner before deletion?
 
vector rez_text_color = <1.0,1.0,1.0>; // Color of floating text if set to show on rez.
 
vector deletion_text_color = <1.0,1.0,1.0>; // Color of floating text if set to show before deletion.
 
float rez_text_alpha = 1.0; // Transparency of floating text if set to show on rez.
 
float deletion_text_alpha = 1.0; // Transparency of floating text if set to show before deletion.
 
// CHANGE ONLY THE SETTINGS ABOVE //

OnRezTextOptionsFunctionThingy(integer o)
{
    if(display_rez_text != "")
    llSetText(display_rez_text, rez_text_color, rez_text_alpha);
    if(localchat_rez_text != "")
    llSay(0, localchat_rez_text);
    if(ownerchat_rez_text != "")
    llOwnerSay(ownerchat_rez_text);
    if(!o)
    {
        integer count = 0;
        integer NOI = llGetInventoryNumber(INVENTORY_ALL);
        if(NOI)
        {
            folder_contents = [];
            do
            {
                string name = llGetInventoryName(INVENTORY_ALL, count);
                if(name == me)
                {
                    if(give_this_script)
                    folder_contents += [name];
                }
                else
                folder_contents += [name];
            }
            while((++count) < NOI);
        }
        folder_name = llGetObjectDesc();
    }
}
 
default
{
    on_rez(integer param)
    {
        owner = llGetOwner();
        me = llGetScriptName();
        OnRezTextOptionsFunctionThingy(FALSE);
    }
    touch_start(integer nd)
    {
        if(!open)
        {
            integer give = FALSE;
            key toucher = llDetectedKey(0);
            if(allow_only_owner)
            {
                if(toucher == owner)
                give = TRUE;
            }
            else
            {
                give = TRUE;
            }
            if(give)
            {
                open = TRUE;
                llGiveInventoryList(toucher, folder_name, folder_contents);
            }
            if(open)
            {
                if(display_deletion_text != "")
                llSetText(display_deletion_text, deletion_text_color, deletion_text_alpha);
                if(localchat_deletion_text != "")
                llSay(0, localchat_deletion_text);
                if(ownerchat_deletion_text != "")
                llOwnerSay(ownerchat_deletion_text);
                if(self_delete)
                {
                    if(timed_deletion)
                    llSetTimerEvent(deletion_delay);
                    else
                    llDie();
                }
                else
                {
                    open = FALSE;
                    OnRezTextOptionsFunctionThingy(TRUE);
                }
            }
        }
    }
    timer()
    {
        llDie();
    }
}

Random Item Giver

IN ITS PRESENT STATE THIS SCRIPT SHOULD NOT BE USED TO GIVE ITEMS WITH NO COPY PERMISSIONS

// V2 //
 
integer NOI;
 
default
{
    state_entry()
    {
        NOI = (llGetInventoryNumber(INVENTORY_ALL) - 1);
    }
    touch_start(integer nd)
    {
        while(nd && NOI)
        {
            string inv;
            while((inv = llGetInventoryName(INVENTORY_ALL, llRound(llFrand((float)NOI)))) == llGetScriptName());
            llGiveInventory(llDetectedKey(--nd), inv);
        }
    }
    changed(integer change)
    {
        if(change & (CHANGED_INVENTORY | CHANGED_OWNER))
        llResetScript();
    }
}

Programmable Song Player

Due the the 10 second limit on sounds we need to play whole songs as a sequence of clips. This does that.

  • You can add up to 11 (inclusive) complete songs (however many sound files there are per song) and select which to play.
  • If a song is playing you can select the next to play and a playlist is formed. The playlist can be added to at anytime during playback.
  • The volume is adjustable at anytime, including during playback.
  • Reads the song snippets from the sound files placed in the object inventory. They will be played in alphabetical/numerical order.
  • Follow the instructions at the top of the script. Very little editing is needed.
    • There is a chance that the memory will break if the playlist is made too long. V3 will include a measure against that but I have to sleep occasionally.
// V2 //
 
// This list is all you need to edit. List the names of the songs (each collection of sound files that makes one song)
// followed by the length of those sound clips (each song should contain clips of equal length)

// The list should be structured like so -

// list songs = ["First Song", 9.0, "Second Song", 9.65, "Third Song", 9.45];

// The names of the songs must be identical to some part of the sound files used for that song like so -

//// In the prim inventory (along with this script) -

////// Box_Of_Rain_wav_1
////// Box_Of_Rain_wav_2
////// Box_Of_Rain_wav_3
////// Servant 1
////// Servant 2
////// Servant 3

//// In the script -

////// list songs = ["Box_Of_Rain", 9.2, "Servant", 9.8];

// The script will play the clips in alpha/numerical order so name them wisely.

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////ONLY EDIT BELOW HERE///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
list songs = ["Box_Of_Rain", 9.2, "Servant", 9.8]; // YUP! EDIT THIS BIT ;-)
 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////ONLY EDIT ABOVE HERE///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
integer volume = 10;
 
integer lis_count;
 
integer playing;
 
integer busy;
 
integer part;
 
integer lis;
 
integer sl;
 
float delay;
 
list cancel = ["CANCEL"];
 
list playlist;
 
list waiting;
 
list song;
 
string vol_str = "Volume";
 
string song_str = "Songs";
 
string song_name;
 
list StrideOfList(list src, integer stride, integer start, integer end)
{
    list l = [];
    integer ll = llGetListLength(src);
    if(start < 0)start += ll;
    if(end < 0)end += ll;
    if(end < start) return llList2List(src, start, start);
    while(start <= end)
    {
        l += llList2List(src, start, start);
        start += stride;
    }
    return l;
}
 
list Volumes(integer vol)
{
    integer v = 0;
    list l = [];
    do
    {
        if(v != vol)
        l += [((string)v)];
    }
    while((++v) <= 10);
    return l;
}
 
PageOne(key k, integer c)
{
    llDialog(k, "\nAdjust the volume or select a song to play?", [vol_str, song_str] + cancel, c);
}
 
PlaySong(string n)
{
    song = [];
    integer c = -1;
    string name = "";
    do
    {
        if(llSubStringIndex((name = llGetInventoryName(INVENTORY_SOUND, (++c))), n) != -1)
        song += [name];
    }
    while(name);
    delay = llList2Float(songs, (llListFindList(songs, [n]) + 1));
    if((sl = llGetListLength(song)))
    {
        llPreloadSound(llList2String(song, (part = 0)));
        if(sl > 1)
        llPreloadSound(llList2String(song, 1));
        playing = FALSE;
        llSetTimerEvent(0.01);
    }
}
 
integer Chan()
{
    return llRound((llFrand(-5000000.0) + -500000.0));
}
 
float ScaleVol(integer v)
{
    return (v * 0.1);
}
 
Listen(integer c, key a)
{
    lis = llListen(c, "", a, "");
}
 
RemoveListen(integer b)
{
    llListenRemove(lis);
    lis_count = 0;
    if(b)
    busy = FALSE;
    lis = 0;
}
 
SetListenTimer(integer p)
{
    if(p)
    while(((++lis_count) * llRound(delay)) < 30);
    else
    {
        lis_count = 1;
        llSetTimerEvent(30.0);
    }
}
 
integer CheckWaitingRoom(integer c)
{
    if(waiting)
    {
        key a = llList2Key(waiting, 0);
        if(!c)
        {
            RemoveListen(0);
            Listen((c = Chan()), a);
            SetListenTimer(playing);
        }
        PageOne(a, c);
        waiting = llDeleteSubList(waiting, 0, 0);
        return 1;
    }
    return 0;
}
 
default
{
    on_rez(integer param)
    {
        llStopSound();
        llResetScript();
    }
    changed(integer change)
    {
        if(change & CHANGED_INVENTORY)
        llResetScript();
    }
    touch_start(integer nd)
    {
        while(nd)
        {
            key agent = llDetectedKey(--nd);
            if(!busy)
            {
                busy = TRUE;
                integer channel = Chan();
                SetListenTimer(playing);
                Listen(channel, agent);
                PageOne(agent, channel);
            }
            else
            {
                list a = [agent];
                if(llListFindList(waiting, a) == -1)
                waiting += a;
            }
        }
    }
    listen(integer chan, string name, key id, string msg)
    {
        if(msg != llList2String(cancel, 0))
        {
            SetListenTimer(playing);
            if(msg == vol_str)
            {
                llDialog(id, "\nChange the volume?\nThe current volume is set at \"" + ((string)volume) + "\"", cancel + Volumes(volume), chan);
                return;
            }
            if(msg == song_str)
            {
                string current = "";
                if(playlist)
                {
                    current = "\n\nThe songs currently queued are\n\"" + llList2String(playlist, 0) + "\" (currently playing)";
                    if(llGetListLength(playlist) > 1)
                    current += "\n\"" + llDumpList2String(llList2List(playlist, 1, -1), "\"\n\"") + "\"";
                }
                llDialog(id, llGetSubString(("\nSelect a song to play?" + current), 0, 500), cancel + StrideOfList(songs, 2, 0, -1), chan);
                return;
            }
            if(llListFindList(Volumes(volume), [msg]) != -1)
            {
                llAdjustSoundVolume(ScaleVol((volume = ((integer)msg))));
                PageOne(id, chan);
                return;
            }
            if(llGetListLength((playlist += [msg])) == 1)
            PlaySong((song_name = msg));
        }
        if(CheckWaitingRoom(chan))
        return;
        RemoveListen(1);
    }
    timer()
    {
        if(playlist)
        {
            if(!playing)
            {
                llSetTimerEvent(delay);
                playing = TRUE;
            }
            llPlaySound(llList2String(song, part), ScaleVol(volume));
            if((++part) == sl)
            {
                if(llGetListLength(playlist) > 1)
                {
                    song_name = llList2String((playlist = llDeleteSubList(playlist, 0, 0)), 0);
                    llSleep(delay);
                    PlaySong(song_name);
                }
                else
                {
                    llSetTimerEvent(0.0);
                    song_name = "";
                    playing = FALSE;
                    playlist = [];
                }
            }
            else if(part == (sl - 1))
            llPreloadSound(llList2String(song, 0));
            else
            llPreloadSound(llList2String(song, (part + 1)));
        }
        if(lis && (!(--lis_count)))
        {
            if(!(CheckWaitingRoom(0)))
            RemoveListen(1);
        }
    }
}

Single Prim Double Doors

Just drop the script into a fresh prim and it will become the doors.

Can be made to allow only owner use by writing the word "owner" in the prim description.

// V3 //

float auto_close = 10.0; // The time the door remains open before auto closing. Set to zero for no auto closure.

integer open;
 
OperateDoors()
{
    if(!open)
    {
        float f = 0.0;
        while((f += 0.01) <= 1.0)
        llSetLinkPrimitiveParamsFast(LINK_THIS, [9, 0, 0, <0.375,0.875,0.0>, 0.95, ZERO_VECTOR, <f,1.0,0.0>, ZERO_VECTOR]);
    }
    else
    {
        float f = 1.0;
        while((f -= 0.01) >= -1.0)
        llSetLinkPrimitiveParamsFast(LINK_THIS, [9, 0, 0, <0.375,0.875,0.0>, 0.95, ZERO_VECTOR, <f,1.0,0.0>, ZERO_VECTOR]);
    }
    llSetTimerEvent(auto_close);
    open = (!open);
}
 
default
{
    state_entry()
    {
        vector pos = llGetPos();
        llSetLinkPrimitiveParamsFast(LINK_THIS, [9, 0, 0, <0.375,0.875,0.0>, 0.95, ZERO_VECTOR, <0.0,1.0,0.0>, ZERO_VECTOR,
                                                 17, -1, TEXTURE_BLANK, <1.0,1.0,0.0>, ZERO_VECTOR, 0.0,
                                                 6, <pos.x,pos.y,(pos.z - 0.25)>,
                                                 18, -1, ZERO_VECTOR, 0.4,
                                                 8, <PI,0.0,0.0,PI>,
                                                 7, <3.0,5.0,0.01>]);
    }
    touch_start(integer nd)
    {
        if(llToLower(llGetObjectDesc()) == "owner")
        {
            while(nd)
            {
                if(llDetectedKey(--nd) == llGetOwner())
                OperateDoors();
            }
        }
        else
        OperateDoors();
    }
    timer()
    {
        llSetTimerEvent(0.0);
        if(open)
        OperateDoors();
    }
}

Give Only to Agents of an Age

Simple freebie giver that discriminates against old people. Use to allow only newer residents to grab your freebies.

  • The measure of age isn't perfect but, the worst it will be off by is a day or so.

Load the prim up with stuff (of any type (set free scripts to "Not Running")) and the script will automatically read the contents and be ready to hand them out.

// V1 //

integer noobage = 30; // Age in days upto which an agent is considered eligible.

string folder_name = "Folder"; // name of folder as it appears in the agents inventory.

///////////////////////////////////////////////////////////////////////////////////////

list inv = [];

integer Inv = 0;

integer busy = 0;

list waiting = [];

key iq = NULL_KEY;

key Agent = NULL_KEY;

integer ThankYouForTheDays(string d)
{
    return llRound((((float)llGetSubString(d, 0, 3)) * 365.25) +
                   (((float)llGetSubString(d, 5, 6)) * 30.4375) +
                   ((float)llGetSubString(d, 8, 9)));
}

integer Noob(string dob, string date)
{
    if((ThankYouForTheDays(date) - ThankYouForTheDays(dob)) <= noobage)
    return 1;
    return 0;
}

default
{
    on_rez(integer param)
    {
        llResetScript();
    }
    changed(integer change)
    {
        if(change & (CHANGED_OWNER | CHANGED_INVENTORY))
        llResetScript();
    }
    state_entry()
    {
        integer noi = llGetInventoryNumber(INVENTORY_ALL);
        string name;
        while(noi)
        {
            if((name = llGetInventoryName(INVENTORY_ALL, (--noi))) != llGetScriptName())
            inv += [name];
        }
        Inv = llGetListLength(inv);
    }
    touch_start(integer nd)
    {
        while(nd && Inv)
        {
            key agent = llDetectedKey(--nd);
            if(!busy)
            {
                busy = TRUE;
                iq = llRequestAgentData((Agent = agent), DATA_BORN);
            }
            else
            {
                if(llListFindList(waiting, [agent]) == -1)
                waiting += [agent];
            }
        }
    }
    dataserver(key q, string data)
    {
        if(q == iq)
        {
            if(Noob(data, llGetDate()))
            llGiveInventoryList(Agent, folder_name, inv);
            if(llGetListLength(waiting))
            {
                iq = llRequestAgentData((Agent = llList2Key(waiting, 0)), DATA_BORN);
                waiting = llDeleteSubList(waiting, 0, 0);
            }
            else
            busy = FALSE;
        }
    }
}

More Scripts...

If you have any comments about the content of this page please post them HERE