SimpleMLPStylingScript

Ok, bit of old and ugly code here. Publishing anyways as example.
What it does. This is an MLP plugin that allows styling of objects. Textures, colors, shinyness. Those are usually enough for most furniture.
Per link, you must describe in the link properties if it is subject to a particular styling paramaters. Those are: Color1, Color2, Texture and Shiny. They are represent as :C+: :C2+: :T+: and :S+:
So, a linked prim, like a cushion, that is subject to color and texture, would read: :C+:T+:
Another linked prim, like a wooden base, would be subject to color2 (wood shades) and shininess. It's description would read :C2+:S+:
You can activate the plugin by sending commands via a linked message on channel 13335
Example entry in MLP or TMCP notecard:
<lsl>
MENU Styling | OWNER
LINKMSG Light Colors |1,-4,-13335,LightPalette
LINKMSG Dark Colors |1,-4,-13335,Palette
LINKMSG Adjust Color|1,-4,-13335,AdjustColor
LINKMSG Fabric|1,-4,-13335,MenuTexture
LINKMSG Wood Color |1,-4,-13335,WoodPalette
//LINKMSG SomeTexture|0,-4,-13335,SetTexture:<uuid>
//LINKMSG Color Menu|1,-4,-13335,MenuColor
//LINKMSG Gray|0,-4,-13335,SetColor:<0.5,0.5,0.5>
TOMENU Shadow
LINKMSG Shiny Wood|0,-4,-13335,SetShiny:3
LINKMSG Satin Wood|0,-4,-13335,SetShiny:1
LINKMSG Pale Wood|0,-4,-13335,SetShiny:0
TOMENU Size
BACK
MENU Shadow | ALL
This example sets the root prim's alpha.. adjust link number to whatever the shadow texture was
LINKMSG No Shadow|0,-4,-13335,SetAlpha:1:0
LINKMSG Light Shadow|0,-4,-13335,SetAlpha:1:0.5
LINKMSG Full Shadow|0,-4,-13335,SetAlpha:1:1.0
BACK
MENU Size | OWNER
LINKMSG Grow|0,-4,-13335,ObjectGrow
LINKMSG Shrink|0,-4,-13335,ObjectShrink
BACK
</lsl>
The styling script is as follows, and again, sorry for bit messy code.. Publishing anyways, might post an update.
<lsl>
//THIS SCRIPT ASSUMES A FEW THINGS
//* THAT ITS CALLED / INITIATED BY MLP or something else that invokes a linked message
//That the root prim is colorable just like all childs
//That the root prim needs no (re)texturing but all childs do.
//Must customize this script for color palette, textures, and/or menu stuff you want in or out - no external configuration
//+BRIGHT CONTRAST+ +SATURATION
//-BRIGHT CONTRAST- -SATURATION
//+RED //+BLUE //+GREEN
//-RED //-BLUE //-GREEN
//PALETTE
vector myColor; //reads root prim color on startup
integer channel;
integer handle;
list Palette=[ "BORDEAUX", "PINK", "AQUA",
 "TEAL", "SKY", "NAVY", 
 "OKER", "BROWN", "CREAM",
 "BLACK", "GREY", "DARKBROWN"];
 
list PaletteC=[ <0.35,0,0>, <1,0.5,0.5>, <0.3,1.0,0.8>,
 <0,0.35,0.6>, <0.7,0.75,1>, <0,0,0.35>,
 <0.61,0.6,0.12>, <0.3,0.2,0.05>, <1.0,1.0,0.9>,
 <0.01,0.01,0.05>, <0.35,0.35,0.35>, <0.12,0.08,0>];
list PaletteLight=["BLUE1", "BLUE2", "BLUE3",
 "PINK1", "PINK2", "PINK3", 
 "GREEN1", "GREEN2", "CREAM1",
 "WHITE", "GREY2", "AMBER" ];
 
list PaletteL=[ <0.8,0.8,1.0>, <0.9,0.9,1.0>, <0.7,0.8,1.0>,
 <1.0,0.7,0.7>, <1.0,0.8,0.8>, <1.0,0.9,0.9>,
 <0.7,1.0,0.7>, <0.82,1.0,0.8>, <1.0,0.960,0.879>,
 <1.0,1.0,1.0>, <0.75,0.75,0.75>, <1.0, 0.9, 0.6>];
 
list PaletteWood =[ "Cherry", "Oak", "Mahogany",
 "Pine", "Ebony", "Maple",
 "OldOak", "Rosewood", "Elm",
 "Walnut", "DarkWalnut", "Onyx"];
list PaletteW=[ <0.6,0.28,0.18>, <0.62,0.41,0.21>, <0.26,0.08,0.05>,
 <0.76,0.53,0.19>, <0.12,0.11,0.11>, <0.77,0.45,0.26>,
 <0.59,0.4,0.24>, <0.3,0.15,0.15>, <0.4,0.25,0.2>,
 <0.5,0.40,0.28>, <0.29,0.14,0.05>, <0.22,0.19,0.14>];
list Textures = [
 "d14c73dd-9844-3fec-3405-c2cfa6cfae92",
 "29e827fe-6d57-e155-eaed-236a58b71244",
 //"1ae6c524-9a2e-b3a5-6349-4b99dfd861a3",
 //"06811c28-baae-68f8-18b6-38c7819f977f",
 "3486effe-7ab4-d955-6b4f-a85a3325a287",
 //"9e14c601-a7b0-e0e3-585d-a494c320fa87",
 //"80d859fb-dab4-9446-2d79-2d2a9693759d"
 "59d84d87-6ff5-a1b7-3f3b-d45c09ac05c1",
 "a523d079-6e2e-5832-8ac5-30b8c6092508",
 "feddf1ac-8176-11fe-0bc1-696544037253",
 "12d82751-1cd1-8f25-166c-5e2bcb2ed2d6",
 "24cf6699-b625-c06c-b2cd-984b28eb09e0",
 "7b71d0bc-d329-b94e-2fa8-0b584ca0e80c",
 "d598017c-0f6a-42ec-52f6-899be6e82878",
 "ddd57884-5a7b-f658-c8ab-d34df5d6d38e",
 "3fda0baa-d584-7d22-ed54-3943ef26c37f" 
];
list TextureNames = [
 "Stripes",
 "Ghecko",
 //"Bleached",
 //"Modern",
 "LineArt",
 //"Flowers",
 //"Victorian"
 "Leaves",
 "Old green",
 "Classic Leaves",
 "African",
 "Worn",
 "Abstract",
 "Elephant",
 "Wave",
 "Leather"
 ];
string colorStr() {
 return "\nCurrent: [ R="+(string)llRound(100*myColor.x)+" G="+(string)llRound(100*myColor.y)+" B="+(string)llRound(100*myColor.z)+" ]"; 
}
menuPalette (key id) { 
 llDialog (id, "Choose a color"+colorStr(), llListSort(Palette,1,TRUE), channel);
 setListen();
}
menuPaletteL (key id) { 
 llDialog (id, "Choose a color"+colorStr(), llListSort(PaletteLight,1,TRUE), channel);
}
menuWoodPalette (key id) { 
 llDialog (id, "Choose a color"+colorStr(), llListSort(PaletteWood,1,TRUE), channel);
}
menuAdjust (key id) {
 llDialog (id, "Adjust color\nHint: use HUE for small color shifts."+colorStr(),
 [
 "- SATURATION", "- HUE", "+ HUE",
 "+ SATURATION", "- BLUE", "+ BLUE",
 "- BRIGHT", "- GREEN", "+ GREEN",
 "+ BRIGHT", "- RED", "+ RED"
 ],
 channel); 
}
menuColor(key id) {
 llDialog(id, "Option", ["Adjust", "Palette", "Palette Light"], channel); 
}
menuTexture(key id) {
 /*
 list l;
 integer i=llGetListLength(Textures);
 for (;i;i--) {
 l+="Fabric "+(string)i; 
 }
 llDialog (id, "Select fabric", l, channel);
 */
 llDialog (id, "Select fabric", llListSort(TextureNames,1,TRUE), channel);
}
scale(float s) {
 if (s<0.10)
 return;
 llSetScale(s*llGetScale()); 
 if (llGetNumberOfPrims()>1) {
 integer i;
 for (i=2; i<=llGetNumberOfPrims(); i++) {
 list l=llGetLinkPrimitiveParams(i, [PRIM_POS_LOCAL, PRIM_SIZE]);
 //llOwnerSay ("PP:"+(string)l);
 vector newpos=s*(llList2Vector(l,0)); 
 vector newscale=s*llList2Vector(l,1); 
 if (newscale==ZERO_VECTOR) //something went wrong
 return; 
 llSetLinkPrimitiveParamsFast (i, [PRIM_POS_LOCAL, newpos, PRIM_SIZE, newscale]); 
 }
 } 
}
setColor (vector c) {
 //check bounds
 if (c.x < 0) c.x=0;
 if (c.x > 1) c.x=1; 
 if (c.y < 0) c.y=0;
 if (c.y > 1) c.y=1; 
 if (c.z < 0) c.z=0;
 if (c.z > 1) c.z=1; 
 myColor=c;
 if (llGetNumberOfPrims()==1)
 llSetColor(myColor, ALL_SIDES);
 else {
 integer i;
 for (i=0; i<=llGetNumberOfPrims(); i++) { //root is 0 or 1, silly SL
 string d=llList2String(llGetLinkPrimitiveParams(i, [PRIM_DESC]),0);
 if (-1!=llSubStringIndex(d, ":C+:"))
 llSetLinkColor(i, myColor, ALL_SIDES);
 }
 }
}
setColor2 (vector c) {
 //check bounds
 if (c.x < 0) c.x=0;
 if (c.x > 1) c.x=1; 
 if (c.y < 0) c.y=0;
 if (c.y > 1) c.y=1; 
 if (c.z < 0) c.z=0;
 if (c.z > 1) c.z=1; 
 myColor=c;
 if (llGetNumberOfPrims()==1)
 llSetColor(myColor, ALL_SIDES);
 else {
 integer i;
 for (i=0; i<=llGetNumberOfPrims(); i++) { //root is 0 or 1, silly SL
 string d=llList2String(llGetLinkPrimitiveParams(i, [PRIM_DESC]),0);
 if (-1!=llSubStringIndex(d, ":C2+:"))
 llSetLinkColor(i, myColor, ALL_SIDES);
 }
 }
}
setTexture (string texture) {
 if (llGetNumberOfPrims()==1)
 llSetTexture(texture, ALL_SIDES); 
 else {
 integer i;
 for (i=0; i<=llGetNumberOfPrims(); i++) { //root is 0 or 1, silly SL
 string d=llList2String(llGetLinkPrimitiveParams(i, [PRIM_DESC]),0);
 if (-1!=llSubStringIndex(d, ":T+:"))
 llSetLinkTexture(i, texture, ALL_SIDES);
 }
 }
}
setShiny (integer s) {
 integer i;
 for (i=0; i<=llGetNumberOfPrims(); i++) { //root is 0 or 1, silly SL
 string d=llList2String(llGetLinkPrimitiveParams(i, [PRIM_DESC]),0);
 if (-1!=llSubStringIndex(d, ":S+:"))
 llSetLinkPrimitiveParams(i, [PRIM_BUMP_SHINY, ALL_SIDES,s, 
 //existing bumpmap:
 llList2Integer(llGetLinkPrimitiveParams(i, [PRIM_BUMP_SHINY, ALL_SIDES]),1)
 ]);
 }
}
setListen() {
 llListenControl (handle, TRUE);
 llSetTimerEvent (0.0);
 llSetTimerEvent (120.0);
}
//funky color conv, tx Sally!
vector RGB2HSV( vector rgb )
{
 float R = rgb.x;
 if (R<0) // catch malformed input
 R=0;
 else if (R>1)
 R=1;
 float G = rgb.y;
 if (G<0) // catch malformed input
 G=0;
 else if (G>1)
 G=1;
 float B = rgb.z;
 if (B<0) // catch malformed input
 B=0;
 else if (B>1)
 B=1;
 
 float H;
 float S;
 float V;
 
 list rgbList = [R, G, B]; // list used to get min and max
 
 float min;
 float max;
 float achromatic; // =1 if R=G=B
 float delta;
 
 vector hsv; // the return HSV vector
 
 min = llListStatistics(LIST_STAT_MIN, rgbList); //MIN of ( R, G, B );
 max = llListStatistics(LIST_STAT_MAX, rgbList); //MAX of ( R, G, B );
 if (R==G && G==B)
 achromatic = 1; // it is a shade of grey, white or black
 else
 achromatic = 0;
 
 V = max; // V = brightness Value form 0 to 1
 delta = max - min;
 
 if( max != 0 )
 S = delta / max; // S = saturation from 0 to 1
 else {
 // R = G = B = 0 // S = 0, V = 0, H = 0
 S = 0; 
 V = 0; 
 H = 0;
 
 hsv.x = H;
 hsv.y = S;
 hsv.z = V;
 return hsv; //H = S = V = 0
 }
 
 if (achromatic == 1)
 H = 0;
 else if( R == max )
 H = 0 + ( G - B ) / delta; // between red & yellow
 else if( G == max )
 H = 2 + ( B - R ) / delta; // between yellow & cyan
 else
 H = 4 + ( R - G ) / delta; // between cyan & red
 
 
 H *= 60; // H is traditionally a figure between 0 and 360 degrees
 if( H < 0 )
 H += 360;
 
 hsv.x = H;
 hsv.y = S;
 hsv.z = V;
 return hsv;
}
vector HSV2RGB( vector hsv )
{
 integer i;
 
 float H = hsv.x;
 while (H<0) // catch malformed H input
 H+=360;
 while (H>=360)
 H-=360;
 float S = hsv.y;
 if (S<0) // catch malformed S input
 S=0;
 else if (S>1)
 S=1;
 float V = hsv.z;
 if (V<0) // catch malformed V input
 V=0;
 else if (V>1)
 V=1;
 
 float R;
 float G;
 float B;
 
 float f; // variables for calculating base color mixing around the "spectrum circle"
 float p;
 float q;
 float t;
 
 vector rgb;
 
 if( S == 0 ) { // achromatic (grey) simply set R,G, & B = Value
 R = V;
 G = V;
 B = V;
 
 rgb.x = R;
 rgb.y = G;
 rgb.z = B;
 return rgb;
 }
 
 H /= 60; // Hue factored into range 0 to 5
 i = llFloor( H ); // integer floor of Hue
 f = H - i; // factorial part of H
 
 p = V * ( 1 - S );
 q = V * ( 1 - S * f );
 t = V * ( 1 - S * ( 1 - f ) );
 
 if (i==0){
 R = V;
 G = t;
 B = p;
 } else if (i==1){
 R = q;
 G = V;
 B = p;
 } else if (i==2){
 R = p;
 G = V;
 B = t;
 } else if (i==3){
 R = p;
 G = q;
 B = V;
 } else if (i==4){
 R = t;
 G = p;
 B = V;
 } else { 
 R = V;
 G = p;
 B = q;
 }
 
 rgb.x = R;
 rgb.y = G;
 rgb.z = B;
 
 return rgb;
}
default
{
 state_entry()
 {
 myColor = llGetColor(ALL_SIDES);
 integer i;
 for (i=0; i<=llGetNumberOfPrims(); i++) { //root is 0 or 1, silly SL
 string d=llList2String(llGetLinkPrimitiveParams(i, [PRIM_DESC]),0);
 if (-1!=llSubStringIndex(d, ":C+:")) {
 myColor=llList2Vector(llGetLinkPrimitiveParams(i, [PRIM_COLOR, ALL_SIDES]),0);
 }
 }
 
 
 //llOwnerSay("Color: "+(string)myColor);
 channel=10000+llRound(llFrand(320932));
 handle=llListen(channel, "", "", "");
 llListenControl(handle, FALSE);
 }
 
 on_rez(integer n) {
 llResetScript(); 
 }
 link_message(integer ch, integer n, string data, key id) {
 if (n==-13335) {
 //hack.. just don't flood this please (...)
 //but we try to get this menu on top of MLP menu
 //llSleep (1.0);
 
 list l=llParseString2List(data, [":"], []);
 string d=llList2String(l,0);
 string p=llList2String(l,1);
 //interesting, styling command
 setListen();
 if (d=="MenuColor")
 menuColor(id);
 else if (d=="MenuTexture")
 menuTexture(id);
 else if (d=="ObjectGrow")
 scale(1.05);
 else if (d=="ObjectShrink")
 scale(1.0/1.05);
 else if (d=="Palette")
 menuPalette(id);
 else if (d=="LightPalette")
 menuPaletteL(id); 
 else if (d=="WoodPalette")
 menuWoodPalette(id); 
 else if (d=="AdjustColor")
 menuAdjust(id);
 else if (d=="SetTexture") {
 //we really need a texture handle that'd perfectly fit
 setTexture(p); 
 } else if (d=="SetColor") {
 setColor ((vector)p); 
 } else if (d=="SetColor2") {
 setColor2 ((vector)p); 
 } else if (d=="SetAlpha") {
 llSetLinkAlpha((integer)p, (float)llList2String(l, 2), ALL_SIDES); 
 } else if (d=="SetShiny") {
 setShiny((integer)p); 
 } else if (d=="Shiny") {
 llSetLinkPrimitiveParams((integer)p, [PRIM_BUMP_SHINY, ALL_SIDES,(integer)llList2String(l,2), 
 //existing bumpmap:
 llList2Integer(llGetLinkPrimitiveParams((integer)p, [PRIM_BUMP_SHINY, ALL_SIDES]),1)
 ]);
 } else if (d=="Link___") {
 //template for any value on any link..
 llSetLinkPrimitiveParamsFast((integer)p, [(integer)llList2String(l,2), (float)llList2String(l,3)]);
 }
 
 } 
 }
 
 listen (integer ch, string n, key id, string d) {
 
 //only listen to agents
 if (llGetAgentSize(id)); else return; 
 
 //user still active; assume no other spam on this channel 
 setListen();
 
 if (d=="<<BACK")
 menuColor(id);
 else if (d=="Adjust")
 menuAdjust(id);
 else if (d=="Palette")
 menuPalette(id);
 else if (d=="Palette Light")
 menuPaletteL(id);
 else {
 integer i=llListFindList(Palette+PaletteLight, [d]);
 if (i>=0) {
 //set color to palette entry
 setColor(llList2Vector(PaletteC+PaletteL, i));
 if (-1!=llListFindList(Palette, [d]))
 menuPalette(id);
 else
 menuPaletteL(id);
 return; 
 }
 i=llListFindList(PaletteWood, [d]);
 if (i>=0) {
 //set color to palette entry
 setColor2(llList2Vector(PaletteW, i));
 menuWoodPalette(id);
 return; 
 }
 
 
 list m=llParseString2List(d, [" "], []);
 string o=llList2String(m,0);
 string p=llList2String(m,1);
 
 if ((o=="-") || (o=="+")) {
 float f=-1.0;
 if (o=="+")
 f=1.0;
 if (p=="BRIGHT")
 setColor(0.05*f*<1,1,1> + myColor);
 else if (p=="SATURATION")
 //setColor(myColor + 0.05*f*(myColor-<0.55,0.55,0.55>));
 setColor (HSV2RGB(<0,0.075*f,0>+RGB2HSV(myColor)));
 else if (p=="RED")
 setColor(f*<0.05,0,0> + myColor);
 else if (p=="GREEN")
 setColor(f*<0,0.05,0> + myColor);
 else if (p=="BLUE")
 setColor(f*<0,0,0.05> + myColor);
 else if (p=="HUE")
 setColor (HSV2RGB(<15.0*f,0,0>+RGB2HSV(myColor)));
 menuAdjust(id);
 return;
 }
 /*
 if (o=="Fabric") {
 setTexture(llList2String(Textures, (integer)p-1));
 menuTexture(id);
 }
 */
 i=llListFindList(TextureNames, [d]);
 if (i>=0) {
 setTexture (llList2String(Textures, i));
 menuTexture(id); 
 }
 
 }
 }
 
 timer() {
 llSetTimerEvent(0.0);
 llListenControl (handle, FALSE); 
 }
}
</lsl>
Happy scripting.