Jump to content

Change texture from prim inventory, delete script and texture


MilouRoux
 Share

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

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

Recommended Posts

Hi all,

I'm new to scripting and I'm just trying to create more scripts for practice.  

Right now I am trying to create a script that I can put into a prim, drop a texture, have certain sides change texture and then have the texture and script be deleted from the prim's inventory.

The problem I am having is when I call the delete_all_contents() (more specifically, when the texture is deleted) function the faces are reset to default due to the changed() function. I'm assuming because the script is still inside even though it is deleted.  Any tips on how I can fix this?

Thank you!

 

delete_all_contents()
{
    string thisScript = llGetScriptName();
    string inventoryItemName;
    integer index = llGetInventoryNumber(INVENTORY_ALL);
    while (index)
    {
        --index;        // (faster than index--;)
        inventoryItemName = llGetInventoryName(INVENTORY_ALL, index); 

        llRemoveInventory(thisScript); 
        llRemoveInventory(inventoryItemName);    
    }
}

default
{
    changed(integer change)
    {
        if (change & CHANGED_INVENTORY)
        {
            llOwnerSay("The inventory has changed.");
            string name = llGetInventoryName(INVENTORY_TEXTURE, 0);
            // transparent texture
            string trans = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903";
            // Sets all sides transparent, because I want the rim to be transparent
            llSetTexture(trans, ALL_SIDES);
            // Sets texture on front and back faces
            llSetTexture(name, 3); 
            llSetTexture(name, 1);
        }
    }

    touch(integer num_detected){
        llOwnerSay("Deleting Scripts...");
        delete_all_contents();  
    }
    state_entry()
    {
        llOwnerSay("Milou's Simple Texture change Prim thingy");

    }
}

 

Link to comment
Share on other sites

There's two potential problems I can see at a quick glance.

The first, showstopper, problem is that you change the texture each time the prim's inventory changes.   So when you delete the texture,that triggers the routine again, but this time there's no texture for it to use.

That you can get round, I think, by saying 

  changed(integer change)
    {
        if (change & CHANGED_INVENTORY)
        {
            llOwnerSay("The inventory has changed.");
		string name = llGetInventoryName(INVENTORY_TEXTURE, 0);
		if(llGetInventoryType(name) == INVENTORY_TEXTURE){//if there is a texture in my inventory
				// transparent texture
				string trans = "8dcd4a48-2d37-4909-9f78-f7a9eb4ef903";
				// Sets all sides transparent, because I want the rim to be transparent
				llSetTexture(trans, ALL_SIDES);
				// Sets texture on front and back faces
				llSetTexture(name, 3);
				llSetTexture(name, 1);
			}
        }
    }

The second possible problem is that, if the texture isn't full perms, then removing it from the prim's inventory will revert the texture back to default plywood anyway, but there's no real way round that.   You could do a permissions check to make sure any texture you put in is full perms -- see the wiki  for how to do that, and ask again if you need more help with it -- but that won't solve the underlying problem (if it is a problem for your application).

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

I like Innula's approach, testing to see whether the texture is in inventory or not.  More generally, though, I prefer to apply a directional test when it matters whether I am adding something to inventory or deleting something.  I define a global integer variable (call it giInInventory) and then write the changed event schematically as
 

changed (integer change)
{
    if ( (change & CHANGED_INVENTORY) && (iiGetInventoryNumber(INVENTORY_TEXTURE) > giInInventory)
   {
        // Apply the new texture
    }
    giInInventory = llGetInventoryNumber(INVENTORY_TEXTURE);
}

 The instructions to apply the texture in inventory are only executed if you have just added the texture.  Otherwise, they are ignored.

Within the changed event, you can define a filter as loosely or tightly as you want, sometimes within a single bit of code in the if statement.   With only a little more magic, you can test for a change in a specific type of inventory (textures in this case) or the addition of a specific item ( a texture named "Wall Texture 1") or things like the perms on the item (with llGetInventoryPermMask) or the item's creator (with llGetInventoryCreator) and perform actions only if the new item meets your criteria.  You might want to take a look at the special list functions in http://wiki.secondlife.com/wiki/Category:LSL_List#Extended_List_Operations  for ways to compare one list with another (in this case, the current inventory list with the previous one) for more creative tests.

BTW, since you only use your function delete_all_contents once, it makes more sense to simply leave the code in your touch_start event instead of making it a global function.

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

On 7/1/2017 at 1:31 PM, Innula Zenovka said:

You could do a permissions check to make sure any texture you put in is full perms

If the texture is full perms, can you then get the key for it and set the texture using the key (if that was somehow better)? 

  • Like 1
Link to comment
Share on other sites

Yes, or just drag the texture from your inventory and drop it on the face yourself without bothering with a script.  There are lots of ways to play this game.  As I understand it, though, the OP's goal is not necessarily to create a device but to learn how to write LSL scripts.  I can't count the number of pointless scripts I have written just to see if I could do it.  B|

  • Like 2
Link to comment
Share on other sites

2 hours ago, Rolig Loon said:

Yes, or just drag the texture from your inventory and drop it on the face yourself without bothering with a script.  There are lots of ways to play this game.  As I understand it, though, the OP's goal is not necessarily to create a device but to learn how to write LSL scripts.  I can't count the number of pointless scripts I have written just to see if I could do it.  B|

Oops..I meant, get the texture key from a full-perm texture using a SCRIPT. :-) Then if setting the texture with a script by key instead of by name, then the texture should "stick" even after the texture is deleted from inventory?

  • Like 1
Link to comment
Share on other sites

2 hours ago, Love Zhaoying said:

Oops..I meant, get the texture key from a full-perm texture using a SCRIPT. :-) Then if setting the texture with a script by key instead of by name, then the texture should "stick" even after the texture is deleted from inventory?

Ah.  I hadn't realized, but no matter what the perms, the texture reverts to plywood if you use the texture's name to set the texture and then delete it.

So

This reverts back to plywood 

key k;
string str;
default
{

    touch_end(integer total_number)
    {
         str = llGetInventoryName(INVENTORY_TEXTURE,0);
         if(llStringLength(str)){
            k = llGetInventoryKey(str);
            llSetTexture(str,ALL_SIDES); 
            llRemoveInventory(str);
          } 
    }
}

So (rather to my surprise) does this

key k;
string str;
default
{

    touch_end(integer total_number)
    {
         str = llGetInventoryName(INVENTORY_TEXTURE,0);
         if(llStringLength(str)){
            k = llGetInventoryKey(str);
            llSetTexture(k,ALL_SIDES); 
            llRemoveInventory(str);
          } 
    }
}

But this retains the texture.   I don't understand why removing the texture early makes it work, though.

key k;
string str;
default
{

    touch_end(integer total_number)
    {
         str = llGetInventoryName(INVENTORY_TEXTURE,0);
         if(llStringLength(str)){
            k = llGetInventoryKey(str);
            llRemoveInventory(str);
            llSetTexture(k,ALL_SIDES); 
            
          } 
    }
}

 

  • Like 2
Link to comment
Share on other sites

Ooooh, I bet I know...

You changed its inventory but held onto the data, then applied it, which doesn't change the inventory and make it revert.

Applying the texture doesn't trigger a changed() event.

^-^

Edited by Berksey
  • Thanks 1
Link to comment
Share on other sites

If I had to guess (and I do), I imagine that what matters is whether you have captured the texture's UUID in the variable k before you delete the texture. I suspect that the server checks perms when you use llGetInventoryKey and then assumes that the texture is still in inventory.  Unless you remove the texture before applying it.  You're playing a shell game with the UUID and it works until you lift the shell and show the mark that the UUID is no longer under it.

EDIT: Yeah, what she said ^^  :)

Edited by Rolig Loon
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

This falls into the Interesting And Marginally Useful bits of LSL arcana.  I am very reluctant to use tricks that only work until you reset the script.  The old trick of linking prims that were set to different groups and then using the linkset to detect touchers from either group is another one of those nice but marginally useful tricks.  Fun to know about but not something to count on.

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

Sometimes that's a better way of explaining things, especially when you give multiple examples of something. I do it too,and frequently, but I sensed someone was going to answer before I did (yet again) if I didn't act fast! xD

~Ninja~!

And yeah, I love freaky workarounds and exploiting bugs to make things work properly too, it's just a shame so much of that sort of thing has to be fudged so hard to make it work sometimes, and is so easily undone.

Edited by Berksey
Link to comment
Share on other sites

2 hours ago, Berksey said:

Ooooh, I bet I know...

You changed its inventory but held onto the data, then applied it, which doesn't change the inventory and make it revert.

Applying the texture doesn't trigger a changed() event.

^-^

But there isn't a changed event in my examples, so I don't see how that can be the case.

2 hours ago, Rolig Loon said:

f I had to guess (and I do), I imagine that what matters is whether you have captured the texture's UUID in the variable k before you delete the texture.

Rolig, you don't have to guess.  You can see in my script that in both cases I capture the uuid in the variable k before I delete the texture.   The only difference is whether, having captured the UUID, I delete the texture before or after I set the texture using the UUID.

Just to add to the general strangeness, try this.

key k;
string str;
default
{
    state_entry(){
        llSetTexture(TEXTURE_BLANK,ALL_SIDES);
         str = llGetInventoryName(INVENTORY_TEXTURE,0);
         if(llStringLength(str)){
            k = llGetInventoryKey(str);
        }
    }
    
    changed(integer change){
        if(change & CHANGED_INVENTORY){
            llResetScript();   
        }   
    }

    touch_end(integer total_number)
    {
;
        llSetTexture(k,ALL_SIDES);
        if(llGetInventoryType(str)==INVENTORY_TEXTURE){ 
            llRemoveInventory(str);
        }
    }
}

What happens is that the prim changes to blank when I put the texture in (expected) then, when I touch it, it changes momentarily to the new texture before reverting to plywood when it deletes the new texture.

 However, when I touch it a second time, it uses the stored uuid to retexture the prim and this time, since there's no texture to remove from inventory, it retains the texture.   Deleting the texture after you've textured the prim causes the prim to revert though there's no logical reason I can see why that should happen.

I'm bemused (easily done).

ETA:  Removing the texture by script doesn't trigger the changed event.  I've double-checked with llOwnerSay.   There's nothing in the wiki about this, but I do recall that this is an old bug which LL tried to fix some years ago and then had to revert because it broke no end of old freebie vendors and had them resetting themselves crazily.   

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

You're right, no changed event...

Also, oddly, I have a prim I put a texture on and set to spin rapidly (as a propeller), and then used the script to delete everything inside it, and nothing's changed except the inventory being emptied out... Hmmm. Innula's amused, but I'm gettin kinda creeped out~ 0.0;

I swear, sometimes I think this stuff is just thinly-disguised voodoo or something. I'm waiting to have to call in an exorcist to deal with a possessed linkset or something. xD

Edited by Berksey
Link to comment
Share on other sites

It appears that if you delete a texture, it checks if the prim is USING that texture then deletes it AND clears it from the prim.

Everything is now somewhat clear to me with that minor bit of understanding.

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

Wait, it does it on purpose?

But that would be like a prim thinking, "hey, they aren't calling for any particle effects at the moment, so I think I'll just not emit particles everywhere right now!"

Oh, right! I bet it does it because it knows you want the texture to stay! That makes sense.

Thought the world had gone topsy-turvy for a minute there... xD

  • Haha 1
Link to comment
Share on other sites

I suppose the problem is that, when you delete the texture, the server has no way of knowing (or at least not conveniently) what the texture's permissions were.   Neither, it seems, does it know whether you used the texture's name to set the object's texture, or whether you read the UUID and used that.

So it simply reverts the object's texture to default, since that's the correct behaviour if the texture isn't full perms.

  • Like 2
Link to comment
Share on other sites

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