Jump to content

What is wrong with this inactivity timer?


Life Camino
 Share

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

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

Recommended Posts

I'm using this inactivity timer in a remote scene rezzer script and it sometimes works and sometimes does not.  When it works, it works exactly as expected.  When it does not work, it seems to be determining that agents are within range when they really are not in range.

For example, if there are eight agents in the region, five of them might be together in a group 250m, or so, away at a lower altitude and three could be at the top of the sim over 1000m away, and the script will think that there are four agents within 100m.  I can look at the avatar positions on the minimap.  I can do the math in my head and know that they are hundreds of meters out of range.  I can even be 500m out of range and my key still end up in the list of agents that are within 100m.  So, what have I done wrong, or what is happening, here?  The script sometimes realizes that there is no one within 100m, but other times it does not.  Why?

 

timer()
    {
        llSetTimerEvent(0.0);

        if (inactive_flag && llGetUnixTime() - inactivity_timestamp > inactivity_timer && inactivity_timer != 0)
        {
            llOwnerSay("Inactivity timer expired.  Clearing scene, now...");
            llListenRemove(crate_listen_handle);
            llMessageLinked(LINK_THIS, 0, "AVRS_CLEAR", "");
            llRegionSay(crate_channel, "SCENE_CLEARED"); 
            llSleep(5.0);
            llDie();
        }            
        list agents = llGetAgentList(AGENT_LIST_REGION, []);
        integer n = llGetListLength(agents);
        integer i;
        for (; i< n; i++)
        {
            key current_agent = llList2Key(agents, i);
            list agent_details = llGetObjectDetails(current_agent, [OBJECT_POS]);
            vector agent_pos = llList2Vector(agent_details, 0);
            if (llVecDist(agent_pos, llGetPos()) > 100)
            {
                agents = llDeleteSubList(agents, i, i);//We only want to keep the agents who are in range
            }
        }
        if (llGetListLength(agents) == 0 && !inactive_flag && inactivity_timer != 0)
        {
            llOwnerSay("The scene has just gone inactive...");
            inactive_flag = TRUE;
            inactivity_timestamp = llGetUnixTime();
        }
        else if (llGetListLength(agents) > 0)
        {
            inactive_flag = FALSE;
            inactivity_timestamp = llGetUnixTime();
        }
        llSetTimerEvent(1.0);
    }

 

Link to comment
Share on other sites

When you know that you will be deleting items from a list in a looping operation, always start at the end of the list and count backwards.  That way, you are always removing elements at the high end and will not be affecting the indices of elements that you will need to examine later.  Otherwise, if you count upwards from the start of the list and then delete item #4, for example, all of the subequent items will be renumbered so that the next item the script examines will be the item that used to be #6 and is now #5.  It will never see the one that used to be #5.

Link to comment
Share on other sites

Problem solved - it works - ok - but for an activity timer ...

You only need to loop through the list until you find the 1st one thats is < 100m, then you can stop the loop and drop the list, no need to continue, no need to delete elements.

You check for 100m, why not using a sensor with a range of max 96m instead of checking the whole sim everytime?

The efforts of getting a list of avatars are only useful if its more than just an activity check.

Link to comment
Share on other sites


Life Camino wrote:

I chose not to use a sensor; because, at some point I may want to make the range user definable and then 96m becomes a limit.  By taking this approach, I can specify a much greater range, if needed.  Your other point is well-taken.

integer someone_is_here (float radius) {	list agents = llGetAgentList(AGENT_LIST_REGION,[]);	vector pos = llGetPos();	integer i = llGetListLength(agents);	while (--i>=0) {		if (llVecDist(llList2Vector(llGetObjectDetails(llList2Key(agents,i),[OBJECT_POS]),0),pos)<radius) return TRUE;        }        return FALSE;}

 

Link to comment
Share on other sites

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