Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

how does the llSensor function work?

Senuka Harbinger
A-Life, one bit at a time
Join date: 24 Oct 2005
Posts: 491
11-17-2005 21:21
or rather, how the hell do I find out what was scanned when the llSensor function is called?

what I'm trying to do is create a simple HUD attachment that when clicked scans avatars within a certain specified radius, and by clicking one of two buttons will cycle through the avatars scanned (displaying the currently selected avatar name with a llSetText Script). my problem is that I have no idea how to acess what is returned from calling the llSensor command. the wiki is very helpful in telling me what is returned, but not how to look at the info returned (using llOwnerSay to show the avatar names of avatar keys that are scanned for example).
Nada Epoch
The Librarian
Join date: 4 Nov 2002
Posts: 1,423
11-17-2005 21:31
You need to utilize the sensor event, found here in the wiki. you will porbably need to store the found information in a list, and then the two buttons cycle through that list.

I used the button code from this thread in the scripting library, well rather from the discussion thread on it(Strife Onizuka variant).

And I haven't tested the code, so um, trouble shoot at will :-).
CODE

list gAvs;
int gMarker;

default
{
touch_start(integer total_number)
{
string name = llGetLinkName(llDetectedLinkNumber(0));
if(name == "left")
{
llOwnerSay(llList2String(gAvs,gMarker);
gMarker++;
if(gMarker >= llGetListLength(gAvs))
gMarker = 0;
}
else if(name == "right")
{
llOwnerSay(llList2String(gAvs,gMarker);
gMarker--;
if(gMarker < 0)
gMarker = llGetListLength(gAvs)-1;
}
else if(name == "scan")
{
gAvs =[];
gMarker = 0;
llSensor("", NULL_KEY, AGENT, 10, PI);
}
}

sensor(integer total_number)
{
integer i;
for ( i = 0; i < total_number; i++ )
{
gAvs = gAvs + [llDetectedName(i)];
}
}

no_sensor() {
llOwnerSay("Nobody is around.");
}
}
_____________________
i've got nothing. ;)
Senuka Harbinger
A-Life, one bit at a time
Join date: 24 Oct 2005
Posts: 491
11-18-2005 10:20
thanks a heap. I found no real problems with your script aside from some typos. now I've modded it to my own uses, and I can't seem to get it to display a "target number out of total targets". any suggestions on why my method isn't working?

CODE

list gAvs; //avatar info from the scan
integer gMarker; //which info we are looking at
string currtar = "None"; //Current Target
integer i = 0; //added this in the hopes of having a "target out of" command but it's not working :(
vector color =<1,1,1>; //Sets the color of the text in the radar based on if there are nearby people or not. namely red means there are people nearby, green means it's all clear

default
{
touch_start(integer total_number) //things to do when the HUD attachment is touched since this is in the root prim these are triggered whenever *any* child prim is touched, but we're only going to do something when specific prims are touched.
{
string name = llGetLinkName(llDetectedLinkNumber(0)); //detects changes in the child prims that are linked to this parent prim. namely, it allows me to create buttons without a script in each button.
if(name == "left") //the button named left has been pushed
{
string currtar = (llList2String(gAvs,gMarker)); //lets get a name from these avatars and make that our current target
if (currtar == "") currtar = "None"; //if there are no names on the scan list, then rather than having a missing target, have it say "None" instead
llSetText("Current Target: \n" + currtar + " \n" + (string) i + "/" + (string) total_number,color,1); //Sets the text on the target screen. the whole (string) i +"/" + (string) total_number part is what's not working. I want it to display something like 3/9 meaning target number 3 out of 9 total
gMarker++; //increases the line of info we're looking at by 1
if(gMarker >= llGetListLength(gAvs)) //checks to see if the line of info we want is greater than the total number of lines of info. if it is, then it means we hit the end and we want to go back to the beginning
gMarker = 0; //sets the line marker to 0 (beginning) because we've reached the end of the list
}
else if(name == "right") //similar to the left button, only this is the one on the right. most of the following is the same as the above
{

string currtar= (llList2String(gAvs,gMarker));
if (currtar == "") currtar = "None";
llSetText("Current Target: \n" + currtar,color,1);
gMarker--;//moves the marker on the line of info back one line.
if(gMarker < 0)//if our info marker has gone below zero (that is, we started at the beginning of the list and want togo back), then we need to set the marker at the end of the list
gMarker = (llGetListLength(gAvs) - 1); //sets the marker at the end of the list.
}
else if(name == "scan") //detects if the actual radar has been touched. this starts the scan.
{
llOwnerSay("Scanning");//lets me know this is scanning. will be removed from the final product.
gAvs =[]; //sets the avatar list to zero I assume (not too familiar with the whole scanning thing in general
gMarker = 0; //Sets the marker to the start of the list for things we find in our scan
llSensor("", NULL_KEY, AGENT, 50, PI); //calls the actual sensor event. in this case we aren't looking for any specific names or keys, only agents (avatars) with a range of 50 meters and PI scanning radius (full sphere)
}
}

sensor(integer total_number) //the sensor event if something is found with the llSensor function
{
color = <1,0,0>; //since we scanned avatars set the color for the text to red. could be hostiles around >_> <_<
llSetText ((string)total_number + " avatars detected", color, 1 ); //displays the number of avatars detected
integer i; //for setting up a loop of somekind
for ( i = 0; i < total_number; i++ ) //the "For I = 0 to total_number loop if you were programming in QBasic
{
gAvs = gAvs + [llDetectedName(i)]; //I assume this builds a list of avatars. not too sure how I would access people's keys from this section if I wanted to add in missiles that homed in on someone.
}
}

no_sensor() //if nothing is found using the llsensor function, then we call up this event
{
color = <0,1,0>; //since no one's around, there are no hostiles. green is good :)
llSetText("No Targets Found",color,.5); //Sets the radar text informing you that there are no targets

}
}


[edit] did some heavy commenting in the hopes it might help :)
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
11-18-2005 10:41
CODE

llSetText("Current Target: \n" + currtar + " \n" + (string) i + "/" + (string) total_number,color,1);


That's probably because you're using total_number inside the touch_start event. In there, total_number is the number of avatars who have simultaneously touched your object. So in that call, total_number is almost always 1. What you need is to store the total_number in the sensor event to a global variable, and use that. That's the only time you know how many avs you scanned. Or use the length of the gAvs list.

Also, you're using i - where is that set? The only time I see it set is to loop through the sensor and fill up your list. It's not set anywhere inside the touch_start event, and you probably want to set it to something. I just took a quick look, so I might have missed where you're setting it.
Nada Epoch
The Librarian
Join date: 4 Nov 2002
Posts: 1,423
11-18-2005 12:16
I removed the global variables you put in because they were not necessary. You get the total number of avatars found by checking the length of the list, and you get the name by getting the string found in the list at the position denoted by gMarker.

Oh and i modified the logic slightly.
  1. Check to see if it is supposed to scan first
  2. if not scanning, and there are avatars in the list then cycle through them approriately
  3. if there are no avatars in the list, request that the player run a scan.


CODE
list gAvs; //avatar info from the scan 
integer gMarker; //which info we are looking at

vector color = <1,1,1>; //Sets the color of the text in the radar based on if there are nearby people or not. namely red means there are people nearby, green means it's all clear

default
{
touch_start(integer total_number) //things to do when the HUD attachment is touched since this is in the root prim these are triggered whenever *any* child prim is touched, but we're only going to do something when specific prims are touched.
{
string name = llGetLinkName(llDetectedLinkNumber(0)); // detects changes in the child prims that are linked to this parent prim.
// namely, it allows me to create buttons without a script in each button.
if(name == "scan") //detects if the actual radar has been touched. this starts the scan.
{
llOwnerSay("Scanning");//lets me know this is scanning. will be removed from the final product.
gAvs =[]; //sets the avatar list to zero I assume (not too familiar with the whole scanning thing in general
gMarker = 0; //Sets the marker to the start of the list for things we find in our scan
llSensor("", NULL_KEY, AGENT, 50, PI); //calls the actual sensor event. in this case we aren't looking for any specific names or keys, only agents (avatars) with a range of 50 meters and PI scanning radius (full sphere)
}
else if (llGetListLength(gAvs) > 0) //if it isn't a scan, and there are avatars in the list, then proceed with cycling through the targets
{
if(name == "left") //the button named left has been pushed
{
llSetText("Current Target: \n" + llList2String(gAvs,gMarker) + " \n" + (string) (gMarker+1) + "/" + llGetListLength(gAvs),color,1); //Sets the text on the target screen.you have to add 1 to gMarker when you display it because other wise you would end up with 0-8 of 9 instead of 1-9 of 9
gMarker++; //increases the line of info we're looking at by 1
if(gMarker >= llGetListLength(gAvs)) //checks to see if the line of info we want is greater than the total number of lines of info. if it is, then it means we hit the end and we want to go back to the beginning
gMarker = 0; //sets the line marker to 0 (beginning) because we've reached the end of the list
}
else if(name == "right") //similar to the left button, only this is the one on the right. most of the following is the same as the above
{
llSetText("Current Target: \n" + llList2String(gAvs,gMarker) + " \n" + (string) (gMarker+1) + "/" + llGetListLength(gAvs),color,1); //Sets the text on the target screen.
gMarker--;//moves the marker on the line of info back one line.
if(gMarker < 0)//if our info marker has gone below zero (that is, we started at the beginning of the list and want togo back), then we need to set the marker at the end of the list
gMarker = (llGetListLength(gAvs) - 1); //sets the marker at the end of the list.
}
}
else //you get here if you push the left or right button and the scan is empty.
{
llSetText("No targets found, you will need to scan before you cycle through targets.",color,1);
}
}

sensor(integer total_number) //the sensor event if something is found with the llSensor function
{
color = <1,0,0>; //since we scanned avatars set the color for the text to red. could be hostiles around >_> <_<
//totalAv = total_number; this code is not needed because you can get the total number found by checking the length of the list
llSetText ((string)total_number + " avatars detected", color, 1 ); //displays the number of avatars detected
integer i; //for setting up a loop to go throught all the avatars you found in the sensor event
for ( i = 0; i < total_number; i++ ) //the "For I = 0 to total_number loop if you were programming in QBasic
{
gAvs = gAvs + [llDetectedName(i)]; //I assume this builds a list of avatars. not too sure how I would access people's keys from this section if I wanted to add in missiles that homed in on someone.
//You would need to add their keys instead of their names llDetecetKey(i). which would be fine, because you could then use the llKey2Name() to get the persons name. it is totally up to you.
}
}

no_sensor() //if nothing is found using the llsensor function, then we call up this event
{
color = <0,1,0>; //since no one's around, there are no hostiles. green is good :)
llSetText("No Targets Found",color,.5); //Sets the radar text informing you that there are no targets

}
}
_____________________
i've got nothing. ;)
Senuka Harbinger
A-Life, one bit at a time
Join date: 24 Oct 2005
Posts: 491
11-18-2005 12:39
From: Ziggy Puff
CODE

llSetText("Current Target: \n" + currtar + " \n" + (string) i + "/" + (string) total_number,color,1);


That's probably because you're using total_number inside the touch_start event. In there, total_number is the number of avatars who have simultaneously touched your object. So in that call, total_number is almost always 1. What you need is to store the total_number in the sensor event to a global variable, and use that. That's the only time you know how many avs you scanned. Or use the length of the gAvs list.

Also, you're using i - where is that set? The only time I see it set is to loop through the sensor and fill up your list. It's not set anywhere inside the touch_start event, and you probably want to set it to something. I just took a quick look, so I might have missed where you're setting it.

thanks. that's my problem excactly :) now if only I could figure out how to get the distance to autoupdate without crashing my script