Reply
Kayaker Magic
Posts: 151
Topics: 27
Registered: ‎02-12-2010
0 Kudos

How to use llAvatarOnLinkSitTarget

I'm trying to use the new llLinkSitTarget and llAvatarOnLinkSitTarget to decrease the number of scripts in a build. I have a row of theater seats that is linked into one build, and currently each child seat prim has its own script. This is because llSitTarget only sets the position and llAvatarOnSitTarget only returns the id of the avatar sitting on the calling prim. The two new functions look like they will allow me to manage all the child prim seats from a single script in the root.

I can call llLinkSitTarget in a loop to set all the seats up.

When changed() happens, I can search through all the child prims and ask llAvatarOnLinkSitTarget which seat has someone sitting on it. I have to keep a list of seated avatars so I know when one of the prims acquires or looses a sitter.

Once I know the key of a newly sat avatar, I can llRequestPermissions to animate that particular avatar.

But then I run into a problem:

run_time_permissions does not tell me WHICH avatar I just got permission to animate and llStartAnimation doesn't give me an option to specify which of them to animate. llRequestPermissions only seems to remember the permissions for one avatar at a time and calling it again releases previous permissions (according to the Wiki) and apparently also releases the previous avatar at the same time. Each script seems to have its own copy and only one copy of the currently granted permissions and avatar, so the only way to do what I want is to have one script per prim, which is how I did it before the new LinkSitTarget functions.

Is my analysis correct? Is there some other way to use the new LinkSitTarget functions?

 

low carbonated footprint
Contributor
Cerise Sorbet
Posts: 2,479
0 Kudos

Re: How to use llAvatarOnLinkSitTarget

[ Edited ]

Reply to Kayaker Magic - view message

You can use llGetPermissionsKey to learn who is holding the permissions grant right now.

You can use llDetectedKey on a touch event, or a listen key, to learn who last asked for an animation change, and run llReuqestPermissions against that key to change their poses.

Sometimes it can be easier to skip the llAvatarOnSitTarget stuff and instead loop backwards through the prims, and check something like llGetAgentSize to detect and count the avatars.

Dora Gustafson
Posts: 1,836
Registered: ‎10-05-2009
0 Kudos

Re: How to use llAvatarOnLinkSitTarget

Reply to Kayaker Magic - view message

Your analysis looks correct.
The only new thing I see is that you can have all scripts in the root prim.
A script can not hold more than one permission, so you will still need one script per permission.

The advantage of having all scripts in the root is that all scripts can use the animations contained in the root,
you don't need a set of animations in each prim.

Innula Zenovka
Posts: 6,994
Registered: ‎06-02-2009
0 Kudos

Re: How to use llAvatarOnLinkSitTarget

[ Edited ]

Reply to Kayaker Magic - view message

Would something like this work,. on the argument that the link number of whoever last sat down will always equal llGetNumberOfPrims()?

I've not tested this, and I have no idea how you would stop the animations when people get up (if that's necessary), but off the top of my head it might work.

 

list have_permissions;

//Gets the link number of a seated avatar
// useful snippet from http://wiki.secondlife.com/wiki/LlAvatarOnSitTarget
integer GetAgentLinkNumber(key avatar)
{
	integer link_num = llGetNumberOfPrims();
	while (link_num > 1) // Check only child prims.
	{
		if (llGetLinkKey(link_num) == avatar) // If it is the avatar we want
		{
			return link_num; // then return the link number
		}
		--link_num; // else go on with next child.
	}
	// Avatar wasn't found
	return FALSE; // 0 (zero) for easy testing.
}
default
{
	state_entry()
	{
		//llSay(0, "Hello, Avatar!");
	}

	changed(integer change)
	{
		if (change & CHANGED_LINK){
			key k = llGetLinkKey(llGetNumberOfPrims());
			integer max = llGetListLength(have_permissions);
			if(max){
				while(max--){
					if (GetAgentLinkNumber(llList2Key(have_permissions,max))==FALSE){//someone must have got off
						have_permissions = llDeleteSubList(max,max);// forget about them
					}
				}

			}
			if(llGetAgentSize(k)!=ZERO_VECTOR){// it's an avatar
				if(!~llListFindList(have_permissions,[k])){//and not one we have, or have had, permissions for
					llRequestPermissions(k,PERMISSION_TRIGGER_ANIMATION);// so rectify that
				}
			}


		}
	}

	run_time_permissions(integer permissions)
	{
		if (permissions & PERMISSION_TRIGGER_ANIMATION){
			have_permissions+=[llGetPermissionsKey()]; // add them to the list
			//do animation stuff
		}
	}

}

 

Rolig Loon
Posts: 24,256
Registered: ‎10-05-2009
0 Kudos

Re: How to use llAvatarOnLinkSitTarget

Reply to Kayaker Magic - view message

The newly-seated avatar is always the highest-numbered link in the linkset, so you can always get its UUID from

llGetLinkKey(llGetNumberOfPrims())

Unless each sit target is meant to have a unique animation associated with it, it really doesn't matter which prim the new arrival sat on. Just use that newly-acquired UUID to llRequestPermissions and trigger the animation.  A script can only handle one avatar's permissions at a time, but you only need the permission to trigger the animation.   Once it's going, it doesn't make any difference that the script may have turned its attention to a different seated av.  The only time it gets a little tricky is if one of the seated avs needs permission to change animations or do something else.  If that happens, you use a touch_start event to trigger a new permission request for that av.

BTW, there's a note in the wiki entry for llLinkSitTarget that you might find helpful ...

If an object has multiple seats (each seat has a script that sets a sit target with llSitTarget, 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.
Not as dumb as I look
Qie Niangao
Posts: 4,929
Registered: ‎02-25-2009
0 Kudos

Re: How to use llAvatarOnLinkSitTarget

Reply to Rolig Loon - view message

... and if there are sit targets set in the linkset and all of them are full, the avatar may or may not be seated at all, in no pattern I've been able to detect.

Another old-time mystery, related to this: "A script can only handle one avatar's permissions at a time, but you only need the permission to trigger the animation.   Once it's going, it doesn't make any difference that the script may have turned its attention to a different seated av. " In the past, it's been common practice for poseball and other animation scripts to try to llStopAnimation() when an avatar stands from the object that animated them, and for that the script would still need permission. I think this is superstitious (or obsolete?), and that simply standing from the object removes all animations triggered by scripts in the object, but I'd be very interested to learn circumstances where it's actually useful in helping to prevent stuck animations.

We know animations can be stuck even with llStopAnimation() -- it's not as if it's reliably transmitted or anything. If the avatar has left the sim already, e.g., teleported out while still seated, the script would err if it tried to stop the animation, and this seems to be to most common way of getting stuck. But maybe there are others that are somehow helped by llStopAnimation().

Innula Zenovka
Posts: 6,994
Registered: ‎06-02-2009
0 Kudos

Re: How to use llAvatarOnLinkSitTarget

Reply to Qie Niangao - view message

As I recall, llStopAnimation is, or can be,  useful if the script has been playing a looping animation of priority 4 and the avatar's AO wants to play a stand or walk animation of a lower priority.   

There's an oddity with this, though, that I would need to test.   From memory, you need not just to call llStopAnimation but also actually explicitly to start another animation (e.g. the default stand), otherwise it tends not to work.    We explored this ages ago, in the old, old Scripting Forum when I found I couldn't stop an animation; I'd have to look out the details or look at one of my scripts when I get in world (it's not something I come across very often because my business partner makes all our animations and she very rarely finds a need to use priority 4 for anything).

Rolig Loon
Posts: 24,256
Registered: ‎10-05-2009
0 Kudos

Re: How to use llAvatarOnLinkSitTarget

Reply to Qie Niangao - view message

I think things have changed subtlely in recent times, because it has been a while since I had to issue a llStopAnimation as an avatar left a sit target.  The permission seems to be released automatically, although I know this was not always the case in the past.  It certainly makes life easier if we don't need to keep track of which avatar is sitting where, and it keeps users from getting those annoying messages about PERMISSION_TRIGGER_ANIMATION not being granted. 

Not as dumb as I look
Innula Zenovka
Posts: 6,994
Registered: ‎06-02-2009
0 Kudos

Re: How to use llAvatarOnLinkSitTarget

Reply to Rolig Loon - view message

The problem comes, I think, if you're playing a looping animation when you stand up.   Something needs to stop it.   That something might be your AO, of course, but -- at least as far as I understand it -- if you've got a high priority looping animation playing when you stand up, it's likely to cause problems unless something with animation permissions stops it for you and starts to play something else.

Rolig Loon
Posts: 24,256
Registered: ‎10-05-2009
0 Kudos

Re: How to use llAvatarOnLinkSitTarget

Reply to Innula Zenovka - view message

Yes, I can see that.  In fact, I have used a trivial looping animation that keeps the avatar's right arm angled and at waist level -- for holding a teacup, for example -- and it typically does not cancel immediately when the avatar stands.  I had forgotten that because my own AO overrides it shortly anyway, but that might not happen with all AOs.  Good point.  I wonder how serious a problem this is, though? Like your partner, I rarely have high-priority looping animations to deal with, other than the teacup one.

 

Not as dumb as I look