/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // // rights of fair usage, the disclaimer and warranty conditions. // /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// string wasKeyValueGet(string var, string kvp) { list dVars = llParseString2List(kvp, ["&"], []); do { list data = llParseString2List(llList2String(dVars, 0), ["="], []); string k = llList2String(data, 0); if(k != var) jump continue; return llList2String(data, 1); @continue; dVars = llDeleteSubList(dVars, 0, 0); } while(llGetListLength(dVars)); return ""; } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// string wasKeyValueSet(string var, string val, string kvp) { list dVars = llParseString2List(kvp, ["&"], []); if(llGetListLength(dVars) == 0) return var + "=" + val; list result = []; do { list data = llParseString2List(llList2String(dVars, 0), ["="], []); string k = llList2String(data, 0); if(k == "") jump continue; if(k == var && val == "") jump continue; if(k == var) { result += k + "=" + val; val = ""; jump continue; } string v = llList2String(data, 1); if(v == "") jump continue; result += k + "=" + v; @continue; dVars = llDeleteSubList(dVars, 0, 0); } while(llGetListLength(dVars)); if(val != "") result += var + "=" + val; return llDumpList2String(result, "&"); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// vector wasStringToVector(string in) { list v = llParseString2List(in, ["<", ",", ">"], []); return <llList2Float(v, 0), llList2Float(v, 1), llList2Float(v, 2)>; } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// integer wasMenuIndex = 0; list wasDialogMenu(list input, list actions, string direction) { integer cut = 11-wasListCountExclude(actions, [""]); if(direction == ">" && (wasMenuIndex+1)*cut+wasMenuIndex+1 < llGetListLength(input)) { ++wasMenuIndex; jump slice; } if(direction == "<" && wasMenuIndex-1 >= 0) { --wasMenuIndex; jump slice; } @slice; integer multiple = wasMenuIndex*cut; input = llList2List(input, multiple+wasMenuIndex, multiple+cut+wasMenuIndex); input = wasListMerge(input, actions, ""); return input; } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// integer wasListCountExclude(list input, list exclude) { if(llGetListLength(input) == 0) return 0; if(llListFindList(exclude, (list)llList2String(input, 0)) == -1) return 1 + wasListCountExclude(llDeleteSubList(input, 0, 0), exclude); return wasListCountExclude(llDeleteSubList(input, 0, 0), exclude); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// list wasListMerge(list l, list m, string merge) { if(llGetListLength(l) == 0 && llGetListLength(m) == 0) return []; string a = llList2String(m, 0); if(a != merge) return [ a ] + wasListMerge(l, llDeleteSubList(m, 0, 0), merge); return [ llList2String(l, 0) ] + wasListMerge(llDeleteSubList(l, 0, 0), llDeleteSubList(m, 0, 0), merge); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2011 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// string wasProgress(integer percent, integer length, list symbols) { percent /= (integer)((float)100.0/(length)); string p = llList2String(symbols,0); integer itra = 0; do { if(itra>percent-1) p += llList2String(symbols,2); else p += llList2String(symbols,1); } while(++itra<length); return p + llList2String(symbols,3); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// vector wasPercentToGradient(float percent, string rgb) { if(llStringLength(rgb) != 2) { llSay(DEBUG_CHANNEL, "Assert failed, rgb parameter must consist of a pair of either r, g, or b."); return ZERO_VECTOR; } string a = llGetSubString(rgb, 0, 0); string b = llGetSubString(rgb, 1, 1); list col = [ "r", "g", "b" ]; integer ax = llListFindList(col, (list)a); integer bx = llListFindList(col, (list)b); if(ax == -1 || bx == -1) { llSay(DEBUG_CHANNEL, "Asset failed, rgb parameters must contain either r, g, or b letters."); return ZERO_VECTOR; } col = llListReplaceList(col, (list)((100-percent)/100), ax, ax); col = llListReplaceList(col, (list)(percent/100), bx, bx); return 2*<llList2Float(col, 0), llList2Float(col, 1), llList2Float(col, 2)>; } integer i = 0; integer channel = 0; key toucher = NULL_KEY; list monogram = []; string DIALOG_PREAMBLE = "\n Welcome to the Secretary Glasses.\nCreated in 2013 by Wizardry and Steamworks\n 28 September 2013: Version: 1.0"; default { state_entry() { if(wasKeyValueGet("auto", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)) == "on") llSensorRepeat("", "", AGENT, 3, TWO_PI, 3); if(toucher == NULL_KEY) return; llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE + "\n\nAuto Tilt: " + wasKeyValueGet("auto", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)), ["⬆ Up", "⬇ Down", "⎙ Options"], channel); } touch_start(integer total_number) { toucher = llDetectedKey(0); channel = (integer)("0x8" + llGetSubString(toucher, 0, 6)); llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE + "\n\nAuto Tilt: " + wasKeyValueGet("auto", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)), ["⬆ Up", "⬇ Down", "⎙ Options"], channel); } listen(integer channel, string name, key toucher, string message) { if(message == "⬆ Up") { if(wasKeyValueGet("status", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)) == "up") return; llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION); llSetTimerEvent(.5); llListenRemove(i); return; } if(message == "⬇ Down") { if(wasKeyValueGet("status", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)) == "down") return; llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION); llSetTimerEvent(.5); llListenRemove(i); return; } // REGION: OWNER if(toucher != llGetOwner()) { llInstantMessage(toucher, "Sorry, this option is restricted to the owner."); llListenRemove(i); return; } if(message == "⎙ Options") state options; // REGION: OWNER } sensor(integer num) { if(wasKeyValueGet("status", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)) == "up") return; llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION); llSetTimerEvent(.5); } no_sensor() { if(wasKeyValueGet("status", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)) == "down") return; llRequestPermissions(llGetOwner(), PERMISSION_TRIGGER_ANIMATION); llSetTimerEvent(.5); } run_time_permissions(integer perm) { if(!(perm & PERMISSION_TRIGGER_ANIMATION)) return; if(llGetInventoryType("Glasses") != INVENTORY_ANIMATION) return; llStartAnimation("Glasses"); } timer() { if(wasKeyValueGet("status", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)) == "up") { llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROT_LOCAL, ZERO_ROTATION, PRIM_POS_LOCAL, llGetLocalPos() - wasStringToVector(wasKeyValueGet("tilt", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)))]); llSetLinkPrimitiveParamsFast(13, [PRIM_DESC, wasKeyValueSet("status", "down", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0))]); jump reset; } llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROT_LOCAL, llEuler2Rot(<0,-50,0>*DEG_TO_RAD), PRIM_POS_LOCAL, llGetLocalPos() + wasStringToVector(wasKeyValueGet("tilt", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0)))]); llSetLinkPrimitiveParamsFast(13, [PRIM_DESC, wasKeyValueSet("status", "up", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0))]); @reset; llResetScript(); } on_rez(integer num) { llResetScript(); } } state options { state_entry() { llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, ["⏏ Exit", "⎙ Color", "⎙ Opacity", "⎙ Bright", "⎙ Glow", "⎙ Size", "⎙ Adjust Tilt", "⎙ Auto Tilt", "⎙ Stamp"], channel); } touch_start(integer num) { if(llDetectedKey(0) != llGetOwner()) return; llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, ["⏏ Exit", "⎙ Color", "⎙ Opacity", "⎙ Bright", "⎙ Glow", "⎙ Size", "⎙ Adjust Tilt", "⎙ Auto Tilt", "⎙ Stamp"], channel); } listen(integer channel, string name, key toucher, string message) { if(message == "⏏ Exit") state default; if(message == "⎙ Color") state color; if(message == "⎙ Opacity") state opacity; if(message == "⎙ Bright") state bright; if(message == "⎙ Glow") state glow; if(message == "⎙ Size") state size; if(message == "⎙ Adjust Tilt") state tilt; if(message == "⎙ Auto Tilt") state auto; if(message == "⎙ Stamp") state read_monogram; } on_rez(integer num) { llResetScript(); } } state color { state_entry() { llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, ["Rims ⌥", "Lenses ⎃", "⏏ Exit"], channel); } touch_start(integer num) { if(llDetectedKey(0) != llGetOwner()) return; llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, ["Rims ⌥", "Lenses ⎃", "⏏ Exit"], channel); } listen(integer channel, string name, key toucher, string message) { if(message == "⏏ Exit") state options; if(message == "Rims ⌥") { monogram = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 15, 16, 17, 18, 19 ]; state color_parts; } if(message == "Lenses ⎃") { monogram = [ 10, 14 ]; state color_parts; } @menu; llDialog(toucher, DIALOG_PREAMBLE, ["Rims ⌥", "Lenses ⎃", "⏏ Exit"], channel); } on_rez(integer num) { llResetScript(); } } state color_parts { state_entry() { llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, ["R ▼", "G ▼", "B ▼", "R ▲", "G ▲", "B ▲", "⏏ Exit"], channel); } touch_start(integer num) { if(llDetectedKey(0) != llGetOwner()) return; llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, ["R ▼", "G ▼", "B ▼", "R ▲", "G ▲", "B ▲", "⏏ Exit"], channel); } listen(integer channel, string name, key toucher, string message) { if(message == "⏏ Exit") state options; list params = llGetLinkPrimitiveParams(llList2Integer(monogram, -1), [PRIM_COLOR, ALL_SIDES]); vector color = llList2Vector(params, 0); float alpha = llList2Float(params, 1); i = llGetListLength(monogram)-1; do { if(message == "R ▼") llSetLinkPrimitiveParamsFast(llList2Integer(monogram, i), [PRIM_COLOR, ALL_SIDES, color-<.1,0,0>, alpha]); if(message == "R ▲") llSetLinkPrimitiveParamsFast(llList2Integer(monogram, i), [PRIM_COLOR, ALL_SIDES, color+<.1,0,0>, alpha]); if(message == "G ▼") llSetLinkPrimitiveParamsFast(llList2Integer(monogram, i), [PRIM_COLOR, ALL_SIDES, color-<0,.1,0>, alpha]); if(message == "G ▲") llSetLinkPrimitiveParamsFast(llList2Integer(monogram, i), [PRIM_COLOR, ALL_SIDES, color+<0,.1,0>, alpha]); if(message == "B ▼") llSetLinkPrimitiveParamsFast(llList2Integer(monogram, i), [PRIM_COLOR, ALL_SIDES, color-<0,0,.1>, alpha]); if(message == "B ▲") llSetLinkPrimitiveParamsFast(llList2Integer(monogram, i), [PRIM_COLOR, ALL_SIDES, color+<0,0,.1>, alpha]); @skip; } while(--i>-1); llDialog(toucher, DIALOG_PREAMBLE, ["R ▼", "G ▼", "B ▼", "R ▲", "G ▲", "B ▲", "⏏ Exit"], channel); } on_rez(integer num) { llResetScript(); } } state opacity { state_entry() { llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, ["⏏ Exit", "Opacity ▼", "Opacity ▲"], channel); } touch_start(integer num) { if(llDetectedKey(0) != llGetOwner()) return; llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, ["⏏ Exit", "Opacity ▼", "Opacity ▲"], channel); } listen(integer channel, string name, key toucher, string message) { if(message == "⏏ Exit") state options; list params = llGetLinkPrimitiveParams(10, [PRIM_COLOR, ALL_SIDES]); vector color = llList2Vector(params, 0); float alpha = llList2Float(params, 1); if(message == "Opacity ▼") { llSetLinkPrimitiveParamsFast(10, [PRIM_COLOR, ALL_SIDES, color, alpha-.1]); llSetLinkPrimitiveParamsFast(14, [PRIM_COLOR, ALL_SIDES, color, alpha-.1]); jump menu; } if(message == "Opacity ▲") { llSetLinkPrimitiveParamsFast(10, [PRIM_COLOR, ALL_SIDES, color, alpha+.1]); llSetLinkPrimitiveParamsFast(14, [PRIM_COLOR, ALL_SIDES, color, alpha+.1]); jump menu; } @menu; llDialog(toucher, DIALOG_PREAMBLE, ["⏏ Exit", "Opacity ▼", "Opacity ▲"], channel); } on_rez(integer num) { llResetScript(); } } state bright { state_entry() { llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, ["⏏ Exit", "◉ ON", "◯ OFF"], channel); } touch_start(integer num) { if(llDetectedKey(0) != llGetOwner()) return; llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, ["⏏ Exit", "◉ ON", "◯ OFF"], channel); } listen(integer channel, string name, key toucher, string message) { if(message == "⏏ Exit") state options; if(message == "◉ ON") { llSetLinkPrimitiveParamsFast(10, [PRIM_FULLBRIGHT, ALL_SIDES, TRUE]); llSetLinkPrimitiveParamsFast(14, [PRIM_FULLBRIGHT, ALL_SIDES, TRUE]); jump menu; } if(message == "◯ OFF") { llSetLinkPrimitiveParamsFast(10, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE]); llSetLinkPrimitiveParamsFast(14, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE]); } @menu; llDialog(toucher, DIALOG_PREAMBLE, ["⏏ Exit", "◉ ON", "◯ OFF"], channel); } on_rez(integer num) { llResetScript(); } } state glow { state_entry() { llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, ["⏏ Exit", "Glow ▼", "Glow ▲"], channel); } touch_start(integer num) { if(llDetectedKey(0) != llGetOwner()) return; llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, ["⏏ Exit", "Glow ▼", "Glow ▲"], channel); } listen(integer channel, string name, key toucher, string message) { if(message == "⏏ Exit") state options; list params = llGetLinkPrimitiveParams(10, [PRIM_GLOW, ALL_SIDES]); float glow = llList2Float(params, 0); if(message == "Glow ▼") { if(glow - .01 < 0) jump menu; llSetLinkPrimitiveParamsFast(10, [PRIM_GLOW, ALL_SIDES, glow-.01]); llSetLinkPrimitiveParamsFast(14, [PRIM_GLOW, ALL_SIDES, glow-.01]); jump menu; } if(message == "Glow ▲") { if(glow + .01 > 1) jump menu; llSetLinkPrimitiveParamsFast(10, [PRIM_GLOW, ALL_SIDES, glow+.01]); llSetLinkPrimitiveParamsFast(14, [PRIM_GLOW, ALL_SIDES, glow+.01]); jump menu; } @menu; llDialog(toucher, DIALOG_PREAMBLE, ["⏏ Exit", "Glow ▼", "Glow ▲"], channel); } on_rez(integer num) { llResetScript(); } } state size { state_entry() { llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, ["-.01", "-.02", "-.05", "+.01", "+.02", "+.05", "⏏ Exit"], channel); } touch_start(integer num) { if(llDetectedKey(0) != llGetOwner()) return; llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, ["-.01", "-.02", "-.05", "+.01", "+.02", "+.05", "⏏ Exit"], channel); } listen(integer channel, string name, key toucher, string message) { if(message == "⏏ Exit") state options; if((float)message == 0) return; float scale = 1 + (float)message; integer i = llGetNumberOfPrims(); do { vector linkScale = llList2Vector(llGetLinkPrimitiveParams(i, [PRIM_SIZE]), 0); vector linkPos = llList2Vector(llGetLinkPrimitiveParams(i, [PRIM_POS_LOCAL]), 0); llSetLinkPrimitiveParamsFast(i, [PRIM_SIZE, scale * linkScale, PRIM_POSITION, scale * linkPos]); } while(--i>1); llDialog(toucher, DIALOG_PREAMBLE, ["-.01", "-.02", "-.05", "+.01", "+.02", "+.05", "⏏ Exit"], channel); } on_rez(integer num) { llResetScript(); } } state tilt { state_entry() { llListen(channel, "", toucher, ""); llTextBox(toucher, DIALOG_PREAMBLE + "n\n This menu lets you adjust the displacement vector when the glasses are put up. Current tilt adjustment vector: " + (string)wasStringToVector(wasKeyValueGet("tilt", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0))), channel); } touch_start(integer num) { if(llDetectedKey(0) != llGetOwner()) return; state options; } listen(integer channel, string name, key toucher, string message) { vector tilt = wasStringToVector(message); if(tilt == ZERO_VECTOR) { llSetLinkPrimitiveParamsFast(13, [PRIM_DESC, wasKeyValueSet("tilt", "<.02,0,.04>", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0))]); jump main; } llSetLinkPrimitiveParamsFast(13, [PRIM_DESC, wasKeyValueSet("tilt", (string)tilt, llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0))]); @main; state default; } on_rez(integer num) { llResetScript(); } } state auto { state_entry() { llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE + "\n\nTurning this opon on will automatically tilt the glasses up once you are standing close to an avatar and put them back down again when you move away from avatars.", ["⏏ Exit", "◉ ON", "◯ OFF" ], channel); } touch_start(integer num) { if(llDetectedKey(0) != llGetOwner()) return; llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE + "\n\nTurning this option on will automatically tilt the glasses up once you are standing close to an avatar and put them back down again when you move away from avatars.", ["⏏ Exit", "◉ ON", "◯ OFF" ], channel); } listen(integer channel, string name, key toucher, string message) { if(message == "◉ ON") { llSetLinkPrimitiveParamsFast(13, [PRIM_DESC, wasKeyValueSet("auto", "on", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0))]); jump options; } if(message == "◯ OFF") llSetLinkPrimitiveParamsFast(13, [PRIM_DESC, wasKeyValueSet("auto", "off", llList2String(llGetLinkPrimitiveParams(13, [PRIM_DESC]), 0))]); @options; state options; } on_rez(integer num) { llResetScript(); } } state read_monogram { state_entry() { if(llGetInventoryType("Monogram") == INVENTORY_NOTECARD) jump found_notecard; llSay(DEBUG_CHANNEL, "Failed to find Monogram notecard."); return; @found_notecard; monogram = []; i = 0; llGetNotecardLine("Monogram", i); } dataserver(key id, string data) { if(data == EOF) { llSetText("", <0,0,0>, .0); state monogram_menu; } if(data != "") monogram += data; data = (string)(100 * i/26); llSetText("Please wait, loading menu...\n" + wasProgress((integer)data, 10, ["[", "█", "░", "]"]) + "\n Memory: " + (string)llGetFreeMemory() + "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", wasPercentToGradient((integer)data, "rg"), 1); llGetNotecardLine("Monogram", ++i); } on_rez(integer num) { llResetScript(); } } state monogram_menu { state_entry() { wasMenuIndex = 0; llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, wasDialogMenu(["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"], ["⏏ Exit", "⟻ Back", "Next ⟼"], ""), channel); } touch_start(integer num) { if(llDetectedKey(0) != llGetOwner()) return; llListen(channel, "", toucher, ""); llDialog(toucher, DIALOG_PREAMBLE, wasDialogMenu(["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"], ["⏏ Exit", "⟻ Back", "Next ⟼"], ""), channel); } listen(integer channel, string name, key toucher, string message) { if(message == "⏏ Exit") { monogram = []; state options; } if(message == "⟻ Back") { llDialog(toucher, DIALOG_PREAMBLE, wasDialogMenu(["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"], ["⏏ Exit", "⟻ Back", "Next ⟼"], "<"), channel); return; } if(message == "Next ⟼") { llDialog(toucher, DIALOG_PREAMBLE, wasDialogMenu(["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"], ["⏏ Exit", "⟻ Back", "Next ⟼"], ">"), channel); return; } i = llListFindList(["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"], (list)message); llSetLinkPrimitiveParamsFast(19, [PRIM_TYPE, PRIM_TYPE_SCULPT, llList2String(monogram, i), PRIM_SCULPT_TYPE_SPHERE]); } on_rez(integer num) { llResetScript(); } }