Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

sit 2 avs on 1 prim - Forum appeal

Cherry Hainsworth
Registered User
Join date: 31 Jul 2006
Posts: 125
01-17-2008 20:22
I know it's possible. I believe it's possible with only a short script, and I also know the method is a closely-guarded secret.

I want to write a script that will do this correctly, because people keep asking me for 'cuddle' poses & I don't want to disfigure my lovely rugs with an extra prim! I want to *share* the resultant (working) script, because I benefit so much from open-sourced work that secret scripts annoy me greatly.

Trouble is, my understanding of how permissions work is very weak. I'm posting my clumsy effort below (sorry, still haven't managed to retain the indents in this forum) in the hope that some of you better scripters will help out.

Then we'll be able to take the credit for ridding SL of its poseball clutter ... :)

CODE

string TITLE = "";
string ANIMATION;
string animation_one = "firstanimation";
string animation_two = "nextanimation";
string sit_text = "animate 2 avs";
key AVATAR;
key avatar_one;
key avatar_two;
key trigger;

key dataserver_key = NULL_KEY;

// -------------
// paste the animation parameters here
// you can get these by using Lex Neva's Sit Target Helper

// first
vector offset_one = <-0.04186, 0.20812, -0.83974>;
rotation rotation_one = <-0.06104, 0.99810, 0.00044, 0.00864>;

// second
vector offset_two = <0.36500, 0.34380, -0.83989>;
rotation rotation_two = <-0.09583, 0.99536, 0.00077, 0.00859>;

// -------------
// the sit function
sit()
{ AVATAR = llAvatarOnSitTarget();
if(llKey2Name(AVATAR) != "")
{
llRequestPermissions(AVATAR, PERMISSION_TRIGGER_ANIMATION);
}
else
{
if (llKey2Name(llGetPermissionsKey()) != "" && trigger == llGetPermissionsKey())
{
llStopAnimation(ANIMATION);
trigger = NULL_KEY;
}
}
}

// -------------


use_defaults()
{
llSetSitText(sit_text);
llSetText(TITLE,<1,1,1>,0);
}

init()
{

if(llGetInventoryNumber(INVENTORY_ANIMATION) == 0) //Make sure we actually got something to pose with.
{
llWhisper(0,"Error: No animation found. Cannot pose.");
ANIMATION = "sit";
}
else
ANIMATION = animation_one;
}

default
{
state_entry()
{
llSitTarget(offset_one, rotation_one);
init();
}

touch_start(integer detected)
{

}

changed(integer change)
{
if(change & CHANGED_LINK)
{
sit();
avatar_one = AVATAR;


if(change & CHANGED_LINK & AVATAR == avatar_one)
{
ANIMATION = animation_two;
llSitTarget(offset_two, rotation_two);
sit();
avatar_two = AVATAR;
}
}
}

run_time_permissions(integer perm)
{

AVATAR = llAvatarOnSitTarget();
if(perm & PERMISSION_TRIGGER_ANIMATION && llKey2Name(AVATAR) != "" && AVATAR == llGetPermissionsKey())
{
trigger = AVATAR;
llStopAnimation("sit");
llStartAnimation(ANIMATION);
llSetText("",<1,1,1>,0);
AVATAR = "";
}
}
}
Gordon Wendt
404 - User not found
Join date: 10 May 2006
Posts: 1,024
01-17-2008 20:37
I've never tried it but from what I know about the permissions system and the animation system couldn't you in theory have one av sit have it start the animation then after a detected sit (using CHANGED_LINK) change llSitPosition to the second position and the animation to the second animation which I think will set those for the next person but the first person will still be using the previous sit position and animation, the tricky part of that though is how to deal with either person standing up.
_____________________
Twitter: http://www.twitter.com/GWendt
Plurk: http://www.plurk.com/GordonWendt

GW Designs: XStreetSL

Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671
01-17-2008 22:19
From: Gordon Wendt
...change llSitPosition to the second position and the animation to the second animation which I think will set those for the next person...
I've been tinkering with a system like this myself, and though it's been a while since I worked on it, I seem to recall that if an av is already sitting on a prim, and a second sits on the same prim, the SitTarget is irrelevant. The second av will simply attempt a "dumb sit" on the location they right-clicked on, as though no SitTarget were set, which might potentially result in a "No suitable place to sit" response.
Dylan Rickenbacker
Animator
Join date: 11 Oct 2006
Posts: 365
01-17-2008 22:42
Sorry no idea how, but it can be done. The Pillow Talk people do it all the time.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-17-2008 23:18
To the best of my knowledge, only one avatar can sit on a prim that has a sit target set. If there are other prims in the object without sit targets, another avatar can sit on one of them IF all the sit targets are filled (otherwise they'll just pop onto the next available sit target). That's why vehicles and furniture often have an extra sit target in a non-seat prim that simply unsits the avatar because the vehicle/furniture is "full".

Now just because you may need a prim per sit target does NOT mean you need pose balls. You can just as easily use prims that are naturally a part of the build. You can have the back of a couch have a sit target, the armrest, the knob on the bottom of the leg, etc. And they can all place the sit targets so that the avatars appear to be sitting in natural positions on the furniture. It is better to put a sit target in each cushion though, because it may give a more intuitive way to choose where you sit (otherwise they might have to click on some small prim somewhere unrelated on the object, or just be happy with the natural order of sit locations), but if you don't have that and are worried about number of prims, it still might be better to put a sit target on that little button do-dad than to add a pose ball.

For a carpet? Hmm. If the carpet is normally one prim, you might just have to add invisible prims, or break it up into halves or something.

The other choice is to animate avatars without the sitting (or to grab permissions and unsit them). The downside to this is that you might not want the avatars to move around while they are posing. And that's a tricky problem unless you require that they accept control permissions, or the land/object ownership allows for pushes or something ( :-O ). I suppose you could even use an object/prim that acts like a "cage", so long as there is an easy way for the avatar to "stand up" and get out of it.
Squirrel Wood
Nuteater. Beware!
Join date: 14 Jun 2006
Posts: 471
01-17-2008 23:23
Only the first avatar who sits on a prim will "occupy" that prims sit target. Though you can shift the sit target around and have others sit on the same prim without problem, llAvatarOnSitTarget() will always return the key of the first person who sat on the prim.

So you will need to determine if there's more than one avatar sitting on your prim and then use llSetLinkPrimitiveparams to position them the way you want and then just request permission for one, start the animation, then request permission for the next and so on.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-17-2008 23:24
Oh. Here's another idea. While the first avatar is sitting on the object, you could actually do a "temp-rez" transparent object that just covers the main object. When another avatar sits, they'll actually be sitting on a temporary transparent "pose ball". The beauty of this is that temporary objects don't get deleted while someone is sitting on them, but they will as soon as the sitter gets up.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-17-2008 23:26
From: Squirrel Wood
Though you can shift the sit target around and have others sit on the same prim without problem, llAvatarOnSitTarget() will always return the key of the first person who sat on the prim.

I don't think that's true, actually. I believe you get a message like "another avatar is already sitting there," and you can't sit down. But it can APPEAR--through clever placement of sit targets--as if two avatars are sitting on the same prim. At least this is the way it used to be.
Deanna Trollop
BZ Enterprises
Join date: 30 Jan 2006
Posts: 671
01-18-2008 00:06
Two (or more) avatars *can* sit on a single prim which has a SitTarget applied, apparently so long as there is enough room for the 2nd av to sit without interpenetrating with the 1st av's collision cylinder. If you specify a <0,0,1> SitTarget offset on a default .5m cube, and two avs attempt to sit on it, the 2nd will get "No room to sit here, try another spot." However, apply a <2,0,0> offset to the same cube, the 1st av will "sit" 2m away from it, and the 2nd will be able to sit on top of the cube just fine.
Taeas Stirling
Registered User
Join date: 4 Sep 2004
Posts: 74
01-18-2008 00:15
cua Curie posted a script that does what you want. I have used it and it seems to work, I have set 4 on a one prim bench. Been a while though, your milage may vary :)

/54/f8/64644/1.html
Cherry Hainsworth
Registered User
Join date: 31 Jul 2006
Posts: 125
01-18-2008 08:09
From: Squirrel Wood
Only the first avatar who sits on a prim will "occupy" that prims sit target. Though you can shift the sit target around and have others sit on the same prim without problem, llAvatarOnSitTarget() will always return the key of the first person who sat on the prim.

So you will need to determine if there's more than one avatar sitting on your prim and then use llSetLinkPrimitiveparams to position them the way you want and then just request permission for one, start the animation, then request permission for the next and so on.


Aha ..... Here we go, looks like I'm heading for a crash course on permissions ;)
Thank you, Squirrel, this is just the sort of insight that's needed!

Taeas - I read your thread about a hundred times :o but got stuck when I tried translating it to work for 2 different anims in set positions (which, obviously, you need for a 'cuddle') & fixing the permissions issue. How did you incorporate Cua Curie's script into yours?

Deanna - blimey, really??!! You mean it might work if my cuddles are somewhat less cuddlesome?

Hewee - an invisible extra prim is the way we mere mortals (?) usually get around the issue. But it's restrictive in terms of functionality, and - as Dylan says - the Pillow Talk people do it all the time ;)

I'll be experimenting again later today .....

Thanks for all the input! :)
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-18-2008 09:58
Huh. Interesting. Okay. NVM llAvatarOnSitTarget(). Do all such avatars show up in the link set, and are some permissions (animation, control, camera, etc.) still obtained automatically for them, or is some/all of that only for the avatar "on the sit target?"
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
01-18-2008 10:54
From: Hewee Zetkin
Huh. Interesting. Okay. NVM llAvatarOnSitTarget(). Do all such avatars show up in the link set, and are some permissions (animation, control, camera, etc.) still obtained automatically for them, or is some/all of that only for the avatar "on the sit target?"
All the sitting avatars will be in the linkset, and all the usual perms will be automatically granted on request. (I do this all the time--moving seated avatars using llSetLinkPrimitiveParams--with no llSitTarget set at all. Now I want to play around with using a sit target and moving it to stay clear of the moving avatars.)
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-18-2008 15:20
Awesome. You don't even have to move the sit target. Just push an avatar away from it as soon at it is seated.

CODE

integer N_SEATS = 6;
float SIT_RADIUS = 3.0;
float SIT_HEIGHT = 0.5;
vector INITIAL_SIT_POS = <0.0, 0.0, 0.5>;
rotation INITIAL_SIT_ROT = ZERO_ROTATION;


integer nLinkPrims;

integer nextSitPos = 0;
list seatedAgents = [];
integer nSeatedAgents = 0;


integer initialized = FALSE;
init()
{
if (initialized)
{
return;
}
initialized = TRUE;

seatedAgents = [ NULL_KEY ];
integer listSize = 1;
while (2*listSize <= N_SEATS)
{
seatedAgents = (seatedAgents=[])+seatedAgents+seatedAgents;
listSize *= 2;
}
if (listSize < N_SEATS)
{
seatedAgents = (seatedAgents=[])+seatedAgents+llList2List(seatedAgents, 0, N_SEATS-listSize);
}
nSeatedAgents = 0;

nLinkPrims = llGetNumberOfPrims();
}

moveLinkElementToSitPos(integer linkIndex, integer sitPos)
{
float theta = sitPos*(TWO_PI/N_SEATS);
float xn = llCos(theta);
float yn = llSin(theta);

vector pos = <SIT_RADIUS*xn, SIT_RADIUS*yn, SIT_HEIGHT>;

vector frameX = <-xn, -yn, 0.0>;
vector frameY = <yn, -xn, 0.0>;
vector frameZ = <0.0, 0.0, 1.0>;
rotation frame = llAxes2Rot(frameX, frameY, frameZ);

llSetLinkPrimitiveParams(linkIndex, [ PRIM_POSITION, pos, PRIM_ROTATION, frame ]);
}

updateSeatedAgents()
{
integer i;

integer nCurrentAgents = llGetNumberOfPrims()-nLinkPrims;
list currentAgents = [];
for (i = 0; i < nCurrentAgents; ++i)
{
currentAgents = (currentAgents=[])+currentAgents+llGetLinkKey(nLinkPrims+1+i);
}

for (i = 0; i < nSeatedAgents; ++i)
{
key agent = llList2Key(seatedAgents, i);
if (agent != NULL_KEY)
{
if (llListFindList(currentAgents, [ agent ]) < 0)
{
seatedAgents = llListReplaceList(seatedAgents, [ NULL_KEY ], i, i);

llOwnerSay("DEBUG - Agent '"+llKey2Name(agent)+"' stood up.");
}
}
}

if (nCurrentAgents > 0)
{
integer linkElement = nLinkPrims+nCurrentAgents;
key lastAgent = llList2Key(currentAgents, -1);

if (llListFindList(seatedAgents, [ lastAgent ]) < 0)
{
seatedAgents = llListReplaceList(seatedAgents, [ lastAgent ], nextSitPos, nextSitPos);
moveLinkElementToSitPos(linkElement, nextSitPos);
++nSeatedAgents;
++nextSitPos;

llOwnerSay("DEBUG - Agent '"+llKey2Name(lastAgent)+"' sat down.");
}
}
}


default
{
state_entry()
{
init();

nextSitPos = 0;
llSitTarget(INITIAL_SIT_POS, INITIAL_SIT_ROT);
}

changed(integer changes)
{
if (changes & CHANGED_LINK)
{
updateSeatedAgents();
}
}
}


I didn't go so far as to test whether there's someone already at a position on this one, or to animate (which'll require multiple scripts if the animations are to be turned off). And you are seated in the middle of the object for a moment before you move to the correct location, but that makes it a little simpler code-wise. Enhancements to fix these left as an excercise. :-)
Cherry Hainsworth
Registered User
Join date: 31 Jul 2006
Posts: 125
01-18-2008 20:37
Oh, how cool :D

Can't play in SL tonight as I'm stuck on a PHP script .... and am going shopping tomorrow; I need the break!

Hopefully, with your guidance, we'll have our library script(s) by Sunday -
C :)
Cherry Hainsworth
Registered User
Join date: 31 Jul 2006
Posts: 125
01-20-2008 19:21
Progress report: Little progress!

It seems Pillow Talk use extra prims (hence the pillows, heh!) - though their poses are so natural, I nearly bought the shop ;)

Investigated permissions, etc, in as much detail as I could find. Learned a lot ... but, although I now 'think' I see how Cua Curie's script works, am in doubt about whether you can apply the same principle to animated sits.

BUT ...... There's still no evident reason why it can't or shouldn't work! Grrr!

Having spent the night amusing my neighbours by sitting upside-down, halfway through, and in a weird sideways position on my blasted rug, I haven't quite given up. But I am calling it a night. If anybody else is keen enough to keep experimenting with this, please let us know how you get on!

Cheers (upside-down-wise),
Cherry :/
_____________________
=================
My stuff on XSt:-
http://tinyurl.com/383mgh
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-20-2008 21:39
You'll need multiple scripts (note: not multiple PRIMS) for animating, if you plan to automatically stop animations when the avatars stand up without a dialog or anything.

I've now expanded the script I wrote above to do just this. I have a one-prim conference table prototype that will sit as many avatars as I have added helper scripts, automatically moving the avatars to sit a well-separated distance from each other around the outside of a dynamically sized circle (this is similar to several gadgets out there like MystiTool (sp?) and the Multi Gadget, only it doesn't rez chairs). All avatars are animated with a particular sitting animation. The helper scripts are paused when they haven't been allocated a sitting avatar.

It works well. Keep at it, and you'll find something that works for you too. :-)
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
01-20-2008 22:38
From: Hewee Zetkin
You'll need multiple scripts (note: not multiple PRIMS) for animating, if you plan to automatically stop animations when the avatars stand up without a dialog or anything.
So I thought, too, for the longest time. But try it without any llStopAnimation() at all and see what happens. :cool:
_____________________
Archived for Your Protection
Beezle Warburton
=o.O=
Join date: 10 Nov 2006
Posts: 1,169
01-21-2008 00:24
From: Hewee Zetkin
You'll need multiple scripts (note: not multiple PRIMS) for animating, if you plan to automatically stop animations when the avatars stand up without a dialog or anything.


Interesting. Wonder if one of the free dance things that are all over could be abused for multi-seating purposes.
_____________________
Though this be madness, yet there is method in't.
-- William Shakespeare

Warburton's Whimsies:
In SL
Apez.biz
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-21-2008 01:08
From: Qie Niangao
So I thought, too, for the longest time. But try it without any llStopAnimation() at all and see what happens. :cool:

You CAN leave avatars in bad states that way. It kinda depends on the animation (whether it is looped or not).
Beezle Warburton
=o.O=
Join date: 10 Nov 2006
Posts: 1,169
01-21-2008 01:18
From: Hewee Zetkin
You CAN leave avatars in bad states that way. It kinda depends on the animation (whether it is looped or not).


I've had that happen with poorly scripted freebie weapons and drinks.
_____________________
Though this be madness, yet there is method in't.
-- William Shakespeare

Warburton's Whimsies:
In SL
Apez.biz
Cherry Hainsworth
Registered User
Join date: 31 Jul 2006
Posts: 125
01-21-2008 06:36
From: Beezle Warburton
Interesting. Wonder if one of the free dance things that are all over could be abused for multi-seating purposes.


You're a genius. I even have a version of Evil Fool's famous script, which I customised ages ago. I'd forgotten about it.
Thanks!
_____________________
=================
My stuff on XSt:-
http://tinyurl.com/383mgh
Qie Niangao
Coin-operated
Join date: 24 May 2006
Posts: 7,138
01-21-2008 06:51
From: Beezle Warburton
Interesting. Wonder if one of the free dance things that are all over could be abused for multi-seating purposes.
Done that. It's kinda empowering to be able to animate a sim's worth of avatars on a single copy of an animation, and to be able to temp-rez on demand poseballs that have no animations inside. After I wrote mine, found a product already on the market (something like "Multi-Animation Tool";) that's described to do something similar, so never got 'round to packaging mine for sale. To be reasonably general-use, it's a non-trivial scripting effort, though (sync'd multi-avatar animations, sync'd animation *sequences*... etc.).

For these, you really do need multiple scripts, by the way, because the thing you're sitting on isn't the thing that gets permission to animate you; rather, it just positions you and acts as the trigger for the scripts in the prim with all the animations. But if the scripts are reasonably clever about it, once you've given permission for one such animation, you're good-to-go for all the others--across login sessions, etc.--till another avatar takes "your" script slot.
From: Beezle Warburton
From: Hewee Zetkin
You CAN leave avatars in bad states that way. It kinda depends on the animation (whether it is looped or not).
I've had that happen with poorly scripted freebie weapons and drinks.
Well, attachments are a different problem. For that matter, it's kinda luck-of-the-draw whether or not llStopAnimation() will get a chance to execute when the detachment attach() event occurs.

As for looped-vs-unlooped... well, I don't think so. I haven't been able to strand an avatar in a sitting animation when they stand (and an unlooped sit animation would be kinda weird, wouldn't it?)... and one of the ones I use most often is priority 4, so I'd know about it if it were still playing. ;) Of course, if you TP out while seated, it happens--but with or without that llStopAnimation. I've tried a lot of animations, looped and unlooped, different priorities, with and without llSitTarget()s--I'd really like to know if there's a way to break this.
_____________________
Archived for Your Protection
Lear Cale
wordy bugger
Join date: 22 Aug 2007
Posts: 3,569
01-21-2008 07:10
From: Beezle Warburton
I've had that happen with poorly scripted freebie weapons and drinks.


This tends to happen when taking off a worn item with animation script when in a no-script area. I've never tried to debug the root cause, but it seems that the wrong handler gets called. (Also, I noticed that if I detach version 2 xcite in a no-script area, it warns me that I've dropped it. Not sure whether this happens for later versions.)
Cherry Hainsworth
Registered User
Join date: 31 Jul 2006
Posts: 125
01-23-2008 21:35
From: Qie Niangao
I haven't been able to strand an avatar in a sitting animation when they stand (and an unlooped sit animation would be kinda weird, wouldn't it?)... and one of the ones I use most often is priority 4, so I'd know about it if it were still playing. ;) Of course, if you TP out while seated, it happens--but with or without that llStopAnimation. I've tried a lot of animations, looped and unlooped, different priorities, with and without llSitTarget()s--I'd really like to know if there's a way to break this.


Hah, I should have your problems ....

Yep, I've left myself stuck sitting and doomed to dance (which is even more surreal than sitting 'walking', especially if you have a meeting to go to!). I'd gladly replicate for you, only these entertainments are always the result of crap scripting. Not the kind of thing I treasure!

Still, next time I mess up I'll offer you the leftovers ;)
_____________________
=================
My stuff on XSt:-
http://tinyurl.com/383mgh