Jump to content

llReturnObjectsByID


Leander Tyles
 Share

You are about to reply to a thread that has been inactive for 3865 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Hello,

after discovering this kewl new function in the other guys thread i tried making my own little gadget but im having a few problems


i blanked out   // llReturnObjectsByID(SendHome);
 while testing it so i dont mess up

and made it report back what item names it would be returning

the problem is i reconise some of these item names in the list because I OWN THEM,

which means they would have been returned to me... not good atall

i dont think thiers a problem with the script tho?

if (llList2Key(temp,0) != gCreatorKey && llOverMyLand(llDetectedKey(i)) == TRUE) 

so whys this happening, what to do hmm

integer minHeight = 0;
integer maxHeight = 4000;
integer increment = 96; // 41 ish scans
integer scanRange = 96;
float   waitTime = 1.0;

integer gON;
integer gOK;
key gCreatorKey;

vector gStartPos;
integer gReturnToStartPos=TRUE;

Warp(vector pos) {
    list rules;
    integer num = llRound(llVecDist(llGetPos(),pos)/10)+1;
    integer x;
    for(x=0; x<num; ++x) rules=(rules=[])+rules+[PRIM_POSITION,pos];
    llSetPrimitiveParams(rules);
}

Move() {
    llSleep(waitTime);
    vector pos = llGetPos();
    integer height = (integer)pos.z;
    integer newHeight = height + increment;
    
    if (height + increment >= maxHeight) {
       gON = FALSE; // turned off so stay still
       Warp(gStartPos); // back to starting position
       llSetAlpha(0.5, ALL_SIDES);
       llOwnerSay("OPERATION COMPLETE");     
}
    
    if (gON == TRUE) {
    Warp(<pos.x, pos.y, newHeight>);
    llSensor("","",ACTIVE|PASSIVE, scanRange, PI);
}
}

default {
    state_entry() {
       gCreatorKey = llGetOwner();
       llRequestPermissions(llGetOwner(),PERMISSION_RETURN_OBJECTS);
       llSetObjectName("PRIM SWEEPER");
       gStartPos = llGetPos();
       llOwnerSay("NOW STARTED: will scan every hour unless deactivated");
       llSetTimerEvent(3600); // perform routine every hour
    }
    
    run_time_permissions(integer perm)
    {
        if (perm & PERMISSION_RETURN_OBJECTS)
        {
            gOK = TRUE;
        }
    }

    timer() {
        llSensor("","",ACTIVE|PASSIVE, scanRange, PI); // lets begin
        gON = TRUE;
    }

    touch_start(integer total_number)
    {
        if (llGetOwner() == llDetectedKey(0))
        {
            if (gOK)
            {
                gON = !gON; // pretty useless realy not asif i can stop it once its started, unless short interval break before start
                llRegionSayTo(llDetectedKey(0),0,"Device switched " + llList2String(["OFF","ON"],gON) );
                vector pos = llGetPos();
                Warp(<pos.x, pos.y, minHeight>); // start at the floor / ground but stored in any starting place
                llSetAlpha(0.0, ALL_SIDES); // totaly invisible
                llSetStatus(STATUS_PHANTOM, TRUE); // phantom
                llSensor("","",ACTIVE|PASSIVE, scanRange, PI); // lets begin
                
            }
            else
            {
                llRequestPermissions(llGetOwner(),PERMISSION_RETURN_OBJECTS);
            }
        }
    }
 
    changed(integer change)
    {
        if (change & CHANGED_OWNER)
            llResetScript();
    }
       
    sensor(integer num)
    {        
        list SendHome;
        integer i;
        while (i< num)
        {
            list temp = llGetObjectDetails(llDetectedKey(i),[OBJECT_CREATOR]);
            if (llList2Key(temp,0) != gCreatorKey && llOverMyLand(llDetectedKey(i)) == TRUE)  
            // Or substitute your favorite filter here
            // very important to ensure its over your land because if your an estate manager you`ll return neighbours items
            {
                llRegionSayTo(llGetOwner(),0,"WOULD BE RETURNING " + (string)llDetectedName(i));
                SendHome += [llDetectedKey(i)];
            }
            ++i;
        }
        //llReturnObjectsByID(SendHome);
        if (gON == TRUE) { Move(); }
    }
    
    no_sensor() {
         if (gON == TRUE) { Move(); }
    }
}

// my todolist
// notify owner of number of prims returned to each individual
// only additems to sendhome list if no avatar is detected during the scan

 

 infact i notice the other guys script does the same

Link to comment
Share on other sites

On 1st view I noticed 4 things.

- replace warp by llSetRegionPos (warp is obsolete but still working)

- you confuse owner and creator. The script will return all objects you bought.

- this statement:

if (llList2Key(temp,0) != gCreatorKey && llOverMyLand(llDetectedKey(i)) == TRUE)

You know in what order LSL processes that? Well I have a clue but I'm never sure so i suggest to use parentheses

if (  (llList2Key(temp,0) != gCreatorKey)  && llOverMyLand(llDetectedKey(i)))

- The sensor range of 96m descripes a sphere and NOT a cube. So if you make a sensor sweep of 96m and move by 96m after that - alot of space remains unsearched.

 

 

Link to comment
Share on other sites

One major limitation with sensors is that they only return the nearest sixteen objects that match the filter, so it's very easy for other objects to "hide behind" a clump of sixteen or more objects. That's why this is all so very inefficient: the motion of sensor probes and / or the angle they scan must adapt when a scan gets sixteen returns -- and must adapt in a way that still eventually scans the entire volume of interest. This can get arbitrarily costly at best, and even may be impossible for large numbers of exactly co-located objects.

Link to comment
Share on other sites

thats too advanced for me, but my gadget scans from ground level upto the sky then takes a break

even if it doesnt return all the prims on its first journey,

since its configured to happen every hour it will clear them all up eventually


happy days

 

i dont think thiers anything wrong with the script i posted,

just got to be brave enough to run it

i performed a little test just to detect objects nearby which aint owned by me....

its asif the filter does nothing because it still reports back to me a list of objects that i own

but the good news is they aint being returned.

 

thats what i dont understand o well

 

Link to comment
Share on other sites

The question isn't whether you OWN them.  It's whether you CREATED them. Your script and the one I posted the other day will both list items that I own if they are items that I did not create.  To verify, try two experiments:

1. Create a few plywood prims and label them clearly.  Put them near your detector and switch it on.  The detector won't see them, because you created them.

2.  Substitute OBJECT_OWNER for OBJECT_CREATOR in your script.  You'll find that it lists only your own items.

Now, a couple of other comments:

1. Be careful moving your detector all over the place.  If it's not over your own land, you could annoy neighbors.  Worse yet, your neighbor could have alien scripts turned off over his parcel, so your scanner will stall. 

2. If you really MUST move it, don't use that old Warp method.  It's clumsy and slow.  Just use llSetRegionPos.

If you look through the forum archives, you'll find several versions of multiplex scanners described.  Void Singer created a lovely one that I have used and modified for ages.  There was a burst of activity on the topic about 2010 -- before the viewers started including Area Search and the Pathfinding linkset search tools that made most of them obsolete.  You can query many types of information without having to move a scanner now.

Link to comment
Share on other sites

thanks, understood

a question regarding the sensor, im now scanning for agents and objects at the same time

 

llSensor("","",AGENT|ACTIVE|PASSIVE, scanRange, PI);

 

if an agent is detected i would like it to skip that area

 

is it possible to determine wether the results happen to be an avatar?

 

or am i going about it wrong, maybe i need to perform twice as many scans

1) scan to ensure no avatars around

2) then scan for junk/prims afterwards

 

i allow people to rez items, i dont want to cleanup if they still thier

 

actually now that i think of it, considering the limitations maybe scanning for agents only first is the best option

 

Link to comment
Share on other sites

If you do it that way, then you don't truly care how many objects have been detected.  If there's even one avatar in range, you ignore everything else.  Of course, then you have also used server time doing a worthless scan.  If there's NO avatar around, however, you have a perfectly good scan, so there's no need to do another one.  Given that you can rarely get as many as 50 avatars in a region, chances are pretty good that most places your scanner visits are avatar free, so this is probably the most efficient way to write your sensor. Unfortunately, it still means filtering each scan with a quick loop to detect avatars

while (number_detected){    if (llGetAgentSize(llDetectedKey(--num_detected)) )    {        //This is an avatar    }}

 

 

Link to comment
Share on other sites

wasnt sure how to merge the code together so i done it like this hopefully correct, not tested

could have possibly used lDetectedType(i) aswell

 

   sensor(integer num)    {                list SendHome;        integer i;        while (i< num)        {            list temp = llGetObjectDetails(llDetectedKey(i),[OBJECT_OWNER]);                        if (llGetAgentSize(llDetectedKey(i)) == ZERO_VECTOR)              {             Move();   // this is an avatar so lets move            }            if (llList2Key(temp,0) != gOwnerKey && llGetAgentSize(llDetectedKey(i)) == ZERO_VECTOR && llOverMyLand(llDetectedKey(i)) == TRUE)                llRegionSayTo(llGetOwner(),0,"WOULD BE RETURNING " + (string)llDetectedName(i));                SendHome += [llDetectedKey(i)];            }            ++i;        }         llReturnObjectsByID(SendHome);        if (gON == TRUE) { Move(); }    }

 

Link to comment
Share on other sites


Leander Tyles wrote:

wasnt sure how to merge the code together so i done it like this hopefully correct, not tested

could have possibly used lDetectedType(i) aswell

 
   sensor(integer num)    {                list SendHome;        integer i;        while (i< num)        {            list temp = llGetObjectDetails(llDetectedKey(i),[OBJECT_OWNER]);                        if (llGetAgentSize(llDetectedKey(i)) == ZERO_VECTOR)              {             Move();   // this is an avatar so lets move            }            if (llList2Key(temp,0) != gOwnerKey && llGetAgentSize(llDetectedKey(i)) == ZERO_VECTOR && llOverMyLand(llDetectedKey(i)) == TRUE)                llRegionSayTo(llGetOwner(),0,"WOULD BE RETURNING " + (string)llDetectedName(i));                SendHome += [llDetectedKey(i)];            }            ++i;        }         llReturnObjectsByID(SendHome);        if (gON == TRUE) { Move(); }    }

 

That won't work. After not detecting an Avatar your program execution jumps to Move() but then returns still within your sensor event.

 

I'd suggest you slow down here and start testing what you have so far. Come back when you run into a problem.

Link to comment
Share on other sites

Close.  Two things, one of which is stylistic biut cautionary....

1.  If your first if test yields TRUE, then you don't want to do the second test at all, and you don't want to return any objects at all, right?  So you'll want to make SendHome = []  and then make your second if test an if else.

2. It's wise to get in the habit of bracketing each condition in your if tests separately in parentheses, as someone suggested further back in this thread.  Yes, that's partly a stylistic issue, but it can save you a lot of grief as you get truly complex tests like this one.  The compiler is supposed to evaluate statements from right to left and should generate implied brackets properly, but there's no guarantee that it will.  In any case, putting the parentheses in yourself is a reality check -- a way of verifying that you have actually written things the way you meant them.

Link to comment
Share on other sites


Rolig Loon wrote:

Close.  Two things, one of which is stylistic biut cautionary....

1.  If your first
if
test yields TRUE, then you don't want to do the second test at all, and you don't want to return any objects at all, right?  So you'll want to make
SendHome = [] 
and then make your second
if
test an
if else
.

2. It's wise to get in the habit of bracketing each condition in your
if
tests separately in parentheses, as someone suggested further back in this thread.  Yes, that's partly a stylistic issue, but it can save you a lot of grief as you get truly complex tests like this one.  The compiler is supposed to evaluate statements from right to left and
should
generate implied brackets properly, but there's no guarantee that it will.  In any case, putting the parentheses in yourself is a reality check -- a way of verifying that you have actually written things the way you meant them.

Completely agree on #2 but your suggestion for #1 is incorrect. A direct return; is required if an Avatar is sensed, otherwise the list may still be added to afterwards.

Link to comment
Share on other sites

In fact, 2 separate loops are required here:

 

    sensor(integer num)    {                list SendHome;        integer i = 0;
// NOTE: May fail to detect an Avatar if there are 16 or more objects within the scan area! while (i < num) { if (llGetAgentSize(llDetectedKey(i)) != ZERO_VECTOR) {
 // found an avatar here so lets move on if (gON == TRUE)
{ Move(); }
return; }
++i; // Oops, editted to add this line! ) i = 0; while (i < num) { list temp = llGetObjectDetails(llDetectedKey(i),[OBJECT_OWNER]);
if ((llList2Key(temp,0) != gOwnerKey) && (llOverMyLand(llDetectedKey(i)) == TRUE)) { llRegionSayTo(gOwnerKey, 0, "WOULD BE RETURNING " + (string)llDetectedName(i)); SendHome += [llDetectedKey(i)]; } ++i; }
llReturnObjectsByID(SendHome); if (gON == TRUE)
{ Move(); }
}

 

Link to comment
Share on other sites

No no no! Just one loop, after all. That return does catch it properly...

 

    sensor(integer num)    {                list SendHome;        integer i = 0;        // NOTE: May fail to detect an Avatar if there are 16 or more objects within the scan area!        while (i < num)        {            if (llGetAgentSize(llDetectedKey(i)) != ZERO_VECTOR)              {                // found an avatar here so lets move on                if (gON == TRUE)                {                    Move();                }                return;            }            else if ((llList2Key(llGetObjectDetails(llDetectedKey(i),[OBJECT_OWNER]),0) != gOwnerKey) && (llOverMyLand(llDetectedKey(i)) == TRUE))            {                llRegionSayTo(gOwnerKey, 0, "WOULD BE RETURNING " + (string)llDetectedName(i));                SendHome += [llDetectedKey(i)];            }            ++i;        }        llReturnObjectsByID(SendHome);        if (gON == TRUE)        {            Move();        }    }

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 3865 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...