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