Jump to content

Listen for specified time


Patrick Playfair
 Share

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

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

Recommended Posts

I have a HUD dispenser that rezzes HUD on collision.  The HUD then gets Experience permissions and auto-attaches.  I would like to check and see if they already have one, so that they do not attach multiple HUDS.  I have written a script using a listener to check and see if they have a HUD and IF they do, I do nothing, ELSE  I want to dispense a HUD.  Problem is if I do not get a response from a HUD, the dispenser just listens for ever,  Is there a way to LISTEN for x number of seconds, then stop?

integer myChannel;
integer Key2Number(key objKey) 
{
    return ((integer)("0x"+llGetSubString((string)objKey,-8,-1)) & 0x3FFFFFFF) ^ 0x3FFFFFFF;
}

integer handle;

default
{
    touch_start(integer num_detected) 
    {
        myChannel = Key2Number(llGetOwner()); //generate an integer based on the owner's uuid
        handle = llListen(myChannel,"","","");//start listening for someone saying anything on this special channel
        string avkey = (string) myChannel;
        llRegionSay(myChannel, "PING"); // ping for HUD on unique channel
        llSay(0,"Pinging on Channel " + avkey);
        
    }


    listen(integer channel, string name, key id, string message)
    {
          llSetTimerEvent(3.0);
          if (message == "I hear you")
            {
                llSay(0,"HUD says '" + message + "', so I don't have to do anything");
            }
          else
            {
                llSay(0,"No response, I need to REZZ a HUD");
            }
          
          
    }
    timer() 
    {
        llSay(0,"3 seconds is up");
        llListenRemove(handle);
        llSetTimerEvent(0);
    }

}
Link to comment
Share on other sites

First thing that occurs to me is that you are pinging the visitors on a unique channel... except you are not, you used llGetOwner, which will get YOUR uuid, not theirs, so it always uses a channel unique to YOU, meaning anyone with a hud within range will respond, and using regionsay that means everybody who has used the dispenser in the whole damn region..

 

You'd be better off using 1 channel for all pings but using llRegionSayTo and directing that at the uuid of the agent that touched or collided with the dispenser

Link to comment
Share on other sites

Actually, I rezzed a couple of boxes in my sandbox for testing, and used my key for  testing purposes.  I will be changing the GetOwner to GetDetected in the dispenser, and GetOwner in the HUD (which will both be the same) for the purpose of obtaining a unique channel.  I will also be changing touch start to a collision event when I am finished testing.  I am satisfied with the way everything is working, except how to DO something if no response in X amount of time.

Link to comment
Share on other sites

If you're really set on this approach of using avatar-specific channels, you'll need to open and close a whole new channel for each avatar -- that is, you'll need to llListen() every time before you ping, starting a timer, and then llListenRemove each time you either get a response or the timer expires. (Note that it's when the timer expires that you need to attach a HUD, not when you get a response to the ping.)

Now the better way to do it has already been suggested: use llRegionSayTo() on a single channel and just keep the listener active all the time. Or if there won't be all that many participants, it may be worth using llListenControl() to temporarily suspend the listener when there are no outstanding pings.

(Note also that if this is ever to scale to many participants, this whole approach needs rework, to replace the timer-per-ping with a work list of outstanding pings and their expiration times. As it stands now, a participant who arrives while another participant's ping is outstanding will restart that pending timer, so if either of them already has a HUD the other won't get one, and if neither of them has a HUD only the last to arrive will get one.)

Link to comment
Share on other sites

I have changed my test script to go ahead and use a collision event, and changed the llGetOwner to llDetected key and will repost the code.  The problem is still with the TIMER.  Although I have set a timer event, it never gets to the "no response" section.  If there is no response, I want it to tell me, but it doesn't.  I am not having trouble talking to the HUD, or receiving responses from the HUD.  Shutting down the timer when no response is received is where I am struggling here.

 

integer myChannel;integer Key2Number(key objKey) {    return ((integer)("0x"+llGetSubString((string)objKey,-8,-1)) & 0x3FFFFFFF) ^ 0x3FFFFFFF;}integer handle;default{    collision_start(integer num_detected)     {        myChannel = Key2Number(llDetectedKey(0)); //generate an integer based on the owner's uuid        handle = llListen(myChannel,"","","");//start listening for someone saying anything on this special channel        string avkey = (string) myChannel;        llRegionSay(myChannel, "PING"); // ping for HUD on unique channel        llSay(0,"Pinging on Channel " + avkey);        llSetTimerEvent(5);    }    timer()        {    llListenRemove(handle); //Stop Listening    llSetTimerEvent(0.0);    }    listen(integer channel, string name, key id, string message)    {          if (message == "I hear you")          // IF there is a response, tell me in chat            {                llSay(0,"HUD says '" + message + "', so I don't have to do anything");            }          else          // IF there is NOT a response, tell me in chat            {                llSay(0,"No response, I need to REZZ a HUD");            }    }}
Link to comment
Share on other sites

That's not what this script is doing, though. Right now its "no response" section is in the listen() handler, in a place where it will happen only if it "hears" some response other than "I hear you".

To do something in lieu of a response, that code should instead be in the timer() handler -- alongside the part where you are correctly calling llListenRemove.

Link to comment
Share on other sites

 add a flag variable mebbe?....something like...

 

 timer()        {         if(responseFlag)         llListenRemove(handle); //Stop Listening, do nothing         else        { llSay(0,"No response, I need to REZZ a HUD");          // rez hud function or code here        }           llSetTimerEvent(0.0);  
responseFlag = 0; } listen(integer channel, string name, key id, string message) { if (message == "I hear you") // IF there is a response, tell me in chat { llSay(0,"HUD says '" + message + "', so I don't have to do anything"); responseFlag = 1; } }

 

Link to comment
Share on other sites

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

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...