Jump to content

Needing help with animation in a command listen script


Sumomo Cheri
 Share

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

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

Recommended Posts

So im trying to make a fun little sign that shows up when you call out commands in local and ticks 5 seconds or so and goes away but i also am trying to pull in animations to the script so that when the command is said your hand is placed into the hold gun animation from like the pop gun script and stops animated when the sign vanishes but im not getting it to work with out error of animation request and im at a block of knowing what to do and ive made the script into a complete mess now.

key owner;
string sound = "6f02e5e7-5025-d56c-2d35-8273e44011cc";
integer h_listen;
integer have_permissions = FALSE; 

default
{
   
    
    state_entry()
    {
           if (!have_permissions) 
        {
            llRequestPermissions(llGetOwner(),  
                PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS);   
      llOwnerSay("say !Command or !Command1 or !Command2 in local chat");
    owner = llGetOwner();
    h_listen = llListen(0,"",owner,"");
}
} 
 on_rez(integer param)
    {

    }

     run_time_permissions(integer permissions)
    {
       
        if (permissions == PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS)
        {
            if (!have_permissions)
            {
            }
            llTakeControls(CONTROL_ML_LBUTTON, TRUE, FALSE);
            llStartAnimation("hold_R_handgun");
            have_permissions = TRUE;
        }
    }

    attach(key attachedAgent)
    {
       
        if (attachedAgent != NULL_KEY)
        {
           
            llRequestPermissions(llGetOwner(),  
                PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS);   
        }
        else
        {
            if (have_permissions)
            {
                llStopAnimation("hold_R_handgun");
                llStopAnimation("aim_R_handgun");
                llReleaseControls();
                llSetRot(<0,0,0,1>);
                have_permissions = FALSE;
            }
        }
    }
   listen(integer channel,string name, key id, string msg)
   {
        if(channel==0 && llToLower(msg)=="!Command")
        {
            
        llTriggerSound(sound, 1.0);
    llRequestPermissions(llGetOwner(),  
                PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS); 
        llStartAnimation("hold_R_handgun");
        llSetLinkAlpha(LINK_SET,1,ALL_SIDES);
        llSetTexture("IMGUUID", 2);
        llSetTexture("IMGUUID", 0);
            have_permissions = TRUE;
            llSleep(5.0);
            llSetLinkAlpha(LINK_SET,0,ALL_SIDES);
             llStopAnimation("hold_R_handgun");
        }
        
        if(channel==0 && llToLower(msg)=="!command1")
        {
        llTriggerSound(sound, 1.0);
     llRequestPermissions(llGetOwner(),  
                PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS); 
        llStartAnimation("hold_R_handgun");
        llSetLinkAlpha(LINK_SET,1,ALL_SIDES);
        llSetTexture("IMGUUID", 2);
        llSetTexture("IMGUUID", 0);
            have_permissions = TRUE;
            llSleep(5.0);
            llSetLinkAlpha(LINK_SET,0,ALL_SIDES);
             llStopAnimation("hold_R_handgun");
        }
        
        if(channel==0 && llToLower(msg)=="!Command2")
        {
        llTriggerSound(sound, 1.0);
    llRequestPermissions(llGetOwner(),  
                PERMISSION_TRIGGER_ANIMATION| PERMISSION_TAKE_CONTROLS); 
        llStartAnimation("hold_R_handgun");
        llSetLinkAlpha(LINK_SET,1,ALL_SIDES);
        llSetTexture("IMGUUID", 2);
        llSetTexture("IMGUUID", 0);
            have_permissions = TRUE;
            llSleep(5.0);
            llSetLinkAlpha(LINK_SET,0,ALL_SIDES);
             llStopAnimation("hold_R_handgun");
        
        }

    }

}

 

Link to comment
Share on other sites

Okay, first off, your permissions request is really only necessary once. I'd put it in the state_entry block.

You can also leave out the | PERMISSION_TAKE_CONTROLS and all control related functions, really, if all you want to do is show a sign, as you're not really needing mouselook to do any of this stuff. The thing is, you're adapting the popgun script, and you'll want to leave out anything unnecessary. I've used the popgun to make lots of things, so I'mma try to clean it up some and show you how I'd do it...


string sound = "6f02e5e7-5025-d56c-2d35-8273e44011cc";
string animation = "hold_R_handgun";

default
{
   changed(integer change)
   {
       if(change & CHANGED_OWNER)
       {
        llResetScript();
       }
    }

    state_entry()
    {
      llSetLinkAlpha(LINK_SET,0,ALL_SIDES);
      llPreloadSound(sound);
      llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION);   
      llOwnerSay("say start or stop in local chat");
      llListen(0,"",llGetOwner(),"");
}
 on_rez(integer param)
    {
      llResetScript();
    }

   listen(integer channel,string name, key id, string msg)
   {
      string message = llToLower(msg);
      key owner = llGetOwner();
      if (!owner) {
       return;
       }
        else
        if(message == "start")
        {
        llPlaySound(sound, 1.0);
        llStartAnimation(animation);
        llSetLinkAlpha(LINK_SET,1,ALL_SIDES);
        llSetTimerEvent(5.0);
        }
        else
        if(message == "stop")
        {
        llSetLinkAlpha(LINK_SET,0,ALL_SIDES);
        llStopAnimation(animation);
        }
    }
    timer()
        {
        llSetLinkAlpha(LINK_SET,0,ALL_SIDES);
        llStopAnimation(animation);
        }
}

This might try to cause an error on compiling, cos I'm just typing it up quickly, but it's to get you closer to the right idea... It might have a mistake or two. Mind you I've also taken the liberty of simplifying it to pretty much the bare bones, so you can see the basic functions at work. Saying "start" should begin the animation, make the sign visible, and leave it up for 5 seconds before putting it away again, and "stop" ends the animation prematurely and puts the sign away in case you just want to stop early. I put the normal ending of the 5-second pause in a timer event instead of using llSleep() because if the script is asleep it can't hear chat commands.

If you're wanting to do different textures for different signs with the "!command1" or "!command2" thing, you can do that easily by recycling what's there. I just kept it simple... ^-^; Notice how different it is than the original popgun script; while I myself learned a lot from that old thing, eventually you'll start thinking in terms of effects you wish to produce and stringing them together without having to adapt scripts with unnecessary effects and functions in them. ^-^ You're off to a decent start though!

Also, always remember to use "else" between "if" statements if they're in a row, or you'll end up not really being able to do half of them when you use the chat commands, even if it compiles. It'll treat everything before the final "if" as if it doesn't exist.

Hope this helps make things a little simpler, and if you need any more help with it, just ask. ^-^

Edited by Berksey
cleaning it up some
  • Like 1
Link to comment
Share on other sites

@Berksey Sorry to be picky, but I would cut

      key owner = llGetOwner();
      if (!owner) {
       return;
       }

from the script.   You don't need that test, since you've set the listener to listen to the owner only, and I'm not at all sure what (if anything) the test if(!owner) means.   I know you mean 

if(id != llGetOwner() 

but, if it were necessary (which it isn't here) you'd have to write it out in full.   You can use if(uuid) to test that uuid is a valid key, but you can't use if(!uuid) for anything, as far as I know.   See the .wiki article on keys for further details.

@Sumomo Cheri Do you have to use 0, the public chat channel, for this?   The open listener on 0 means that, every time anyone on the region says anything in open chat, the simulator has to check to see if the person is the object's owner.   If it is, then the simulator has to check if the owner is within 20 metres of the object and, if she is, then the script has to evaluate whether what it's just heard is a valid command or not.  That's a lot of unnecessary work for the simulator, and it's why it's generally considered very bad practice to have scripts listen all the time on 0 without a good reason.

Also, I would strongly advise you not to use llSleep as a lazy way to set up a timer.  It won't do much harm here, except that it renders the second test, 

        if(message == "stop")
        {
        llSetLinkAlpha(LINK_SET,0,ALL_SIDES);
        llStopAnimation("hold_R_handgun");
        }

completely superfluous since during the 5 seconds the script is sleeping, it can't do anything if you issue the stop command.   After 5 seconds, it's going to stop the animation and hide the sign anyway, so there's no point in having a separate command to stop things early.

Far better to stop the animation in a timer event in the normal course of things, but leave yourself the option of stopping the animation and the timer in the listen event, too..

I mention this partly because I think using llSleep as a timer is a really bad habit to get into.   It almost always has unexpected consequences, and certainly almost every time someone asks me to fix a script and it contains llSleep when a timer would be more appropriate, that's what's causing the problem.

To my mind, you should use llSleep only for very short periods, when you want to make sure something can't happen until something else has had time to do something (e.g. the simulator has had time to register the uuid of something you've just rezzed by script).   Normally I expect to call llSleep for no more than 0.2 seconds, if that.   If you want to call it for anything over a second or two, it's always going to be safer to use a timer.

(Sorry,  I'll get off my soap box now).

 

  • Like 1
Link to comment
Share on other sites

@Innula Zenovka: Yeah I knew it wasn't perfect probably, I'm a night owl and I'd just logged on... ^-^; but cool, I was actually wondering if I should bother with that bit, as it's kept RegionSayTo from working a few times on things, anyway... That's way simpler and makes good sense, Innula, thank you~! Also, I never knew that thing about channel 0 either, so thanks for mentioning it, that's good to know.

Yeah, I've found it's just like that with llSleep, you really only want to use it to stop anything else happening while, say, an animation finishes playing, or to let a particle explosion finish before using llDie to delete the firecracker or whatever. Timer events are totally the way to go if you're just trying to set a timer on something.

I was making edits for like a half an hour, so at some point I did drop all the sleeps it had in it... by then I had dropped all the sleeps in me too, so I was a little more on the ball. xD

I knew once the experts got here it would all get sorted proper!

@Sumomo Cheri: Your AO is probably using high-prioroty animations, i.e., it's overriding the animation for the sign. This is common, and most of the time the best workaround is just to turn the AO off for anything else that's using an animation.

Edited by Berksey
timer event, not timer, lol
Link to comment
Share on other sites

@BerkseyThe way the simulator handles listeners -- which is not always intuitive -- is summarised in the notes in the wiki article on llListen.   That was written before llRegionSayTo became available, so really needs revising to reflect the fact llRegionSayTo is always the most economical means of communication if you're sending the message to a particular object/avatar.

I see I was mistaken on the order of events -- the simulator performs the distance check before testing for filters, so it's even worse than I thought -- if you have an open listener on 0, every time anyone on the region says anything in public chat, the simulator calculates the distance between the avatar and every object on the region that's listening on 0.   That's potentially a lot of calculations going on all the time.

  • Like 1
Link to comment
Share on other sites

I think you can use the Take_Controls stuff if you want your script to work in no script areas?

I'm not real sure, and it's been a long time, but it used to be something like...

// no script area hack?

state_entry { if(llGetAttached()) llRequestPermissions(llGetOwner(), PERMISSION_TAKE_CONTROLS); }
attach(key k) { if(k) llRequestPermissions(llGetOwner(), PERMISSION_TAKE_CONTROLS); }
run_time_permissions(integer p) { if (p & PERMISSION_TAKE_CONTROLS) llTakeControls(CONTROL_FWD, TRUE, TRUE); }
control(key k, integer l, integer e) {}

  • Like 3
Link to comment
Share on other sites

Yes.  The wiki article on llTakeControls explains 

Quote

If a script has taken controls, it and other scripts in the same prim will not be stopped if the Agent enters a "No Outside Scripts" parcel. This is done to keep vehicle control alive and AOs functional. This is an intentional feature.

The script does have actually to call llTakeControls for this to work -- simply requesting permission to take controls isn't sufficient.  The script doesn't, though, need a control event.

  • Like 1
Link to comment
Share on other sites

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