Jump to content
animats

Can a script tell if an object has been moved via "build"?

Recommended Posts

So I have an script which, for a physical object, returns it to its starting point after a while. Works fine.

When the script is initialized, or the object is rezzed, it captures the current position, which becomes its new home position. It returns to there. But if someone re-arranges the objects with the build tools, the script does not know this. So it returns to the old position.

Having the builder manually reset the object scripts works, but it's a pain. I'd like this to Just Work. Any way to detect "build_end"?

Share this post


Link to post
Share on other sites

No, but you could fake something like that.  Just off the top of my head...

vector  vHomePos;

default
{
    state_entry()
    {
        if (llGetSubString(llGetObjectDesc(), 0,0) == "<")    // Is the home position stored in the object description?
        {
            vHomePos = (vector)llGetObjectDesc();    // If so, use it.
        }
        else
        {
            vHomePos = llGetPos();    // Otherwise, home is right here
            llSetObjectDesc((string)vHomePos);    // So save it.
        }
        llSetTimerEvent(60.0);   // Start polling every minute
    }

    timer()
    {
        vector vHere = llGetPos();    Here's where we are now
        if (llVecDist(vHere,vHomePos) > 0.1)   If this isn't home ...
        {
            vHomePos = vHere;    // Make it home
        }
    }

     touch_start(integer num)
    {
        llSetObjectDesc((string)vHomePos);    // As soon as someone touches the object record the updated "home" position
    }
}

   This isn't perfect.  It still means that someone has to touch the object to update "home".  Until that happens, though, "home" is temporarily wherever it has been for more than a minute.  If you take the object without clicking on it,  the old "home" position will still be in its description field, so you may want to think of a way to force it to update there after, say, an hour or two.  Maybe ....  Anyway, just an idea.

Edited by Rolig Loon

Share this post


Link to post
Share on other sites

As far as I remember, the moving__end event  fires when you stop moving the object using the build tools.  The wiki suggests it does, too. 

Worth a try.

If it does work, then you will need -- if I correctly understand what you're doing -- to set a flag when the object starts moving under normal circumstances (when you touch it to start it moving, or however you trigger the movement by script) so the script knows, in the moving_end event, if the motion that has just ceased was caused by the script or by an external agency like the owner dragging it around.

Share this post


Link to post
Share on other sites

The wiki caveats for the moving_end event say that "This event's behavior is undefined for non-physical movement (llSetPos, movement via build tool, etc.) although these movements will often trigger it."  Moving an object with the build tool may trigger the event, but it isn't guaranteed to.  This matches my own frustrating experience in writing a script for a client a few years ago.  In my opinion, that behavior is not reliable enough to count on.  At least, I didn't feel comfortable selling my client a script that depended on it.

Share this post


Link to post
Share on other sites

Using "touch" to update the home position means "touch" can't be used for other purposes. Also, anybody can "touch"; only people with build privileges should be able to move it permanently. I'd also rather not have a timer running; that uses resources on objects that are doing nothing.

moving_start() and moving_end() might help, but they're broken. Reported as a bug in 2007: https://jira.secondlife.com/browse/SCR-82? Closed as "Won't fix" in 2012. I tested a little; it's possible to move something via "build" and not get a moving_end event.

Needs more thought.

Share this post


Link to post
Share on other sites
15 minutes ago, animats said:

Using "touch" to update the home position means "touch" can't be used for other purposes. Also, anybody can "touch"; only people with build privileges should be able to move it permanently. I'd also rather not have a timer running; that uses resources on objects that are doing nothing.

Those are good concerns, but not necessarily limiting.  You can still use the touch_start event for other things as well.  It's just that regardless of what else the event does, it will always update the description field when you click the object.  And you'd want that to happen no matter who touches it.  The touch_start event's purpose here is to force that description field to update to the current value of vHomePos.  As for having a timer running, the load on the servers from having a timer triggering once a minute to do that tiny bit of work is negligible -- not worth worrying about at all.

24 minutes ago, animats said:

moving_start() and moving_end() might help, but they're broken. Reported as a bug in 2007: https://jira.secondlife.com/browse/SCR-82? Closed as "Won't fix" in 2012. I tested a little; it's possible to move something via "build" and not get a moving_end event.

Yes, that's my experience too.  Too bad.  If it worked, that would be the ideal solution.

Share this post


Link to post
Share on other sites
11 hours ago, animats said:

So I have an script which, for a physical object...

A physical object? You might try the not_at_target() event, paired with llTarget(), and possibly not_at_rot_target() with llRotTarget(). (Oh, I see Debbie Trilling made a similar comment on the jira back in 2009.) I'm not 100% sure these are more reliable than the useless moving_end, but may be worth a try.

I wouldn't try too hard, though, because as Rolig says, load from an occasional timer() event is de minimis.

Share this post


Link to post
Share on other sites

I looked at how the library "Domino" works. That has physics off until a collision is reported. Then physics is turned on, and the domino can be knocked around. If it moves with physics off, it has to be the build tool or some script doing it, not action in the world. So that's how "domino" solves this problem.

About half the time, though, you can walk through the stock domino without setting off the collision. Try it.

(The "touch event" approach won't work. The goal here is to have an environment avatars can mess up, but which is reliably reset after a while. Can't let anybody but a builder change the home position.)

Share this post


Link to post
Share on other sites
29 minutes ago, animats said:

(The "touch event" approach won't work. The goal here is to have an environment avatars can mess up, but which is reliably reset after a while. Can't let anybody but a builder change the home position.)

I think I'm failing to understand something here.  The person "touching" your object isn't doing any editing at all.  The touch is simply storing the current value of vHomePos in the object's description field.  That position will only change if the timer event detects that the object has moved -- presumably because some authorized person who does have permission to edit has moved it.  Unless some authorized person has moved the object, a "touch" doesn't do a thing.

Share this post


Link to post
Share on other sites

I have a good solution working now.

  • The object starts with physics off, waiting for a collision event. So the object can't move and is at its build location.
  • On a collision event, the home location is captured. That's where it will go when moved back. Then, physics is enabled for the object, and we go to "hit" state.
  • The object gets knocked around by avatars and other objects. A timer is running. Every 5 seconds, llSensor is called, and if a no_sensor event is reported, indicating no nearby avatars, the object is moved back to its home position.

No need for "touch" events. Moving the object with the build tools works. Rezzing and derezzing work. The only remaining concern is what happens if the object is shoved into another sim, and returning to the old position using llSetPos isn't enough. Need to check for that. Anyone know of a sandbox which crosses a sim boundary?

I have a little bar fight scene set up, with chairs and tables, bottles and cans. Everything can be knocked over. Bottles fall off the table and roll around.  Looks good. Works OK for objects sitting on other objects, such as the bottles and cans. When physics turns on for the table, the bottles and cans get a collision event, and physics turns on for them, too.

The mess persists as long as anybody is nearby. When nobody is nearby, it all resets successfully.

There's an amusing side effect. When you sit in a chair that uses this script, physics turns on for the chair. That's fine.You can still sit in the chair. You can stand up and leave. It acts like a normal chair. But if someone else bumps into the occupied chair, the avatar gets banged around, still sit-locked to the chair. Sitting on an object with physics gives the avatar physics.  The avatar can escape from this by standing. This may be useful in some roleplay scenarios. Makes the world more dynamic and lively.

collidetest_002.jpg

collidetest_003a.jpg

  • Like 2

Share this post


Link to post
Share on other sites

Fantastic!  Congratulations.  It looks like you have worked out a good solution and have made a fun site.

Instead of trying to make an object find its way home if it gets knocked out of the region, maybe it would be easier to script it to die and then just rez a new one in the home region. Just before the vagabond object dies, have it shout its vHomePos and name to the rezzer, so that the rezzer knows where to put the replacement.  As long as the object isn't moving so fast that it's out of shout range before it has a chance to yell, that should work.  I think.   ;)
 

       

Share this post


Link to post
Share on other sites
19 hours ago, animats said:

I have a good solution working now.

  • The object starts with physics off, waiting for a collision event. So the object can't move and is at its build location.
  • On a collision event, the home location is captured. That's where it will go when moved back. Then, physics is enabled for the object, and we go to "hit" state.
  • The object gets knocked around by avatars and other objects. A timer is running. Every 5 seconds, llSensor is called, and if a no_sensor event is reported, indicating no nearby avatars, the object is moved back to its home position.

No need for "touch" events. Moving the object with the build tools works. Rezzing and derezzing work. The only remaining concern is what happens if the object is shoved into another sim, and returning to the old position using llSetPos isn't enough. Need to check for that. Anyone know of a sandbox which crosses a sim boundary?

I have a little bar fight scene set up, with chairs and tables, bottles and cans. Everything can be knocked over. Bottles fall off the table and roll around.  Looks good. Works OK for objects sitting on other objects, such as the bottles and cans. When physics turns on for the table, the bottles and cans get a collision event, and physics turns on for them, too.

The mess persists as long as anybody is nearby. When nobody is nearby, it all resets successfully.

There's an amusing side effect. When you sit in a chair that uses this script, physics turns on for the chair. That's fine.You can still sit in the chair. You can stand up and leave. It acts like a normal chair. But if someone else bumps into the occupied chair, the avatar gets banged around, still sit-locked to the chair. Sitting on an object with physics gives the avatar physics.  The avatar can escape from this by standing. This may be useful in some roleplay scenarios. Makes the world more dynamic and lively.

collidetest_002.jpg

collidetest_003a.jpg

So much fun! 

Share this post


Link to post
Share on other sites

OK, the normal cases work fine. I've been able to deal with region crossings. (Turn PHANTOM and PHYSICS on, apply a velocity towards home until in the right region. Then use llSetPos.)

But I've found a case that doesn't work. There are some problems if the object goes into another parcel with certain settings.

A parcel with total keep-out for other objects is fine. The object hits the permissions wall, doesn't enter the parcel, and the script brings it home. But if the permissions are set to Object entry for Everyone ON, Run scripts for Everyone OFF, the object can get in, and then its come-home script dies. This leaves the object stuck, perhaps in mid-air, in phantom mode.The property owner or the object owner can return or delete it, but otherwise it's stuck there.

Other than that, it's looking good.

stuckinmidair.png

Share this post


Link to post
Share on other sites

If scripts are turned off, the only way that the object is going to die without manual intervention is if it is set as temp_on_rez, which will severely limit the type of objects you use.

Share this post


Link to post
Share on other sites

llSetStatus with STATUS_DIE_AT_EDGE is another option and will kill the object if it leaves the sim. Once it's set no scripts required to perform the kill.

Share this post


Link to post
Share on other sites
11 hours ago, animats said:

But if the permissions are set to Object entry for Everyone ON, Run scripts for Everyone OFF, the object can get in, and then its come-home script dies. This leaves the object stuck, perhaps in mid-air, in phantom mode.The property owner or the object owner can return or delete it, but otherwise it's stuck there.

Would the llTakeControls method work here? Or does the person giving the perms have to be online for it to still work? Might be worth a try

Share this post


Link to post
Share on other sites
1 hour ago, Ruthven Willenov said:

Would the llTakeControls method work here? Or does the person giving the perms have to be online for it to still work? Might be worth a try

I would be surprised if it worked if the person who granted permissions isn't around, but it may depend on context.  Quoting from the wiki on llTakeControls:

Once the PERMISSION_TAKE_CONTROLS permission is granted, it can be revoked from inside the script (with llReleaseControls or a new llRequestPermissions call), or if the user chooses Release Keys from the viewer. The script will also lose this permission on reset, or if the object is deleted, detached, or dropped.

So, if you took controls upon sitting or attaching something, the permissions would be revoked when you log out.

Share this post


Link to post
Share on other sites
9 minutes ago, Rolig Loon said:

So, if you took controls upon sitting or attaching something, the permissions would be revoked when you log out.

Right, but if the owner is just granting the permission on rez, but the script taking the controls never handles any sitting or attach events, would the controls be released when they log out?

The only problem I would see is in the chairs, and in that case, I would have a separate script to handle the sitting anyways because of the 1 person permissions limit .

Time to test, lol

Edited by Ruthven Willenov

Share this post


Link to post
Share on other sites

Fixed the problem by talking to the neighbors. Object entry ON, scripts OFF was just a bogus setting that they were given after a land auction. That setting breaks other things. If there are wandering birds or cats around, they'll die when they cross a property with those settings. So don't set your property that way.

To see this working, visit my little cafe at Vallone/240/21/36. Sit in one of the chairs and enjoy the fountain. Then wreck the place. All the furniture, plants, and bottles can be knocked around. When you leave, everything goes back as before. Use weapons if you like. Let me know of any problems. Thanks.

cafe_001_001.jpg

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...