Jump to content
Wandering Soulstar

More Animation Scripting Question

Recommended Posts

It's me again 🙂

After Qie kindly clued me in on the basics of sit animation, Topic: Automatic Sit Animation, I started moving forward in the code and have come up with some additional questions as I am not clear on how parts work, even after trying to read the AVSitter code that Cindy pointed me to. Let me set the scenario and then phrase my questions:

  • I have a linkset (an Elevator).
  • As part of this set I have four prims that are where people can sit.
  • This is controlled by one single script, that identifies the links and sets the sit targets on start

My questions come as I am not certain how the animation is being started/stopped for a particular AV on a particular target. The following is my code atm for the relevant events:

    changed(integer change)
    {
        //see if we have someone sitting ...
        if (change & CHANGED_LINK)
        {
            //NUM_LINKS stored at start before anyone could be seated                       
            integer newSeated = llGetNumberOfPrims() - NUM_LINKS;
            //if no one seated turn off the open chat listen
            if (newSeated == 0 )
            {
                llListenRemove(gOpenChatHandle);
            }
            // if first seated start listen and advise
            else if (newSeated > 0 && gNumSeated == 0)
            {
                gOpenChatHandle = llListen(CHAT_CH, EMPTY_STR, NULL_KEY, EMPTY_STR);
                llWhisper(CHAT_CH, "When everyone is seated and you are ready, just say go in chat");
            }

            gNumSeated = newSeated;

            //now need to either set the pose for a newly seated AV, of stop for someone that has stood
            //first get the keys of all currently seated
            integer x;
            list newSeatedAVs = [];
            for (x = NUM_LINKS + 1; x <= NUM_LINKS + gNumSeated; x++)
            {
                //add the key to the list
                newSeatedAVs = newSeatedAVs + [llGetLinkKey(x)];
            }

            //first check to see if any AVs have stood up .. to stop their Animation
            integer curSeated = llGetListLength(gSeatedAVs);
            for (x = curSeated - 1; x > -1; x--)
            {
                if (llListFindList(newSeatedAVs, llList2List(gSeatedAVs, x, x)) == NOT_FOUND)
                {
                    //here I need to stop their Animation
                    //not clear how to target a particular AV

                    //remove the AV from the list
                    gSeatedAvs = llDeleteSubList(gSeatedAVs, x, x);
                }
            }

            //check to see if any of the currently seated AVs are truly new and need to set their anim
            for (x = 0; x < gNumSeated; x++)
            {
                if (llListFindList(gSeatedAVs, llList2List(newSeatedAVs, x, x)) == NOT_FOUND)
                {
                    //request permission to get the animation set
                    llRequestPermissions(llList2Key(newSeatedAVs, x), PERMISSION_TRIGGER_ANIMATION);
                }
            }

        }//end changed link
    }

    run_time_permissions(integer permissions)
    {
        if (perm & PERMISSION_TRIGGER_ANIMATION)
        {
            //get their key
            key user = llGetPermissionsKey();

            //add to the list
            gSeatedAVs = gSeatedAVs + [user];

            //Am assuming that this acts on the AV that I requested permisions for?
            
            ///stop the default sit
            llStopAnimation(DEF_SIT);

            //and start mine
            llStartAnimation(ELEV_STAND);          
        } 
    } 

My questions thus come at two points:

  1. In the changed event when I have detected that an AV has stood up, how do I stop the animation for that particular AV
  2. in the run_time_permissions I am assuming that I am setting the animation for the AV that I asked permission for .. correct? If not, again how to target.

 

As Always .. Thanks!

Wanda

Share this post


Link to post
Share on other sites

a script can only contain 1 set of agent (avatar) permissions at a time

when an avatar sits the script obtains their permissions

when a 2nd avatar sits then the script obtains this 2nd avatar's permissions, which removes the 1st avatar's permissions from the script

a multiple avatar seat requires 1 script for each sitter, when we want to do anything further (after the initial sit) to the avatars that require their permission

is why Cindy in the other post referred you to the AVSitter script system. Mutlti-sits are a standard feature of AVSitter. And AVSitter is the most widely used sit system in SL

this said. You can make your own. But you will need at least a sitter script for each seat

 

 

Edited by ellestones
(after the initial sit)
  • Thanks 1

Share this post


Link to post
Share on other sites

to answer your specific question about how to stop the animation

when the avatar stands then the linkset changes, so we know that they have got off. The script still has their animation permission, so we can apply the llStopAnimation to them even tho they are no longer sitting

.

Edited by ellestones
typo

Share this post


Link to post
Share on other sites

hmmm .. ok . .now this leads me to other questions <ha ha> ... if I now have a script in each of the sitter prims am I correct in my understanding that the changed event will fire in each of these four scripts when an AV sits or stands, and the way for a particular script to know it it was them that was sat on is through llAvatarOnSitTarget(), coming up null if not there and with a key if so?

Share this post


Link to post
Share on other sites

the simpliest way to do your own multi-sit is to put a script in each seat prim of the linkset. Each seat prim having a SitTarget yes

when a avatar sits on the linkset. Change event fires.  In the change event  then yes, use llAvatarOnSitTarget() as the agent key for request permissions

  • Thanks 1

Share this post


Link to post
Share on other sites

should add about this

the change event in each of the seat prim scripts will fire when any avatar sits or stands, so be careful with that. You need to check who is an existing sitter and who is the new sitter and/or stander 

Share this post


Link to post
Share on other sites

Thanks @ellestones that is what I understood:

    changed(integer change)
    {
        if(change & CHANGED_LINK)
        {
            integer num = 0;
            //see if I was sat on .. or someone that was sitting has gotten up
            key user = llAvatarOnSitTarget();
            if (user != NULL_KEY)
            {
                //they sat ... request permissions to pose them
                llRequestPermissions(user, PERMISSION_TRIGGER_ANIMATION);
                num = 1;
            }
            //if we had someone .. then they have stood up and we need to stop their animation
            else if (gCurUser != NULL_KEY)
            {
                llStopAnimation(ELEV_STAND);
                gCurUser = NULL_KEY;
                num = -1;
            }
            //advise main
            if (num != 0)
            {
                string sNum = (string)num;
                llMessageLinked(LINK_ALL_OTHERS, MAIN_CH, F_SEATED, sNum);
            }
        }
    }
    
    link_message(integer sender, integer channel, string function, key data)
    {
        if (channel == MAIN_CH)
        {
            //call from main to unseat any AV
            if (function == F_UNSEAT && gCurUser != NULL_KEY)
            {
                llUnSit(gCurUser);
                llStopAnimation(ELEV_STAND);
            }
        }
    }
    
     run_time_permissions(integer permissions)
    {
        if (permissions & PERMISSION_TRIGGER_ANIMATION)
        {
            //get their key
            gCurUser = llGetPermissionsKey();
            
            ///stop the default sit
            llStopAnimation(DEF_SIT);

            //and start mine
            llStartAnimation(ELEV_STAND);
          
        } 
    }   

 

Share this post


Link to post
Share on other sites

consider the use case where Avatar1 is already sitting. Then Avatar2 sits

the script that Avatar1 is sitting on will fire the change event also and they will be asked for permissions again (which is ok in this case) but it will also send a link message that Avatar1 has sat, even tho they are already sitting.  Same will happen with Avatar1 and Avatar2 scripts when Avatar3 sits

a fix for this can be to put a test in

Quote

changed(integer change)
{
   if (change & CHANGED_LINK)
   {
   	if ((llGetPermissionsKey() == NULL_KEY) || (llGetPermissionsKey() != llAvatarOnSitTarget()))
        {
            ... is NULL_KEY or New Avatar has sat ...

             integer num ... etc
        }
   }
}

 

 

Edited by ellestones
tpyo

Share this post


Link to post
Share on other sites

Actually, with the requirement that I have a 'sit' script in each sit prim, I have pulled the change event from the main. The code in the individual scripts is:

 

    changed(integer change)
    {
        if(change & CHANGED_LINK)
        {
            integer num = 0;
            //see if I was sat on .. or someone that was sitting has gotten up
            key user = llAvatarOnSitTarget();
            if (user != NULL_KEY)
            {
                //they sat ... request permissions to pose them
                llRequestPermissions(user, PERMISSION_TRIGGER_ANIMATION);
                num = 1;
            }
            //if we had someone .. then they have stood up and we need to stop their animation
            else if (gCurUser != NULL_KEY)
            {
                llStopAnimation(ELEV_STAND);
                gCurUser = NULL_KEY;
                num = -1;
            }
            //advise main
            if (num != 0)
            {
                string sNum = (string)num;
                llMessageLinked(LINK_ALL_OTHERS, MAIN_CH, F_SEATED, sNum);
            }
        }
    }
    

    run_time_permissions(integer permissions)
    {
        if (permissions & PERMISSION_TRIGGER_ANIMATION)
        {
            //get their key
            gCurUser = llGetPermissionsKey();
            
            ///stop the default sit
            llStopAnimation(DEF_SIT);

            //and start mine
            llStartAnimation(ELEV_STAND);
          
        } 
    }        

 

Share this post


Link to post
Share on other sites

You might also try using llLinkSitTarget and then testing llAvatarOnLinkSitTarget() to determine which avatar is seated where.  Those functions, plus llGetObjectDetails  with OBJECT_SIT_COUNT, will give you other options for being creative when you have multiple seats and multiple avs. 

Share this post


Link to post
Share on other sites

You can only create one sit target per link, which means that you can only use LSL scripting to manage one sit target.  If the object is large enough, other avatars can also sit on it, unless you have designated the object as SCRIPTED_SIT_ONLY. That can potentially confuse things. One typical way to handle multiple avs on the same object is to use Strife Onizuka's UpdateSitTarget function, which you should probably experiment with.

EDIT: I should also point out that you can use llLinkSitTarget creatively to get rid of hitchhiking avs.  Create a child prim that nobody can possibly sit on (make it tiny and bury it inside the object, possibly).  Then define a link sit target on that prim.  If someone is already seated on your visible seat, a second person will automatically be seated on the next available sit target -- that is, your hidden one.  (From the wiki: 

If an object has multiple seats (each seat has a script that sets a sit target, or the linkset has a script that assigns several llLinkSitTargets), the following method determines which sit target an avatar ends up at:

  • If the prim that is clicked on has a sit target and that sit target is not full, that sit target is used.
  • If the prim that is clicked on has no sit target, and one or more other linked prims have sit targets that are not full, the sit target of the prim with the lowest link number will be used. )

So, then you simply tell your script that if( llAvatarOnlLinkSitTarget(2) ) { llUnsit(llAvatarOnLinkSitTarget(2);  }  . 

Edited by Rolig Loon
  • Like 2

Share this post


Link to post
Share on other sites
2 hours ago, Wandering Soulstar said:

One last question .. can more than one AV sit on the same prim? i.e. do I need to do something after the first AV has seated to keep that from happening?

as Rolig mentions we can use llUnsit on any agent

is lots of ways we can design our scripts, different approaches, methods, etc

my approach is to not use SitTargets at all.  I take the same approach commonly use in danceballs, which have a controller script tracking who and when permissions are needed, x number of slave scripts to handle the individual permissions and 1 of each animation file, all in one prim of the linkset. The approach works for the different use cases. Touch to animate. Sit to animate. Collide to animate

in your first posted script you were on this approach - a controller script. Using the change event to track who sat, who got off, then passing an informational link message to the other scripts in the linkset, which is how controller + slaves method generally work by design

the controller+slave method means that we can have multiple avatars all sitting on 1 prim ( and any number of prims) at the same time, up to the number of slave scripts. When another avatar sits and we don't have a slave script for them then unsit that extra person

only the controller script has a change event. When an avatar sits on the prim, we can get their key and save it into our list of current sitting agents. Move the agent (as a linked prim) to a designated position/rotation relative to the prim. Assign the agents key to the next available slave script (link message) to handle their animation permissions. When they stand then controller sends link message to that slave script to stop animation, and then removes the agent from the list

  • Like 2

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.


×
×
  • Create New...