Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

List Hover Text TO Prim I guess

Kimmy Gable
Registered User
Join date: 8 Apr 2006
Posts: 14
12-23-2009 03:16
Well I altered a list maker done on the forums by one of the lindens. So it works on touch to create the list rather then sensors. I am wanting to use it to send the names to other prims. The other linked prims would show the name in hover text. Here is the script
CODE

list single_name_list;
list visitor_list;
integer isNameOnList( string name )
{
list single_name_list;
single_name_list += name;
return (-1 != llListFindList( visitor_list, single_name_list ) );
}
sendEmail()
{
string csv = llList2CSV( visitor_list );
}
resetList()
{
single_name_list = llDeleteSubList(single_name_list, 0, llGetListLength(single_name_list));
llSay( 0, "Done resetting.");
}
default
{
state_entry()
{
llListen(0, "", llGetOwner(), "");
}
timer()
{
resetList();
}
touch_start( integer number_detected )
{
integer i;
for( i = 0; i < number_detected; i++ )
{
{
string detected_name = llDetectedName( i );
if( isNameOnList( detected_name ) == FALSE )
{
float seconds = llGetWallclock();
float minutes = seconds / 60.0;
float hours = minutes / 60.0;
integer hours_int = (integer) hours;
integer minutes_int = ((integer)minutes) % 60;
if( minutes_int < 10 )
{
}
else
{
}
visitor_list += detected_name;
}
}
}
}
listen( integer channel, string name, key id, string message )
{
if( id != llGetOwner() )
{
return;
}
else
if( message == "say list" )
{
llSay( 0, "Racers:" );
integer len = llGetListLength( visitor_list );
integer i;
for( i = 0; i < len; i++ )
{
llSay( 0, llList2String(visitor_list, i) );
}
llSay( 0, "Total = " + (string)len );
}
else
if( message == "reset list" )
{
visitor_list = llDeleteSubList(visitor_list, 0, llGetListLength(visitor_list));
llSay( 0, "Done resetting.");
}
}
}


Basicly when they touch the board there name is added to the list. That works. Now when they touch I would like there name to go to a specific linked box and show in hover text. Then when someone else touches there name would go to a diffrent box in hover text.
ANY help would be great.
Indeterminate Schism
Registered User
Join date: 24 May 2008
Posts: 236
12-23-2009 05:25
You will need a script in each of your linked prims to set the hovertext for that prim. When a name is added to the list have the main script send a linked message (llMessageLinked) to the relevant child prim. The script in that prim should wait for linked messages, recognise when a message comes to it and set the hovertext as appropriate.
Kimmy Gable
Registered User
Join date: 8 Apr 2006
Posts: 14
12-23-2009 05:29
Thanks Indeterminate,
But that is where I am getting lost. So they touch to be added, then it would store that info and send it to another prim. Now this linked set will have 16 linked boxes. So the names have to be sent to a specific box. What I am not sure of is how to figure out what sort of message to use to find that box and even more important how to figure out how to get that persons name to be set to that box.
Haravikk Mistral
Registered User
Join date: 8 Oct 2005
Posts: 2,482
12-23-2009 05:51
Easiest way is to give each of the name boxes a unique name or description, then loop through in your main script to find the one you want. You could use a function like:

CODE
integer getLinkNumber(string name) {
integer x = llGetNumberOfPrims();
while ((--x) > 1)
if (llGetLinkName(x) == name) return x;
return -1;
}


To use it you do something like:

CODE
// Add getLinkNumber() here

default {
touch_start(integer x) {
while ((--x) >= 0) {
string name = "";
// Figure out the link-name you're interested in
integer link = getLinkNumber(name);
if (~link) // Is link 0 or greater?
llMessageLinked(link, 1234, llDetectedName(x), NULL_KEY); // Send data
}
}
}


For greater efficiency you can use the function to get the link-numbers you need, and store these in global variables, making sure to re-load them if the object is ever edited (see the changed() event for info on that).

If you want to use the description to identify each prim, then you'll want to replace the llGetLinkName(x) part in getLinkNumber() with:

(string)llGetObjectDetails(llGetLinkKey(x), [OBJECT_DESC])

A more complicated, but arguably more correct, solution would have individual prims communicating with the root-script to identify themselves, however the overhead is quite large so the simpler method of "scraping" prim-names/descriptions is much easier overall.
_____________________
Computer (Mac Pro):
2 x Quad Core 3.2ghz Xeon
10gb DDR2 800mhz FB-DIMMS
4 x 750gb, 32mb cache hard-drives (RAID-0/striped)
NVidia GeForce 8800GT (512mb)
Kimmy Gable
Registered User
Join date: 8 Apr 2006
Posts: 14
12-23-2009 06:04
Hi Haravikk Mistral

Well this did help allot with me understanding it, Now I am having troubles adding it to my exsisting script.
Kimmy Gable
Registered User
Join date: 8 Apr 2006
Posts: 14
12-23-2009 09:09
Ok, I added to the scripts some of the parts with your help. But can't get it to work. Not sure what I am doing wrong. Here is the latest code

CODE

list single_name_list;
list visitor_list;
integer isNameOnList( string name )
{
list single_name_list;
single_name_list += name;
return (-1 != llListFindList( visitor_list, single_name_list ) );
}
sendEmail()
{
string csv = llList2CSV( visitor_list );
}
resetList()
{
single_name_list = llDeleteSubList(single_name_list, 0, llGetListLength(single_name_list));
llSay( 0, "Done resetting.");
}
default
{
state_entry()
{
llListen(0, "", llGetOwner(), "");
}
timer()
{
resetList();
}
touch_start(integer x )
{
string detected_name;
integer i;
integer number_detected;
for( i = 0; i < number_detected; i++ )
{
{
string detected_name = llDetectedName( i );
if( isNameOnList( detected_name ) == FALSE )
{
while ((--x) >= 0) {


integer link = getLinkNumber(detected_name);
if (~link) // Is link 0 or greater?
llMessageLinked(link, 1234, llDetectedName(x), NULL_KEY); // Send data
}

float seconds = llGetWallclock();
float minutes = seconds / 60.0;
float hours = minutes / 60.0;
integer hours_int = (integer) hours;
integer minutes_int = ((integer)minutes) % 60;
if( minutes_int < 10 )

{

{




visitor_list += detected_name;
}
}
}
}
}
}


listen( integer channel, string name, key id, string message )
{
if( id != llGetOwner() )
{
return;
}
else
if( message == "say list" )
{
llSay( 0, "Racers:" );
integer len = llGetListLength( visitor_list );
integer i;
for( i = 0; i < len; i++ )
{
llSay( 0, llList2String(visitor_list, i) );
}

}
else
if( message == "reset list" )
{
visitor_list = llDeleteSubList(visitor_list, 0, llGetListLength(visitor_list));
llSay( 0, "Done resetting.");
if( message == "sort" )
{
llListSort([visitor_list], 1, TRUE);

}
}
}
}
Laurie Stilman
Registered User
Join date: 11 Apr 2006
Posts: 45
12-23-2009 13:14
What isn't working? There's a lot of redundant and/or unused code there, but here are some things to check:

- using Haravikk's getLinkNumber() example the way you have, you'll only match a prim if its name exactly matches that of the avatar that touched the object. Is that what you wanted?

- llMessageLinked() will send a message to a particular linked prim but, as mentioned above, you will need a script in each prim of the linkset to receive and act on that message. Did you add one? You didn't show the code if so.

Here's a simplified pair of scripts that should be closer to what you want. Note that I removed code not related to the main problem, and haven't tested this in-world:

// -------- 8< PLACE IN ROOT PRIM 8< --------
list visitor_list = [];

integer isNameOnList( string name ) {
return (-1 != llListFindList( visitor_list, (list) name ) );
}

default {
touch_end(integer count) {
integer num_prims = llGetNumberOfPrims(); // get the number of prims
num_prims = num_prims - 1; // don't count root prim
integer num_visitors = llGetListLength(visitor_list);

while (--count >= 0) {
string name = llDetectedName(count);
if (isNameOnList(name)) {
llSay(0, name + " is already on the list";);
} else if (num_visitors + 1 > num_prims) {
llSay(0, "too many visitors";);
} else {
// add visitor to visitor_list
visitor_list += name;
num_visitors = num_visitors + 1;

// tell appropriate child prim to set its hover text
integer prim_num = num_visitors + 1; // +1 to skip root
llMessageLinked(prim_num, 0, name, NULL_KEY);
}
}
}
}
// -------- 8< END ROOT PRIM SCRIPT 8< --------


// -------- 8< PLACE IN EACH CHILD PRIM PRIM 8< --------
default {
link_message(integer sender_num, integer num, string name, key id) {
llSetText(name, <1,1,1>, 1.0);
}
}// -------- 8< END CHILD PRIM SCRIPT 8< --------
Kimmy Gable
Registered User
Join date: 8 Apr 2006
Posts: 14
12-23-2009 15:09
THANK YOU SO MUCH!. That is exactly what I was looking for!

Can I please ask for one more thing? I am trying to figure out how to "sort" the board. So only the names that are set to the prims would rearange.
Laurie Stilman
Registered User
Join date: 11 Apr 2006
Posts: 45
12-23-2009 15:22
Something simple like this should do it I think:

sortBoard() {
visitor_list = llListSortList(visitor_list);
integer count = llGetListLength(visitor_list);
while (--count >= 0) {
string name = llList2String(visitor_list, count);
llMessageLinked(count+1, 0, name, NULL_KEY);
}
}
Kimmy Gable
Registered User
Join date: 8 Apr 2006
Posts: 14
12-23-2009 15:42
Well I can't test it, I can't figure out where to put it, I added this code below for a linked message.

CODE

list visitor_list = [];

integer isNameOnList( string name ) {
return (-1 != llListFindList( visitor_list, (list) name ) );
}

default {

state_entry()
{

}
touch_end(integer count) {
integer num_prims = llGetNumberOfPrims(); // get the number of prims
num_prims = num_prims - 1; // don't count root prim
integer num_visitors = llGetListLength(visitor_list);

while (--count >= 0) {
string name = llDetectedName(count);
if (isNameOnList(name)) {
} else if (num_visitors + 1 > num_prims) {
llSay(0, "too many visitors");
} else {
// add visitor to visitor_list
visitor_list += name;
num_visitors = num_visitors + 1;

// tell appropriate child prim to set its hover text
integer prim_num = num_visitors + 1; // +1 to skip root
llMessageLinked(prim_num, 0, name, NULL_KEY);
}
}
}
link_message(integer sender_num, integer num, string message, key id) {
{
if( message == "Reset" )
{
visitor_list = llDeleteSubList(visitor_list, 0, llGetListLength(visitor_list));
llSay( 0, "Done resetting.");
if( message == "Sort" )
{
sortBoard() {
visitor_list = llListSortList(visitor_list);
integer count = llGetListLength(visitor_list);
while (--count >= 0) {
string name = llList2String(visitor_list, count);
llMessageLinked(count+1, 0, name, NULL_KEY);
}
}
if( message == "SayList" )
{
llSay( 0, "Racers:" );
integer len = llGetListLength( visitor_list );
integer i;
for( i = 0; i < len; i++ )
{
llSay( 0, llList2String(visitor_list, i) );
}


}
}
}
}
}

I am sooooo sorry I am trying to learn.......
Laurie Stilman
Registered User
Join date: 11 Apr 2006
Posts: 45
12-23-2009 18:15
The code I posted is a function, which must come before the state ("default { ...";) part of the script. You can either remove the enclosing function declaration (the first line, "sortBoard() {" and trailing "}";), or move the whole thing up before "default {" and change your if condition to "if (message == "Sort";) { sortBoard(); }". And you might want to do a little reading on the LSL Portal to understand basic script structure a little better :-)

Hope that helps!
Kimmy Gable
Registered User
Join date: 8 Apr 2006
Posts: 14
12-23-2009 20:09
Well I understand how that works but I keep getting the same error an not sure why.
Everytime I try to save it, it says here visitor_list = llListSortList(visitor_list); that visitor_list name is not defined with in scope



CODE

if( message == "Sort" )
{
string visitor_list;
visitor_list = llListSortList(visitor_list);
integer count = llGetListLength(visitor_list);
while (--count >= 0) {
string name = llList2String(visitor_list, count);
llMessageLinked(count+1, 0, name, NULL_KEY);
Pete Olihenge
Registered User
Join date: 9 Nov 2009
Posts: 315
12-24-2009 01:36
It is objecting to "llListSortList"; the function is called llListSort, and it requires more than one parameter. See http://wiki.secondlife.com/wiki/LlListSort. Also, in your example you declare visitor_list as a string - it should be a list - and sorting a newly declared, and thus empty, list is a bit pointless.