Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

rez/derez at flip of a switch

Lefty Belvedere
Lefty Belvedere
Join date: 11 Oct 2004
Posts: 276
06-23-2005 10:14
i'm not much of a scripter but i would like help setting up a way to rez and derez objects from a conroller. I've seen it done but have no idea how to do it. Could somebody send me a free script that i've missed or perhaps IM me for creation for a fee?

thanx in advance,
Lefty
Jon Marlin
Builder, Coder, RL & SL
Join date: 10 Mar 2005
Posts: 297
06-23-2005 10:30
When you rez an object from a script, you can pass in an integer, which is passed to the on_rez event as the start parameter.

If the parent object picks some big number at random, and passes that in, the child object can set up a listener on that channel. When the parent object wants to kill the child, it does an llSay on that channel, and the child listener, on receiving that command, kills itself by calling llDie.

- Jon
Masakazu Kojima
ケロ
Join date: 23 Apr 2004
Posts: 232
06-23-2005 13:19
Another way to do this, without using any listens, is using llSetRemoteScriptAccessPin(), llRemoteLoadScriptPin(), and the object_rez() event.

When you rez the object, pass it a PIN as a parameter, and store the object's key when object_rez() is called. To delete it, use llRemoteLoadScriptPin() to give it a script that just calls llDie().

For example:
CODE
// Rezzer
string OBJECT_NAME = "thing"; // Name of object to rez
vector OBJECT_OFFSET_POS = <0,0,3>; // Position to rez object at
rotation OBJECT_OFFSET_ROT = ZERO_ROTATION;// Rotation to rez object at
vector OBJECT_VELOCITY = ZERO_VECTOR; // Velocity to rez object at

string DIE_SCRIPT_NAME = "die"; // Name of the die script
integer PIN_MAX = 2147483647; // INT_MAX
integer PIN_MIN = 1; // avoid 0 because it is used as the
// start param when rezzed from inv

integer OWNER_ONLY = FALSE; // If only owner can use

key object_key = NULL_KEY; // Key of rezzed object
integer object_rezzed = FALSE; // Whether object is rezzed
integer object_pin; // PIN for rezzed object

integer random_pin() {
return llCeil( llFrand(PIN_MAX - PIN_MIN) ) + PIN_MIN;
}

default {
touch_start(integer num) {
if ( OWNER_ONLY && (llDetectedKey(0) != llGetOwner()) )
return;

if ( object_rezzed ) { // Object is already rezzed
llRemoteLoadScriptPin( object_key, DIE_SCRIPT_NAME, object_pin, TRUE, TRUE );
object_key = NULL_KEY;
object_rezzed = FALSE;
} else {
object_pin = random_pin();
llRezObject(
OBJECT_NAME, llGetPos() + OBJECT_OFFSET_POS, OBJECT_VELOCITY,
llGetRot() * OBJECT_OFFSET_ROT, object_pin
);
object_rezzed = TRUE;
}
}

object_rez(key id) {
object_key = id;
}
}

CODE
// Die script. Put this in the same object as the previous script.
default {
state_entry() {
// llGetStartParameter() is 0 when rezzed from inventory.
// We check it so we don't delete the rezzer object by accident.
if ( llGetStartParameter() != 0 )
llDie();
else
llSetScriptState( llGetScriptName(), FALSE ); // disable ourselves
}
}

CODE
// PIN script. Put this in the object you are rezzing.
integer DELETE_SCRIPT = TRUE; // if TRUE, this script will delete itself.
// PINs are a persistant object property, so once
// a PIN is set this script is no longer needed.

default {
on_rez(integer param) {
// param is 0 when rezzed from agent inventory
if ( param != 0 ) {
llSetRemoteScriptAccessPin(param);
if ( DELETE_SCRIPT )
llRemoveInventory( llGetScriptName() );
}
}
}
Note that llRemoteLoadScript() has a 3 second delay associated with it, so this may not be practical if you are rapidly rezzing objects (though I think it deletes the object faster than a listen). Also note that llRezObject() silently fails if something goes wrong, and the above rezzer script makes no attempt to find out whether the object is ever rezzed or not. If the object doesn't rez for some reason, the script will need to be reset. You could add a timeout to get around this, but if the object does eventually rez, you're left with a sort of confusing situation. This method also has the advantage of working across any distance as long as both objects are in the same sim.
Lefty Belvedere
Lefty Belvedere
Join date: 11 Oct 2004
Posts: 276
06-23-2005 17:25
this is great stuff, thanx!

just for a little setup clarification...

i setup all the objects where i want them to rez, name them, enter their info in the rezzer script and then put the rezzer and die script in a prim.

then i put the PIN script in the objects i want rezed and then all these objects into the prim along with the two other scripts.


is that right? i'm trying this tonight! thanx!

~Lefty
Masakazu Kojima
ケロ
Join date: 23 Apr 2004
Posts: 232
06-23-2005 18:19
From: Lefty Belvedere
i setup all the objects where i want them to rez, name them, enter their info in the rezzer script and then put the rezzer and die script in a prim.

then i put the PIN script in the objects i want rezed and then all these objects into the prim along with the two other scripts.
The script I provided only supports rezzing/derezzing a single object, so you will either need to make seperate rezzer prims for each object or link all the objects you want to rez together. You could modify the script to use a list instead of a single key, but the 3 second delay on llRemoteLoadScriptPin would make derezzing them all take a long time.

Also, it uses offsets relative to the rezzer prim as the location to rez the object at, so you will need to change it to use an absolute position or calculate the offsets yourself. Keep in mind that a script can't rez an object more than 10 meters away. To make it use absolute positions, change "OBJECT_OFFSET_POS" to "OBJECT_POS" and "llGetPos() + OBJECT_OFFSET_POS" to just "OBJECT_POS". You will probably want to do the same thing for the rotation too.

You can get the info to put into the script easily by dropping this script in the prim you're going to rez when it is all set up how you want it:
CODE
default {
touch_start(integer num) {
llOwnerSay("string OBJECT_NAME = \"" + llGetObjectName() + "\";");
llOwnerSay("vector OBJECT_POS = " + (string)llGetPos() + ";");
llOwnerSay("rotation OBJECT_ROT = " + (string)llGetRot() + ";");
}
}
Lit Noir
Arrant Knave
Join date: 3 Jan 2004
Posts: 260
06-24-2005 10:46
I remember that RezObject didn't always offset from the coords of the calling object in the expected way, the calling object's center I think would be off from the edit window. Is this "bug" still around?

Not hard to work around really, just a bit of trial and error. But if the problem exists, figured I'd mention it as not knowing about it can cause frustration.

And another FYI on the maximum 10m offset, you will not get an error if the object fails to rez because because more than 10m away, it just won't appear. Many times my rezzers will create nothing, wondering what the hell is wrong with the RezObject command, only to find out I got the position wrong and it was trying to rez too far away. Much slapping of forehead then ensues.