Jump to content

Question about avatar keys in script. (How to check if the same key is already present?)


Minareth Irata
 Share

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

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

Recommended Posts

Hi, I'm making a little script to detect if an avatar is near, and so far it does tell if someone is near but it keeps repeating, logic of course since I'm using llSensorRepeat.

Now I wish the script to store a name and remember it, and when it uses sensor again and notices the same name/key comes along again, to not say it again, only to 'forget' the name when the agent leaves sensor range.

Also do I wish it to be able to detect more than one name at a time, can anyone tell me how?

Link to comment
Share on other sites

  • Create a global variable list that holds the avatars previously detected
  • in no_sensor() clear the list - because, obviously, no avatars are detected
  • in sensor() use the parameter of number detected - up to 16 is the limit for sensors
  • Loop through each of the detected avatars using llDetectedKey(n) or llDetectedName(n) - whichever you want to store
  • Use llListFindList() to see if they were previously detected (in your global list)
  • If not, report them
  • After you've looped through all the currently-detected avatars update the global list to who is here in this sweep
Link to comment
Share on other sites

I tried to do what your list said, getting no compiler errors, but neither the item does what it's supposed to do, can you perhaps point out where it went wrong?

list detected_users;default{    state_entry()    {        llSensorRepeat("","",AGENT,96,PI, 1);     }    sensor(integer iNum)    {        integer i;        detected_users = [];        for( i=0; i<iNum; i++ )        {            detected_users += [llDetectedName(i)];         }        integer index = llListFindList(detected_users, [llDetectedName(i)]);        if (index != -1)        {            llInstantMessage(llGetOwner(), llDumpList2String(detected_users, "\n"));        }    }        no_sensor()    {        detected_users = [];    }}

 

Link to comment
Share on other sites

Close, easier to show you with a complete example - although I haven't compiled this:

list Visitors;default{	state_entry(){		llSensorRepeat("", "", AGENT, 96.0, PI, 1.0);	}	no_sensor(){		Visitors = [];	}	sensor(integer Number){		string Name;		list New;		while(Number--){			Name = llDetectedName(Number);			New += [Name];			if(-1 == llListFindList(Visitors, [Name])){				llOwnerSay(Name + " detected");			}		}		Visitors = New;	}}

 

state_entry() and no_sensor() don't need any explanation;

sensor() does :-)

I am building a 'new' list from every name detected in this sweep.

Each name is then checked to see if it was detected in the list from the PREVIOUS sweep (the global Visitors list)

Once all names have been checked the new list from this sweep replaces/updates the visitors list, ready for the next sweep.

  • Like 1
Link to comment
Share on other sites

You're welcome.  I used some structures and syntax that I prefer but that might not be the ones you are first used to.  This version of the script is structured differently and commented to try to make things clearer.  I hope it helps

 

list Current;	// Avatars found during the current sensor sweeplist Previous;	// Avatars found during the previous sensor sweepdefault{	state_entry(){		// Check for avatars every 5 seconds - should be quick enough for most purposes without being laggy		llSensorRepeat("", "", AGENT, 96.0, PI, 5.0);	}	no_sensor(){		// Nothing was detected in the current sweep, so next time Previous starts empty		Previous = [];	}	sensor(integer Number){		// One or more avatars detected.  Rebuild the Current list as they are checked		Current = [];		integer Counter;		string Name;		// Loop through all the detected avatars		for(Counter = 0; Counter < Number; Counter++){			// Extract their name (this is just so the script doesn't have to keep calling the function)			Name = llDetectedName(Counter);			// Add them to the list of currently-detected avatars			Current += [Name];			// Check to see if they were detected in the previous sweep			if(llListFindList(Previous, [Name]) == -1){				// If not, they are new - do whatever the script is for here				llOwnerSay(Name + " detected");			}		}		// Remember the list of avatars from this sweep so it can be used in the next one		Previous = Current;	}}

 

Link to comment
Share on other sites

  • 2 weeks later...

That's only one step farther than you've gone already.  You have a list named Previous that holds the names of all avatars that were within range the last time the sensor fired. So, all you need to do is compare names in Current list to ones in the Previous list.  Anyone who was in the list named Previous but is not in Current must have left.

So,

integer len = llGetListLength(Previous);integer i;for (i = 0; i < len; ++i){     if (!~llListFindList(Current,llList2String(Previous,i))     //That is, if the ith element of Previous is NOT in the list named Current .....    {        llSay(0, llList2String(Previous,i) + " has left the building.");    }}

 

Link to comment
Share on other sites

I do it a bit differently, on the basis that if there's more than 16 people in range, the sensor will only detect the first 16 of them, so the fact you don't detect someone doesn't necessarily mean they've moved out of range.    So, once I've spotted someone, I grab their key, too, and use llGetObjectDetails to see if they're still around.   Something like this:

 

float frequency = 5.0;float range=96.0;integer max;integer toggle;key owner;key k;list detected;string s;vector pos;clean_list(){	list temp = llList2ListStrided(detected,0,-1,2);//pull out a list of the keys	max = llGetListLength(temp);	while(max--){//loop through the list of keys		k = llList2Key(temp,max);		if(llGetAgentSize(k)==ZERO_VECTOR//left the sim			||llVecDist(pos,llList2Vector(llGetObjectDetails(k,[OBJECT_POS]),0))>range){//still on sim but out of range				integer n = llListFindList(detected,[k]);//find the agent's key in the detected list				llOwnerSay(llList2String(detected,(n+1))+" is no longer in range");				detected=llDeleteSubList(detected,n,(n+1));//remove the key and the name from the list			}	}}default{	state_entry()	{		owner = llGetOwner();	}	touch_start(integer total_number)	{		if(llDetectedKey(0)==owner){			toggle=!toggle;			if(toggle){				llOwnerSay("Turning on");				pos = llGetPos();				llSensorRepeat("","",AGENT,range,PI,frequency);			}			else{				llOwnerSay("Turning off");				llSensorRemove();			}		}	}	sensor(integer total_number)	{		max = total_number;		while(max--){			k = llDetectedKey(max);			if(!~llListFindList(detected,[k])){				s = llGetUsername(k);				llOwnerSay("Just detected "+s);				detected +=[k]+[s];			}		}		clean_list();	}	no_sensor(){		clean_list();	}}

 

Link to comment
Share on other sites

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