// ===================================================================== // 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(); } }