Don't click here unless you want to be banned.

LSL Wiki : LibrarySenWarp

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl814.us.archive.org

Functional Warper/Smooth Movement Demo


This is a warppos that is functional without using the llSetPrimitiveParams hack found in 'warppos'. As an alternative, it utilizes parallel calls to llSetPos().

There are two scripts involved; here is the first script, which is the 'master control' - you will probably want to change this a bit to suit your particular needs.

Here's a short log that helped SOMEONE anyway: (grinning)

[15:12] Sendao Goodman: There's a function in the master script
[15:12] Sendao Goodman: smoothMove( float timetilexec, float timetotake, vector moveoff, integer repeats )
[15:12] Sendao Goodman: it's sort of like llMoveToTarget
[15:12] Hewitt Huet: how to set the variables?
[15:13] Sendao Goodman: the senWarp function has an example, but
[15:13] Sendao Goodman: timetilexec and timetotake are in seconds
[15:13] Sendao Goodman: timetotake is how long it takes to get to the point
[15:13] Sendao Goodman: moveoff is a RELATIVE vector
[15:13] Sendao Goodman: (so if you want to move to a point 50,50,50 and you're at 25,25,25 you would want a moveoff of 25,25,25
[15:14] Sendao Goodman: repeats is tweakable
[15:14] Sendao Goodman: for smoothness... hm, 4 worked well

vector warppoint;
key av;

vector vecTime()
{
    vector tsp;
    list tsv;

    tsv = llParseString2List( llGetTimestamp(), ["T", ":", "Z"], [] );

    tsp.x = llList2Integer(tsv, 1) - 8;
    if( tsp.x < 0 ) {
        tsp.x += 24;
    }
    tsp.y = llList2Integer(tsv, 2);
    tsp.z = llList2Float(tsv, 3);

    return tsp;
}

vector fixTime( vector inTime )
{
    vector oTime = inTime;
    
    while( oTime.z >= 60.0 ) {
        oTime.z -= 60.0;
        oTime.y++;
    }
    while( oTime.y >= 60.0 ) {
        oTime.y -= 60.0;
        oTime.z++;
    }
    return oTime;
}



string vec2str(vector v)
{
    return (string)v.x + "," + (string)v.y + "," + (string)v.z;
}
vector str2vec(string s)
{
    list l;
    l = llParseString2List( s, [","], [] );
    return < llList2Float(l, 0), llList2Float(l, 1), llList2Float(l, 2) >;
}

smoothMove( float timetilexec, float timetotake, vector moveoff, integer repeats )
{
    vector persecond = moveoff / timetotake;
    vector vStart = vecTime();
    vStart.z += timetilexec;
    vStart = fixTime(vStart);
    
    llMessageLinked( LINK_THIS, 999, vec2str(llGetPos()) + "~" + vec2str(vStart) + "~" + vec2str(persecond) + "~" + (string)timetotake + "~" + (string)repeats, NULL_KEY );
}


senWarp( vector d )
{
    smoothMove( 1.0, 1.0, d-llGetPos(), 4 );
    llSleep(3.0); // this sleep is needed for llDie() calls to not be earlieeeeee
}

integer listkey;

default
{
    state_entry()
    {
        llSitTarget( <0,0,1>, ZERO_ROTATION );
    }

    // Rez communications example - standard rezzer/rezzed configuration, sp is a random negative number
    on_rez(integer sp)
    {
        llSitTarget( <0,0,0.1>, ZERO_ROTATION );
        if( sp != 0 ) {
            listkey = llListen(sp, "", NULL_KEY, "");
            llSay(sp, "okay");
        }
    }
    
    listen( integer ch, string nam, key id, string msg )
    {
        warppoint = str2vec(msg);
        llListenRemove(listkey); // no need to keep listening.
    }
    
    // touch_start
    // DEMO MODE - jump to 200 meters, then down to ground level
    touch_start( integer nd )
    {
        if( llDetectedKey(0) == llGetOwner() ) {
            warppoint = llGetPos();
            if( warppoint.z > llGround( warppoint ) + 30 ) {
                warppoint.z = llGround( warppoint ) + 1.0;
            } else {
                warppoint.z = llGround( warppoint ) + 200.0;
            }
        }
    }
    
    run_time_permissions( integer whocares )
    {
        llStopAnimation("sit"); // doesn't work for some reason?
        warpPos(warppoint);
        llUnSit(av); // maybe not necessary, with llDie() call
//      llDie(); // uncomment this line for oneshot teleporters
        // otherwise you'll want to call warpPos(startpos)
    }
    
    changed( integer change )
    {
        if( change & CHANGED_LINK ) {
            av = llAvatarOnSitTarget();
            llSleep(0.5);
            if( av != NULL_KEY ) {
                llRequestPermissions( av, PERMISSION_TRIGGER_ANIMATION );
            }
        }
    }
}

Put that script into an object. Then take 10 copies of this second script and put them all in the same object, same primitive, just one prim is fine. An example contents list:

MasterMover
SmoothMoveX 1
SmoothMoveX 2
SmoothMoveX 3
SmoothMoveX 4
SmoothMoveX 5
SmoothMoveX 6
SmoothMoveX 7
SmoothMoveX 8
SmoothMoveX 9
SmoothMoveX 10

Note that you can use as many of the 'SmoothMove' scripts as you want, but 10 is what I have tested with. The SmoothMove script (included below) will count the number of scripts available to it and act accordingly, so you can adjust to your particular needs. You will also want to change the MasterMove script's senWarp() function to accurately account for the number of repetitions needed per second. I would suggest that with 10 scripts approximately 4 repetitions per second are needed (this is per script btw); test to your delight. This shit is totally wicked, I'm loving it all over the rotation and movement spectrum.

vector vecTime()
{
    vector tsp;
    list tsv;

    tsv = llParseString2List( llGetTimestamp(), ["T", ":", "Z"], [] );

    tsp.x = llList2Integer(tsv, 1) - 8;
    if( tsp.x < 0 ) {
        tsp.x += 24;
    }
    tsp.y = llList2Integer(tsv, 2);
    tsp.z = llList2Float(tsv, 3);

    return tsp;
}

float timeDiffNow( vector vTarget )
{
    vector vTime = vecTime();
    return (vTarget.x - vTime.x)*3600.0 + (vTarget.y - vTime.y) * 60.0 + (vTarget.z - vTime.z);
}

vector str2vec(string s)
{
    list l;
    l = llParseString2List( s, [","], [] );
    return < llList2Float(l, 0), llList2Float(l, 1), llList2Float(l, 2) >;
}

rotation str2rot(string s)
{
    list l;
    l = llParseString2List(s, [","], []);
    return < llList2Float(l, 0), llList2Float(l, 1), llList2Float(l, 2), llList2Float(l, 3) >;
}


integer scriptid;
integer scriptcount;
countScripts()
{
    integer invcount = llGetInventoryNumber(INVENTORY_SCRIPT);
    integer i;
    string myfirstname = llList2String( llParseString2List(llGetScriptName(), [" "], []), 0 );
    string ofirstname;
    
    scriptcount=0;
    for( i = 0 ; i < invcount; ++i ) {
        ofirstname = llList2String( llParseString2List(llGetInventoryName(INVENTORY_SCRIPT, i), [" "], []), 0 );
        if( ofirstname == myfirstname ) {
            scriptcount++;
        }
    }
}

default {
    state_entry()
    {
        scriptid = llList2Integer( llParseString2List(llGetScriptName(), [" "], []), 1 );
        countScripts();
    }
    link_message( integer sp, integer num, string str, key id )
    {
        if( num == 999 ) {
            list lMsg = llParseString2List(str, ["~"], []);
            vector vStartPos = str2vec( llList2String(lMsg,0) );
            vector vStartTime = str2vec( llList2String(lMsg,1) );
            vector vDistPerSec = str2vec( llList2String(lMsg,2) );    
            float fTimeToTake = llList2Float(lMsg,3);
            integer repeats = llList2Integer(lMsg,4);
            float onecycle = fTimeToTake/(float)repeats;
            integer count;
            float secs;
            
            
            // Offset time.
            float myoffset = ( onecycle / (float)scriptcount ) * (float)scriptid;
            
            for( count = 0; count < repeats && secs < fTimeToTake; count++ ) {
                secs = -timeDiffNow( vStartTime );
                // should we be moving yet?
                while( secs < (float)count*onecycle + myoffset ) {
                    secs = -timeDiffNow( vStartTime );
                }

                if( secs > fTimeToTake ) {
                    secs = fTimeToTake;
                }
                
                llSetPos(vStartPos + ( vDistPerSec * secs ));
            }
        }
    }
}

Back to your regularly scheduled programming: ScriptLibrary
Comments [Hide comments/form]
Appears to have a height limit of 769 metres
-- ppp200-107.lns1.bne1.internode.on.net (2007-04-11 15:45:43)
Attach a comment to this page: