Jump to content

Dropping llOwnerSay strings? (RLV)


LailaSystem
 Share

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

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

Recommended Posts

Hey, 

I'm currently trying to send RLV command using llOwnerSay through menu buttons 

The issue i'm having is that the first time i click the menu button nothing happens, the second time the bool i have in there switches but the command isnt sent, the third time i click it the bool flips again and the command is sent 

meaning i have in this case, far touch restricted but my boolean saying it is false (not restricted) and i had to click it three times... 

any help would be highly appreciated

key owner;
key toucher; 
key locker; 

list MainM = ["Lock/Unlock","Owners","--"];
list LockerM = ["Lock/Unlock","Owners","RLV Options"];
list OwnersM = ["Add Primary", "Remove Primary", "--"];
list RLVM = ["Far Touch","Touch Self","Touch Others","Touch World","<BACK>","TEST"];

integer Channel = 1234567;
integer handle; 
integer hasOwner = FALSE; 
integer islocked = FALSE;

integer far = FALSE;
integer self = FALSE;
integer others = FALSE; 
integer world = FALSE;


MainMenu(key id)
{
    handle = llListen(Channel,"","","");
    llDialog(id,"Main Menu", MainM,Channel);
}

OwnersMenu(key id) 
{
    handle = llListen(Channel,"","","");
    llDialog(id,"Owners Menu", OwnersM,Channel);
}

LockerMenu(key id)
{
        handle = llListen(Channel,"","","");
        llDialog(id,"Locker Menu", LockerM,Channel);
}

RLVMenu(key id)
{
        handle = llListen(Channel,"","","");
        llDialog(id,"RLV Menu", RLVM, Channel);
}

RLVUnlock()
{
    llOwnerSay("Unlocked");
    llOwnerSay( "@clear");
    owner = ""; 
    llSetLinkPrimitiveParamsFast(2, [PRIM_DESC, "iamunlocked"]);
    islocked = FALSE;
    far = FALSE;
    self = FALSE;
    others = FALSE; 
    world = FALSE;
    llListenRemove(handle);
}

RLVLock()
{
    llOwnerSay("Locked");
    llOwnerSay( "@remoutfit=n" );
    llOwnerSay( "@remattach=n");
    llOwnerSay("@detach:ATTACH_RUARM=y");
    llSetLinkPrimitiveParamsFast(2, [PRIM_DESC, "iamlocked"]);
    islocked=TRUE;
}

RLVFar()
{
    if(world == TRUE)
    {   
        llOwnerSay("@fartouch=y");
    }
}

RLVWorld()
{
    if(world == TRUE)
    {   
        llOwnerSay("@touchworld=y");
    }

}

RLVOthers()
{
        if(world == TRUE)
    {   
        llOwnerSay("@touchattachother=y");
    }
}

RLVSelf()
{
        if(world == TRUE)
    {   
        llOwnerSay("@touchattachself=y");;
    }
}

default
{
    state_entry()
    {

    }

    touch_start(integer x)
    {
       if(hasOwner == TRUE)
       {
            if(llDetectedKey(0) == llGetObjectDesc())
            {
                owner = llGetObjectDesc();
                MainMenu(owner);
            }
            else
            {
                string ToucherName = llKey2Name(llDetectedKey(0));
                llSay(PUBLIC_CHANNEL,"NOT OWNER: You have no access to these restraints " + ToucherName);
            }
       }

       else if(hasOwner == FALSE)
       {
            if(llDetectedKey(0) != NULL_KEY)
            {
                toucher = llDetectedKey(0);
                MainMenu(toucher);  
            }
        }
    }
    
    //Menu Options below
    listen(integer chan, string Name, key id, string message)
    {
        if(chan == Channel)
        {
            if(message == "Lock/Unlock")
            {
                llSetObjectDesc(toucher);
                RLVLock();
                llListenRemove(handle);
                state locked;

            }
            
            if(message == "Owners")
            {
                OwnersMenu(toucher);
                llListenRemove(handle);
            }
            
            //TO DO: OWNERS MENU OPTIONS
        }   
    }
}

state locked
{
    state_entry()
    {
        llOwnerSay("You have been locked by " + "secondlife:///app/agent/" + llGetObjectDesc() + "/displayname");  
    }   
    
        attach(key id)
    {

        if("iamlocked" == llList2String(llGetLinkPrimitiveParams(2, [ PRIM_DESC ]), 0))
        {
        islocked = TRUE;
        }
        
        if(islocked == TRUE)
        {
          llOwnerSay( "@remoutfit=n" );
          llOwnerSay( "@remattach=n");
          RLVFar();
          RLVWorld();
          RLVOthers();
          RLVSelf(); 
        }
    }
    
    touch_start(integer x) 
    {
        if(llDetectedKey(0) == llGetObjectDesc())
        {
            owner = llDetectedKey(0);
            LockerMenu(owner);
        }
        else
        {
        string ToucherName = llKey2Name(llDetectedKey(0));
        llSay(PUBLIC_CHANNEL,"NOT LOCKER: You have no access to these restraints " + ToucherName);
        }
    }
    
        listen(integer chan, string Name, key id, string message)
    {
        if(chan == Channel)
        {
            if(message == "Lock/Unlock")
            {
                llSetObjectDesc("");
                RLVUnlock();
                llListenRemove(handle);
                state default;
            }
            
            else if(message == "RLV Options") 
            {
                RLVMenu(owner);
                llListenRemove(handle);
            }
            
            else if(message == "Touch Self") 
            {
                llSay(PUBLIC_CHANNEL, "SELF");
                if(self == TRUE)
                {
                     llOwnerSay("@touchattachself=n");
                     self = FALSE;
                     llListenRemove(handle);
                }
                
                else 
                {
                     llOwnerSay("@touchattachself=y");
                     self = TRUE; 
                     llListenRemove(handle);
                }

            }

            else if(message == "Far Touch") 
            {
                llSay(PUBLIC_CHANNEL, "FAR");
                if(far == TRUE)
                {
                     llOwnerSay("@fartouch=n");
                     far = FALSE;  
                     llListenRemove(handle);
                }
                
                else
                {
                     llOwnerSay("@fartouch=y");
                     far = TRUE; 
                     llListenRemove(handle);
                }

            }
            
            else if(message == "Touch Others") 
            {
                llSay(PUBLIC_CHANNEL, "OTHERS");
                if(others == TRUE)
                {
                     llOwnerSay("@touchattachother=n");
                     others = FALSE;  
                     llListenRemove(handle);
                }
                
                else 
                {
                     llOwnerSay("@touchattachother=y");
                     others = TRUE; 
                     llListenRemove(handle);                     
                }
            }
            
            else if(message == "Touch World") 
            {
                llSay(PUBLIC_CHANNEL, "WORLD");
                if(world == TRUE)
                {   
                    llOwnerSay("@touchworld=n");
                    world = FALSE;
                    llListenRemove(handle);
                }
                else
                {
                   llOwnerSay("@touchworld=y");
                     world = TRUE; 
                     llListenRemove(handle);
                }
            }
            
            else if(message == "<BACK>") 
            {
                llSay(PUBLIC_CHANNEL, "BACK");
                LockerMenu(owner);
                llListenRemove(handle);
            }
            else if(message == "TEST") 
            {
                if(self == TRUE)
                {
                llSay(PUBLIC_CHANNEL, "Self True");
                }
                if(self == FALSE)
                {
                llSay(PUBLIC_CHANNEL, "Self false");
                }
                if(far == TRUE)
                {
                llSay(PUBLIC_CHANNEL, "Far True");
                }
                if(far == FALSE)
                {
                llSay(PUBLIC_CHANNEL, "far false");
                }
                if(others == TRUE)
                {
                llSay(PUBLIC_CHANNEL, "others True");
                }
                if(others == FALSE)
                {                
                llSay(PUBLIC_CHANNEL, "others false");
                }
                if(world == TRUE)
                {
                llSay(PUBLIC_CHANNEL, "world True");
                }
                if(world == FALSE)
                {
                llSay(PUBLIC_CHANNEL, "world false");
                }
                
                llListenRemove(handle);
            }
        }
    }
}

 

 

 

Link to comment
Share on other sites

the submenu dialog listener handle is being removed immediately after being created


menu()
{
   hande = llListen
   dialog
}
llListenRemove(handle)

ListenRemove should be called at the top of the listen event

menu()
{
   hande = llListen
   dialog
}

listen
{
    llListenRemove(handle);
    if (message) ...
}

 

  • Like 1
Link to comment
Share on other sites

3 hours ago, Mollymews said:

ListenRemove should be called at the top of the listen event

I'm a bit unsure that this will work, my experience has been removing the listener effectively stops further processing, so the subsequent body of the listen event then will not complete.

 

What I have done in all my multi-dialog scripts is to set an integer immediately on entering the listen event to be false, set it to true if any of the messages require a further dialog, and at the end of the listen event, if this variable is still false, remove the handle. There is also a global string timerAction which is set appropriately to let a 30-seconds no-buttons pressed remove the listen event.

 

However, I have never worked with RLV so I don't know if the timer is appropriate.

 

Listen(integer ch, ...)
{
    integer more = false;
    // if we are using a timer to timeout after 30 seconds of nop user response, set it to
    // 0.0 here

    if( msg = "do stuff")
    {
        more = true;
        llDialog(...)
        if using a timer to timeout set it to 30.0 here
	}
    // and so on down the long chain of nested ifs and elses ...
    // until
    if( !more )
    {
        llListenRemove(lhandle);
    }
}

timer()
{
    if( timerAction == "listen")
    {
        llSetTimerEvent(0.0);
        timerAction = "";
        llListenRemove(lhandle);
    }
}

 

Link to comment
Share on other sites

3 hours ago, Profaitchikenz Haiku said:

I'm a bit unsure that this will work, my experience has been removing the listener effectively stops further processing, so the subsequent body of the listen event then will not complete.

I have never seen this happen, and I always remove the listener at the start of the listen event when it's appropriate to do so. And this is the first and only suggestion I've ever seen that doing so might be problematic. Could you point me to anything that describes the issue (JIRAs, forum posts, etc.) in any more detail?

Link to comment
Share on other sites

is like KT says in this instance

the way the OP code is written is that the submenus are being called from within the listen event. OP code is creating a new listener for each submenu dialog.  As wrote there is a 1 to 1 correspondence between each menu/dialog call and the subsequent listen event response

you are right tho Prof as well in the N to 1 situation. Removing the listener inside the listen event can be problematic when the listen event is being fired independently by more than one input. Dialog and typed chat for example.  In the OP case as wrote, there is only one input - the dialog, for which a new listener is being created each time 

 

 

 

Link to comment
Share on other sites

3 hours ago, KT Kingsley said:

Could you point me to anything that describes the issue

Fraid not, this came about after lots of head-scratching and trials when I developed a multi-dialog system, my notes are scribbles on paper not text files, but what I found was that when I removed the listener, no subsequent code in the block that held the llListenRemove was executed, at least, none that I could test for, as the timer reset and timer string had already been reset. 

ETA just read Molly's post in more detail, so what you're saying is if there will only ever be one channel open for a listen it's Ok to remove the listen as soon as the event is entered but it won't affect the remainder of the event being processed, but if there is a handle for a listen to a fixed channel for llRegionSay open all the time and also there will be occasional listens for channels for dialogs with avatars, removing those listen events is what causes a halt to their processing?

Edited by Profaitchikenz Haiku
  • Thanks 1
Link to comment
Share on other sites

I'm probably misunderstanding something here, because I'm using a script that does have a couple of permanent listeners open, but also opens ad hoc listeners for dialogs and RLV responses, and these ad hoc listeners are removed at the start of the if/else if blocks that process the code:

    listen (integer channel, string name, key id, string message)
    {
        if (channel == dialog_channel) // ad hoc
        {
            llListenRemove (dialog_listener);
            // stuff still gets done
        }
        else if (channel == rlv_channel) // ad hoc
        {
            llListenRemove (rlv_listener);
            // stuff still gets done
        }
        else if (channel == comms_channel) // always open
        {
            // stuff gets done
        }
        else if (channel == status_channel) // always open
        {
            // stuff gets done
        }
    }

(To the OP: sorry about the sidetracking here, but incidental snippets of information like this can be extremely interesting too.)

  • Like 1
Link to comment
Share on other sites

yes is a pretty interesting topic, and is worth a hijack for a discussion. So that we as readers and scripters can get some further insights into how important, flow order is to our codes

apologies to OP for again using their codes as an example for this discussion. There is a fault in the flow order. A similar form showing the fault:

integer MENU_CHANNEL = 1;

integer handle;

default
{
   state_entry()
   {
      // MainMenu
      handle = llListen(CHANNEL, ...);
      llDialog(... [Submenu1, Submenu2] ... MENU_CHANNEL);
   }

   listen(...)
   {
      if (channel == MENU_CHANNEL)
      {
         if (message == Submenu1)
         {
            handle = llListen(MENU_CHANNEL, ...);
            llDialog( ... [Submenu1Item1, Submenu1Item2, ...] ... MENU_CHANNEL);
            llListenRemove(handle);
         } 
         if (message == Submenu2)
         {
            handle = llListen(MENU_CHANNEL, ...);
            llDialog( ... [Submenu2Item1, Submenu2Item2, ...] ... MENU_CHANNEL);
            llListenRemove(handle);
         }
         if (message == MainMenu)
         {
            llListenRemove(handle);
      	    handle = llListen(MENU_CHANNEL, ...);
      	    llDialog(... [Submenu1, Submenu2] ... MENU_CHANNEL); 
         }
      } 
   }
}

as wrote, the listen handle for the submenuitems dialogs is being removed immediately after it is created, so the listen event will not fire for the submenu dialogs. The listen event for 'message == MainMenu does fire, as the flow order of the code removes the listen for the previous received message then creates a new listener for the MainMenu dialog

if the listener handle is to be removed then it needs to be done after the corresponding listen event has fired. And as Prof indicates, it can also be removed on a timer to cater for the instance where the user closes/ignores the dialog. And in most cases using a timer to close open listens in the user ignore instances is a good practice

it is ok to remove a listener in the listen event provided that we are mindful to do this for the designated channel as KT shows. I didn't mention about the designated channel in my previous which I should have   

 

 

 

Edited by Mollymews
tidy up
  • Thanks 1
Link to comment
Share on other sites

The logic of the code seems very confused. Here are some excerpts:

RLVUnlock()
{
    llListenRemove(handle);
}

// Later...
if(message == "Lock/Unlock")
{
    llSetObjectDesc("");
    RLVUnlock();            // Listen gets removed
    llListenRemove(handle); // Redundant
    state default;
}
// These menu functions change the global variable
OwnersMenu(key id) 
{
    handle = llListen(Channel,"","","");
    llDialog(id,"Owners Menu", OwnersM,Channel);
}

// Later, every time those menu functions are called...
if(message == "Owners")
{
    OwnersMenu(toucher);    // New handle is set
    llListenRemove(handle); // He's dead, Jim.
}

You can't do this, because it breaks your menu. A new dialog is opened, but nothing is listening for that new dialog's buttons. A bandaid resolution would be to remove the previous handle and THEN set a new one, in each menu function. For example:

OwnersMenu(key id) 
{
    llListenRemove(handle);              // Remove previous
    handle = llListen(Channel,"","",""); // Set new
    llDialog(id,"Owners Menu", OwnersM,Channel);
}

// Later, every time those menu functions are called...
if(message == "Owners")
{
    OwnersMenu(toucher); // Everything is A-OK
}

But at this point you'll always have one listen open so there's no point even having the ListenRemove there to begin with.

Edited by Wulfie Reanimator
Link to comment
Share on other sites

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