-->

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();
                }
            }
        }
    }
}

llDetectedPos

default
{
    state_entry()
    {
        llSetText("llDetectedPos()\nTouch to detect pos",<1,1,1>,1);
    }
 
    touch_start(integer total_number)
    {
      llSay(0,(string)llDetectedPos(0));
    }
}

Wind On Physical Object

// Wind affects avatar clothing/hair, trees, and can affect particles and flexible prims.
// Wind "naturally" (programatically) varies in velocity and direction.
// Wind does not cause friction. (from the wiki)
//
// This script takes the vector returned by llWind, which represents the
// speed and direction of the wind at the current position (it doesnt' use any
// offset hence 'ZERO_VECTOR'),
// and applys an impulse to the object to match it, simulating the impulse that
// would be applied by the wind.
//
// It doesnt really work well unless youre object is small/light enough to be actually
// moved by the impulse. Otherwise it tends to just sit there and vibrate.
//
// Of course the '/35' is the result of my own experimentation, you will probably
// want to play with this value until it suits your own object.
 
default
{
 
        state_entry()
        {
                llApplyImpulse(llWind(ZERO_VECTOR)/35,TRUE);
                llResetScript();
        }
 
}

Springboard

default
{
    collision_start(integer total_number)
    {
        llPushObject(llDetectedKey(0), <0,100,0>, <0,0,0>, FALSE);
    }
}

Sword Script

integer SWORD = 1;
integer PUNCH12 = 2;
integer PUNCHL = 3;
integer KICK = 4;
integer FLIP = 5;
 
integer strike_type;
 
default
{
    state_entry()
    {
        llSetStatus(STATUS_BLOCK_GRAB, TRUE);
    }
    run_time_permissions(integer perm)
    {
        if (perm)
        {
                llTakeControls(CONTROL_ML_LBUTTON | CONTROL_LBUTTON | CONTROL_UP | CONTROL_FWD | CONTROL_BACK | CONTROL_ROT_LEFT | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_RIGHT | CONTROL_DOWN, TRUE, TRUE);
        }
    }
 
    attach(key on)
    {
        if (on != NULL_KEY)
        {
            integer perm = llGetPermissions();
 
            if (perm != (PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION))
            {
                llRequestPermissions(on, PERMISSION_TAKE_CONTROLS | PERMISSION_TRIGGER_ANIMATION);
            }
            else
            {
                llTakeControls(CONTROL_ML_LBUTTON | CONTROL_LBUTTON | CONTROL_UP | CONTROL_FWD | CONTROL_BACK | CONTROL_ROT_LEFT | CONTROL_LEFT | CONTROL_RIGHT | CONTROL_ROT_RIGHT, TRUE, TRUE);
            }
 
        }
        else
        {
            llSay(0, "releasing controls");
            llTakeControls(FALSE, TRUE, TRUE);
        }
    }
 
    timer()
    {
        if (  (strike_type == FLIP)
            || (strike_type == SWORD))
        {
            llSensor("", "", ACTIVE | AGENT, 4.0, PI_BY_TWO*0.5);
        }
        else
        {
            llSensor("", "", ACTIVE | AGENT, 3.0, PI_BY_TWO*0.5);
        }
        llSetTimerEvent(0.0);
    }
 
    control(key owner, integer level, integer edge)
    {
        if (level & (CONTROL_ML_LBUTTON | CONTROL_LBUTTON))
        {
            if (edge & CONTROL_UP)
            {
                llApplyImpulse(<0,0,3.5>,FALSE);
                llStartAnimation("backflip");
                llSetTimerEvent(0.25);
                strike_type = FLIP;
            }
            if (edge & CONTROL_FWD)
            {
                llStartAnimation("sword_strike_R");
                llSleep(0.5);
                llSetTimerEvent(0.25);
                strike_type = SWORD;
            }
            if (edge & (CONTROL_LEFT | CONTROL_ROT_LEFT))
            {
                llStartAnimation("punch_L");
                llSetTimerEvent(0.25);
                strike_type = PUNCHL;
            }
            if (edge & (CONTROL_RIGHT | CONTROL_ROT_RIGHT))
            {
                llStartAnimation("kick_roundhouse_R");
                llSetTimerEvent(0.25);
                strike_type = KICK;
            }
            if (edge & CONTROL_BACK)
            {
                llStartAnimation("punch_onetwo");
                llSetTimerEvent(0.25);
                strike_type = PUNCH12;
            }
            if (edge & CONTROL_DOWN)
            {
                llMoveToTarget(llGetPos(), 0.25);
                llSleep(1.0);
                llStopMoveToTarget();
            }
        }
    }
 
    sensor(integer tnum)
    {
        vector dir = llDetectedPos(0) - llGetPos();
        dir.z = 0.0;
        dir = llVecNorm(dir);
        rotation rot = llGetRot();
        if (strike_type == SWORD)
        {
            llTriggerSound("crunch", 0.5);
            dir += llRot2Up(rot);
            dir *= 200.0;
            llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
        }
        else if (strike_type == PUNCH12)
        {
            llTriggerSound("crunch", 0.2);
            dir += dir;
            dir *= 100.0;
            llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
        }
        else if (strike_type == PUNCHL)
        {
            llTriggerSound("crunch", 0.2);
            dir -= llRot2Left(rot);
            dir *= 100.0;
            llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
        }
        else if (strike_type == KICK)
        {
            llTriggerSound("crunch", 0.2);
            dir += dir;
            dir *= 100.0;
            llPushObject(llDetectedKey(0), dir, ZERO_VECTOR, FALSE);
        }
        else if (strike_type == FLIP)
        {
            llTriggerSound("crunch", 0.2);
            llPushObject(llDetectedKey(0), <0,0,150>, ZERO_VECTOR, FALSE);
        }
        strike_type= 0;
    }
}