Application to Other Glasses

The code contains a few object-specific quirks that are hard-coded in the glasses. This is meant to reduce the size of the script but they can be batch-changed with find and replace so that the script will work for other glasses. The lens linked-primitive numbers are hard-coded, in the script bellow you will find hard-coded numerical values such as:

llGetLinkPrimitiveParams(13
llSetLinkPrimitiveParamsFast(7
llSetLinkPrimitiveParamsFast(9

The numbers represent:

These numbers have to be changed to match the new pair of glasses to which the script has to be adapted.

The monogram code, found in the script at various places, can be commented out, or the link number has to be changed to point to the monogram linked primitive. In this case the linked primitive that changes is the link number 2 and is hard-coded in various places as:

llSetLinkPrimitiveParamsFast(2

Code

carbon_glasses.lsl
///////////////////////////////////////////////////////////////////////////
//  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 = [];
 
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, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1\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, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1\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, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["⏏ 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, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["⏏ 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, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["R ▼", "G ▼", "B ▼", "R ▲", "G ▲", "B ▲", "⏏ Exit"], channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["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(7, [PRIM_COLOR, ALL_SIDES]);
        vector color = llList2Vector(params, 0);
        float alpha = llList2Float(params, 1);
        if(message == "R ▼") {
            llSetLinkPrimitiveParamsFast(7, [PRIM_COLOR, ALL_SIDES, color-<.1,0,0>, alpha]);
            llSetLinkPrimitiveParamsFast(9, [PRIM_COLOR, ALL_SIDES, color-<.1,0,0>, alpha]);
            jump menu;
        }
        if(message == "R ▲") {
            llSetLinkPrimitiveParamsFast(7, [PRIM_COLOR, ALL_SIDES, color+<.1,0,0>, alpha]);
            llSetLinkPrimitiveParamsFast(9, [PRIM_COLOR, ALL_SIDES, color+<.1,0,0>, alpha]);
            jump menu;
        }
        if(message == "G ▼") {
            llSetLinkPrimitiveParamsFast(7, [PRIM_COLOR, ALL_SIDES, color-<0,.1,0>, alpha]);
            llSetLinkPrimitiveParamsFast(9, [PRIM_COLOR, ALL_SIDES, color-<0,.1,0>, alpha]);
            jump menu;
        }
        if(message == "G ▲") {
            llSetLinkPrimitiveParamsFast(7, [PRIM_COLOR, ALL_SIDES, color+<0,.1,0>, alpha]);
            llSetLinkPrimitiveParamsFast(9, [PRIM_COLOR, ALL_SIDES, color+<0,.1,0>, alpha]);
            jump menu;
        }
        if(message == "B ▼") {
            llSetLinkPrimitiveParamsFast(7, [PRIM_COLOR, ALL_SIDES, color-<0,0,.1>, alpha]);
            llSetLinkPrimitiveParamsFast(9, [PRIM_COLOR, ALL_SIDES, color-<0,0,.1>, alpha]);
            jump menu;
        }
        if(message == "B ▲") {
            llSetLinkPrimitiveParamsFast(7, [PRIM_COLOR, ALL_SIDES, color+<0,0,.1>, alpha]);
            llSetLinkPrimitiveParamsFast(9, [PRIM_COLOR, ALL_SIDES, color+<0,0,.1>, alpha]);
            jump menu;
        }
@menu;
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["R ▼", "G ▼", "B ▼", "R ▲", "G ▲", "B ▲", "⏏ Exit"], channel);
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state opacity {
    state_entry() {
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["⏏ Exit", "Opacity ▼", "Opacity ▲"], channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["⏏ Exit", "Opacity ▼", "Opacity ▲"], channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "⏏ Exit") state options;
        list params = llGetLinkPrimitiveParams(7, [PRIM_COLOR, ALL_SIDES]);
        vector color = llList2Vector(params, 0);
        float alpha = llList2Float(params, 1);
        if(message == "Opacity ▼") {
            llSetLinkPrimitiveParamsFast(7, [PRIM_COLOR, ALL_SIDES, color, alpha-.1]);
            llSetLinkPrimitiveParamsFast(9, [PRIM_COLOR, ALL_SIDES, color, alpha-.1]);
            jump menu;
        }
        if(message == "Opacity ▲") {
            llSetLinkPrimitiveParamsFast(7, [PRIM_COLOR, ALL_SIDES, color, alpha+.1]);
            llSetLinkPrimitiveParamsFast(9, [PRIM_COLOR, ALL_SIDES, color, alpha+.1]);
            jump menu;
        }
@menu;
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["⏏ Exit", "Opacity ▼", "Opacity ▲"], channel);
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state bright {
    state_entry() {
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["⏏ Exit", "◉ ON", "◯ OFF"], channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["⏏ Exit", "◉ ON", "◯ OFF"], channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "⏏ Exit") state options;
        if(message == "◉ ON") {
            llSetLinkPrimitiveParamsFast(7, [PRIM_FULLBRIGHT, ALL_SIDES, TRUE]);
            llSetLinkPrimitiveParamsFast(9, [PRIM_FULLBRIGHT, ALL_SIDES, TRUE]);
            jump menu;
        }
        if(message == "◯ OFF") {
            llSetLinkPrimitiveParamsFast(7, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE]);
            llSetLinkPrimitiveParamsFast(9, [PRIM_FULLBRIGHT, ALL_SIDES, FALSE]);
        }
@menu;
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["⏏ Exit", "◉ ON", "◯ OFF"], channel);
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state glow {
    state_entry() {
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["⏏ Exit", "Glow ▼", "Glow ▲"], channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["⏏ Exit", "Glow ▼", "Glow ▲"], channel);
    }
    listen(integer channel, string name, key toucher, string message) {
        if(message == "⏏ Exit") state options;
        list params = llGetLinkPrimitiveParams(7, [PRIM_GLOW, ALL_SIDES]);
        float glow = llList2Float(params, 0);
        if(message == "Glow ▼") {
            if(glow - .01 < 0) jump menu;
            llSetLinkPrimitiveParamsFast(7, [PRIM_GLOW, ALL_SIDES, glow-.01]);
            llSetLinkPrimitiveParamsFast(9, [PRIM_GLOW, ALL_SIDES, glow-.01]);
            jump menu;
        }
        if(message == "Glow ▲") {
            if(glow + .01 > 1) jump menu;
            llSetLinkPrimitiveParamsFast(7, [PRIM_GLOW, ALL_SIDES, glow+.01]);
            llSetLinkPrimitiveParamsFast(9, [PRIM_GLOW, ALL_SIDES, glow+.01]);
            jump menu;
        }
@menu;
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["⏏ Exit", "Glow ▼", "Glow ▲"], channel);
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state size {
    state_entry() {
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["-.01", "-.02", "-.05", "+.01", "+.02", "+.05", "⏏ Exit"], channel);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["-.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, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", ["-.01", "-.02", "-.05", "+.01", "+.02", "+.05", "⏏ Exit"], channel);
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state tilt {
    state_entry() {
        llListen(channel, "", toucher, "");
        llTextBox(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1\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, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1\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);
    }
    touch_start(integer num) {
        if(llDetectedKey(0) != llGetOwner()) return;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1\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() {
        i = llGetInventoryNumber(INVENTORY_NOTECARD)-1;
        do {
            if(llGetInventoryName(INVENTORY_NOTECARD, i) == "Monogram")
            jump found_notecard;
        } while(--i>-1);
        llSay(DEBUG_CHANNEL, "Failed to find Monogram notecard.");
        return;
@found_notecard;
        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;
        integer percent = 100 * i/26;
        llSetText("Please wait, loading menu...\n" + wasProgress(percent, 10, ["[", "█", "░", "]"]) + "\n Memory: " + (string)llGetFreeMemory() + "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n", wasPercentToGradient(percent, "rg"), 1);
        llGetNotecardLine("Monogram", ++i);
    }
    on_rez(integer num) {
        llResetScript();
    }
}
 
state monogram_menu {
    state_entry() {
        wasMenuIndex = 0;
        llListen(channel, "", toucher, "");
        llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", 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, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", 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, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", 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, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", 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 = llGetListLength(monogram)-1;
        do {
            list m = llParseString2List(llList2String(monogram, i), ["="], []);
            if(message == llList2String(m, 0)) {
                llSetLinkPrimitiveParamsFast(2, [PRIM_TYPE, PRIM_TYPE_SCULPT, llList2String(m, 1), PRIM_SCULPT_TYPE_SPHERE]);
                llDialog(toucher, "\n            Welcome to the Carbon Glasses.\nCreated in 2013 by Wizardry and Steamworks\n                 15 May 2013: Version: 1.1", 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;
            }
        } while(--i>-1);
    }
    on_rez(integer num) {
        llResetScript();
    }
}