Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Sensors, lists, and llDiag consternation

Talan Mackenzie
The Rocketeer
Join date: 15 Aug 2004
Posts: 14
01-19-2005 23:04
The premise of the following code is to llSensor on touch, grab the names of all avatars in range, stuff them in a list, then feed that list into a dialog box.

CODE
key TOUCHER = "";
list LNAMES = [];

default
{
state_entry()
{
//later
}

touch_start(integer total_number)
{
TOUCHER = llDetectedKey(0);
llSensor("", "", AGENT, 96, PI);
}
sensor(integer total_number)
{
string names;
integer i;
for(i = 0; i < total_number; i++)
{
names += llDetectedName(i) + ",";
}
//debug llSay(0, names);
LNAMES = llCSV2List(names);
//debug llSay(0, (string)LNAMES);
llDialog(TOUCHER, "Target:", LNAMES, 912);
}
}


The unhappy result is that my item chats, "llDialog: all buttons must have label strings".

This is baffling. Since the number of buttons within llDialog is taken from the same list that the button labels come from, there should never be any more of one than the other. Uncommenting those debug lines reveal that there's no crap information finding its way into the list. So uh.. anyone know what's wrong here?
Kurt Zidane
Just Human
Join date: 1 Apr 2004
Posts: 636
01-20-2005 00:57
your for loop formats data as fallowed. "data,"
witch means if It detects 3 people. "Bob Lindon, JakeLindon, dart lindon" the string names will equal "Bob Lindon,Jake Lindon,Dart Lindon," When you run that through llCSV2List you'll end up with the list [Bob Lindon","Jake Lindon,"Dart Lindon",""].

So you have a few choice..
you could reformat your loop, and add preprossing. Think of it like this. You making a machine to build a fence. It can only do exactly what it's set to do. A fence is made up of fence post, bar, fence post, bar, fenc post. The problem is if you set the machine to start with bar, when it get to the end you have [fence post, bar, fence post, bar] if you start with a bar you have this problem. [ bar, fence post, bar, fence post] then you have the problem that the first bar fall on the ground. So... what do you do. Well you instruct the machine to ether plant the first fence post, before the loop. Or instruct the machine to plant the fence post at the end after the loop. Ether one will work, but one must be done.

so you ether do this:
CODE
string names;

names = llDetectedName ( 0 ); // because we know this action is only called when there is an avatar. We can assume there is at leasat one
integer i ;
for(i = 1; i < total_number; i++)
{
names += "," + llDetectedName(i);
}


or this
CODE
string names;

there is at leasat one
integer i ;
for(i = 0; i < ( total_number - 1 ); i++)
{
names += "," + llDetectedName(i);
}
names = llDetectedName ( total_number - 1 );



or this is me, but I wouldn't use strings at all. I would use list. This way you don't need to call the string to list function. No need to mess around with formating. And no need to pre or post prossess the loop. chears
CODE

list myList = [];

integer i ;
for(i = 0; i < total_number ; i++)
{
myList += llDetectedName(i);
}
Kurt Zidane
Just Human
Join date: 1 Apr 2004
Posts: 636
01-20-2005 01:09
Another thing you could do, if you want to use string to list. and not pre or post prosses the loop. You could just delete the last item in the list. Because we all know the last item in the list will be [""].

btw if I didn't say "" is what cuasing your dialog box to spit out that error.
Zonax Delorean
Registered User
Join date: 5 Jun 2004
Posts: 767
01-20-2005 05:50
Warning: sensors can return 16 results maximum, but llDialog can only take 12 (if i'm correct).
Evil Fool
"==" != "="
Join date: 30 Jul 2004
Posts: 110
01-20-2005 13:39
made this script quite a while ago... never got around to selling it... check it out (will post it in the script library in a few)

CODE

//Formatted Sensor Dialog script by Evil Fool
// You may give this script away for free, but please leave creator information in.
// Next owner MUST have script modify access if any of this code is used in part or whole
//CONFIG
integer gOwnerOnly = FALSE;
integer gChann = -93190;
integer gStride = 9;
//END CONFIG

list names;
integer gPos = 0;
key tReq;

dialog(key id)
{
integer nTop = gPos + gStride - 1;
list buttons = llList2List(names, gPos, nTop);
string msg = llDumpList2String(buttons, "\n");
if (gPos >= gStride)
{
buttons += ["PREVIOUS"];
}else{
buttons += [" "];
}

if (nTop - 1 < llGetListLength(names))
{
buttons += ["NEXT"];
}else{
buttons += [" "];
}

while(llGetListLength(buttons) % 3 != 0)
{
buttons = llListInsertList(buttons, [" "], gStride);
}

llDialog(id, msg, buttons, gChann);
}

default
{
state_entry()
{
llListen(gChann, "", NULL_KEY, "");
}

touch_start(integer num_times)
{
if ( ( gOwnerOnly == TRUE && llDetectedKey(0) == llGetOwner() ) || gOwnerOnly == FALSE)
{
tReq = llDetectedKey(0);
llWhisper(0, "Restarting script for user " + llDetectedName(0) + "!");
llSensor("", NULL_KEY, AGENT, 96.0, PI);
}
}

sensor(integer num_detected)
{
names = [];
gPos = 0;
integer i;
for (i = 0; i < num_detected; i++)
{
names = names + llDetectedName(i);
}
dialog(tReq);
}

listen(integer channel, string name, key id, string msg)
{
if (msg == "NEXT")
{
gPos = gPos + gStride;
dialog(id);
}else if (msg == "PREVIOUS")
{
gPos = gPos - gStride;
dialog(id);
}else if (msg == " ")
{
llSay(0, "Sorry, this is just a filler!");
}else{
llSay(0, msg);
}
}
}


currently only supports 1 user using it at a time... but its pretty cool (you can set it to owner only, using the gOwnerOnly setting at the top, if you realy want)

what this does: pretty much the same thing the first one does, but also formats the list with NEXT and PREV boxes, sizes it, etc... have fun with it, but don't sell it (make sure next owner has mod perms if you do give it away free)
Christopher Omega
Oxymoron
Join date: 28 Mar 2003
Posts: 1,828
01-20-2005 18:15
Actually, you're experiancing a bug with llCSV2List. llCSV2List processes only based on seperaters of the form ", " (comma and space) not just "," (comma). It will return an empty list, or a list with one null element [""] (I think) when it gets a string seperated by only commas, and not comma-spaces.
==Chris
Kurt Zidane
Just Human
Join date: 1 Apr 2004
Posts: 636
01-20-2005 18:38
I had no problems with CSV and "," look:
CODE
default
{
state_entry()
{
list elements;
string message;
integer max;

message = "item one,item two,item three";
elements = llCSV2List ( message );
max = llGetListLength ( elements );

llSay ( 0, "list Length: " +(string) max );


integer counter;
for ( counter = 0; counter < max; counter++ )
{
llSay ( 0, "List Item #" + (string)( counter + 1 ) + " value: '" + llList2String ( elements, counter ) + "'." ) ;
}
}
}



out is:
CODE
Object: list Length: 3
Object: List Item #1 value: 'item one'.
Object: List Item #2 value: 'item two'.
Object: List Item #3 value: 'item three'.


but if the last char in the string is "," then this is what happens.
CODE
default
{
state_entry()
{
list elements;
string message;
integer max;

message = "item one,item two,item three,";
elements = llCSV2List ( message );
max = llGetListLength ( elements );

llSay ( 0, "list Length: " +(string) max );


integer counter;
for ( counter = 0; counter < max; counter++ )
{
llSay ( 0, "List Item #" + (string)( counter + 1 ) + " value: '" + llList2String ( elements, counter ) + "'." ) ;
}
}
}


out put:
CODE
Object: list Length: 4
Object: List Item #1 value: 'item one'.
Object: List Item #2 value: 'item two'.
Object: List Item #3 value: 'item three'.
Object: List Item #4 value: ''.
Talan Mackenzie
The Rocketeer
Join date: 15 Aug 2004
Posts: 14
Extra list entry due to comma found, summarily eradicated.
01-20-2005 21:36
Kurt Zidane is entirely correct. A quick test with llGetListLength reveals an extra entry at the end of each list due to that comma. I reformatted to sensor directly to the list with no string step, and all is well. Thanks for the quick response.