YaK:: SecondLife Script Samples [Changes]   [Calendar]   [Search]   [Index]   [PhotoTags]   
[mega_changes]
[photos]

SecondLife Script Samples


This is from a Stalking Lava Fire, we picked up free somewhere:

// legalize it!
// or fuck off

string victim;
key target;
key sound = "awakebun";
float min = 15;
float max = 25;
integer changed_pos = FALSE;
vector start_pos = <128,128,10>;


warpPos( vector destpos)
{   //R&D by Keknehv Psaltery, 05/25/2006
    //with a little pokeing by Strife, and a bit more
    //some more munging by Talarus Luan
    //Final cleanup by Keknehv Psaltery
    // Compute the number of jumps necessary
    integer jumps = (integer)(llVecDist(destpos, llGetPos()) / 10.0) + 1;
    // Try and avoid stack/heap collisions
    if (jumps > 100 )
        jumps = 100;    //  1km should be plenty
    list rules = [ PRIM_POSITION, destpos ];  //The start for the rules list
    integer count = 1;
    while ( ( count = count << 1 ) < jumps)
        rules = (rules=[]) + rules + rules;   //should tighten memory use.
    llSetPrimitiveParams( rules + llList2List( rules, (count - jumps) << 1, count) );
}



default
{
    state_entry()
    {

        llListen(6645,"",llGetOwner() ,"");
    }
    on_rez(integer start_param)
    {


        start_pos = llGetPos();
        llPlaySound("bambagrowl",1.0);
        llOwnerSay("touch me to start scanning");
    }
    touch_start(integer num_detected)
    {
            if (llDetectedKey(0) == llGetOwner())
            {
                llSensor("",NULL_KEY,AGENT,96,PI);
            }
    }
    no_sensor()
    {
        llSay(0,"waiting...");
        state searching;
    }
    sensor(integer num)
    {
        list targets;
        integer i;
        if(num > 12)
            num = 12;
            for(i=0;i<num;i++)
        {
            targets += [llDetectedName(i)];
        }
        llDialog(llGetOwner(),"select target to trace",targets,6645);
    }
    listen(integer channel, string name, key id, string message)
    {
        victim = message;
        llOwnerSay("touch again to stop assimilation");
        state tracing;
    }
}

state tracing
{


        state_entry()
        {
                        llSetText("", <1,0,0>, 1.0);
            llSetTimerEvent(5.0);
            llSensorRepeat(victim,NULL_KEY,AGENT,96,PI,1.0);

        }
        no_sensor()
        {
            state searching;
        }
        sensor(integer num)
        {

            warpPos(llDetectedPos(0)  + <0, 0, 0> );


        }
        touch_start(integer num_detected)
        {
            if (llDetectedKey(0) == llGetOwner())
            {
                llOwnerSay("touch again to start scanning");


                state default;
            }

        }
        timer()
        {


            float time = min + llFrand(max - min);
            llSetTimerEvent(time);
        }

}



state searching
{
    state_entry()
    {
            llSetTextureAnim(FALSE | SMOOTH | PING_PONG | LOOP | REVERSE, ALL_SIDES, 1, 1, 0.70, 0.2, 0.2);
            llSetText(victim + " out of range...", <1,0,0>, 1.0);
        llSetTimerEvent(1);
    }
    timer()
    {
        llSensor(victim,NULL_KEY,AGENT,96,PI);
        if (changed_pos==FALSE)
        {
            llSetTimerEvent(4);
        } else {
            llSetTimerEvent(20);
        }
    }
    no_sensor()
    {

        if (changed_pos==FALSE)
        {
            llOwnerSay("target out of range - going back to start position " + (string)start_pos);
            warpPos(start_pos);
            changed_pos=TRUE;

        }
    }
    sensor(integer num)
    {
        vector here = llGetPos();
        string str="located "+(string)victim+" at "+(string)here;
        llOwnerSay(str);
        changed_pos=FALSE;
        llPlaySound("bambagrowl",1.0);
        state tracing;
    }
    touch_start(integer num_detected)
    {
        if (llDetectedKey(0) == llGetOwner())
        {
            llOwnerSay("touch again to start scanning");
            llSetText("no target", <1,0,0>, 1.0);
            llParticleSystem([]);
            state default;
        }

    }


}

// Azurescens Herouin

 // Simple airplane script example

// THIS SCRIPT IS PUBLIC DOMAIN! Do not delete the credits at the top of this script!

// Nov 25, 2003 - created by Andrew Linden and posted in the Second Life scripting forum
// Jan 05, 2004 - Cubey Terra - minor changes: customized controls, added enable/disable physics events
// Feel free to copy, modify, and use this script.

// Always give credit to Andrew Linden and all people who modify it in a readme or in the object description.



// assumes that the root primitive is oriented such that its
// local x-axis points toward the nose of the plane, and its
// local z-axis points toward the top

// control flags that we set later
integer gAngularControls = 0;
integer gLinearControls = 0;

// we keep track of angular history for more responsive turns
integer gOldAngularLevel = 0;

// the linear motor uses an accumulator model rather than keeping track
// of the linear control level history
vector gLinearMotor = <0, 0, 0>;

default
{
    state_entry()
    {
        llSetSitText("Fly");
        llCollisionSound("", 0.0);

        // the sit and camera placement is very shape dependent
        // so modify these to suit your vehicle
        llSitTarget(<0.6, 0.0, 0.20>, ZERO_ROTATION);
        llSetCameraEyeOffset(<-10.0, 0.0, 2.0> );
        llSetCameraAtOffset(<3.0, 0.0, 1.0> );

        llSetVehicleType(VEHICLE_TYPE_AIRPLANE);

        // weak angular deflection
         llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY, 0.1);
         llSetVehicleFloatParam(VEHICLE_ANGULAR_DEFLECTION_TIMESCALE, 1.0);

        // strong linear deflection
         llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_EFFICIENCY, 1.0);
         llSetVehicleFloatParam(VEHICLE_LINEAR_DEFLECTION_TIMESCALE, 0.2);

        // somewhat responsive linear motor
         llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_TIMESCALE, 0.5);
         llSetVehicleFloatParam(VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE, 20);

        // somewhat responsive angular motor, but with 3 second decay timescale
         llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_TIMESCALE, 0.5);
         llSetVehicleFloatParam(VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE, 3);

        // very weak friction
         //llSetVehicleVectorParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, <1000.0, 1000.0, 1000.0> ); // CUBEY - original line
         llSetVehicleVectorParam( VEHICLE_LINEAR_FRICTION_TIMESCALE, <200, 20, 20> ); // CUBEY - increased friction
         llSetVehicleVectorParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, <1000.0, 1000.0, 1000.0> );

         llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.65);  // almost wobbly - CUBEY - increased from .25 to improve stability
         llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 1.5);    // mediocre response

         llSetVehicleFloatParam(VEHICLE_BANKING_EFFICIENCY, 0.4);    // medium strength
        llSetVehicleFloatParam(VEHICLE_BANKING_TIMESCALE, 0.1);     // very responsive
        llSetVehicleFloatParam(VEHICLE_BANKING_MIX, 0.95);          // more banking when moving

        // hover can be better than sliding along the ground during takeoff and landing
        // but it only works over the terrain (not objects)
        //llSetVehicleFloatParam(VEHICLE_HOVER_HEIGHT, 3.0);
        //llSetVehicleFloatParam(VEHICLE_HOVER_EFFICIENCY, 0.5);
        //llSetVehicleFloatParam(VEHICLE_HOVER_TIMESCALE, 2.0);
        //llSetVehicleFlags(VEHICLE_FLAG_HOVER_UP_ONLY);

        // non-zero buoyancy helps the airplane stay up
        // set to zero if you don't want this crutch
        llSetVehicleFloatParam(VEHICLE_BUOYANCY, 0.2);

        // define these here for convenience later
        // CUBEY - modified these as per Shadow's prefs
        gAngularControls = CONTROL_RIGHT | CONTROL_LEFT | CONTROL_ROT_RIGHT | CONTROL_ROT_LEFT | CONTROL_BACK | CONTROL_FWD;
        gLinearControls = CONTROL_UP | CONTROL_DOWN;

        llSetStatus(STATUS_PHYSICS, FALSE); //CUBEY - ensure that physics are disabled when plane is rezzed so it doesn't fly off
    }

    changed(integer change)
    {
        if (change & CHANGED_LINK)
        {
            key agent = llAvatarOnSitTarget();
            if (agent)
            {
                if (agent != llGetOwner())
                {
                    // only the owner can use this vehicle
                    llSay(0, "You aren't the owner -- only the owner can fly this plane.");
                    llUnSit(agent);
                    llPushObject(agent, <0,0,10>, ZERO_VECTOR, FALSE);
                }
                else
                {
                    // clear linear motor on successful sit
                    gLinearMotor = <0, 0, 0>;
                     llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, gLinearMotor);

                    //llSetStatus(STATUS_PHYSICS, TRUE);
                     llSetVehicleFloatParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, 1000.0);
                     llSetVehicleFloatParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, 1000.0);
                    llRequestPermissions(agent, PERMISSION_TRIGGER_ANIMATION | PERMISSION_TAKE_CONTROLS);
                }
            }
            else
            {
                // stop the motors
                gLinearMotor = <0, 0, 0>;
                 llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, gLinearMotor);
                 llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, gLinearMotor);

                // use friction to stop the vehicle rather than pinning it in place
                //llSetStatus(STATUS_PHYSICS, FALSE);
                 llSetVehicleFloatParam(VEHICLE_LINEAR_FRICTION_TIMESCALE, 1.0);
                 llSetVehicleFloatParam(VEHICLE_ANGULAR_FRICTION_TIMESCALE, 1.0);

                // driver is getting up
                llReleaseControls();
                llStopAnimation("sit");
                llSetStatus(STATUS_PHYSICS, FALSE); //CUBEY - turn off physics to make sure the parked plane can't be moved
            }
        }

    }

    run_time_permissions(integer perm)
    {
        if (perm)
        {
            llStartAnimation("sit");
            llTakeControls(gAngularControls | gLinearControls, TRUE, FALSE);
            llSetStatus(STATUS_PHYSICS, TRUE); //CUBEY - enable physics when avatar sits
        }
    }

    control(key id, integer level, integer edge)
    {
        // only change linear motor if one of the linear controls are pressed
        vector motor;
        integer motor_changed = level & gLinearControls;
        if (motor_changed)
        {
            if(level & CONTROL_UP) //CUBEY
            {
                if (gLinearMotor.x < 0)
                {
                    gLinearMotor.x = 0;
                }
                else if (gLinearMotor.x < 30)
                {
                    gLinearMotor.x += 5;
                }
                motor_changed = TRUE;
            }
            if(level & CONTROL_DOWN) //CUBEY
            {
                if (gLinearMotor.x > 0)
                {
                    gLinearMotor.x = 0;
                }
                else if (gLinearMotor.x > -30)
                {
                    gLinearMotor.x -= 5;
                };
                motor_changed = TRUE;
            }
             llSetVehicleVectorParam(VEHICLE_LINEAR_MOTOR_DIRECTION, gLinearMotor);
        }

        // only change angular motor if the angular levels have changed
        motor_changed = (edge & gOldAngularLevel) + (level & gAngularControls);
        if (motor_changed)
        {
            motor = <0,0,0>;
            if(level & (CONTROL_RIGHT|CONTROL_ROT_RIGHT))
            {
                // add roll component ==> triggers banking behavior
                motor.x += 10;
            }
            if(level & (CONTROL_LEFT|CONTROL_ROT_LEFT))
            {
                motor.x -= 10;
            }
            if(level & (CONTROL_BACK)) // CUBEY
            {
                // add pitch component ==> causes vehicle lift nose (in local frame)
                motor.y -= 8;
            }
            if(level & (CONTROL_FWD)) // CUBEY
            {
                motor.y += 8;
            }
             llSetVehicleVectorParam(VEHICLE_ANGULAR_MOTOR_DIRECTION, motor);
        }
        // store the angular level history for the next control callback
        gOldAngularLevel = level & gAngularControls;
    }
}

This is my first pass on a ski lift.

vector Lo = <128,120,50>;
vector Hi = <10,150,110>;
vector Side = <0, -5, 0>;

integer Period = 40;
integer TTL = 600;
integer Life; // time to live
vector Corner;
float Phase;


Balloon() {
    llSetVehicleType(VEHICLE_TYPE_BALLOON);
    llSetVehicleFlags( VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT  );

    // more like a baloon
    llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 1.0);
    //llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_TIMESCALE, 3.0);
    llSetVehicleFloatParam(VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY, 0.8);

    llSetVehicleFloatParam(VEHICLE_HOVER_TIMESCALE, 1.0);
    //llSetVehicleFloatParam(VEHICLE_HOVER_TIMESCALE, 3.0);
    llSetVehicleFloatParam(VEHICLE_HOVER_EFFICIENCY, 0.8);

    // more like a plane
    llSetVehicleFloatParam(VEHICLE_BANKING_EFFICIENCY, 0.5);
    llSetVehicleFloatParam(VEHICLE_BANKING_MIX, 0.5);

    llSitTarget( <.4,0,.4>, ZERO_ROTATION );
    llSetSitText("RIDE");
    llSetCameraEyeOffset(<-3, 0, 3>);
    llSetCameraAtOffset(<2, 0, 2>);
}

SetAltitude(float alt) {
    llSetVehicleFloatParam( VEHICLE_HOVER_HEIGHT, alt );
}

vector TargetFromNormalized(float t) {
    vector b; //begin
    vector e; //end

    // This t ranges 0 .. 1
    if ( t < 0.1 ) {
        t = t / 0.1;
        b = Lo+Side;
        e = Lo;
    } else if ( t < 0.5 ) {
        t = (t+-0.1)/0.4;
        b = Lo;
        e = Hi;
    } else if ( t < 0.6 ) {
        t = (t+-.5)/.1;
        b = Hi;
        e = Hi+Side;
    } else {
        t = (t+-.6) / .4;
        b = Hi+Side;
        e = Lo+Side;
    }
    return b + t*(e-b);
}




vector TargetFromTimeOfDay(integer periodSecs) {

        integer period = periodSecs * 1000; // now in ms
        float t = llGetTimeOfDay(); // secs
        integer rem = (integer)(t*1000) % period; // ms
        t = (float)rem / (float)period; // normalized 0 .. 1

        // adjust for phase
        t += Phase;
        if (t>1) t= t+-1;

        vector targ = TargetFromNormalized(t);
        return targ;
}
SetAcceleration(vector desired_acceleration) {
    // Using Newtons Second law, thanks to lsl wiki
    //float mass = llGetMass();
    //llSetForce(mass * (desired_acceleration + <0,0,9.8>), FALSE);
    llApplyImpulse(llGetMass()*desired_acceleration,FALSE);
}
SetVel(vector velocity) {
    float clamp = 15;
    vector accel = velocity - llGetVel();
    if ( llVecMag(accel) > clamp ) {
        accel = clamp * llVecNorm(accel);
    }
    //llShout(0, "SetVel " +(string)velocity+ " Accel " + (string)accel );
    SetAcceleration( accel );
}
SetTarget(vector targ) {
    vector diff = targ - llGetPos();
    SetVel(diff); // time frame 1 sec.
}
Move() {
    vector targ = TargetFromTimeOfDay(Period);
    float dist = llVecMag( targ - llGetPos() );
    //llShout( 0, (string)dist + " ########## " + (string)( TargetFromTimeOfDay(120) ) );
    //llShout(0, "At " +(string)llGetPos()+ " To " +(string)targ );
    // TODO
    SetAltitude(targ.z);
    SetTarget(targ);
}



default
{
    on_rez(integer a) {
        Phase = (float)(a%1000)/1000.0; // phase: a from 0 to 999
        state moving;
    }
    state_entry()
    {
        llSetStatus(STATUS_PHYSICS, FALSE);
        llSay(0, "Hello, Avatar!");
    }

    touch_start(integer total_number)
    {
        llSay(0, "Touched.");
        state moving;
    }
}

state moving {
    state_entry() {
        llListen(404, "", NULL_KEY, "");
        llSetTimerEvent(1.0);
        Life = TTL;
        Corner = llGetRegionCorner();
        llSetStatus(STATUS_PHYSICS, TRUE);
        Balloon();
        Move();
    }
    timer() {
        //-- Life;//NO Longer Needed
        if (Life < 0) {
            llShout(0, "TTL Bye at " + (string)llGetPos() );
            llDie();
        }
        if (Corner != llGetRegionCorner()) {
            llShout(0, "Wrong Corner: " + (string)llGetRegionName());
            llDie();
        }

        Move();
    }
    //touch_start(integer ignore) {
    //    state default;
    //}
    listen(integer channel, string name, key id, string message) {
        llShout(404, (string)llGetPos() );
        llDie();
    }
}

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@  Above here is the seat, named "Ride Me".
@@@  Following here is the rezzer object.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

string Payload = "Ride Me";
integer N = 8;

Rez(integer a) {
    llRezObject(Payload, llGetPos()+<0,0,5>, <0,0,0>, <0,0,0,0>, a);
}

default
{
    touch_start(integer total_number)
    {
        llSay(0, "Creating ski lift");
        integer i;
        for ( i=0; i<N; i++) {
            Rez(i*1000/N);
        }
        state running;
    }
}
state running {
    touch_start(integer ignore) {
        llSay(0, "Destructing ski lift");
        llShout(404, "Die");
        state default;
    }
}


The beginnings of an Artificial Life project, a simplified Polyworld-like idea: Blue Bovine Script


// ALife by Strick Unknown; simplified Polyworld
list tape;
integer tn;
integer tp;
string prog;
integer pc;
integer chan;
integer minx;
integer maxx;
integer miny;
integer maxy;
vector f1; // closest friend
vector f2;
vector f3;
vector A; // accumulator for interp
object_move_to(vector position) {
    vector last;
    do {
        last = llGetPos();
        llSetPos(position);
    } while ((llVecDist(llGetPos(),position) > 0.001) && (llGetPos() != last));
}
critter_move_offset( vector off )
{
    if (llVecMag(off)>1.0) { off= llVecNorm(off);} // move at most 1 meter
    if (llVecMag(off)>0.1) {
        llSay(0, "off= " + (string)off );
        // turn in direction of motion
        vector reference; // = llRot2Left( llGetRot() );
        reference= <0, PI/2, 0>;
        llSay(0, "reference= " + (string)reference );
        rotation between;// = llRotBetween( llVecNorm(off), reference );
        between= llRotBetween( reference, llVecNorm(off) );
        llSay(0, "between= " + (string)between );
        llSetRot( llEuler2Rot(<0,PI/2,0>) * between );

        //llSetRot( llEuler2Rot(llRot2Up(llEuler2Rot(llVecNorm(off)))) );
        //llSetRot( (llEuler2Rot(<0,0,PI/2>) * between) * llEuler2Rot(<0,-PI/2,0>) );

    }
    vector p= llGetPos() + off;
    if (minx<=p.x && p.x<maxx && miny<=p.y && p.y<maxy) {
        float z = llGround(< 0.0, 0.0, 0.0 >);
        llSay(0, "Moving to " + (string)p );
        object_move_to( < p.x, p.y, z+2.0 > );
    } else {
        llSay(0, "Cant move offset " + (string)off );
    }
}

vector Tget(integer i) {
    return llList2Vector(tape, i);
}
Tput(integer i, vector v) {
    tape= llListReplaceList( tape, [v], i, i );
}
run_prog()
{
    // initialize tape with input values
    vector rand= < llFrand(2.0)+-1.0, llFrand(2.0)+-1.0, 0 >;
    tape = [ f1, f2, f3, rand, <0.,0.,0.>, <1.,0.,0.>, <0.,1.,0.>, <0.,0.,1.> ];
    tn = llGetListLength(tape);
    tp= 0;
    A= < 0., 0., 0. >;

    // interpret program prog
    integer n= llStringLength(prog);
    for ( pc= 0; pc < n; pc++ ) {
        string c= llGetSubString( prog, pc, pc );
        //llSay(0, "Program step " + (string)pc + " : " + c );
        if (c=="<") { tp--; if (tp<0) { tp= tn+-1;} } // regress ptr
        else if (c==">") { tp++; if (tp>=tn) { tp= 0;} } // advance ptr
        else if (c=="!") { Tput(tp, A); } // store
        else if (c=="^") { A= Tget(tp); } // recall
        else if (c=="+") { A= A + Tget(tp); } // add
        else if (c=="-") { A= -A; } // negate
        else if (c=="*") { A= 2.0 * A; } // double
        else if (c=="/") { A= 0.5 * A; } // half
        else if (c==".") { A= < A * Tget(tp), 0.0, 0.0>; } // dot product
        else if (c=="%") { A= A % Tget(tp); } // cross product
    }
    // Program finished, move by tape[tp]
    vector off= Tget(tp);
    critter_move_offset(off);
}
default
{
    state_entry()
    {
        llSay(0, "Hello, Avatar!");
        llSetTimerEvent(0);
    }

    touch_start(integer total_number)
    {
        state run;
    }
}
state run
{
    state_entry()
    {
        list tmp= llParseString2List( llGetObjectDesc(), [";"], [ ] );
        if ( 6 <= llGetListLength(tmp) ) {
            chan= (integer)llList2String(tmp, 0);
            minx= (integer)llList2String(tmp, 1);
            maxx= (integer)llList2String(tmp, 2);
            miny= (integer)llList2String(tmp, 3);
            maxy= (integer)llList2String(tmp, 4);
            prog= llList2String(tmp, 5);
        } else {
            llSay(0, "Description has not 6 fields, failing");
            state default;
        }
        llSay(0, "Running...");
        llSetTimerEvent(5);


        f1= <999., 999., 999.>;
        f2= f1;
        f3= f1;
        llSensor(llGetObjectName(), NULL_KEY, PASSIVE | SCRIPTED, 96, PI);
    }
    touch_start(integer total_number)
    {
        llSetTimerEvent(0);
        state default;
    }
    timer()
    {
        f1= <999., 999., 999.>;
        f2= f1;
        f3= f1;
        llSensor(llGetObjectName(), NULL_KEY, PASSIVE | SCRIPTED, 96, PI);
    }
    sensor(integer total_number) // total_number is the number of avatars detected.
    {
        llSay(0, (string)total_number + " " + llGetObjectName() + " detected" );
        integer i;
        vector me= llGetPos();
        float dist1= 999.;
        float dist2= 999.;
        float dist3= 999.;
        for (i = 0; i < total_number; i++)
        {
            vector p= llDetectedPos(i)-me;
            llSay(0, "Hello " + llDetectedName(i) + " offset " + (string)p );
            float mydist= llVecMag(p);
            // remember the 3 closest
            if (mydist<dist1) {
                f3=f2; dist3= dist2; f2=f1; dist2= dist1; f1=p; dist1= mydist;
            } else if (mydist<dist2) {
                f3=f2; dist3= dist2; f2=p; dist2= mydist;
            } else if (mydist<dist3) {
                f3= p; dist3= mydist;
            }
        }
        llSay(0, "f1= " + (string)f1 );
        llSay(0, "f2= " + (string)f2 );
        run_prog();
    }

    // if nobody is within 10 meters, say so.
    no_sensor() {
        llSay(0, "Nobody is around.");
        run_prog();
    }
}

(unless otherwise marked) Copyright 2002-2014 YakPeople. All rights reserved.
(last modified 2007-02-27)       [Login]
This page is referenced by the following pages:
Discussion #777 Message: 2007-01-05 19.57.51 strick