Jump to content

Odd rezzer behaviour


Phil Deakins
 Share

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

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

Recommended Posts

This probably doesn't belong in this sub-forum but just in case someone has come across it and dealt with it before, I'll post it.

I've recently made some rezzers which store customers can click on to rez and view the next item - it's a common type of system. The way it works is that each item in the rezzer contains a script. The script deletes the item when told to do so by the rezzer. That happens when someone has clicked the rezzer to see the next item. Customers can buy a copy of the rezzed item, just as though the items were permanently rezzed - just like most stuff in my store. The "kill" script in the item deletes itself when the item is rezzed IF it has a new owner, so there's no possibility of it being triggered later on after someone has bought an item. It uses a complex code anyway, so the chances of it being triggered are extremely remote, but deleting itself on a change of owner makes it theoretically impossible.

The problem is this. Almost every day, one or more of the rezzers rez items *without* the kill script in them so, when the next item is rezzed, the current one doesn't delete itself and it can finish up with a lot of items rezzed in the same spot, which makes buying an item a lottery. At first I thought it happened when the sim was restarted for an update but I've found it happens whether or not there's been an update. All the items in the rezzer's directory do have the kill script in them.

I don't think there's anything I can do to fix it but I wondered if anyone has any ideas?

While I've been writing this, it occured to me that, if the kill script in a newly rezzed item does not receive the owner - if llGetOwner() fails - then the script would delete itself because of an owner mismatch. Does anyone know if not receiving the owner is a possibility - during times of server lag, for instance? If so, I need to change the system.

 

ETA:

I thought I'd add the code in the kill script that I use for this purpose in case it throws any light on the problem. This is in on_rez :-

        string name = llKey2Name(llGetOwner());
        if(name != original_owner)
        {
             // delete this script
            llRemoveInventory(llGetScriptName());
        }
 

original_owner is my name and is hard coded.

 

Link to comment
Share on other sites

Phil,

I think the problem is not that the item rezzes without the script, but that the Kill script does not llDie() before it kills itself. I've seen this happen before.

The kill script probably should not delete itself unless it has a new owner. Double check that the script executes an llDie() then does a return. I've seen some that accidentally execute a self-delete before the llDie takes. Don't ask me how, but it does.

Right after someone rezzes an item, if they attempt to switch items again too soon, messages get out of order and you wind up with odd behavior. I'd also add a time delay or other "enable" on the switch item buttons so that they cannot work again until the rezzed item is initialized and has told the rezzer "okay, I'm stable and ready to die".

Link to comment
Share on other sites

That's an interesting idea, Darrius, but the kill script doesn't remove itself at all unless there is a new owner. It only llDie()s the obejct. Here it is in full:-

integer channel;
string CODE = "xxxxxxxxxxxxxxxxxxxxx";
string original_owner = "Phil Deakins";

default
{
    on_rez(integer param)
    {
        channel = param;
        string name = llKey2Name(llGetOwner());
        if(name != original_owner)
        {
             // delete this script
            llRemoveInventory(llGetScriptName());
        }
        llListen(channel,"","",CODE);
    }
   
    listen(integer CHANNEL, string name, key id, string message)
    {
        llDie();
    }
}

The actual code is not xxxxxxxxxxxxxxxxxxxxx, of course :)

Link to comment
Share on other sites

I think the problem is that if the item is rezzed from your vendor when you aren't on the same sim, llKey2Name(llGetOwner()) is going to fall over.

This is how I do it:

 changed (integer change){
        if (change & CHANGED_OWNER){
            llRemoveInventory(llGetScriptName());        
        }
    }

 

  • Like 1
Link to comment
Share on other sites

yup, Innula's got it...llKey2Name only works if the avatar has been on the region in the last 30seconds or so, if not, it comes up blank....

 

additionally, llRemoveInventory might be a bit slow to delete, leaving the listen open.

oh and if the customer cycles through fast enough, the current object may not have it's listen set up or be running by the time that kill message comes through.... so it may take one or more cycles of your menu to clear it, assuming the same channel is uesd for that vendor.

 

here's how I would do it....

key     gKeyVendor = "hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh";float   gFltRange  = #.#;string  gMsgKill   = "X";integer gChnKill   = ###;default{	state_entry(){		if (llGetOwner() == gKeyVendor){ //-- only set up listen for the vendor owner.			llListen( gChnKill, "", "", gMsgKill );		}else{ //-- get rid of this script for all others.			llRemoveInventory( llGetScriptName() );		}	}	on_rez( integer vIntBgn ){		if (llGetOwner() != gKeyVendor){			llResetScript(); //-- prevent queued listens from firing.		}	}		listen( integer vIntChn, string vStrNom, key vKeySrc, string vStrMsg ){		if (llGetOwnerKey( vKeySrc ) == gKeyVendor){ //-- ignore objects not owned by the vendor			if (llVecDist( llGetLocalPos(), llList2Vector( llGetObjectDetails( vKeySrc, [OBJECT_POSITION] ) ) ) < gFltRange){ //-- ignore objects too far away.				if (llGetOwner() == gKeyVendor){ //-- be absolutely sure we haven't changed owners before killing the object					llDie();				}			}		}	}}

why not a dynamic listen channel? because if it changes and the next item gets called too fast, or script sets up too slow, the object might get abandoned as the channel changes.

why a reset/on_rez, instead of the remove/changed event? because remove inventory can be slow, and other events may still fire before it completes, which could cause a dead object. on-rez is guaranteed to fire first. there's also a bug with spontaneous misfires of CHANGED_OWNER in "buy copy" objects (which would kill the original) which I'm guessing is what such a holo-vendor uses.

the distance check is so that you can mount multiple vendors in a single area, without them canceling each others objects, while stil using a preset channel.

is the third check in the listen really necessary? probably not, but to be safe.., if the listen event has already been entered, we don't want it to finish it's work if we aren't sure that the owner hasn't changed (because the current event must be exited before on_rez will fire)

Link to comment
Share on other sites


Innula Zenovka wrote:

I think the problem is that if the item is rezzed from your vendor when you aren't on the same sim, llKey2Name(llGetOwner()) is going to fall over.

This is how I do it:

 changed (integer change){

        if (change & CHANGED_OWNER){

            llRemoveInventory(llGetScriptName());        

        }

    }

 

 

Wonderful! I had no idea that llKey2Name() fails in those circumstances. That'll be why I couldn't make them fall over no matter fast I clicked to rez the next item - and I tried a number of times, as fast as I could click the mouse button. I've also never used, or even noticed, the "changed" event. I'll do it your way. Many thanks, Innula!

 

ETA:

Of course I've come across the "changed" event before, but not often enough for me to readily bring it to mind, but never the CHANGED_OWNER value.

 

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 4776 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...