LlSitTarget/GetSitTarget

From Second Life Wiki
Jump to navigation Jump to search
  1. Create a box.
  2. Drop this script into box.
  3. Sit a Random Avatar (RA) on the box.
  4. Create a second box.
  5. Sit your avatar on the second box.
  6. Click the first box.
    RA on first box should move so they are sitting in your avatar, as if they were sitting on the second box.
  7. Move the second box.
    Your avatar will move with the box, the other avatar will stay floating in air.
  8. Click the first box again.
    RA should move so they are sitting in your avatar, as if they were sitting on the second box.
  9. See how this could be handy for quickly figuring out sit target offsets?
list GetSitTarget(integer prim, key av)
{//WARNING: This function is very good but not perfect. Do not repeatedly pass GetSitTarget to llSitTarget or UpdateSitTarget.
 //Do not use this on moving avatars or objects, the results will very likely be wrong.
    vector tp = llGetAgentSize(av);
    if (tp)
    {//llGetObjectDetails is used so the av is not required to be seated on the object with the sit target.
        list details = llGetLinkPrimitiveParams(prim, [PRIM_POSITION, PRIM_ROTATION]) + llGetObjectDetails(av, [OBJECT_POS, OBJECT_ROT]);
        rotation f = llList2Rot(details, 1);
        rotation r = llList2Rot(details, 3) / f;
        float fAdjust = ((((0.008906 * tp.z) + -0.049831) * tp.z) + 0.088967) * tp.z;
        return [((llList2Vector(details, 2) - llList2Vector(details, 0)) / f) + (llRot2Up(r) * fAdjust) - <0.0, 0.0, 0.4>, r];
    }
    return [];
}//Written by Strife Onizuka, size adjustment provided by Talarus Luan

//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 sit target; 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

default
{
    touch_start(integer c)
    {
        integer link = llDetectedLinkNumber(0);
        key user = llDetectedKey(0);
        list vr  = GetSitTarget(link, user);
        if (vr != [])
        {
            UpdateLinkSitTarget(link, llList2Vector(vr, 0), llList2Rot(vr, 1));
            llRegionSayTo(user, PUBLIC_CHANNEL, llList2CSV(vr));
        }
    }
}

UpdateLinkSitTarget taken from User:Strife_Onizuka/UpdateLinkSitTarget