the MAIN issue with something like this, is the strict limits on sensors.
Sensors can only detect the 16 nearest objects, avatars, etc. this means, literally, what you'd need to do, is make a single sensor, that moves through the land, in a search pattern. If you gave it criteria like : if (llGetOwnerKey(llDetectedKey(0)) == friend's key) then it could slowly, and methodically plod through your land, moving perhaps .5m at a time.. and reporting back it's findings via IM or email or something.
like I said, the problem is, you can't filter a search BY owner, you have to filter the RESULTS of the search by owner. And again, only the 16 nearest objects to the sensor will be reported. So if you had 16 unlinked prims forming a wall, and a prim of your friend's behind that wall, the sensor might not even SEE that prim.. so you have to keep it moving, and rescanning.
with the new build height being 4096m, and the fact that you can't SCRIPT a prim to move below the ground... a search like this could take hours and hours... and might still miss a few things.
if you have access to the estate tools, you might get lucky if the item is scripted. You can do a "top scripts" search and hope that your friend's name shows up.
It's conceivable that something might be doable with a custom SL client.. but I wouldn't have a clue where to even begin building it.
Your best advice is to ask your friend if it's safe to return their prims..
Worst case scenario... here's a modified version of Argent's "Detect My Stuff" script. Put it in a prim, and wear it, and fly around your land.. it's not super fast at scanning.. but it's been useful, particularly in open areas.
key myfriend = "";
// insert your friend's key in the quotes above.
// use < http://w-hat.com/name2key > to find your friend's key.
// This Script is distributed under the terms of the modified BSD license, reproduced at the end
// of the script. The license and acknowledgments listed must be included in some fashion if
// this script is redistributed in a non-readable or non-modifiable form.
list objects;
integer next;
list particle_system;
integer active = -1;
float last_sensed;
list new_objects;
key last_closest_object;
float last_closest_distance;
display(integer next_active, integer force)
{
float now = llGetTime();
if(last_sensed > now) last_sensed = 0.0;
if(next_active == 0)
{
if(active >= 0 && last_sensed > now - 5.0)
{
return;
}
}
else
{
last_sensed = now;
if(force) llSetTimerEvent(0.01);
}
if(active == next_active) return;
active = next_active;
if(active == 0)
{
llSetColor(<0.5,0.5,0.5>,ALL_SIDES);
llSetText("",<0,0,0>,0);
llSetTimerEvent(0);
llParticleSystem([]);
llSetPrimitiveParams([PRIM_FULLBRIGHT,ALL_SIDES,0]);
last_closest_object = NULL_KEY;
last_closest_distance = 96.0;
}
else
{
llSetColor(<1,1,1>,ALL_SIDES);
llSetTimerEvent(0.01);
llSetPrimitiveParams([PRIM_FULLBRIGHT,ALL_SIDES,1]);
}
}
default
{
state_entry()
{
// Have to put it here because LSL doesn't do constant folding, so you can't have constant
// expressions at the global level.
particle_system = [
PSYS_PART_FLAGS,0
|PSYS_PART_EMISSIVE_MASK
|PSYS_PART_TARGET_POS_MASK
|PSYS_PART_TARGET_LINEAR_MASK
|PSYS_PART_FOLLOW_VELOCITY_MASK
|PSYS_PART_INTERP_SCALE_MASK,
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_DROP,
PSYS_SRC_TEXTURE, "1d8d76a1-c9bb-1be8-7fb2-de3e8009044c",
PSYS_PART_START_COLOR, <1.0,0.0,1.0>,
PSYS_PART_START_SCALE, <0.1,0.1,0>,
PSYS_PART_END_SCALE, <0.1,0.1,0.0>,
PSYS_SRC_BURST_PART_COUNT,10,
PSYS_SRC_BURST_RATE,0.0,
PSYS_PART_MAX_AGE,10.0
];
display(0, 0);
//llSensor("", "", ACTIVE|PASSIVE, 96, PI);
llSensorRepeat("", "", ACTIVE|PASSIVE, 96, PI, 1);
}
on_rez(integer p)
{
llResetScript();
}
sensor(integer total_number)
{
integer i;
integer force = 0;
// There's a bug in llSensorRepeat ... sometimes it returns the NEXT 16 objects not
// the FIRST 16 objects. This would be useful if it was reliable, but it's not, so
// it's not good sense to rely on it. So... if the closest object is further away
// then what we saw last time, it's not a good_sense, so ignore this scan. This will
// produce a slight delay if the closest object is deleted of the sensor is moving,
// but shouldn't be noticable unless you're doing something like using this as a HUD.
//
// If you are, and you come up with better code to work around this, send me a copy.
//
// Apologies for the pun, it wasn't avoidable.
key closest_object = llDetectedKey(0);
float closest_distance = llVecDist(llGetPos(), llDetectedPos(0));
integer good_sense = FALSE;
if(closest_object == NULL_KEY)
good_sense = TRUE;
else if(closest_object == last_closest_object)
good_sense = TRUE;
else if(closest_distance < last_closest_distance)
good_sense = TRUE;
last_closest_object = closest_object;
last_closest_distance = closest_distance;
if(!good_sense)
return;
list new_objects = [];
integer offset = 0;
for(i = 0; i < total_number; i++)
{
key id = llDetectedKey(i);
if(llGetOwnerKey(id) == myfriend)
{
if(!force && llList2Key(objects, offset) != id)
{
force = 1;
next = offset;
}
new_objects += [id,llDetectedName(i),llDetectedPos(i)];
offset += 3;
}
}
objects = new_objects;
display(offset != 0, force);
new_objects = [];
}
no_sensor()
{
llOwnerSay("Sensed Nothing");
display(0, 0);
}
timer()
{
integer n = llGetListLength(objects);
if(!n)
{
display(0, 0);
return;
}
if(next >= n) next = 0;
llSetTimerEvent(5);
key id = llList2Key(objects, next);
string name = llList2Key(objects,next+1);
string pos = (string) llList2Vector(objects,next+2);
string total = (string) (n / 3);
string num = (string) (next / 3 + 1);
next+=3;
llParticleSystem(particle_system + [PSYS_SRC_TARGET_KEY,id]);
llSetText(num+"/"+total+": "+name+"\n"+pos+"\n \n \n \n \n",<1,1,1>,1);
}
}
//Copyright (c) 2006, Argent Stonecutter & player
//All rights reserved.
//
//Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
//
// * Redistributions in modifiable form must retain the above copyright notice, this list of conditions and the following disclaimer.
// * Redistributions in non-modifiable form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
// * Neither the name of Argent Stonecutter nor his player may be used to endorse or promote products derived from this software without specific prior written permission.
//
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.