Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Texture Drop to Change a Prim Texture

Ryker Beck
Photographer & Designer
Join date: 23 Feb 2007
Posts: 57
08-11-2008 21:46
Hi all!

I'm sure this has been talked to death and I just can't find the thread, so if you could point me to the proper location, I'd be most grateful. If not, then here's my dilemma!

For the last couple of days I have been working on a locket. The locket works fantastic... Basically it is two prims, with a second, invisible prim acting as the locket door when it's opened. If you click on the locket, the door opens (i.e. the prim hiding the picture inside is set to Alpha 0 and the invisible prim door is set to Alpha 1). Clicking it again returns it to it's original state.

That's all fine and dandy.

However, the problem I realized I'll have with using this locket is this: I can't very well drag and drop a texture onto the prim that houses the picture when an invisible locket door is parked right in front of it, now can I? *dunce*

So my question is this:

Is there any way that I could drag and drop a texture into the locket's inventory, have the prim that houses the locket's picture recognize the fact that there was a texture dropped into the locket, and then automatically update the displayed picture with the texture that was dropped inside the locket's contents?

I'm assuming this will take two scripts... one that will live in the root prim, and another that will live in the picture prim. However, I have absolutely no idea where to begin with scripting the functions of these. If someone could point me in the right direction, I'd be much appreciative.

Thanks! :)

- R
Lightwave Valkyrie
Registered User
Join date: 30 Jan 2004
Posts: 666
08-11-2008 23:05
in the root prim use changed( integer change )//event
if ( change & CHANGED_INVENTORY )
{
string inv_name = llGetInventoryName( INVENTORY_TEXTURE, llGetInventoryNumber( INVENTORY_TEXTURE ) - 1 );

key id = llGetInventoryKey( inv_name );// get inventory key of texture

and send it with link message to the script the texture is in
and set texture in that prim
also llRemoveInventory( inv_name );
after your done so its not collecting in root prim
_____________________
L$ is the root of all evil
videos work! thanks SL :)
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
08-12-2008 01:35
Hmm. I don't think items in prim inventory are ordered in the sequence they were added. I believe they are alphabetical. You might have to keep a list of the previous contents....
Ryker Beck
Photographer & Designer
Join date: 23 Feb 2007
Posts: 57
08-12-2008 09:05
hey Lightwave!
This is awesome and thanks for the feedback, however I honest to god have no clue what I'm doing when it comes to scripting something like this. >.<

Could you point me to a script that's already written (I'd even be willing to buy it full perms on SLex or OnRez) perhaps?
Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
08-12-2008 14:57
Here's a single script I use to do something pretty similar.. I drop the script and several textures into the inventory of a prim I can easily click; this gives me a menu from which I can choose the texture I want to display on the linked prim (called Target).

CODE
string TARGET_PRIM_NAME = "Target"; //name for all the prims you want to change
changeAllTargetPrims(list primParams)
{
integer i;
for (i = llGetNumberOfPrims(); i > 0; --i)
{
if (llGetLinkName(i) == TARGET_PRIM_NAME)
{
llSetLinkPrimitiveParams(i, primParams);
}
}
}

integer randBetween(integer min, integer max) //random number for listener to prevent interference
{
return (integer)(llFrand((float)(max - min)) + min);
}

list buttons;
integer index;
integer MyChannel; // dialog channel
integer listener; // Always set up a handler for a listener
key toucher;
string menuText;
default
{
changed(integer change)
{
if (CHANGED_INVENTORY)
{ llResetScript();}
}
state_entry()
{
MyChannel = -randBetween(1, 100000); //so neighbouring devices don't interfere with each other
integer numberOfTextures = llGetInventoryNumber(INVENTORY_TEXTURE);
for (index=0;index<numberOfTextures;index++)
{
buttons+=(string)index;
menuText += (string)index;
menuText += " - ";
menuText += llGetInventoryName(INVENTORY_TEXTURE,index);
menuText += ";";
}
llListen(MyChannel, "", NULL_KEY, "");
}


touch_start(integer total_number)

{ toucher = llDetectedKey(0);
listener = llListen(MyChannel, "", toucher, "");
llDialog(toucher,menuText,buttons,MyChannel);
llSetTimerEvent(30);
}
listen(integer channel, string name, key id, string message)
{
index = (integer)message;
string textureName = llGetInventoryName(INVENTORY_TEXTURE,index);

list primParams = [PRIM_TEXTURE, ALL_SIDES, textureName,<1,1,0>, <0,0,0>, 0 ];
changeAllTargetPrims( primParams);
}
timer(){
llSetTimerEvent(0);
llListenRemove(listener);
}
}



Shouldn't be too difficult to adapt this to what you want. IM me in world if you need a hand with it.
Ryker Beck
Photographer & Designer
Join date: 23 Feb 2007
Posts: 57
08-12-2008 15:20
You are a gem!
I'll give it a shot and let you know. :) Thanks so much!
Ryker Beck
Photographer & Designer
Join date: 23 Feb 2007
Posts: 57
08-12-2008 15:33
It works BEAUTIFULLY!!!!!
Oh. My. God.
I CANNOT thank you enough. :))) Thank you SO SO SO SO MUCH!
Cordelia Schwarz
Registered User
Join date: 18 Jun 2008
Posts: 14
Changing Texture Tweak
11-10-2008 18:09
From: Innula Zenovka
Here's a single script I use to do something pretty similar.. I drop the script and several textures into the inventory of a prim I can easily click; this gives me a menu from which I can choose the texture I want to display on the linked prim (called Target).

CODE
string TARGET_PRIM_NAME = "Target"; //name for all the prims you want to change
changeAllTargetPrims(list primParams)
{
integer i;
for (i = llGetNumberOfPrims(); i > 0; --i)
{
if (llGetLinkName(i) == TARGET_PRIM_NAME)
{
llSetLinkPrimitiveParams(i, primParams);
}
}
}

integer randBetween(integer min, integer max) //random number for listener to prevent interference
{
return (integer)(llFrand((float)(max - min)) + min);
}

list buttons;
integer index;
integer MyChannel; // dialog channel
integer listener; // Always set up a handler for a listener
key toucher;
string menuText;
default
{
changed(integer change)
{
if (CHANGED_INVENTORY)
{ llResetScript();}
}
state_entry()
{
MyChannel = -randBetween(1, 100000); //so neighbouring devices don't interfere with each other
integer numberOfTextures = llGetInventoryNumber(INVENTORY_TEXTURE);
for (index=0;index<numberOfTextures;index++)
{
buttons+=(string)index;
menuText += (string)index;
menuText += " - ";
menuText += llGetInventoryName(INVENTORY_TEXTURE,index);
menuText += ";";
}
llListen(MyChannel, "", NULL_KEY, "");
}


touch_start(integer total_number)

{ toucher = llDetectedKey(0);
listener = llListen(MyChannel, "", toucher, "");
llDialog(toucher,menuText,buttons,MyChannel);
llSetTimerEvent(30);
}
listen(integer channel, string name, key id, string message)
{
index = (integer)message;
string textureName = llGetInventoryName(INVENTORY_TEXTURE,index);

list primParams = [PRIM_TEXTURE, ALL_SIDES, textureName,<1,1,0>, <0,0,0>, 0 ];
changeAllTargetPrims( primParams);
}
timer(){
llSetTimerEvent(0);
llListenRemove(listener);
}
}



Shouldn't be too difficult to adapt this to what you want. IM me in world if you need a hand with it.



Is there a way to have the texture names on the buttons instead of the numbers?
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
11-10-2008 18:48
yeah, just add the names to the buttons list instead and index
buttons +=(list)(llGetSubString( llGetInventoryName( INVENTORY_TEXTURE, index ), 0, 23);

getsubstring will keep you from any possible error messages for button text greater than 24 characters, although you may want to limit it to 12 or less since that's about the max you can actually see on a button)
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Cordelia Schwarz
Registered User
Join date: 18 Jun 2008
Posts: 14
11-11-2008 09:55
From: Void Singer
yeah, just add the names to the buttons list instead and index
buttons +=(list)(llGetSubString( llGetInventoryName( INVENTORY_TEXTURE, index ), 0, 23);

getsubstring will keep you from any possible error messages for button text greater than 24 characters, although you may want to limit it to 12 or less since that's about the max you can actually see on a button)



I can't seem to get it to work (unless I'm putting it in the wrong line). Could you tell me which line to replace please? Thanx :)
Innula Zenovka
Registered User
Join date: 20 Jun 2007
Posts: 1,825
11-11-2008 10:12
From: Cordelia Schwarz
I can't seem to get it to work (unless I'm putting it in the wrong line). Could you tell me which line to replace please? Thanx :)

There's a typo (missing closing parenthesis). Try
CODE
for (index=0;index<numberOfTextures;index++)
{
buttons +=(list)(llGetSubString( llGetInventoryName( INVENTORY_TEXTURE, index ), 0, 23));
menuText += (string)index;
menuText += " - ";
menuText += llGetInventoryName(INVENTORY_TEXTURE,index);
menuText += ";";
}
You may want to alter the menu text as well, though, on the other hand, it might be helpful to keep it as is, so as better to identity those textures where the first 12 characters (i.e. the button text) doesn't give you a unique (or particularly meaningful) name for the texture.
Cordelia Schwarz
Registered User
Join date: 18 Jun 2008
Posts: 14
11-11-2008 13:51
Thanx Innula and Zoid. It works perfectly! :)
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
11-11-2008 17:42
good catch
_____________________
|
| . "Cat-Like Typing Detected"
| . This post may contain errors in logic, spelling, and
| . grammar known to the SL populace to cause confusion
|
| - Please Use PHP tags when posting scripts/code, Thanks.
| - Can't See PHP or URL Tags Correctly? Check Out This Link...
| -
Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
01-19-2009 09:33
Hmm, does not seem to work right for me, changes to one texture, (wrong one), then does nothing;

CODE

string TARGET_PRIM_NAME = "Stone"; //name for all the prims you want to change
changeAllTargetPrims(list primParams)
{
integer i;
for (i = llGetNumberOfPrims(); i > 0; --i)
{
if (llGetLinkName(i) == TARGET_PRIM_NAME)
{
llSetLinkPrimitiveParams(i, primParams);
}
}
}

integer randBetween(integer min, integer max) //random number for listener to prevent interference
{
return (integer)(llFrand((float)(max - min)) + min);
}

list buttons;
integer index;
integer MyChannel; // dialog channel
integer listener; // Always set up a handler for a listener
key toucher;
string menuText;
default
{
changed(integer change)
{
if (CHANGED_INVENTORY)
{ llResetScript();}
}
state_entry()
{
MyChannel = -randBetween(1, 100000); //so neighbouring devices don't interfere with each other
integer numberOfTextures = llGetInventoryNumber(INVENTORY_TEXTURE);
for (index=0;index<numberOfTextures;index++)
{
buttons +=(list)(llGetSubString( llGetInventoryName( INVENTORY_TEXTURE, index ), 0, 23));
menuText += (string)index;
menuText += " - ";
menuText += llGetInventoryName(INVENTORY_TEXTURE,index);
menuText += ";";
}
llListen(MyChannel, "", NULL_KEY, "");
}


touch_start(integer total_number)

{ toucher = llDetectedKey(0);
listener = llListen(MyChannel, "", toucher, "");
llDialog(toucher,menuText,buttons,MyChannel);
llSetTimerEvent(30);
}
listen(integer channel, string name, key id, string message)
{
index = (integer)message;
string textureName = llGetInventoryName(INVENTORY_TEXTURE,index);

list primParams = [PRIM_TEXTURE, ALL_SIDES, textureName,<1,1,0>, <0,0,0>, 0 ];
changeAllTargetPrims( primParams);
}
timer(){
llSetTimerEvent(0);
llListenRemove(listener);
}
}

Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
01-20-2009 05:41
Hmm ok it's in this line:

buttons +=(list)(llGetSubString( llGetInventoryName( INVENTORY_TEXTURE, index ), 0, 23));

or at least changing the button naming line is what breaks the texture change from happening occurring. I tested by adding a say on texture name and always chooses the same one.
Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
01-20-2009 09:39
Hmm, the naming the buttons works:

buttons +=(list)(llGetSubString( llGetInventoryName( INVENTORY_TEXTURE, index ), 0, 23));

but breaks the texture change from working correctly ( I tested by adding a say on texture name and always chooses the same one - the 1st texture in the prim's inventory):

CODE

listen(integer channel, string name, key id, string message)
{
index = (integer)message;
string textureName = llGetInventoryName(INVENTORY_TEXTURE,index);
llSay(0, "Texture selected - '" + textureName + " '");
list primParams = [PRIM_TEXTURE, ALL_SIDES, textureName,<2,2,0>, <0,0,0>, -90 * DEG_TO_RAD ];
changeAllTargetPrims( primParams);
}
Celty Westwick
Registered User
Join date: 24 Jun 2006
Posts: 145
01-20-2009 09:48
OK the problem was in how "string textureName" was getting defined :), changing it to use message worked.