Parcel Scanning

From Second Life Wiki
Jump to: navigation, search

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);
    }
}