Jump to content
Sign in to follow this  
Mollymews

Multi-sitter animation with single script

Recommended Posts

in a conversation here

the question came up of handling animation permissions for multiple avatars sitting on an object with just one script

this is an example which demonstrates the basics of doing this
 

// this is an example of a way to handle permissions sequentially in a
// single script synchronised multi-person sitter
//
// as wrote assumes that the named animations ASit1..BSit3 are in object Contents
// also assumes that all animation names are unique
// and assumes a single page dialog menu, so MAX_SETS <= 12
// modify the code for a multi-page menu

// data for multi-person sitter. Ordered in columns (SETS) and rows
// where a column is a synchronised animation set for the sitters
// add columns (SETS) and Sitters as wanted
list Data = [
    "Chill",           "Perch",           "Laze",            // texts of menu buttons
    "ASit1",           "ASit2",           "ASit3",           // Sitter1 animation names
    <0.5,0.3,0.8>,     <0.5,0.3,0.8>,     <0.5,0.3,0.8>,     // Sitter1 positions
    <0.0,0.0,0.0,1.0>, <0.0,0.0,0.0,1.0>, <0.0,0.0,0.0,1.0>, // Sitter1 rotations
    "BSit1",           "BSit2",           "BSit3",           // Sitter2 animation names
    <0.0,-0.3,0.8>,    <0.0,-0.3,0.8>,    <0.0,-0.3,0.8>,    // Sitter2 positions
    <0.0,0.0,0.0,1.0>, <0.0,0.0,0.0,1.0>, <0.0,0.0,0.0,1.0>  // Sitter2 rotations
                                                             // add Sitter3..n as wanted
];

// max number of sitters. Must be reflected in list Data
integer MAX_SITTERS = 2;  // 2 sitters: ASit, BSit
// number of synchronised animation sets. Must be reflected in list Data
integer MAX_SETS = 3;   // 3 sets: Chill, Perch, Laze

// dialog menu channel
integer CHANNEL = -171717;  // change to whichever

// strided list for sitters: stride 2 for each sitter: [key, animation name]  
list Sitters;
// registers
integer DataIndex;
integer Handle;
integer LinkPtr;
integer SitterIndex;
integer SittersLen;

default
{   
    touch_start(integer total_number)
    {   // allow only sitters to use touch menu
        key k = llDetectedKey(0);
        integer i = llListFindList(Sitters, [k]);
        if (~i)
        {
            Handle = llListen(CHANNEL, "", k, "");
            llDialog(k, "Choose pose:", llList2List(Data, 0, MAX_SETS-1), CHANNEL);
        }
    }
    
    listen(integer channel, string name, key id, string text)
    {
        llListenRemove(Handle);
        // set index into Data as selected from the menu
        DataIndex = llListFindList(llList2List(Data, 0, MAX_SETS-1), [text]);
        // animate the sitters beginning with the first
        SitterIndex = 0;
        llRequestPermissions(llList2Key(Sitters, SitterIndex), PERMISSION_TRIGGER_ANIMATION);    
    }
     
    changed(integer change)
    {
        if (change & CHANGED_LINK)
        {
            LinkPtr = llGetObjectPrimCount(llGetKey()) + 1;  // point to 1st sitter
            integer n = llGetNumberOfPrims();
            if (LinkPtr > n)
            {  // nobody is sitting now, so tidy up
                Sitters = [];
                DataIndex = 0;
            }
            else if (n - LinkPtr == MAX_SITTERS) // too many sitters
                llUnSit(llGetLinkKey(n));
            else
            {   // we need to find who got on or off
                // first we build a new list of sitters
                // and then substitute Sitters list
                list s;
                integer i;
                for (i = LinkPtr; i <= n; i++)
                {
                    key k = llGetLinkKey(i);
                    string a;
                    integer p = llListFindList(Sitters, [k]) + 1;
                    if (p) // already sitting so copy animation name
                        a = llList2String(Sitters, p);
                    s += [k, a];
                }
                Sitters = s;
                SittersLen = llGetListLength(Sitters) / 2;
                // then animate the sitters beginning with the first
                SitterIndex = 0;
                llRequestPermissions(llList2Key(Sitters, SitterIndex), PERMISSION_TRIGGER_ANIMATION);
            }
        }
    }
    
    run_time_permissions(integer perms)
    {
        if (perms & PERMISSION_TRIGGER_ANIMATION)
        {   // current
            integer i = SitterIndex * 2 + 1;
            string a = llList2String(Sitters, i);  
            // next
            integer d = MAX_SETS * 3 * SitterIndex + MAX_SETS + DataIndex;            
            string b = llList2String(Data, d);
            if (a != b) // different animation name so change
            {   // set pos rot
                llSetLinkPrimitiveParamsFast(LinkPtr + SitterIndex, [
                    PRIM_POS_LOCAL, llList2Vector(Data, d + MAX_SETS),
                    PRIM_ROT_LOCAL, llList2Rot(Data, d + MAX_SETS * 2)]);
                // start stop animations
                llStartAnimation(b);
                if (a != "") llStopAnimation(a);
                // update Sitters with next (now current) animation
                Sitters = llListReplaceList(Sitters, [b], i, i);  
            }
            // do next sitter if any
            if (++SitterIndex < SittersLen)
                llRequestPermissions(llList2Key(Sitters, SitterIndex * 2), PERMISSION_TRIGGER_ANIMATION);
        }
    }
}

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...