Skip to content

Instantly share code, notes, and snippets.

@clairem-sl
Created September 28, 2022 08:25
Show Gist options
  • Select an option

  • Save clairem-sl/abbbb23df94771fa43979d14448e0c27 to your computer and use it in GitHub Desktop.

Select an option

Save clairem-sl/abbbb23df94771fa43979d14448e0c27 to your computer and use it in GitHub Desktop.
Find Abandoned Parcels
// FindAbandonedParcels.lsl
// Released to the Public Domain by Claire Morgenthau
// If Public Domain is not applicable in your jurisdiction,
// you can use one of the following licenses:
// WTFPL, CC0, Unlicense, 0BSD, or MIT-0
integer MINIGRID_SIZE = 8;
// ===== DO NOT EDIT BELOW THIS LINE =====
key GOVERNOR_LINDEN = "3d6181b0-6a4b-97ef-18d8-722652995cf1";
key DEPT_PUBLIC_WORKS = "4a18e287-db5b-0551-2500-087da6e89efb";
// Simple -- and possibly grossly inaccurate -- logic:
integer IsProbablyAbandoned(key owner, string message) {
string strLo = llToLower(message);
// LL-owned parcels
if (owner == GOVERNOR_LINDEN || owner == DEPT_PUBLIC_WORKS) {
if (llSubStringIndex(strLo, "protected land") != -1) return 0;
if (llSubStringIndex(strLo, "route") == 0) return 0;
else return 1;
}
if(llStringLength(message) == 0) return 0;
if(llSubStringIndex(strLo, "abandoned") > -1) return 1;
else return 0;
}
string Vec2IntString(vector vec) {
return
"<" +
(string)((integer)vec.x) + "," +
(string)((integer)vec.y) + "," +
(string)((integer)vec.z) +
">"
;
}
vector COLOR_WHITE = <1.0, 1.0, 1.0>;
vector COLOR_BLACK = <0.0, 0.0, 0.0>;
float OPAQUE = 1.0;
float TRANSP = 0.0;
list PARCEL_WANT_DETAILS = [PARCEL_DETAILS_NAME, PARCEL_DETAILS_DESC, PARCEL_DETAILS_AREA, PARCEL_DETAILS_ID, PARCEL_DETAILS_OWNER];
integer ScanForAbandoned() {
integer x;
integer y;
list parcelDetails;
integer candidates = 0;
list candidatePos = [];
list candidateName = [];
list candidateArea = [];
list candidateID = [];
string status;
string parcelSeen;
string parcelID;
integer parcelArea;
key parcelOwner;
string parcelName;
string parcelNeedle;
// LL does not provide a convenient function to dump a list of parcels in a region,
// so we bruteforce by scanning per 8x8 minigrids.
// The number 8 was chosen by observation of other scanning scripts which had settled for 8.
for (x = 0; x <= 256; x += MINIGRID_SIZE) {
for (y = 0; y <= 256; y += MINIGRID_SIZE) {
status = "(" + (string)x + "," + (string)y + ") " + (string)candidates + " so far";
llSetText(status, COLOR_WHITE, OPAQUE);
vector parcelPos = <(float) x, (float) y, 0.0>;
parcelDetails = llGetParcelDetails(parcelPos, PARCEL_WANT_DETAILS);
parcelID = llList2String(parcelDetails, 3);
parcelNeedle = "@@" + parcelID;
if (llSubStringIndex(parcelSeen, parcelNeedle) == -1) {
parcelSeen = parcelSeen + parcelNeedle;
parcelOwner = llList2Key(parcelDetails, 4);
parcelName = llList2String(parcelDetails, 0);
parcelArea = llList2Integer(parcelDetails, 2);
if (IsProbablyAbandoned(parcelOwner, parcelName)) {
candidates += 1;
parcelArea = llList2Integer(parcelDetails, 2);
candidatePos = candidatePos + parcelPos;
candidateName = candidateName + parcelName;
candidateArea = candidateArea + parcelArea;
candidateID = candidateID + parcelID;
}
}
}
}
llSetText("", COLOR_BLACK, TRANSP);
// Cleanup the heavy objs
parcelDetails = [];
parcelSeen = "";
status = "===== Candidates in " + llGetRegionName() + " =====";
llInstantMessage( llGetOwner(), status);
if (candidates) {
for (x = 0; x < candidates; x++) {
status =
Vec2IntString(llList2Vector(candidatePos, x)) + " " +
llList2String(candidateArea, x) + "m2 " +
"secondlife:///app/parcel/" + llList2String(candidateID, x) + "/about"
;
llOwnerSay(status);
// llInstantMessage( llGetOwner(), status);
}
llInstantMessage( llGetOwner(), "------------------------------");
}
else {
llOwnerSay("----- No candidates found -----");
}
// Cleanup
status = "";
candidatePos = [];
candidateName = [];
candidateArea = [];
candidateID = [];
return 0;
}
// ############################################################
default {
state_entry() {
llOwnerSay("I . AM . STARTED !");
}
touch_start(integer num_detected) {
ScanForAbandoned();
}
changed(integer change)
{
if (change & CHANGED_REGION) {
// llOwnerSay("Don't move too fast! Region is being scanned...");
llInstantMessage( llGetOwner(), "Don't move too fast! Region is being scanned...");
ScanForAbandoned();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment