Jump to content

Any shortcuts to detect avatars entering a parcel?


GTASkinCentral
 Share

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

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

Recommended Posts

Hello!

Does anyone have any shortcuts that will allow me to detect new avatars within a parcel? Every time someone enters the parcel, I want to trigger a number of events. I have thought about having a timer to compare two lists, an archived list and a recent list.

Any help is much appreciated!

  • Like 1
Link to comment
Share on other sites

That's the strategy I would use. 

list WhoIsNew(){    list AllAvs = llGetAgentList(AGENT_LIST_PARCEL,[]);    list NewAvs;    integer i = llGetListLength(AllAvs);    while(i--)    {	if ( !~llListFindList(gHereAlready,llList2List(AllAvs,i,i)) )        {            NewAvs += llList2List(AllAvs,i,i);        }    }    gHereAlready = AllAvs;    return NewAvs;}

 

 

That makes use of the ListXnotY routine in the wiki at http://wiki.secondlife.com/wiki/ListXnotY.  Just remember to declare the global list gHereAlready.  Fire that routine maybe once a minute with your timer.  And if you don't care who the new people are, just make the routine return TRUE or FALSE instead of the list.

 

Link to comment
Share on other sites

As a simple Here/NotHere switch?  As I suggested, return TRUE/FALSE instead of the avatar list, as in

list gHereAlready;integer WhoIsNew(){    list AllAvs = llGetAgentList(AGENT_LIST_PARCEL,[]);    list NewAvs;    integer IsHere;    integer i = llGetListLength(AllAvs);    while(i--)    {	if ( !~llListFindList(gHereAlready,llList2List(AllAvs,i,i)) )        {            NewAvs += llList2List(AllAvs,i,i);            IsHere = TRUE;        }    }    gHereAlready = AllAvs;    return IsHere;}default{    state_entry()    {        llSetTimerEvent(60.0);    }    timer()    {        if(WhoIsNew())        {            // Set off flares, e-mail the owner, start playing a Sousa march ...        }        else        {            llInstantMessage(llGetOwner(),"Still no new visitors <sigh>");        }    }}

 

 

 

 

Link to comment
Share on other sites

In the OP I don't read any request for identifying the agents
In that case the task becomes simple

list agents;default{    state_entry()    {        agents = llGetAgentList(  AGENT_LIST_PARCEL, []);        llSetTimerEvent( 4.0);    }    timer()    {        list L = llGetAgentList(  AGENT_LIST_PARCEL, []);        if ( llGetListLength( L) > llGetListLength( agents) )        {            // the population has increased, take appropriate action        }        agents = L;    }}

This approach will not trigger when the number of entries equals the number of exits in one time window
That may or may not be a problem

:smileysurprised::):smileyvery-happy:

Link to comment
Share on other sites

It depends of the value of the timer in parameter of llSetTimerEvent .
If the value is big ( as for rollig where the value is 60 seconds ) , probability to get both people in and out :

First tick : there are 15 avatars .
between the first tick and second tick , there are one avatar who leaves , and one avatar who enters 
Second tick : there are always 15 avatars . 

If the value of the timer is short , probabilty that the new list is equal with the old list is big .
And we may optimize this , avoiding to call too much llfindlist.

To check quickly if the lists are the same, we may call llFindList with the full new list and the ful old list , and compare their length

The idea is there :

IN PSEUDOCODEif ( llListFindList(beforeList, nowList) == 0 ){	if ( llGetListLength(beforeList) == llGetListLength(nowList))	{	// NO UPDATE OF OLDLIST WITH NEWLIST. And New avatars is EMPTY	}	else	{	// UPDATE OLDLIST WITH NEWLIST . And New avatars is EMPTY	}}else{// WE DON T KNOW IF New Avatars is empty or not , WE NEED TO ITERATE THE LISTS}

 

 

list gHereAlready ;integer WhoIsNew( ){   list AllAvs = llGetAgentList(AGENT_LIST_PARCEL,[]);// if this test > 0 , so the whole AllAvs list is included in gHereAlready // with one block    if ( llListFindList(gHereAlready , AllAvs ) >= 0 )    {      // if lists have different lengths ,      // AllAvs is included in gHereAlready      // It means there are some people who have left     // So we need to update gHereAlready         if ( llGetListLength(gHereAlready) != llGetListLength(AllAvs))        {            gHereAlready = AllAvs;        }     // if lists have equal lengths     // gHereAlready is already equal to AllAvs     // We non t need to update it.     // This is what will happen the most often     // In the 2 cases , we may return directly without doing a loop     // because we know the AllAvs  is included in gHereAlready         return FALSE;    }    if ( llGetListLength(gHereAlready) == 0 )    {        gHereAlready = AllAvs;        return TRUE;    }                list NewAvs;    integer IsHere;    integer i = llGetListLength(AllAvs);    key k;    while(i--)    {        if ( !~llListFindList(gHereAlready,llList2List(AllAvs,i,i)) )        {            NewAvs += llList2List(AllAvs,i,i);            IsHere = TRUE;        }    }    gHereAlready = AllAvs;    return IsHere;}

 

It won t optimize a lot of . It depends of the number of avatars .

Around 35-45 avatars , i ve got around 40-60 ms  with the original version , and  25-35 ms with this version.

 

Link to comment
Share on other sites

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