Radar

De DigiWiki.

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); 
    }
}
Outils personnels
  • Cette page a été consultée 540 fois.
donate
Google Ads