Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Scripting Help Please (Permissions)

Amara Twilight
Registered User
Join date: 16 Feb 2004
Posts: 47
06-24-2008 14:12
Hi there everyone!

I'm having a problem (heh what newbie scripter isn't :) ) and am hoping some kind soul here can help me out. I am trying to create an item that when touched will play an animation but the catcher is that while I want others to be able to activate it, I want the owner to be asked permission when someone clicks on it if it's ok for the animation to play and of course the standard ask permission to animate the avatar of the person clicking.

I can't find a script that does this in the library to try and hack something together. Can someone please help me and explain at least some of what is going on in the script so I can learn?

Thank you
Viktoria Dovgal
Join date: 29 Jul 2007
Posts: 3,593
06-24-2008 18:53
This will do the basic thing you asked for. A little more would need adding if the animation you are using is the looped kind that needs to be stopped, or if more than one person at a time should be animated.

CODE

// ========================================
// global stuff

// As written, this script assumes that the animation is a one shot
// "gesture" kind of animation, in other words it doesn't loop.
// The Linden-supplied dances are that type, so we'll use one.
string animation = "dance4";

integer menuchannel = -847411200; // 1943-02-24
integer menucallback; // to hold onto listens

key owner; // A place to stash the UUID so we don't have to keep looking it up.
key victim; // the person who wants to be animated, if any


// ========================================
// our own little functions, awwww!

// Set up a few things on startup-ish events
Init() {
llListenRemove(menucallback); // just in case
owner = llGetOwner();

// Set up a listener that only acknowledges our owner
// on menuchannel. The permission menu will use this later.
menucallback = llListen(menuchannel, "", owner, "");

// put this listen to sleep, we'll wake it up when we need it.
llListenControl(menucallback, FALSE);

// no animation requests are pending
victim = NULL_KEY;
}


// Don't call this one directly, use AnimationCheck so we can check on permission.
PlayAnimation(key who) {
// The agent presence check is mostly useful when the object is rezzed (not attached).
// It helps keep some error messages from being shouted around.

if (llGetAgentSize(who)) { // The avatar is still here & hasn't crashed? A miracle!
llStartAnimation(animation);
}
}


// See if we need animation permissions. If we have them, toggle the animation.
// If not, try to get permission.
AnimationCheck(key who) {
if ((llGetPermissions() & PERMISSION_TRIGGER_ANIMATION) && (llGetPermissionsKey() == who)) {
PlayAnimation(who);
}
else {
llRequestPermissions(who, PERMISSION_TRIGGER_ANIMATION);
}
}



// ========================================
// LSL events here

default {

// this one gets triggered with llRequestPermissions
run_time_permissions (integer perm) {
if (perm & PERMISSION_TRIGGER_ANIMATION) {
PlayAnimation(llGetPermissionsKey()); // whoever got permissions will be aniimated
}
}

// this one will trigger when a menu button is pressed
listen(integer channel, string name, key id, string message) {
if (channel == menuchannel) { // Is it from the menu?
llListenControl(menucallback, FALSE); // stop listening
llSetTimerEvent(0.); // stop waiting for the menu timeout, it was used.
if (message == "Yes") { // someone pressed the yes button
AnimationCheck(victim); // ask permission and do it
}
// don't really need to do anything on "No"
victim = NULL_KEY; // release the reservation
}
}

// This will happen if llSetTimerEvent is nonzero
timer() {
llSetTimerEvent(0.); // turn off timer so we don't do this every 30 seconds forever
llOwnerSay("menu timed out");
llListenControl(menucallback, FALSE); // stop listening
victim = NULL_KEY; // release the reservation
}

// each time the script is recompiled or reset
state_entry() {
Init();
}

// Any time the object is taken out of inventory (rezzed or attached),
// also when you log in if attached
on_rez(integer rezparam) {
Init();
}

// In case it's rezzed and someone buys it (the fool!)
changed (integer change) {
if (change & CHANGED_OWNER) {
Init();
}
}

touch_start(integer num_detected) {
// we'll only pay attention to the first toucher on each pass

if (victim == NULL_KEY) { // only ask if there isn't already a menu pending

victim = llDetectedKey(0); // well now there is one pending, so there.

if (victim == owner) { // no need to ask if the owner touched
AnimationCheck(owner);
victim = NULL_KEY; // can lose the reservation now
}
else {
// wake up the listener so we can hear menu responses
llListenControl(menucallback, TRUE);

// and put up a dialog.
llDialog(
owner, // send the box to owner
llDetectedName(0) + " wants to be animated, is that OK?", // and say this in the box
["Yes", "No"], // and offer these buttons
menuchannel // dialog buttons will chat here if pressed
);

// This timer is used so that we can give up on an ignored dialog
llSetTimerEvent(30.);
}
}
}
}
_____________________
Amara Twilight
Registered User
Join date: 16 Feb 2004
Posts: 47
06-24-2008 19:30
wow that looks more complicated then I thought :/ The commented sections help a lot!

Sorry I didn't realize that something else needs to be added to stop a looping animation. I thought they just looped till you stood up. What is needed and how to start/stop a looping animation?

EDIT: On a similar note is it difficult to add a one shot facial expression that will turn off at the end too?

For Instance.. I want to make a Crazy Hat that the owner can click to get a menu to do specific things like shoot fireworks out the top (I'll have 2 or 3 things) but I want the owner to also be able to turn the "touch me" on and off on the hat for others.

When it's on and someone touches the hat I want the owner to decide when to give them permission to animate. I'll have the hat fire off a particle effect on the toucher and then animate their face (from anims in the hat) into a goofy expression and start them doing something silly (which i'll animate like cartwheels in place) until they stop the animation. When the animation stops I'd like to be able to remove the expressions and cartwheels, so that's what I'm asking about here.

I'll have to figure the other stuff out (as far as the scripting goes, shouldn't be horrifically hard to create a hud to press for hat animations) and then stitch the scripts together or have them call each other when needed. :)
Viktoria Dovgal
Join date: 29 Jul 2007
Posts: 3,593
06-24-2008 19:38
It looks a lot more imposing than it really is mostly because all the comments pad it out. =)

llStopAnimation() is all you need (like with starting, you need to check permissions). It can get a little more complicated only because you have to decide what to do if someone is already animated. In this example, you wouldn't zero out the victim variable right away, instead you would hang onto that value until it was time to stop.

Do you want the next person who touches to be animated, or for the script to hold onto the same avatar until they go away or click again? And again, is this going to be like a dance ball/chimera where multiple people are animated, or is it just one at a time?

Now I get to add edits! Standing up should usually stop animations automatically, but it's not 100% reliable and it only works if the avatar was sitting (I assumed not sitting in this example since you asked about touches).

Facial expressions are easy, just start one of those express_* animations at the same time you start your own (just add a second llStartAnimation, the facial animatins are not looped so you don't need to stop them).

From: someone
When it's on and someone touches the hat I want the owner to decide when to give them permission to animate. I'll have the hat fire off a particle effect on the toucher and then animate their face (from anims in the hat) into a goofy expression and start them doing something silly (which i'll animate like cartwheels in place) until they stop the animation. When the animation stops I'd like to be able to remove the expressions and cartwheels, so that's what I'm asking about here.

Ah, OK, so the only one avatar at once? That shouldn't be bad, just a few extra lines really. Can put up a second example later. (though from what you describe, a one-shot might be the way to go)
_____________________
Amara Twilight
Registered User
Join date: 16 Feb 2004
Posts: 47
06-24-2008 20:55
LOL seems like you're having a ton of fun with this project of mine hehehe :)

I'm shooting for one person animating at a time, with the owner giving permission if s/he doesn't want the clicker to animate. I want the next person to touch it to also ask the owner permission but only after the person currently animating is tired of letting the animation run it's course.

Question: If the owner moves will the animated person follow the poseball that's attached to the hat that they touched or will they stay in place? in which case then the owner should probably be able to animate others if they left someone who went afk doing cartwheels :)

Maybe just a reset button on the hat that only resets the hat and leaves the person who is animated animating?

Thanks again for the help on this. The commented sections are a huge boon too!