Jump to content

Need help with rez derez


Recommended Posts

Hi , I have an object worn on shoulder, I want to be able to rez an item when clicking on the object, and I did that , I did also so that the rezzed object is randomly selected among a pol in the worn object, but what I would like ot do if possible is derez the previously rezzed object once its rezzed  a new one , but with a permission menu on when rezzed that asks if or not to finalize it

if finalized the object won't be drezezzed when a new one is rezzed, is it possible? also is it possible to add a command on the rezzed object when clicked that desits the avatar and adds an object to the shoulder?

 

Link to comment
Share on other sites

56 minutes ago, Naiman Broome said:

what I would like ot do if possible is derez the previously rezzed object once its rezzed  a new one ,

The object worn on the shoulder needs to keep track of the objects it has rezzed:

when an object is rezzed it announces it's key on a channel that the shoulder item listens to.

The shoulder item keeps a list of the object key and object name.

When a new object of that name is to be rezzed, the shoulder item looks to see if it already has an object of that type in the list.

If so, it uses the stored key with llRegionSayTo()  to tell the first object to derezz.

The first object can then either call llDie() when it gets a "your time is up" message, or it can check with the owner if it should obey or persist.

If it is told to persist it can then stop listening on the channel so that it won't get further messages to die.

The shoulder object will have to remove from the list it keeps any instances that have been told to die.

Complicated but mostly by the amount of book-keeping that is needed

  • Like 2
Link to comment
Share on other sites

8 hours ago, Profaitchikenz Haiku said:

when an object is rezzed it announces it's key on a channel that the shoulder item listens to.

The shoulder item keeps a list of the object key and object name.

Small (but important) thing: The object_rez event gives you the key of the object that was rezzed, so there's no need for the rezzed object to announce itself to the rezzer.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Posted (edited)
2 hours ago, Wulfie Reanimator said:

there's no need for the rezzed object to announce itself to the rezzer.

Not necessarily true. It depends on your implementation, but if for some reason your rezzed object script isn;t isn't already running before it's rezzed, or if it for some reason calls llResetScript() right after rez (due to a changed owner for example) it probably won't hear anything you say to it in the object_rez event, so depending on your setup it may be wise to have the rezzed object announce when it is ready to receive communications.

 Having the rezzed object say its own key is redundant though, as you have that information in the listen() event.

Edit: in this specific case though the object to rezzer communication is indeed unnessessary, as the possible communication to the rezzed object will probably be rather delayed.

Edited by Quistessa
  • Like 2
Link to comment
Share on other sites

Here is what I coded:

 

script on a worn prim :


integer on = TRUE;
default
{
    state_entry(){
               
  
     llListen(312321, "", "", "");  
    }
    attach(key x){
        if(x){
     llResetScript();   
        }
    }
    listen(integer channel, string name, key id, string message)
    {
        if(message == "back"){
        llSleep(0.5);
        }
    }
    touch_end (integer count)
    {
        if(llDetectedKey(0) == llGetOwner()){
        if(on == TRUE){
        llSleep(0.5);
        float number = (float) llFrand(llGetInventoryNumber(INVENTORY_OBJECT));
        string name = llGetInventoryName(INVENTORY_OBJECT,(integer) number);
         //Rezzing stuff here
      {
        float number = (float) llFrand(llGetInventoryNumber(INVENTORY_OBJECT)); // determine the amount of the content and make a random float
        string name = llGetInventoryName(INVENTORY_OBJECT,(integer) number); //getting the name. the float number becomes integer for that
        llRezObject(name, llGetPos() + < 2, 0, -1 >, ZERO_VECTOR,ZERO_ROTATION, 0); //rezz the object, I just let it rezz 1m above the object
}
       }
    }
}

}

 

script on a rezzed prim :

 

 
integer gListener;    
key user;
vector avatarpos;
 
default
{
    touch_start(integer total_number)
    {   
        user = llDetectedKey(0);
        if(user == llGetOwner()){
        avatarpos = llDetectedPos(0);
        llListenRemove(gListener);
        gListener = llListen(-99, "", user, "");
        llDialog(user, "\nDo you wish this prim to die?", ["Take back" ] , -99);
        llSetTimerEvent(60.0);
    }
    }
    listen(integer chan, string name, key id, string msg)
    {
        if (msg == "Take back")
            {
         if(llVecDist(avatarpos, llGetPos()) < 4){
             llOwnerSay("Taking back the item..");
             llRegionSayTo(llGetOwner(),312321,"back");
             llSleep(0.5);
             llDie();
            }
            else{
            llOwnerSay("Sorry, you are too far from the item");    
            }
             }
     llSetTimerEvent(0.1);      
    }
    timer()
    {
        llListenRemove(gListener);
        llSetTimerEvent(0.0);
    }
}

 

What I would like to add is that since I added a randomizer rezzer, I want the script to derezz the previously rezzed item everytime I rez a new one ... is that possible?

I dunno how to implement this.

Link to comment
Share on other sites

Posted (edited)
//Rezzing stuff here
      {
        llRegionSayTo(gID,-99,"Take Back");
        float number = (float) llFrand(llGetInventoryNumber(INVENTORY_OBJECT)); // determine the amount of the content and make a random float
        float name = llGetInventoryName(INVENTORY_OBJECT,(integer) number); //getting the name. the float number becomes integer for that
        llRezObject(name, llGetPos() + < 2, 0, -1 >, ZERO_VECTOR,ZERO_ROTATION, 0); //rezz the object, I just let it rezz 1m above the object
      }

/*...*/

object_rez(key ID)
{
  gID = ID; // gID should be a global variable.
}

looks like you already have 99% of the code in place to do that already. You will also need to remove some code in your rezzed prim to make it have an always-on listener.

We /could/ just write it for you, (and I am often guilty of doing just that on the forums. . .) but I think we've already told you everything you need to know in order to write it yourself. Is there something in particular you're having trouble with?

Edited by Quistessa
  • Like 1
Link to comment
Share on other sites

22 hours ago, Quistessa said:

//Rezzing stuff here
      {
        llRegionSayTo(gID,-99,"Take Back");
        float number = (float) llFrand(llGetInventoryNumber(INVENTORY_OBJECT)); // determine the amount of the content and make a random float
        float name = llGetInventoryName(INVENTORY_OBJECT,(integer) number); //getting the name. the float number becomes integer for that
        llRezObject(name, llGetPos() + < 2, 0, -1 >, ZERO_VECTOR,ZERO_ROTATION, 0); //rezz the object, I just let it rezz 1m above the object
      }

/*...*/

object_rez(key ID)
{
  gID = ID; // gID should be a global variable.
}

looks like you already have 99% of the code in place to do that already. You will also need to remove some code in your rezzed prim to make it have an always-on listener.

We /could/ just write it for you, (and I am often guilty of doing just that on the forums. . .) but I think we've already told you everything you need to know in order to write it yourself. Is there something in particular you're having trouble with?

Yeh I am not getting to finish that 1% part that makes it derez when I rez another item :( .

Link to comment
Share on other sites

an  approach to these kinda use cases is to think about making smart objects that handle their own lives and interactions with each other (their siblings) which are not dependent on a god (rezzer) script for their continued existence after being birthed/rezzed

example smart object for this use case
 

// in smart object

on_rez( ... )
{
    integer channel = -98783; // some channel number
 
    // tell other object(s) with same name as me, listening on the channel, to die
    llRegionSay(channel, "die");

   // listen on channel for a die command from objects with the same name as me
    llListen(channel, llGetObjectName(), NULL_KEY, "die");
}

listen (... key id ...)
{
    // is owner of die command the same as my owner ? if yes then die
    if (llGetOwnerKey(id) == llGetOwner())  
       llDie();
}

 

  • Like 1
Link to comment
Share on other sites

Posted (edited)

Sooooo, what happens when you rezz four objects all called "ThereCanBeOnlyOne" and they all tell each other to die :)

 

(I am hypothesising a situation where you manage to rezz them all siulataineusly  at the same time)

Edited by Profaitchikenz Haiku
Link to comment
Share on other sites

33 minutes ago, Profaitchikenz Haiku said:

Sooooo, what happens when you rezz four objects all called "ThereCanBeOnlyOne" and they all tell each other to die :)

Even if you rez them at exactly the same time, the events have to happen in /some/ order. in cases like these it's useful to model an example situation, and work through logically what happens. If the rezes and messages happen in the "expected" order:

  1. A rezzes
  2. Nobody is around to hear A's deathcall
  3. B rezzes
  4. A hears B's deathcall and dies
  5. Etc. (last rezzed remains alive)

If there is a delay between the rez and the shout:

  1. A rezzes
  2. B rezzes
  3. A tells B to die
  4. B Hears the deathcall and puts a listen on its event stack, then finishes its current event (telling A to die), then dies.
  5. A hears B's deathcall and dies.
  6. Etc. (everyone dies)

Oddly enough, if the deathcall is in a timer() event or if the listen event can otherwise manage to place above the event with the deathcall, then (in the above ordering) B will die before sending its deathcall, letting A remain alive.

Link to comment
Share on other sites

36 minutes ago, Naiman Broome said:

I am lost, any hint on what should I write in those codes?

Molly's suggestion is the simplest if you only ever want to have one instance of an object, there is no need to keep lists of name and keys in the rezzer, the rezzed object does all the housekeeping.

One point you need to know is that an object saying something on a channel it is listening to doesn't hear what it says.

So add the two snippets she's posted in the object that is to be rezzed, together with any other things you want it to do. 

If you want to stop an object from hearing the die command, simply close the listen and it will keep going  until some other method is used to remove it.

Link to comment
Share on other sites

On 6/4/2021 at 12:28 PM, Mollymews said:

an  approach to these kinda use cases is to think about making smart objects that handle their own lives and interactions with each other (their siblings) which are not dependent on a god (rezzer) script for their continued existence after being birthed/rezzed

example smart object for this use case
 


// in smart object

on_rez( ... )
{
    integer channel = -98783; // some channel number
 
    // tell other object(s) with same name as me, listening on the channel, to die
    llRegionSay(channel, "die");

   // listen on channel for a die command from objects with the same name as me
    llListen(channel, llGetObjectName(), NULL_KEY, "die");
}

listen (... key id ...)
{
    // is owner of die command the same as my owner ? if yes then die
    if (llGetOwnerKey(id) == llGetOwner())  
       llDie();
}

 

Problem is that the objects do not have the same name. in case of different names how I remove them?

 

Link to comment
Share on other sites

3 hours ago, Naiman Broome said:

Problem is that the objects do not have the same name. in case of different names how I remove them?

 

is a number of ways to deal with this using a identity token

one of the ways is:
 

in rezzer

integer token = 23456782;  // some identity token number for this app

llRezObject(name, pos, vel, rot, token);


in rezzed object

on_rez(integer token)
{
    // change name of object to token
    string name = (string)token;
    llSetObjectName(name);
    while(llGetObjectName() != name);  // confirm name change

    integer channel = -934567; // some channel number
    llRegionSay(channel, "die");

    llListen(channel, name, NULL_KEY, "die");
}

 

  • Like 1
Link to comment
Share on other sites

Posted (edited)
20 hours ago, Mollymews said:

is a number of ways to deal with this using a identity token

one of the ways is:
 




in rezzer

integer token = 23456782;  // some identity token number for this app

llRezObject(name, pos, vel, rot, token);


in rezzed object

on_rez(integer token)
{
    // change name of object to token
    string name = (string)token;
    llSetObjectName(name);
    while(llGetObjectName() != name);  // confirm name change

    integer channel = -934567; // some channel number
    llRegionSay(channel, "die");

    llListen(channel, name, NULL_KEY, "die");
}

 

This is giving me syntax error , I tried to implement it in the script but seems I am not able to make it work seems :( ?

Quote

 

integer token;
integer gListener;    
key user;
vector avatarpos;

default
{

    touch_start(integer total_number)
    {   
        user = llDetectedKey(0);
        if(user == llGetOwner()){
        avatarpos = llDetectedPos(0);
        llListenRemove(gListener);
        gListener = llListen(-99, "", user, "");
        llDialog(user, "\nDo you wish this prim to die?", ["Take back" ] , -99);
        llSetTimerEvent(60.0);
    }
    on_rez(integer token)
    {
    // change name of object to token
    string name = (string)token;
    llSetObjectName(name);
    while(llGetObjectName() != name);  // confirm name change

    integer channel = -934567; // some channel number
    llRegionSay(channel, "die");

    llListen(channel, name, NULL_KEY, "die");
    }
    }
    listen(integer chan, string name, key id, string msg)
    {
        if (msg == "Take back")
            {
         if(llVecDist(avatarpos, llGetPos()) < 4){
             llOwnerSay("Taking back the item..");
             llRegionSayTo(llGetOwner(),312321,"back");
             llSleep(0.5);
             llDie();
            }
            else{
            llOwnerSay("Sorry, you are too far from the item");    
            }
             }
     llSetTimerEvent(0.1);      
    }
    timer()
    {
        llListenRemove(gListener);
        llSetTimerEvent(0.0);
    }
}

 

 

Edited by Naiman Broome
Link to comment
Share on other sites

Naiman, as wrote your script is killing itself (object containing the script) in response to a dialog input.  In this case the code snippet I provided has no purpose

the purpose of the code snippet is that a newly-rezzed object will kill any object similar to itself (its sibling) that has been previously rezzed

Link to comment
Share on other sites

i thought I would post a more complete test harness, as this technique can be applied to a number of different purposes

// in rezzer

list items;
integer hnd;

default
{
   state_entry()
   {
      // get inventory items
      integer n = llGetInventoryNumber(INVENTORY_OBJECT);
      while (~--n)
      {
         string name = llGetInventoryName(INVENTORY_OBJECT, n);
         //        button caption, item name   
         items += [llGetSubString(name, 0, 11), name];
      }
      // sort alphabetical order
      items = llListSort(items, 2, TRUE);
      
      // setup menu dialog listener and set to inactive
      hnd = llListen(-45872, "", llGetOwner(), "");
      llListenControl(hnd, FALSE);

   }

   touch_start(integer num)
   {
      // set menu dialog listener to active
      llListenControl(hnd, TRUE);
      // show menu dialog using stride 2. (button captions)
      llDialog(llGetOwner(), "Rez item:", llList2ListStrided(items, 0, -1, 2), -45872); 
   }

   listen(integer channel, string name, key id, string text)
   {
      // set menu dialog listener to inactive
      llListenControl(hnd, FALSE);

      // use button caption to find the full name of the selected item 
      integer i = llListFindList(items, [text]) + 1;
      if (i)  // found item
      {
         integer token = 7621348;   // app identity token
      
         llRezObject(llList2String(items, i), llGetPos() + <0, 0, 1>, ZERO_VECTOR, ZERO_ROTATION, token);
      }
   } 
}
// in rezzed object

default
{
   on_rez(integer token)
   {
      // save my name
      string save = llGetObjectName();
      // rename myself to token
      string name = (string)token;
      llSetObjectName(name);
      while(llGetObjectName() != name); // ensure my name has changed
      
      // send the die command to any existing siblings with my token name
      llRegionSay(-345682, "die");

      // set up a listener on my token name for the sibling that will rez after me
      llListen(-345682, name, NULL_KEY, "die");

      // restore my real name
      llSetObjectName(save);
   }

   listen(integer channel, string name, key id, string text)
   {
       // my newly-rezzed token name sibling has told me to die
       if (llGetOwnerKey(id) == llGetOwner())
       {
          llDie();  
       }
   }
}

 

  • Thanks 1
Link to comment
Share on other sites

Ok thankyou , as another question , if I lets say have the item rezzed on ground, removed the rezzer from myself and I want to replace the item right on the spot, touching it , Can I do ?

 

Like I touch the item a manu comes out and rezzes a different version of the item in the same place and rotation and deletes the previous ?

Link to comment
Share on other sites

Posted (edited)
14 hours ago, Naiman Broome said:

Ok thankyou , as another question , if I lets say have the item rezzed on ground, removed the rezzer from myself and I want to replace the item right on the spot, touching it , Can I do ?

 

Like I touch the item a manu comes out and rezzes a different version of the item in the same place and rotation and deletes the previous ?

seems to me (going off your initial OP) that you are wanting to be able to changeout attachments while sitting.  If yes then use the AvSitter system which has all of this capability and more

about AvSitter here: https://avsitter.com/

this said, all the questions you ask subsequently keep changing what you want to do. The answer to all of them is yes, an academic yes. Academic meaning that until you decide what it is you want to do according to some functional specification then there is nothing to implement

Edited by Mollymews
  • Like 1
Link to comment
Share on other sites

On 6/8/2021 at 12:41 AM, Mollymews said:

seems to me (going off your initial OP) that you are wanting to be able to changeout attachments while sitting.  If yes then use the AvSitter system which has all of this capability and more

about AvSitter here: https://avsitter.com/

this said, all the questions you ask subsequently keep changing what you want to do. The answer to all of them is yes, an academic yes. Academic meaning that until you decide what it is you want to do according to some functional specification then there is nothing to implement

Mmm no , I wanted to change the whole chair while sitting , doesnt mind if it makes me stand after I click it , but is possible to delete the chair and replace with a new chair of different shape but same content?

Link to comment
Share on other sites

26 minutes ago, Naiman Broome said:

Mmm no , I wanted to change the whole chair while sitting , doesnt mind if it makes me stand after I click it , but is possible to delete the chair and replace with a new chair of different shape but same content?

This could technically be done if the object you wanted to replace was a sculpt, since we have PRIM_TYPE_SCULPT.

But we don't have a function to replace mesh with other mesh, or otherwise replace an object with another object in the way you're describing.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...