-->

FoxSan's 3D Tools and LSL Script Repository

Tons of LSL scripts, examples and 3D tools, free for all. There are currently 207 scripts and articles in this database.

Magic Blocks

A fun toy and made by Philip Linden!  Hours of very fun, and pleasure.
Click and drag the block to position.  Block will snap into position when near other blocks.
Click and quickly release to make a new block above the old.

SOUND UUID 's
color = 8e9a7375-2a49-6e81-ec26-c6140891333d
off = bac3e333-9624-4b1a-ade2-d2b01d5960aa
on = 271e6a0f-0a76-230b-011e-f78a55e80c36
pulse = 21b2d9ef-8329-bb72-9eaf-35702e876797

NOTE: You will need to re-assemble this all and edit the scripts because I cannot include sounds in this post ;)

vector pos;
vector found_pos;
vector start_touch_pos;
vector diff;
vector scale;
string name_detected;
 
vector PULSE_COLOR = <1,1,1>;
 
float GRAB_ALPHA = 0.5;
float INC = 2.0;                    // Grid spacing for snap, scale
float MAX_INC = 2.5;                // Biggest dimension
 
list colors = [<1,0,0>, <0,1,0>, <0,0,1>,
                <0,1,1>, <1,0,1>, <1,1,0>];
 
//list tones = ["piano_1", "piano_3", "piano_5"];
 
vector color;
integer color_index = 0; 
 
integer CHANNEL = 3442;
integer pulse = FALSE;
integer inhibit = FALSE;
float INHIBIT_DELAY = 2.0;
float DECAY_FACTOR = 0.5;
 
send_pulse()
{
    // Change color briefly and transmit a neural 'pulse'
    inhibit = TRUE;
    llSetTimerEvent(INHIBIT_DELAY);
    //integer tone = llRound(llFrand((float)(llGetListLength(tones) - 1)));
    //llTriggerSound(llList2String(tones, tone), 1.0);
    llSetColor(PULSE_COLOR, ALL_SIDES);
    llSetObjectName("Magic Block P");
    llWhisper(CHANNEL, "pulse");
}
 
vector vec_round(vector vec, float inc)
{
    //  Rounds vector components to the nearest units of inc
    vec *= 1.0/inc;
    vec.x = ((float)llRound(vec.x));
    vec.y = ((float)llRound(vec.y));
    vec.z = ((float)llRound(vec.z));
    vec *= inc;
    return vec;
}
 
set_pos()
{
   //
   //  On finding a neighbor, snap relative to neighbor
   //
   pos = llGetPos();
    llSetColor(color*0.5, ALL_SIDES);
    diff = pos - found_pos;
    diff = vec_round(diff, INC/2.0);
    diff += found_pos;
    llSetPos(diff);
    llTriggerSound("on", 1.0);
    llSetColor(color, ALL_SIDES);
}
 
vector new_color()
{
    integer num_colors = llGetListLength(colors);
    color_index++;
    if (color_index >= num_colors) color_index = 0;
    return llList2Vector(colors, color_index);
}
 
snap()
{
    //  Issues the sensor to look for nearby blocks to snap to
    float range = 3.0;
    llSensor("Magic Block", "", PASSIVE | SCRIPTED, range, 2.0*PI);
}
 
default
{
    state_entry()
    {
        scale = llGetScale();
        color = new_color();
        llSetColor(color, ALL_SIDES);
        llSetStatus(STATUS_BLOCK_GRAB, FALSE);
        llSetBuoyancy(1.0);
        llListen(CHANNEL, "", "", "pulse");
    }
 
    on_rez(integer param)
    {
        found_pos = llGetPos();
        set_pos();
        snap();
    }
 
    timer()
    {
        llSetObjectName("Magic Block");
        llSetTimerEvent(0.0);
        inhibit = FALSE;
        llSetColor(color, ALL_SIDES);
    }
 
    changed(integer change)
    {
        if (change == CHANGED_SCALE)
        {
            scale = llGetScale();
            scale = vec_round(scale, INC);
            if (scale.x == 0.0) scale.x = INC;
            if (scale.y == 0.0) scale.y = INC;
            if (scale.z == 0.0) scale.z = INC;
            if (scale.x > MAX_INC) scale.x = MAX_INC;
            if (scale.y > MAX_INC) scale.y = MAX_INC;
            if (scale.z > MAX_INC) scale.z = MAX_INC;
            llSay(0, "new scale = " + (string)scale);
            llSetScale(scale);
            // Choose a new color for the block
            snap();
        }
    }
 
    touch_start(integer total_number)
    {
        start_touch_pos = llGetPos();
        llSetAlpha(GRAB_ALPHA, ALL_SIDES);
        llTriggerSound("on", 1.0);
        llResetTime();
        llSetStatus(STATUS_PHYSICS, FALSE);
    }
    touch_end(integer total_number)
    {
        llSetStatus(STATUS_PHYSICS, FALSE);
        llSetAlpha(1.0, ALL_SIDES);
        vector moved = llGetPos() - start_touch_pos;
 
        if (llGetTime() < 0.3)
        {
            //  Cycle colors on short click
            llSetPos(start_touch_pos);
            llTriggerSound("color", 1.0);
            color = new_color();
            llSetColor(color, ALL_SIDES);
        }
        else if (llVecMag(moved) < (INC/10.0))
        {
            llSetPos(start_touch_pos);
            send_pulse();
        }
        else
        {
            // Try to find a block to stick to!
            llSetColor(color, ALL_SIDES);
            snap();
        }
        llSetRot(<0,0,0,1>);
    }
 
    listen(integer channel, string name, key id, string message)
    {
        // Received neural pulse, so sense sender's distance
        if (!inhibit)
        {
            pulse = TRUE;
            llSensor("Magic Block P", id, PASSIVE | SCRIPTED, 10.0, 2.0*PI);
        }
    }
 
    no_sensor()
    {
        pulse = FALSE;
    }
    sensor(integer num_detected)
    {
        if (!pulse)
        {
            //
            //  Rotate/snap to nearest box
            //
            //  Issue scale request to this box
            //
            found_pos = llDetectedPos(0);
            set_pos();
        }
        else
        {
            //
            //  Gauge distance to nearest box, decide whether to 'fire'
            //
            pulse = FALSE;
            pos = llGetPos();
            found_pos = llDetectedPos(0);
            diff = pos - found_pos;
            // probability of neural firing is related to distance
            float distance = llVecMag(diff);
            if (distance > 0.0)
            {
                if (distance < INC)
                //if (llFrand(1.0) < ((INC/(distance*distance))*DECAY_FACTOR))
                {
                    send_pulse();
                }
            }
        }
    }
}

Blacklisted: Mouse Pointer Follower

This item has been blacklisted by Linden Labs and if you want to have that funny mouse pointer to follow you again, you will have to assemble it yourself.

If you need the image itself, let me know in-world.

IMAGE UUID : 11e80daf-116f-9b43-3ad6-64f4c932e7ab

Script 1: “Cross’ Particle Function Script”

updateparticles()
{
    llParticleSystem( [
 
        PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_DROP,    // DROP, EXPLODE, ANGLE, ANGLE_CONE, ANGLE_CONE_EMPTY
 
        PSYS_SRC_MAX_AGE, 0.0,                        // How long the emitter runs, 0 should be indefinite
        PSYS_PART_MAX_AGE, 0.65,                       // How long each particle lives, max 30 seconds
        PSYS_SRC_BURST_RATE, 0.5,                     // Interval between generating bursts of particles, in seconds
        PSYS_SRC_BURST_PART_COUNT, 3,              // How many particles to generate with each burst
 
        PSYS_SRC_BURST_RADIUS, 0.0,                   // How far from the source to generate particle bursts, m (not compatible with FOLLOW_SRC)
        PSYS_SRC_BURST_SPEED_MIN, 1.0,                // Minimum speed of generated particles, m/s
        PSYS_SRC_BURST_SPEED_MAX, 1.0,                // Maximum speed of generated particles, m/s
        //PSYS_SRC_ACCEL, < 0, 0, 0 >,                // Particle acceleration vector, m/s
 
        //PSYS_SRC_ANGLE_BEGIN, 0,                    // Angle (in radians) specifying a cone where particles ARE NOT generated
        //PSYS_SRC_ANGLE_END, 0,                      // Angle (in radians) specifying a cone where particles ARE generated
        //PSYS_SRC_OMEGA, < 0, 0, 0 >,                // Angular velocity for ANGLE patterns
 
        PSYS_PART_START_ALPHA, 0.5,                 // Start alpha for particles, 0-1
        //PSYS_PART_END_ALPHA, 1.0,                   // End alpha for particles, 0-1
        PSYS_PART_START_SCALE, < 0.15, 0.2, 0>,      // Start diameter of particles, m
        //PSYS_PART_END_SCALE, < 0.1, 0.1, 0>,        // End diameter of particles, m
        PSYS_PART_START_COLOR, < 1, 1, 1 >,         // Start color of particles
        //PSYS_PART_END_COLOR, < 1, 1, 1 >,           // End color of particles
        PSYS_SRC_TEXTURE, (string)"mouse_pointer",               // Name (or key) of texture to use on particles
 
        //PSYS_SRC_TARGET_KEY, (key) "",              // Particles move towards the object who's key is specified
 
        PSYS_PART_FLAGS,
 
            //PSYS_PART_BOUNCE_MASK |                 // Particles bounce off of the plane of the emitter's z-axis height
            PSYS_PART_EMISSIVE_MASK |               // Particles glow fullbright instead of reflecting light
            PSYS_PART_FOLLOW_SRC_MASK |             // Particles position remains relative with the source, ie. they move with it
            //PSYS_PART_FOLLOW_VELOCITY_MASK |        // Particles rotate to point their vertical axis in the direction of motion
            //PSYS_PART_INTERP_COLOR_MASK |           // Particles interpolate color and alpha from start to end
            //PSYS_PART_INTERP_SCALE_MASK |           // Particles interpolate scale from beginning to end
            //PSYS_PART_TARGET_POS_MASK |             // Particles move towards target defined in PSYS_SRC_TARGET_KEY
            //PSYS_PART_TARGET_LINEAR_MASK |          // Particles move in straight line to target (unofficial?)
            //PSYS_PART_WIND_MASK |                   // Particles are affected by in-world wind
 
        0 ]
    ) ;
}
 
default
{
    state_entry()
    {
        updateparticles() ;
    }
 
    touch_start(integer total_number)
    {
        llResetScript() ;
    }
}

Script 2: “Swarm Follower Script 1.2 (no colorchange)”

vector gvMyOffset = < 1, 0, 0 > ;       // The starting position, relative to the avatar
 
float gfSpinRate = 5 ;                  // The rate at which the objects should revolve, in degrees / second
 
integer gbIsFalling = FALSE ;           // Is the object currently dropping?
 
integer giLostOwner = FALSE ;           // I WANT MY MOMMY!!!!
 
default
{
    state_entry()
    {
        gvMyOffset *= llEuler2Rot( < 0, 0, llFrand( 360 ) > ) ;     // Randomly pick a new starting point somewhere around the avatar.
        gvMyOffset.z = llFrand( 2 ) - 0.75 ;                        // Randomly choose a starting height offset.
 
        llSetStatus( STATUS_PHYSICS | STATUS_PHANTOM, TRUE ) ;
        llCollisionSound( "", 0 ) ;
 
        llListen( 4340, "", llGetOwner(), "" ) ;
        llSensorRepeat( "", llGetOwner(), AGENT, 50, PI, 1 ) ;
    }
 
    on_rez( integer param )
    {
        llSetStatus( STATUS_PHYSICS, FALSE ) ;
        llResetScript() ;
    }
 
    sensor( integer num_detected )
    {
        llSetTimerEvent( 0 ) ;          // Stop the kill timer
        giLostOwner = FALSE ;
 
        vector targetpos = llDetectedPos( 0 ) ;
        vector destination = targetpos + gvMyOffset * llDetectedRot( 0 ) ; // Calculate target pos
 
        llMoveToTarget( destination, 1 ) ;
 
        gvMyOffset *= llEuler2Rot( < 0, 0, 5 * DEG_TO_RAD > ) ;     // Rotate the offset for next sensor pulse
 
        if ( gvMyOffset.z >= 1.0 )
        {
            gbIsFalling = TRUE ;
        }
 
        else if ( gvMyOffset.z <= -1.0 )
        {
            gbIsFalling = FALSE ;
        }
 
        if ( gbIsFalling == TRUE )
        {
            gvMyOffset.z -= llFrand( 0.25 ) ;
        }
 
        else
        {
            gvMyOffset.z += llFrand( 0.25 ) ;
        }
    }
 
    no_sensor()
    {
        if( !giLostOwner )
        {
            giLostOwner = TRUE ;
            llSetTimerEvent( 60 ) ;
        }
    }
 
    timer()
    {
        llDie() ;
    }
 
    listen( integer channel, string name, key id, string message )
    {
        if( message == "die" )
        {
            llDie() ;
        }
    }
 
}

Animated Shark Head

This object starts to flap it’s jaw and play a laughing sound while worn and while you are typing. Include all these scripts in your object. You will need to add your own “check if typing” script. Easy enough :D

default
{
 state_entry()
 {
 llSetPrimitiveParams([PRIM_TYPE, PRIM_TYPE_SCULPT, "f2151490-db9c-bb10-2048-c423b43aa5d1", PRIM_SCULPT_TYPE_SPHERE]);
 }
 on_rez(integer start_param)
 {
 state default;
 }
 link_message(integer from, integer num, string action, key id)
 {
 if(action == "talk")
 {
 state Toggled;
 }
 }
}
 
state Toggled
{
 state_entry()
 {
 llSetTimerEvent(0.1);
 }
 on_rez(integer start_param)
 {
 state default;
 }
 link_message(integer from, integer num, string action, key id)
 {
 if(action == "stop")
 {
 llSetTimerEvent(0);
 state default;
 }
 }
 timer()
 {
 llMessageLinked(LINK_SET, 0, "anim", NULL_KEY);
 llSetTimerEvent(0.9);
 }
 
}

(more…)

Play sound while typing

default
{
    link_message(integer from, integer num, string action, key id)
    {
        if(action == "anim")
        {
            llLoopSound("25365198-05c6-c97b-c849-e5573fe38d92",1);
        }
        if(action == "stop")
        {
            llStopSound();
        }
    }
}

Content Giver to Group with invite

//deliver collar
//deliver sub ao
//offer group membership
 
key rcpt;
string groupID = "45d71cc1-17fc-8ee4-8799-7164ee264811";
 
key collarhttpid;
key aohttpid;
string baseurl = "http://collardata.appspot.com/dist/deliver";
 
default
{
    state_entry()
    {
        rcpt = llGetOwner();
        collarhttpid = llHTTPRequest(baseurl, [HTTP_METHOD, "POST"], "objname=OpenCollar\nrcpt=" + (string)rcpt);
        aohttpid = llHTTPRequest(baseurl, [HTTP_METHOD, "POST"], "objname=OpenCollar Sub AO\nrcpt=" + (string)rcpt);
 
        string url = "secondlife:///app/group/" + groupID + "/about";
        llInstantMessage(rcpt, "The OpenCollar group gives you access to exclusive collar designs and compatible toys.  To join the OpenCollar group, click this link:\n" + url);        
 
    }
 
    http_response(key id, integer status, list meta, string body)
    {
        if (id == collarhttpid)
        {
            if (status == 200)
            {
                llInstantMessage(rcpt, "OpenCollar should be delivered in the next 30 seconds.");
            }
        }
        else if (id == aohttpid)
        {
            if (status == 200)
            {
                llInstantMessage(rcpt, "OpenCollar Sub AO should be delivered in the next 30 seconds.");
            }
        }
    }        
 
    on_rez(integer param)
    {
        llResetScript();
    }
}