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

LSL Wiki : LibraryRadar

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are crawl427.us.archive.org

Radar


Drop this script in a prim and set it on the ground or wear it on your HUD.

//Sable Till - Radar/scannar script.
//You can get a copy of the license this script is under at http://www.gnu.org/copyleft/gpl.html
//Copyright (C) 2006 Sable Till

//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.

string status="none";
list people;
integer maxScanDistance=96;
vector color = <0,1,1>;
integer maxPeople = 8;
integer scanType = AGENT;
integer scanFreq=1;
integer scanDistance=10;

integer count(string name) {
    integer i = llListFindList(people, [name]);
    if(i ==-1){
        people+=[name, 0];
        return 0;
    } else {
        integer count = llList2Integer(people, i+1);
        people=llListReplaceList(people, [count+scanFreq], i+1, i+1);
        return count;
    }
}

//calculate time strings with proper units that are sensibly rounded
string time(integer cnt) {
    if(cnt>3600) {
        return (string)(cnt/3600)+"hr " + (string)((cnt%3600)/60) +"min";        
    }else {
       if(cnt>60) {
            return (string)(cnt/60)+"min";
        } else {
            return (string)cnt+"s";
        }
    }
}
//I'm pretty sure there's a better way to do this but I'm trying to calculate the angle between
//North and the target so I can work out which direction it is in.
float getAngle(vector me, vector target) {
    float hyp = llVecDist(me, target);
    float yDiff = target.y-me.y;
    float xDiff = target.x-me.x;
    float angle = llSin(yDiff/hyp);
    if(xDiff>0 && yDiff>0) {
        return angle*RAD_TO_DEG;
    }
   if(xDiff>0 && yDiff<0) {
        return 90-angle*RAD_TO_DEG;
    }
    if(xDiff<0 && yDiff>0) {
        return angle*RAD_TO_DEG+270;
    }
    if(xDiff<0 && yDiff<0) {
        return angle*RAD_TO_DEG + 270;
    }
    return angle*RAD_TO_DEG;
}

default
{
    state_entry()
    {
        llSensorRepeat("", "",scanType, scanDistance, PI, scanFreq);
        llSetTimerEvent(15);
    }

    sensor(integer num_detected) {
        people=[];
        string result;
        integer n=-1;
        integer distance=0;
        integer detDist;
        string name;
        
        vector pos = llGetPos();
        //get the dist, name and direction of everyone we just scanned.
        for(n=0;n<num_detected && n<maxPeople;++n) {
            vector detPos = llDetectedPos(n);
            detDist = (integer)llVecDist(pos, detPos);
            float angle = getAngle(llGetPos(), detPos);
            name = llKey2Name(llDetectedKey(n));
            if(detDist<96) {
               people+=detDist;
               people+=name;
               people+=angle;
            }
        }
        //sort the strided list
        people = llListSort(people, 3, TRUE);
        //construct settext
        num_detected = llGetListLength(people)/3;
        for(n=0;n<num_detected;++n) {
            detDist=llList2Integer(people, n*3);
            name = llList2String(people, n*3+1);
            float dir = llList2Float(people, n*3+2);
            if(detDist>20 && distance<=20) {
                result+="<- Chat Range Limit ->\n";
            }
            result+=name;
            if(detDist<20) {
                integer cnt = count(name);
                result+=" ["+time(cnt)+"]";
            }
            result+=" ["+(string)detDist+"m]";
            
            if(dir < 0 || dir > 360) {
                llOwnerSay("Error:"+(string)dir+":"+name);
            }
            //determine which compass direction they are in.
            if(dir <= 22.5) {
                result+=" N\n";    
            } else {
            if(dir > 22.5 && dir <= 67.5) {
                result+=" NE\n";    
            } else {
            if(dir > 67.5 && dir <= 112.5) {
                result+=" E\n";    
            } else {
            if(dir > 112.5 && dir <= 157.5) {
                result+=" SE\n";    
            } else {
            if(dir > 157.5 && dir <= 202.5) {
                result+=" S\n";    
            } else {
            if(dir > 202.5 && dir <= 247.5) {
                result+=" SW\n";    
            } else {
            if(dir > 247.5 && dir <= 292.5) {
                result+=" W\n";    
            } else {
            if(dir > 292.5 && dir <= 337.5) {
                result+=" NW\n";    
            } else {
            if(dir > 337.5 && dir < 360) {
                result+=" N\n";
            }
            }                
            }
            
            }}}}}}
             
             distance=detDist;
        }

        //If we detected more (or the same number of) people as maxPeople then shrink down the scan distance to just
        //the distance to the furthest one. Otherwise increment it a bit in case there are people further out.
        if(num_detected>=maxPeople) {
            scanDistance=distance+10;
            llSensorRepeat("", "",scanType, scanDistance, PI, scanFreq);            
        } else {
            if(scanDistance<maxScanDistance) {
                scanDistance+=10;
                llSensorRepeat("", "",scanType, scanDistance, PI, scanFreq);                
            }
        }
        
        result+="\nStatus:" + status + ":" + (string)scanFreq + ":" + (string)scanDistance + ":" + (string)maxScanDistance;
        //adjust max people based on the length of result
        if(llStringLength(result)>254) {
            maxPeople--;
            llOwnerSay("Length is "+(string)llStringLength(result) + 
                " Decrementing maxPeople to "+(string)maxPeople);
        } else {
            if(llStringLength(result)<200 && num_detected>maxPeople) {
                maxPeople++;
                llOwnerSay("Length is "+(string)llStringLength(result) +
                " Incrementing maxPeople to "+(string)maxPeople);
            }
        }
        llSetText(result, color, 1);
    }
    
    no_sensor() {
        llSetText("Status:"+status, color, 1);
        maxScanDistance+=10;        
        llSensorRepeat("", "", scanType, maxScanDistance, PI, scanFreq);         
    }
    
    //all we do here is check the sims fps and dilation and tone down our scanning if necessary.
    timer() {
        float fps = llGetRegionFPS();
        float timeDilation = llGetRegionTimeDilation();
        
        if(fps<35 || timeDilation <0.9) {
            maxScanDistance=32;
            if(scanDistance>maxScanDistance) {
                scanDistance=maxScanDistance;
            }
            scanFreq=240;
            status = "poor";
            llSetTimerEvent(240);
            color=<1,0,0>;
        } else 
        {
        //sim is slightly lagged, we scan every 120seconds and to a max of 64metres
        if(fps<40 || timeDilation<0.95) {
            maxScanDistance=64;
            if(scanDistance>maxScanDistance) {
                scanDistance=maxScanDistance;
            }
            scanFreq=30;
            status = "ok";
            llSetTimerEvent(120);
            color=<1,1,0>;
        } else 
        //sim is fine, we scan every second and to the max distance possible
        {
            maxScanDistance=96;
            if(scanDistance>maxScanDistance) {
                scanDistance=maxScanDistance;
            }
            scanFreq=1;
            llSetTimerEvent(60);                
            status = "good";
            color=<0,1,1>;
        }}
        llSensorRepeat("", "", scanType, scanDistance, PI, scanFreq); 
    }
}
Comments [Hide comments/form]
I had a lot of problems playing with this example, I think there's some problems with the angles- first of all, the definition of angle inside the getAngle function needs to call llAsin, not llSin. The angle calculations are of, I believe: instead of returning the angles given, the four xDiff<>0 and yDiff<>0 cases should return N, 360+N, 180-N, 180+N. And finally, the cases for north, south, west, east etc. need to be adjusted by 90 degrees to compensate.
-- peekaboo.anybrowser.org (2007-03-31 21:22:54)
the

float angle = getAngle(llGetPos(), detPos);

should be changed to

float angle = getAngle(pos, detPos);
-- p54A34385.dip0.t-ipconnect.de (2007-04-01 11:28:27)
I believe there is an error in the getAngle() function. Because you are trying to get the angle between north and the target, that angle should only be affected by X and Y since angle to North it is a concept of the XY plane and Z should not affect any of your calculations. However you are not setting Z equal between the two vectors (or just to 0) so the hypotenuse will be the true distance in 3D space between the two vectors when it should be the distance in 2D space (XY plane). I am pretty sure this will skew the angles to odd values if the targets are not near each other in Z, and get worse as the difference in Z increases.
-- 67.87.189.72.cfl.res.rr.com (2007-04-14 13:56:43)
Someone please remove the garbage above? And my comment once the spam is gone. Thanks.
-- vtelinet-209-134-43-232.vermontel.net (2007-06-23 16:31:04)
Attach a comment to this page: