Colour Menu
Touch it, pick a colour from a menu, and the prim takes it. Twelve named colours to start with, and the list is yours to rewrite.
What it does
It offers the colours as a menu of named buttons and tints the face you choose. The names and the colours live in one list, side by side, so adding a colour is adding two entries and nothing else has to change. Above nine colours it pages the menu, because a dialog holds nine buttons and quietly loses the tenth. With WHOLE_LINKSET a wall built from six prims changes as one.
What you can build with it
A house somebody is choosing the walls of, a car in a showroom, a dress on a stand, the cushions in a room being tried out, a demo of something you sell in eight colours, team colours at an event. It is the cheapest way to make one build look like eight.
How to use it
Settings you can change
5Edit these at the top of the script. Everything works on the defaults · change them only when you need to.
// =====================================================================
// Colour Menu
// skimi3d script library
// https://grid.skimi3d.com/scripts/colour-menu
//
// Touch it, pick a colour, and the prim takes it. The wall of a house
// somebody is buying, a car in a showroom, a dress on a stand, the
// cushions in a room they are trying out.
//
// Plain LSL.
// =====================================================================
// ---------------------------------------------------------------------
// Settings
// ---------------------------------------------------------------------
// The colours offered, as a name and then the colour it stands for.
// The names become the buttons, so keep them to about eleven
// characters, and put them in the order you want them shown.
list COLOURS = [
"White", <1.00, 1.00, 1.00>,
"Bone", <0.94, 0.90, 0.82>,
"Sand", <0.85, 0.74, 0.55>,
"Rust", <0.65, 0.28, 0.16>,
"Moss", <0.36, 0.45, 0.28>,
"Slate", <0.35, 0.39, 0.44>,
"Ink", <0.10, 0.11, 0.14>,
"Rose", <0.90, 0.60, 0.62>,
"Sky", <0.55, 0.72, 0.90>,
"Gold", <0.85, 0.68, 0.25>,
"Plum", <0.42, 0.24, 0.42>,
"Sea", <0.20, 0.52, 0.52>
];
// Which face takes the colour. -1 is every face; a single face number
// paints the cushion and leaves the frame.
integer FACE = -1;
// Colour every prim in the linkset rather than only this one.
integer WHOLE_LINKSET = FALSE;
// The line above the buttons.
string HEADING = "Which colour?";
// Who may change it. 0 = everyone, 1 = only the owner, 2 = same group.
integer WHO_MAY_CHANGE = 0;
// ---------------------------------------------------------------------
// Everything below here is the machinery
// ---------------------------------------------------------------------
float PATIENCE = 60.0; // how long the menu waits for an answer
integer PER_PAGE = 9; // a dialog holds nine buttons and no more
integer gChannel = 0;
integer gListen = 0;
integer gPage = 0;
// Just the names, which are the buttons.
list names()
{
list out = [];
integer n = llGetListLength(COLOURS);
integer i;
// Two entries make one colour, so the step is two and not one.
for (i = 0; i < n; i += 2)
{
out += [llList2String(COLOURS, i)];
}
return out;
}
list page(integer n, list all)
{
integer total = llGetListLength(all);
if (total <= PER_PAGE) return all;
integer room = PER_PAGE - 2;
integer pages = (total + room - 1) / room;
if (n < 0) n = pages - 1;
if (n >= pages) n = 0;
gPage = n;
integer from = n * room;
integer to = from + room - 1;
if (to > total - 1) to = total - 1;
return llList2List(all, from, to) + ["< Back", "Next >"];
}
integer privateChannel(key who)
{
return -1 - (integer)("0x" + llGetSubString((string)who, 0, 6));
}
menu(key who, integer n)
{
if (gListen) llListenRemove(gListen);
gChannel = privateChannel(who);
gListen = llListen(gChannel, "", who, "");
llDialog(who, HEADING, page(n, names()), gChannel);
llSetTimerEvent(PATIENCE);
}
shut()
{
if (gListen) llListenRemove(gListen);
gListen = 0;
gPage = 0;
llSetTimerEvent(0.0);
}
paint(string name)
{
integer at = llListFindList(COLOURS, [name]);
if (at == -1) return;
// The colour sits directly after its name, which is what the stride
// of two is for.
vector c = llList2Vector(COLOURS, at + 1);
integer link = LINK_THIS;
if (WHOLE_LINKSET) link = LINK_SET;
llSetLinkPrimitiveParamsFast(link, [PRIM_COLOR, FACE, c, 1.0]);
}
integer mayChange(key who)
{
if (WHO_MAY_CHANGE == 1) return who == llGetOwner();
if (WHO_MAY_CHANGE == 2) return llSameGroup(who);
return TRUE;
}
default
{
state_entry()
{
shut();
}
touch_start(integer total)
{
key who = llDetectedKey(0);
if (!mayChange(who))
{
llRegionSayTo(who, 0, "This one is not yours to change.");
return;
}
menu(who, 0);
}
listen(integer channel, string name, key who, string message)
{
if (message == "Next >")
{
menu(who, gPage + 1);
return;
}
if (message == "< Back")
{
menu(who, gPage - 1);
return;
}
shut();
paint(message);
}
timer()
{
shut();
}
on_rez(integer start)
{
llResetScript();
}
}
Copy it, make a new script inworld, paste over what is there and save. Nothing here phones home.