Parcel Scanning

From Second Life Wiki
Jump to navigation Jump to 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.

<lsl>list oldOwners = []; list oldGroups = [];

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

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

integer operations = 0;

default {

   state_entry() {
       gridAreas = gridDefault = [0.0, 0.0, 255.0, 255.0];
       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 > 1.0) {
                   if ((owner1 != owner2) || (owner2 != owner3) ||
                       (owner3 != k) || (owner1 != k) || 
                       (llList2Float(details, 2) < 
                           (gridSize * gridSize))) {
                       float midG = llRound(gridSize / 2.0);
                       float midX = llRound(cx + midG);
                       float midY = llRound(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);
   }

} </lsl>