Jump to content

Object speak as owner for chat command


UnNameable
 Share

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

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

Recommended Posts

Hello and thank you in advance for any help anyone can provide. I took the basic scan and hug script from one of the tutorials and through some heavy guess work and trial and error i got it working to my needs. However if the scanned name is too long with the added chat command it breaks the process as it goes beyond the 24 character limit. I was wondering if there was... well I know there is a way around this. However, I am by no means a scripter and can barely make heads or tails of my own script let alone be able to fix this issue. any help or direct answers would make my second life.

integer dlgHandle = -1;
integer dlgChannel = -9999;
list avatarList = [];
reset()
{
    llSetTimerEvent(0.0);
    llListenRemove(dlgHandle);
    dlgHandle = -1;
}
default
{
    touch_start(integer total_number)
    {
        llOwnerSay("Scanning...");
        avatarList = [];
        // Look for any avatars within 50m.
        llSensor("", NULL_KEY, AGENT, 50.0, PI);
    }
    sensor(integer num_detected)
    {
        integer i;
        while((i < num_detected) && (i < 9))
        {
            if (llDetectedKey(i) != llGetOwner())
            {
                avatarList += [llDetectedName(i)];
            }
            ++i;
        }
        if (llGetListLength(avatarList) > 0)
        {
          state dialog;
        }
    }
}
state dialog
{
    state_entry()
    {
        // Set up a listener to detect button clicks.
        dlgHandle = llListen(dlgChannel, "", llGetOwner(), "");

        // Start a new timer.
        llSetTimerEvent(30.0);

        // Add a 'Cancel' button.
        avatarList += ["Cancel"];

        // Display the dialog.
        llDialog(llGetOwner(), "Please select an avatar.", avatarList, dlgChannel);
    }
    listen(integer channel, string name, key id, string message)
   
    {
        // The message parameter holds the caption of the
        // button that was clicked. Search the menu options
        // list for it.

        if ((channel == dlgChannel) && (llListFindList(avatarList, [message]) != -1))
        {
       if (message != "Cancel")
            {
                llDialog(llGetOwner(),"Confirm", ["steal|"+message] ,9);
            }
            reset();
            state default;
        }
    }
    timer()
    {
        reset();
        state default;
    }
}

Link to comment
Share on other sites

There are at least two ways to do it:

  1. shorten the names
  2. number the buttons and list the numbers with the names in the message text

Here is an example for the letter - it can be made nicer by sorting the buttons in an more intuitive way. I added the number to the second dialog - name plus "steal|" in most cases is far too long and produces an error

integer dlgHandle = -1;integer dlgChannel = -9999;list avatarList = [];list btnList;reset(){    llSetTimerEvent(0.0);    llListenRemove(dlgHandle);    dlgHandle = -1;}default{    touch_start(integer total_number)    {        llOwnerSay("Scanning...");        avatarList = [];        // Look for any avatars within 50m.        llSensor("", NULL_KEY, AGENT, 50.0, PI);    }    sensor(integer num_detected)    {        integer i;        while((i < num_detected) && (i < 9))        {            if (llDetectedKey(i) != llGetOwner())            {                avatarList += [llDetectedName(i)];            }            ++i;        }        if (llGetListLength(avatarList) > 0)        {          state dialog;        }    }}state dialog{    state_entry()    {    	integer i = 0;     	string text;    	for (; i < llGetListLength(avatarList); ++i) {    		btnList += (string)(i + 1);    		text += "\n" + (string)(i+1) + " - " + llList2String(avatarList, i);    	}        // Set up a listener to detect button clicks.        dlgHandle = llListen(dlgChannel, "", llGetOwner(), "");        // Start a new timer.        llSetTimerEvent(30.0);        // Add a 'Cancel' button.        avatarList += ["Cancel"];        // Display the dialog.        llDialog(llGetOwner(), "Please select an avatar.\n" + text, btnList, dlgChannel);    }    listen(integer channel, string name, key id, string message)       {        // The message parameter holds the caption of the        // button that was clicked. Search the menu options        // list for it.        if ((channel == dlgChannel) && (llListFindList(btnList, [message]) != -1))        {       if (message != "Cancel")            {                llDialog(llGetOwner(),"Confirm", ["steal|"+llList2String(btnList, (integer)message-1)] ,9);                llOwnerSay(llList2String(avatarList, (integer)message-1));            }            reset();            state default;        }    }    timer()    {        reset();        state default;    }}

 

  • Like 1
Link to comment
Share on other sites

Oh Wow that made the look of it all much more simple looking. Sadly it didnt quite allow the action to proceed as i needed it. The affected object requires the string /9 steal|(avatarname) i.e. /9 steal|UnNameable Resident. Also the said string needs to be owner said not script or object. The original version worked, but lots of names didnt fit the button limit. Heck if I didnt even need the "Confirm" part id be happy.

Link to comment
Share on other sites

I adjusted that, plus made the sorting of the buttons a bit nicer - I hope it works, I couldn't test it.

But still, the likelyhood for the tool to fail is big - the confirm dialog will faiil whenever the full name + steal| are longer than 24 characters

integer dlgHandle = -1;integer dlgChannel = -9999;list avatarList = [];list btnList;string text;reset(){    llSetTimerEvent(0.0);    llListenRemove(dlgHandle);    dlgHandle = -1;}default{    touch_start(integer total_number)    {        llOwnerSay("Scanning...");		avatarList = [];		btnList = [];		text = "";        // Look for any avatars within 50m.        llSensor("", NULL_KEY, AGENT, 50.0, PI);    }    sensor(integer num_detected)    {        integer i;        while((i < num_detected) && (i < 9))        {            if (llDetectedKey(i) != llGetOwner())            {				avatarList += [llDetectedName(i)];				btnList += (string)(i+1);				text += "\n" + (string)(i+1) + " - " + llDetectedName(i);            }            ++i;        }        if (llGetListLength(avatarList) > 0)        {          state dialog;        }    }}state dialog{    state_entry()    {        // Set up a listener to detect button clicks.		dlgHandle = llListen(dlgChannel, "", llGetOwner(), "");		//sort buttons in a more readable way		btnList = llList2List(btnList, -3, -1) + llList2List(btnList, -6, -4) + llList2List(btnList, -9, -7) + llList2List(btnList, -12, -10);        // Start a new timer.        llSetTimerEvent(30.0);        // Add a 'Cancel' button.        btnList += ["Cancel"];        // Display the dialog.        llDialog(llGetOwner(), "Please select an avatar.\n" + text, btnList, dlgChannel);    }    listen(integer channel, string name, key id, string message)       {        // The message parameter holds the caption of the        // button that was clicked. Search the menu options        // list for it.        if ((channel == dlgChannel) && (llListFindList(btnList, [message]) != -1))        {       if (message != "Cancel")            {                llDialog(llGetOwner(),"Confirm", ["steal|"+llList2String(avatarList, (integer)message-1)] ,9);            }            reset();            state default;        }    }    timer()    {        reset();        state default;    }}

 

  • Like 1
Link to comment
Share on other sites

Just for completeness, since Darkie mentioned the other option, you can simply shorten names to fit or (my preferred choice) save only the first name.  This gets a little complicated because we now have three possible name formats in SL, but it's still do-able.  This script puts everything in one state instead of having a separate state dialog.  I didn't bother dealing with what happens if you detect more than 11 avatars in your sensor sweep, but you can take care of that by (1)adding a second page of dialog, (2)decreasing scan distance, or (3) saving only the first 11 names. As with your original script, it doesn't actually DO anything except select an avatar when you finally click the confirming dialog, but I assume you have plans for that part.

This compiles, but I can't guarantee that it is flawless in world. .....

 

list gAvatars;integer gDChan;integer gDLisn;default{	state_entry()	{		gDChan = (integer)("0xF" + llGetSubString(llGetOwner(),0,6));  //Comm channel	}		touch_start(integer total_number)	{		llSensor("","",AGENT,50.0,PI);	}	sensor(integer num)	{		gAvatars = []; //Empty previous list contents		integer i;		for (i=0;i<num;++i)		{			string Name = llDetectedName(i);			integer idx = llSubStringIndex(Name," ");			if (~idx) // This is a legacy name with a first and last name			{				Name = llGetSubString(Name,0,idx-1);			}			else			{				idx = llSubStringIndex(Name,".");				if (~idx)  // This is a name in first.last format				{					Name = llGetSubString(Name,0,idx-1);				}			}			if (llStringLength(Name) > 18)  //Whatever style ... the name is too long still			{				Name = llGetSubString(Name,0,17);			}			gAvatars += [Name];		}		gAvatars += ["Cancel"];		gDLisn = llListen(gDChan,"","","");		llSetTimerEvent(10.0); //Set timeout on dialog		llDialog(llGetOwner(),"Select an avatar:",[gAvatars],gDChan); //Will fail if more than 11 avs	}	timer()  //Timeout	{		llListenRemove(gDLisn);		llSetTimerEvent(0.0);	}	listen(integer channel, string name, key id, string msg)	{		llListenRemove(gDLisn);  //Kill the listen handle		llSetTimerEvent(0.0); //Kill the timer		if (msg != "Cancel")		{			gDLisn = llListen(gDChan,"","","");			llSetTimerEvent(5.0);			llDialog(llGetOwner(),"Confirm", ["steal|"+msg],gDChan); //Here's why you need name lengths < 18		}	}		}

 

 

  • Like 1
Link to comment
Share on other sites

Both of these are absolutely wonderful scripts and i will keep them both to try and reverse engineer it and try to learn what all you both did. You were right Darkie, the menu is much better but again still holds that fatal flaw. Rolig I think I see why your would work but every time the script runs I get a "Lists can not contain lists" error for this segment.

gAvatars = []; //Empty previous list contents		integer i;		for (i=0;i<num;++i)

nearly makes me tear my hair out, but no pain no gain.

Link to comment
Share on other sites

That's very odd indeed.  I don't see a flaw and it compiles with no problem for me.  All I can guess is that you made a cut and paste error and picked up a bogus hidden character somewhere.  It happens.  Try deleting and retyping the troublesome lines.

  • Like 1
Link to comment
Share on other sites

hmmm 14 tries later and still the same error when the prim is clicked and the script runs, little script error icon pops up and i get

Script Warning/Error


Object [script:Steal Script V2] Script run-time error
Lists may not contain lists

But it saves as a script just fine each time, no issues till i try to use it

Link to comment
Share on other sites

You're right - mine needs a second counter

integer dlgHandle = -1;integer dlgChannel = -9999;list avatarList = [];list btnList;string text;reset(){    llSetTimerEvent(0.0);    llListenRemove(dlgHandle);    dlgHandle = -1;}default{    touch_start(integer total_number)    {        llOwnerSay("Scanning...");        avatarList = [];        btnList = [];        text = "";        // Look for any avatars within 50m.        llSensor("", NULL_KEY, AGENT, 50.0, PI);    }    sensor(integer num_detected)    {        integer i;        integer n = 1;        while((i < num_detected) && (i < 9))        {            if (llDetectedKey(i) != llGetOwner())            {                avatarList += [llDetectedName(i)];                btnList += (string)(n);                text += "\n" + (string)(n) + " - " + llDetectedName(i);                ++n;            }            ++i;        }        if (llGetListLength(avatarList) > 0)        {          state dialog;        }    }}state dialog{    state_entry()    {        // Set up a listener to detect button clicks.        dlgHandle = llListen(dlgChannel, "", llGetOwner(), "");        //sort buttons in a more readable way        btnList = llList2List(btnList, -3, -1) + llList2List(btnList, -6, -4) + llList2List(btnList, -9, -7) + llList2List(btnList, -12, -10);        // Start a new timer.        llSetTimerEvent(30.0);        // Add a 'Cancel' button.        btnList += ["Cancel"];        // Display the dialog.        llDialog(llGetOwner(), "Please select an avatar.\n" + text, btnList, dlgChannel);    }    listen(integer channel, string name, key id, string message)       {        // The message parameter holds the caption of the        // button that was clicked. Search the menu options        // list for it.        if ((channel == dlgChannel) && (llListFindList(btnList, [message]) != -1))        {       if (message != "Cancel")            {                llDialog(llGetOwner(),"Confirm", ["steal|"+llList2String(avatarList, (integer)message-1)] ,9);            }            reset();            state default;        }    }    timer()    {        reset();        state default;    }}

 

  • Like 1
Link to comment
Share on other sites

/me bows

hmmm doesnt look as impressive bowing when its not emoted. That just about solved it! the menues pop up, the partial names are listed and can select them. The only issue left I see is that it asks me to confirm twice and when I do the button has 2 "steal|" in it and then get the original error of going over 24 characters in a button. im gunna play around with it and see if i missed something. I dont want to rely too heavily on you both and I have to learn this at some point.

Link to comment
Share on other sites

In line 63 (the second dialog coomand) it should say 9 instead of  gDChan.

But this may not help you, since the dialog will not give you the full name - only the shortened version. Rolig did that for a good reason, but I have mentioned that before several times ;) Anyhow: it looks like you have a second script that listens to channel 9. If that script simply says something based on the result of this  script, it's ok - if it really needs the full name, it will fail.

  • Like 1
Link to comment
Share on other sites

Oh yes! I see that. it sent it for a loop. And everything works as I had wished. You are both very patient and wonderful for helping me out so much. When I take over the world I shall give you both a seat of power. And a cookie.

But your right. I kinda see why she did all that and I see why you went the route you did too. Im certainly going to pour over these and try to learn from them.

Link to comment
Share on other sites

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