Refactoring Strife's UpdateLinkSitTarget for clarity

Soen Eber

Vatican mole
VVO Supporter 🍦🎈👾❤
Joined
Sep 20, 2018
Messages
424
I have (tried) rewriting Strife's well-known UpdateLinkSitTarget function from her page to better understand what it is doing, and to make it more understandable for others.

If anyone with strong experience with the original function has time to review please, please do so - I need a serious vet of what I've done here to make sure I haven't boggled it to pieces, and the thing is, I've only just compiled it, not trusting myself to adequately test this the way it should be.

Instead of "improving" on the existing functionality (with added error-handling, etc) I have chosen to keep the logic and functionality the same, even when it silently fails (or allows, or corrects) for bad inputs. I don't want to break existing code with unforseen warnings for anyone who may attempt to use this in place of the original.

What Strife has done (and does) is a level above me and just about anyone else save for perhaps a handful that can be counted on with two hands.

Code:
// Sets / Updates the sit target moving the avatar on it if necessary.
// Using this while the object is moving may give unpredictable results.
// Written by Strife Onizuka, size adjustment provided by Talarus Luan
//
// Refactored for clarity by Soen Eber 9/18/2019
// I am not in the same league as these two giants; I am merely trying to better understand


// utility functions for UpdateLinkSitTarget

// return the link no the user is actually sitting on
integer primSatOn(key id)
{
    integer nPrims = llGetNumberOfPrims();
    integer ln = nPrims;
    do {
        if (id == llGetLinkKey(ln)) jump breakLoop;
    } while( --ln);
    @breakLoop;
    return ln;
}
integer isRoot(integer ln)
{
    return llGetLinkKey(ln) == llGetLinkKey(1);
}
// returns local pos & rot
list localPosRot(integer ln)
{
    return llGetLinkPrimitiveParams(ln, [PRIM_POS_LOCAL, PRIM_ROT_LOCAL]);
}
float sizeOffset(vector in_size)
{
    return ((((0.008906 * in_size.z) + -0.049831) * in_size.z) + 0.088967) * in_size.z;
}

UpdateLinkSitTarget(integer in_link, vector in_pos, rotation in_rot)
{
    //Set the sit target
    llLinkSitTarget(in_link, in_pos, in_rot);

    // check if someone is sitting on the prim
    key user = llAvatarOnLinkSitTarget(in_link);
    if (user == NULL_KEY) {
        return;
    }

    vector size = llGetAgentSize(user);
    // use the llGetAgentSize hack to verify user actually exists.
    if (size == ZERO_VECTOR) {
        // A borked sit target is rare -- unsitting helps to fix it
        llUnSit(user);
        return;
    }

    integer lnSat = primSatOn(user);

    // initialized to ZERO_VECTOR & ZERO_ROT, respectively
    vector   locPos;
    rotation locRot;
    vector   newPos;
    rotation newRot;

    if (!isRoot(in_link)) {
        list l = llGetLinkPrimitiveParams(in_link, [PRIM_POS_LOCAL, PRIM_ROT_LOCAL]);
        locPos = llList2Vector(l,0);
        locRot = llList2Rot(l,1);
    }
    newPos = ((in_pos + <0.0,0.0,0.4>-(llRot2Up(in_rot) * sizeOffset(size))) * locRot) + locPos;
    newRot = in_rot * locRot;
    llSetLinkPrimitiveParamsFast(lnSat, [PRIM_POS_LOCAL, newPos, PRIM_ROT_LOCAL, newRot]);
}

Strife's original code:
Code:
//Sets / Updates the sit target moving the avatar on it if necessary.
UpdateLinkSitTarget(integer link, vector pos, rotation rot)
{//Using this while the object is moving may give unpredictable results.
    llLinkSitTarget(link, pos, rot);//Set the sit target
    key user = llAvatarOnLinkSitTarget(link);
    if(user)//true if there is a user seated on the sittarget, if so update their position
    {
        vector size = llGetAgentSize(user);
        if(size)//This tests to make sure the user really exists.
        {
            integer linkNum = llGetNumberOfPrims();
            do
            {
                if(user == llGetLinkKey( linkNum ))//just checking to make sure the index is valid.
                {
                    //We need to make the position and rotation local to the current prim
                    list local;
                    if(llGetLinkKey(link) != llGetLinkKey(1))//only need the local rot if it's not the root.
                        local = llGetLinkPrimitiveParams(link, [PRIM_POS_LOCAL, PRIM_ROT_LOCAL]);
                    float fAdjust = ((((0.008906 * size.z) + -0.049831) * size.z) + 0.088967) * size.z;
                    llSetLinkPrimitiveParamsFast(linkNum, [
                            PRIM_POS_LOCAL, ((pos + <0.0,0.0,0.4> - (llRot2Up(rot) * fAdjust)) * llList2Rot(local, 1)) + llList2Vector(local, 0),
                            PRIM_ROT_LOCAL, rot * llList2Rot(local, 1)
                        ]);
                    jump end;//cheaper but a tad slower then return
                }
            }while( --linkNum );
        }
        else
        {//It is rare that the sit target will bork but it does happen, this can help to fix it.
            llUnSit(user);
        }
    }
    @end;
}//Written by Strife Onizuka, size adjustment provided by Talarus Luan
 
Last edited: