Don't click here unless you want to be banned.

LSL Wiki : LibraryCBAgentTracker

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl338.us.archive.org
// AgentTracker

// A specialized sensor that lets modules know if
// a specific agent (defined in trackAgent()) goes farther then
// X amount of distance (defined in trackAgent()) from the point 
// it was at when trackAgent() was called.

// Copyright (C) 2005-2006  Francisco V. Saldana
// 
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
// 
// Francisco V. Saldana can be contacted using his email account 
//  username: dressedinblue, at domain: gmail.com
// and in Second Life by IMming Christopher Omega


// Triggers an agentOutOfRange(key agentKey) method call if agent 
// moves out of range.

// Methods:
// trackAgent(key agentKey, float range)
// Starts tracking the specified agent. Ignores subsequent calls
// unless stopTrackAgent() is called.

// stopTrackAgent(key agentKey) 
// Stops tracking the specified agent.
// A call to trackAgent will start another tracking session.


float SENSOR_INTERVAL = 1.0;

vector startingPosition = ZERO_VECTOR;
float movementRange = 0;
key targetAgentKey = NULL_KEY;

// ========== For method invocation ==========
string randomStr(string chars, integer len) {
    integer numChars = llStringLength(chars);
    string ret;
    integer i;
    for (i = 0; i < len; i++) {
        integer randIndex = llFloor(llFrand(numChars));
        ret += llGetSubString(chars, randIndex, randIndex);
    }
    return ret;
}

string SEPERATOR_CHARS = "`~!@#$%^&*()-_+[]{}\|'\";/?.>,<";
integer SEPERATOR_LEN  = 3;
string dumpList2String(list src) {
    // Generate a seperator not present in any of the
    // elements in the list.
    string chars = (string) src; // Squashes all elements together.
    string seperator;
    do {
        seperator = randomStr(SEPERATOR_CHARS, SEPERATOR_LEN);
    } while (llSubStringIndex(chars, seperator) != -1);
    return seperator + llDumpList2String(src, seperator);
}

list parseStringKeepNulls(string src) {
    // The seperator should be the first SEPERATOR_LEN
    // characters in the string.
    return llParseStringKeepNulls(llDeleteSubString(src, 0, SEPERATOR_LEN - 1),
        [llGetSubString(src, 0, SEPERATOR_LEN - 1)], []);
}

callMethod(integer callId, string methodName, list parameters) { 
    llMessageLinked(LINK_THIS, callId,
        dumpList2String(parameters), methodName);
}

returnValue(string methodName, integer methodIdentifyer, list value) {
    llMessageLinked(LINK_THIS, methodIdentifyer, 
        dumpList2String(value), methodName + "_ret");
}
// =============================================

trigger_agentOutOfRange(key agentKey) {
    callMethod(0, "agentOutOfRange", [agentKey]);
}

trigger_pong(string moduleName) {
    callMethod(0, "pong", [moduleName]);
}

string this;
default {
    state_entry() {
        this = llGetScriptName();
    }
    
    link_message(integer sender, integer num, string parameters, key methodName) {
        if (methodName == "trackAgent") {
            list paramList = parseStringKeepNulls(parameters);
            // Method signature:
            // trackAgent(key agentKey, float range)
            key     agentKey    = (key)     llList2String(paramList, 0);
            float   range       = (float)   llList2String(paramList, 1);
            
            targetAgentKey = agentKey;
            movementRange = range;
            
            // Find the agents initial position:
            llSensor("", targetAgentKey, AGENT, 96, TWO_PI);
        } else if (methodName == "ping") {
            list paramList = parseStringKeepNulls(parameters);
            // Method signature:
            // ping(string moduleName)
            string moduleName = llList2String(paramList, 0);
            if (moduleName == this)
                trigger_pong(this);
        }
    }
    
    sensor(integer numDetected) {
        startingPosition = llDetectedPos(0);
        state tracking;
    }
    
    no_sensor() {
        trigger_agentOutOfRange(targetAgentKey);
    }
}

state tracking {
    state_entry() {
        llSensorRepeat("", targetAgentKey, AGENT, 
            llVecDist(llGetPos(), startingPosition) + movementRange, TWO_PI, SENSOR_INTERVAL);
    }
    
    link_message(integer sender, integer num, string parameters, key methodName) {
        if (methodName == "stopTrackAgent") {
            list paramList = parseStringKeepNulls(parameters);
            // Method signature:
            // stopTrackAgent(key agentKey)
            key agentKey = (key) llList2String(paramList, 0);
            
            if (agentKey == targetAgentKey || agentKey == NULL_KEY)
                state default;
        } else if (methodName == "ping") {
            list paramList = parseStringKeepNulls(parameters);
            // Method signature:
            // ping(string moduleName)
            string moduleName = llList2String(paramList, 0);
            if (moduleName == this)
                trigger_pong(this);
        }
    }
    
    sensor(integer d) {
        float distanceMoved = llVecDist(startingPosition, llDetectedPos(0));
        if (distanceMoved > movementRange) {
            trigger_agentOutOfRange(targetAgentKey);
            state default;
        }
    }
    
    no_sensor() {
        trigger_agentOutOfRange(targetAgentKey);
        state default;
    } 
    
    state_exit() {
        llSensorRemove();
    }
}


LibraryContentBrowser
There is no comment on this page. [Display comments/form]