Jump to content

Multi-sitter animation with single script


Mollymews
 Share

You are about to reply to a thread that has been inactive for 1367 days.

Please take a moment to consider if this thread is worth bumping.

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);
        }
    }
}

 

  • Like 2
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1367 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...