Jump to content

llStopAnimation stops wrong animation when avatar is sitting


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

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

Recommended Posts

I have a very weird problem that I'm trying to hunt down.

I have created wine glasses that can be "picked up" from the table by clicking it. Basically there's a giver on the table that looks like the glass. If you click the glass on the table, it rezzes the glass from inside. The giver and the glass communicate with each other. If you press the giver a second time, the glass gets a message to detach. As both look the same you get the impression that you can by clicking the same spot pick the glass up and put it back down again.

Case 1: The glass has a code to play a holding animation when attached, and to stop playing that animation when it gets detached. I can stand in the room, and click the glass, picking it up and putting it down over and over. No problems whatsoever. The animations start and stop as they are supposed to.

Case 2: Now I do the same when sitting on a prim. Again, I can click the glass over and over again, everything is fine. 

Case 3: I do it again when sitting on a prim, but the prim loops a sitting animation when the avi is sitting down. When I then start clicking the glass, things go down south fast. At some point, pretty randomly, the llStopAnimation of my glass will cause the sitting animation of the prim to disappear. It's called by name in the llStopAnimation call, and the glass knows nothing about the sitting animation.

It appears like the llStopAnimation sometimes stops the wrong animation when an avatar is sitting on a prim, and the prim has a looped animation playing. I wanted to blame it on AVsitter first, but then decided to make a small sitter script that launches the animation. It still breaks.

This is the sitter script:

Quote

integer Sitting = FALSE;
key Sitter = NULL_KEY;
string Anim = "SEbento-Fsit11";

default {
    state_entry() {
        llSitTarget(<0.0, 0.0, 0.1>, ZERO_ROTATION);
        Sitting = FALSE;
        Sitter = NULL_KEY;
    }

    changed(integer change) {
        if (change & CHANGED_LINK) { 
            key av = llAvatarOnSitTarget();
            if (av)  {
                llSay(0, "Hello " + llKey2Name(av) + ", thank you for sitting down");
                Sitter = av;
                Sitting = TRUE;
                llRequestPermissions(av, PERMISSION_TRIGGER_ANIMATION);
            }
            else {
                llSay(0, "Standing up ...");
                Sitting = FALSE;
                if(Sitter)
                    llRequestPermissions(Sitter, PERMISSION_TRIGGER_ANIMATION);
            }
        }
    }
    
    run_time_permissions(integer perms) {
        if(perms & PERMISSION_TRIGGER_ANIMATION) {
            if(Sitting) {
                llSay(0, "Starting anim.");
                llStartAnimation(Anim);
            }
            else {
                llSay(0, "Stopping anim.");
                llStopAnimation(Anim);
            }
        }
    }
}

Here's the only part of the code of the glass that handles animations:

Notes:

CalledFromListen: Means that the glass has received a message that requested it to report its status and detach itself (the giver has been clicked while the glass was attached). That code then calls llRequestPermission(PERMISSION_ATTACH), and in turn I call llDetachFromAvatar() after having the permission.
CalledFromDetach: attach(0) called llRequestPermission(PERMISSION_TRIGGER_ANIMATION), stop the animations that we started
CalledFromAttach: attach(>0) called llRequestPermission(PERMISSION_TRIGGER_ANIMATION), start the holding animation
CalledFromSip: sipping subroutine called llRequestPermission(PERMISSION_TRIGGER_ANIMATION), trigger the sipping animation.
clearCallStats() simply sets those CalledFrom* back to FALSE.
No other place in the code of the script has any llStartAnimation() or llStopAnimation() call, they are only started or stopped from within run_time_permissions.

Quote

    run_time_permissions(integer perms) {
        if(perms & PERMISSION_ATTACH) {
            if(CalledFromListen) {
                clearCallStats();
                llDetachFromAvatar();
                return;
            }
        
            // Otherwise attaching ...
            if(!isAttached)
                llAttachToAvatarTemp( ATTACH_RHAND );
        }
        
        if(perms & PERMISSION_TRIGGER_ANIMATION) {

            if(!isAttached) { // if not attached at all and we end up here, do nothing. should not happen
                clearCallStats();
                return;
            }
                
            if(CalledFromDetach) {
                if(isSipping) {  // just in case
                    llStopAnimation(AnimSipping);
                }
                
                llStopAnimation(AnimHolding);                
            }
            else if(CalledFromAttach) {
                llStartAnimation(AnimHolding);   
            }
            else if(CalledFromSip) {
                llStartAnimation(AnimSipping);
            }

            clearCallStats();
        }
    }

 

I have to add that this behaviour is not 100% predictable. I'd say on average 2 out or 3 times the code works exactly how it is supposed to, and the sitting animation remains functional. 

So I'm quite at a loss here.

The attached screenshots demonstrate the behaviour.

(And forgive the awkward looks of the avi, I detached everything else that may start animations so the debug output animation list is easier to read. 🙂)

 

 

 

 

 

1 - After Sitting Down.PNG

2 - After pickup glass.PNG

3 - After dropping Glass.PNG

Edited by Lilly Kiyori
picture sequence was wrong
Link to comment
Share on other sites

6 hours ago, Qie Niangao said:

Could it be somehow related to this old and very strange Jira about llStopAnimation ?

(I admit I've been lazy and haven't tested nor even looked at the code yet; I just find that jira so freaky.)

Probably, yes. It's a huge bug that has apparently been ignored for almost 4 years now. It makes even halfways basic functionalities that involve animations impossible. You can't even have a sitting avi pick up and drop an object that comes with an animation without the sit to break. It's plain nuts that this isn't being fixed. It's like selling a car, but when you take in food at the drive-in the tyres go flat.

I currently can't imagine a productive way to work around this, except that all wine glasses have to somehow broadcast to all seats on detach, where a script somehow tries to get AVsitter to restart the current animation. Which would be sort of a big pain.

Edited by Lilly Kiyori
Link to comment
Share on other sites

Well, this is the most awkward workaround I have yet coded, it looks ugly (because the avi starts to assume the root position), and it is a blatant race condition, but it's the only thing I see that can be done right now.

I've made a small hack into [AV]sitA. If there already was a sitter on this script id and the pose is known, this restarts the animation without popping the menu back at the user. Unfortunately, 90075 does that, and I didn't find another link message that did.
 

integer RestartOnly = FALSE;


....

default
{
	...
    link_message(integer sender, integer num, string msg, key id)
    {
		...
        if (num == 99998) {
            if(MY_SITTER != NULL_KEY && MY_SITTER == id) {
                RestartOnly = TRUE;
                llRequestPermissions(MY_SITTER, PERMISSION_TRIGGER_ANIMATION);
            }
            return;
        }
		...
	}
	---
    run_time_permissions(integer perm)
    {
		...
	        else if (!MTYPE)
            {
				...
                else
                {
                    if(RestartOnly)
                        RestartOnly = FALSE;
                    else
                        llMessageLinked(LINK_SET, 90005, (string)animation_menu_function, llDumpList2String([CONTROLLER, MY_SITTER], "|")); // 90005=send menu to user
                }
			---
			}
		}
	}
}

A second small script listens in the same prim as the [AV]sitA scripts, and relays any detached message:

 

integer BraindeathChannel = -66996690;
integer Listen = -1;
string AKey = "";

default
{
    state_entry() {
        Listen = llListen(BraindeathChannel, "", NULL_KEY, "");
    }


    listen(integer channel, string name, key id, string message) {
        AKey = message;
        llSetTimerEvent(1);
    }
    
    timer() {
        llMessageLinked(LINK_THIS, 99998, "", AKey);
        llSetTimerEvent(0);
    }
}

 

On detach, the glasses broadcast their holder's UUID on that braindeath channel. All [AV]sitA X scripts get a linked message by the second script that prompts them to see whether they have the avi seated that just detached something, and if yes they restart the current animation. That's the minimally invasive hack I could come up with. It still sucks when the original position of the animations is far from the adjusted position, because for example the AVIs start floating in the air and then get pushed back down, but at least nothing breaks to the point that the user has to stand up and sit down again or do an annoying manual interaction.

 

 

 

  • Thanks 1
Link to comment
Share on other sites

4 hours ago, Lilly Kiyori said:

I'm not aware of a way to start animations via UUID. Can you enlighten me?

Best, Lilly

You can't start an animation using it's UUID, but you can stop an animation with one.

If you need to find the UUID of the animation, either use the 'Copy Asset UUID' function in the viewer, or see here: https://wiki.secondlife.com/wiki/LlGetInventoryKey#Notes

Link to comment
Share on other sites

4 hours ago, Jenna Huntsman said:

You can't start an animation using it's UUID, but you can stop an animation with one.

If you need to find the UUID of the animation, either use the 'Copy Asset UUID' function in the viewer, or see here: https://wiki.secondlife.com/wiki/LlGetInventoryKey#Notes

Same behaviour if I wrap the names in the llStopAnimation calls with llGetInvontoryKey().

Link to comment
Share on other sites

This is the bug Qie linked to above.

I did further testing and verified that when an attachment that is animating you is detached, any object that has a higher value key that also is animating you, whether attached, rezzed or sat on will have its animations stopped.

  • Like 1
  • Thanks 2
Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 765 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...