Parcel Scanning

From Second Life Wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Scanning parcels within a simulator can be a slow process if not done efficiently. In order to solve this I devised a neater way of scanning parcels that can reduce the number of operations required by 50% or more.

The following script by Haravikk Mistral is provided as-is, and will simply test the simulator you place it in for land-owners, then every 24 hours it will re-scan and inform you of any new land-owners, or any that have left. It will do this by treating the region first as a square 256 units wide, test it, and if required will sub-divide it in order to narrow down its search to detect individual parcels.

NOTE: The script's timer is set to a default of 2 seconds, this is assuming that speed is not an issue, and stops the script from causing much lag.

list    oldOwners   = [];
list    oldGroups   = [];

list    newOwners   = [];
list    newGroups   = [];

list    gridAreas   = [];
list    gridDefault = [];

integer operations  = 0;

default {
    state_entry() {
        gridAreas = gridDefault = [0.5, 0.5, 255.5, 255.5];
        llSetTimerEvent(0.01);
    }
    
    timer() {
        float cx    = llList2Float(gridAreas, 0);
        float cy    = llList2Float(gridAreas, 1);
        float tx    = llList2Float(gridAreas, 2);
        float ty    = llList2Float(gridAreas, 3);
        
        gridAreas   = llDeleteSubList(
            (gridAreas = []) + gridAreas, 
            0, 
            3
        );
        
        key owner1 = NULL_KEY;
        key owner2 = NULL_KEY;
        key owner3 = NULL_KEY;
        
        float x = cx; float y = cy; integer pattern = 0;
        @gridProcess;
            ++operations;
            list details = llGetParcelDetails(
                <x, y, 0.0>,
                [
                    PARCEL_DETAILS_OWNER,
                    PARCEL_DETAILS_GROUP,
                    PARCEL_DETAILS_AREA
                ]
            );
            
            key     k = llList2Key(details, 0);
            key     g = llList2Key(details, 1);
            list    l = [k];
            if (!(~llListFindList(oldOwners, l)) && 
                !(~llListFindList(newOwners, l))) {
                if ((k != NULL_KEY) && (k != g)) newOwners += l;
                else {
                    k = g;
                    l = [k];
                    
                    if (!(~llListFindList(oldGroups, l)) && 
                        !(~llListFindList(newGroups, l))) {
                        if (k != NULL_KEY) newGroups += l;
                    }
                }
            }
            
            if (!pattern) {
                owner1 = k;
                y = ty;
            } else if (1 == pattern) {
                owner2 = k;
                x = tx;
            } else if (2 == pattern) {
                owner3 = k;
                y = cy;
            } else if (3 == pattern) {
                float gridSize = tx - cx;
                if (gridSize > 4.0) {
                    if ((owner1 != owner2) || (owner2 != owner3) ||
                        (owner3 != k) || (owner1 != k) || 
                        (llList2Float(details, 2) < 
                            (gridSize * gridSize))) {
                        float midG = llRound(gridSize / 2.0);
                        float midX = cx + midG;
                        float midY = cy + midG;
                        
                        list newGrids = [];
                        if (midX > cx) {
                            if (midY > cy) 
                                newGrids = [
                                    cx, cy, midX, midY,
                                    midX, cy, tx, midY,
                                    cx, midY, midX, ty,
                                    midX, midY, tx, ty
                                ];
                            else 
                                newGrids = [
                                    cx, cy, midX, ty,
                                    midX, cy, tx, ty
                                ];
                        } else if (midY > cy) 
                            newGrids = [
                                cx, cy, tx, midY,
                                cx, midY, tx, ty
                            ];
    
                        if (newGrids != []) 
                            gridAreas = (gridAreas = []) + 
                                newGrids + gridAreas;
                    }
                }
            }
        if (3 > pattern) {
            ++pattern;
            jump gridProcess;
        }
        
        if ([] == gridAreas) {
            string msg = "Complete after " + 
                    (string)operations + " operations.";
            
            integer x = oldOwners != [];
            while ((--x) >= 0) {
                integer index = llListFindList(
                    newOwners, [llList2Key(oldOwners, x)]
                );
                
                if (~index) 
                    newOwners = llDeleteSubList(
                        (newOwners = []) + newOwners, 
                        index, 
                        index
                    );
                else 
                    oldOwners = llDeleteSubList(
                        (oldOwners = []) + oldOwners,
                        x,
                        x
                    );
            }
                    
            if (x = newOwners != []) {
                msg += "\nNew land owners:";
                while ((--x) >= 0) 
                    msg += "\n" + llList2String(newOwners, x);
                msg += "\n";
            }
            
            if (x = oldOwners != []) {
                msg += "\nAbsent land owners:";
                while ((--x) >= 0) 
                    msg += "\n" + llList2String(oldOwners, x);
                msg += "\n";
            }
            
            oldOwners = (oldOwners = newOwners = []) + 
                oldOwners + newOwners;
                
            x = oldGroups != [];
            while ((--x) >= 0) {
                integer index = llListFindList(
                    newGroups, [llList2Key(oldGroups, x)]
                );
                
                if (~index) 
                    newGroups = llDeleteSubList(
                        (newGroups = []) + newGroups, 
                        index, 
                        index
                    );
                else 
                    oldGroups = llDeleteSubList(
                        (oldGroups = []) + oldGroups,
                        x,
                        x
                    );
            }
                    
            if (x = newGroups != []) {
                msg += "\nNew land groups:";
                while ((--x) >= 0) 
                    msg += "\n" + llList2String(newGroups, x);
                msg += "\n";
            }
            
            if (x = oldGroups != []) {
                msg += "\nAbsent land groups:";
                while ((--x) >= 0) 
                    msg += "\n" + llList2String(oldGroups, x);
            }
            
            oldGroups = (oldGroups = newGroups = []) + 
                oldGroups + newGroups;
                
            llInstantMessage(llGetOwner(), (msg = "") + msg);
                
            gridAreas = gridDefault;
            float time = 86400.0 - llGetGMTclock();
            if (time < 3600.0) time += 86400.0;
            
            llSetTimerEvent(time);
        } else llSetTimerEvent(2.0);
    }
}