Home Position
Remembers where a thing belongs and puts it back there, on a touch or by itself. For everything visitors leave in the sea.
What it does
When the script starts it writes down where the object is standing, and that is home ever after. A touch sends it back; set CHECK_EVERY and it goes back on its own once it has wandered further than DRIFT. Comparing against a distance rather than an exact spot is deliberate: an object that snapped back at the slightest movement would wrestle with the person nudging it into place. It uses llSetRegionPos, which reaches anywhere in the region rather than ten metres at a time, and it says out loud when that is refused.
What you can build with it
The chairs round a table, a ball in a garden, props in a photo studio, cups on a bar, the pieces of a game, cushions in a club, anything on a sandbox that people are allowed to move. Somebody always leaves them in the sea.
How to use it
Settings you can change
5Edit these at the top of the script. Everything works on the defaults · change them only when you need to.
// =====================================================================
// Home Position
// skimi3d script library
// https://grid.skimi3d.com/scripts/home-position
//
// Remembers where a thing belongs and puts it back there.
//
// For anything visitors are allowed to pick up and push about: the
// chairs round a table, the ball in a garden, the props in a photo
// studio, the cups on a bar. Somebody always leaves them in the sea.
//
// Plain LSL.
// =====================================================================
// ---------------------------------------------------------------------
// Settings
// ---------------------------------------------------------------------
// Touching it sends it home. Owner or group only, set below.
integer GO_HOME_ON_TOUCH = TRUE;
// Put it back by itself. Seconds between checks; 0.0 never checks and
// leaves it to the touch.
//
// A number here is a script that wakes up for ever, so make it a large
// one. Sixty seconds is a busy prop; three hundred is plenty for the
// furniture in a garden.
float CHECK_EVERY = 0.0;
// How far it has to have wandered before that counts as moved, in
// metres. Small numbers make it fight the person editing it.
float DRIFT = 0.5;
// Put its rotation back as well, not only its place.
integer KEEP_ROTATION = TRUE;
// Who may send it home by touch. 0 = everyone, 1 = only the owner,
// 2 = anyone wearing the same group tag.
integer WHO_MAY_SEND_HOME = 1;
// ---------------------------------------------------------------------
// Everything below here is the machinery
// ---------------------------------------------------------------------
vector gHome;
rotation gHomeRot;
goHome()
{
// llSetRegionPos reaches anywhere in the region, unlike llSetPos,
// which only moves a thing ten metres at a time. It answers with
// zero rather than complaining, and the three reasons it refuses
// are worth saying out loud.
integer ok = llSetRegionPos(gHome);
if (!ok)
{
llOwnerSay("I could not go home. Either I am physical, or I am being worn, or home is outside this region.");
return;
}
if (KEEP_ROTATION) llSetRot(gHomeRot);
}
integer maySend(key who)
{
if (WHO_MAY_SEND_HOME == 1) return who == llGetOwner();
if (WHO_MAY_SEND_HOME == 2) return llSameGroup(who);
return TRUE;
}
default
{
state_entry()
{
// WHEREVER IT IS NOW IS HOME. Put the thing exactly where it
// belongs before you drop the script in, and reset the script
// whenever you move it somewhere it should stay.
gHome = llGetPos();
gHomeRot = llGetRot();
if (CHECK_EVERY > 0.0) llSetTimerEvent(CHECK_EVERY);
if (CHECK_EVERY <= 0.0) llSetTimerEvent(0.0);
llOwnerSay("Home is set to " + (string)gHome + ". Reset me if I should live somewhere else.");
}
touch_start(integer total)
{
if (!GO_HOME_ON_TOUCH) return;
key who = llDetectedKey(0);
if (!maySend(who))
{
llRegionSayTo(who, 0, "This one is not yours to move.");
return;
}
goHome();
}
timer()
{
// Only when it has really wandered. Comparing against a
// distance rather than against the exact spot is what stops it
// wrestling with somebody who is nudging it into place.
if (llVecDist(llGetPos(), gHome) < DRIFT) return;
goHome();
}
on_rez(integer start)
{
// A rezzed copy belongs where it was rezzed, not where the
// original lived.
llResetScript();
}
}
Copy it, make a new script inworld, paste over what is there and save. Nothing here phones home.