/////////////////////////////////////////////////////////////////////////// // 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) 2015 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// string wasKeyValueGet(string k, string data) { if(llStringLength(data) == 0) return ""; if(llStringLength(k) == 0) return ""; list a = llParseStringKeepNulls(data, ["&", "="], []); integer i = llListFindList(llList2ListStrided(a, 0, -1, 2), [ k ]); if(i != -1) return llList2String(a, 2*i+1); return ""; } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// string wasKeyValueSet(string k, string v, string data) { if(llStringLength(k) == 0) return ""; if(llStringLength(v) == 0) return ""; if(llStringLength(data) == 0) return k + "=" + v; integer i = llListFindList( llList2ListStrided( llParseString2List(data, ["&", "="], []), 0, -1, 2 ), [ k ]); if(i != -1) return llDumpList2String( llListReplaceList( llParseString2List(data, ["&"], []), [ k + "=" + v ], i, i), "&"); return data + "&" + k + "=" + v; } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// string wasKeyValueEncode(list data) { list k = llList2ListStrided(data, 0, -1, 2); list v = llList2ListStrided(llDeleteSubList(data, 0, 0), 0, -1, 2); data = []; do { data += llList2String(k, 0) + "=" + llList2String(v, 0); k = llDeleteSubList(k, 0, 0); v = llDeleteSubList(v, 0, 0); } while(llGetListLength(k) != 0); return llDumpList2String(data, "&"); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// list wasKeyValueDecode(string data) { return llParseString2List(data, ["&", "="], []); } /////////////////////////////////////////////////////////////////////////// // Copyright (C) 2013 Wizardry and Steamworks - License: GNU GPLv3 // /////////////////////////////////////////////////////////////////////////// list wasDialogMenu(list input, list actions, string direction) { integer cut = 11-wasListCountExclude(actions, [""]); integer wasMenuIndex = (integer)wasKeyValueGet("index", llGetObjectDesc()); if(direction == ">" && (wasMenuIndex+1)*cut+wasMenuIndex+1 < llGetListLength(input)) { ++wasMenuIndex; llSetObjectDesc(wasKeyValueSet("index", (string)wasMenuIndex, llGetObjectDesc())); jump slice; } if(direction == "<" && wasMenuIndex-1 >= 0) { --wasMenuIndex; llSetObjectDesc(wasKeyValueSet("index", (string)wasMenuIndex, llGetObjectDesc())); 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) 2013 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)>; } // Reading variables. integer nLine = 0; integer lines = 0; // Animation list list animations = []; // Menu list list menuList = []; // Toucher storage. key mav = NULL_KEY; // Current animation set. string set = ""; default { state_entry() { if((integer)wasKeyValueGet("session", llGetObjectDesc()) == 0) llSetObjectDesc(wasKeyValueSet("session", (string)((integer)llFrand(1879048193)), llGetObjectDesc())); menuList = ["◉ STOP", "⌠ Settings ⌡", "⌠ Items ⌡" ]; string mode = wasKeyValueGet("mode", llGetObjectDesc()); nLine = llGetInventoryNumber(INVENTORY_NOTECARD)-1; do { list m = wasKeyValueDecode(llGetInventoryName(INVENTORY_NOTECARD, nLine)); string itemMaturity = llList2String(m, 1); string item = llList2String(m,0); if(itemMaturity == "pg") { menuList += "☀ " + item; jump continue; } if(itemMaturity == "mature" && (mode == "mature" || mode == "adult")) { menuList += "♥ " + item; jump continue; } if(itemMaturity == "adult" && mode == "adult") { menuList += "☯ " + item; jump continue; } @continue; } while(--nLine>-1); if(mav == NULL_KEY) return; integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6)) + (integer)wasKeyValueGet("session", llGetObjectDesc()); llListen(comChannel, "", mav, ""); llDialog(mav, "\n Welcome to the Lounge Armchair.\nCreated in 2014 by Wizardry and Steamworks\n 26 May 2014: Version: 1.0", menuList, comChannel); } touch_start(integer num) { mav = llDetectedKey(0); integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6)) + (integer)wasKeyValueGet("session", llGetObjectDesc()); llListen(comChannel, "", mav, ""); llDialog(mav, "\n Welcome to the Lounge Armchair.\nCreated in 2014 by Wizardry and Steamworks\n 26 May 2014: Version: 1.0", menuList, comChannel); } listen(integer channel, string name, key id, string message) { if(message == "◉ STOP") { llWhisper(channel, "sex=f&die=f"); llSetObjectDesc(wasKeyValueSet("f", "off", llGetObjectDesc())); llWhisper(channel, "sex=m&die=m"); llSetObjectDesc(wasKeyValueSet("m", "off", llGetObjectDesc())); llResetScript(); } if(message == "⌠ Settings ⌡") { if(id != llGetOwner()) { llInstantMessage(id, "Sorry, this option is restricted to the owner."); return; } menuList = []; state settings; } if(message == "⌠ Items ⌡") { menuList = []; state items; } list m = llParseString2List(message, [" "], []); if(llList2String(m, 0) == "☀") { set = wasKeyValueEncode([llList2String(m, 1), "pg"]); jump count; } if(llList2String(m, 0) == "♥") { set = wasKeyValueEncode([llList2String(m, 1), "mature"]); jump count; } if(llList2String(m, 0) == "☯") { set = wasKeyValueEncode([llList2String(m, 1), "adult"]); jump count; } @count; menuList = []; state count; } on_rez(integer num) { llSetObjectDesc(wasKeyValueSet("session", "0", llGetObjectDesc())); llResetScript(); } } state items { state_entry() { menuList = [ "⏏ Exit" ]; integer i = llGetInventoryNumber(INVENTORY_OBJECT)-1; do { string name = llGetInventoryName(INVENTORY_OBJECT, i); if(name == "m" || name == "f") jump continue; menuList += name; @continue; } while(--i>-1); if(mav == NULL_KEY) return; integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6)) + (integer)wasKeyValueGet("session", llGetObjectDesc()); llListen(comChannel, "", mav, ""); llDialog(mav, "Please select an item from the list below or click the exit button to return to the previous menu.", menuList, comChannel); } listen(integer channel, string name, key id, string message) { if(message == "⏏ Exit") { menuList = []; state default; } llGiveInventory(id, message); llDialog(id, "Please select an item from the list below or click the exit button to return to the previous menu.", menuList, channel); } on_rez(integer num) { llSetObjectDesc(wasKeyValueSet("session", "0", llGetObjectDesc())); llResetScript(); } } // locked to owner state settings { state_entry() { menuList = [ "⏏ Exit", "⌠ Textures ⌡", "⌠ Mode ⌡"]; if(mav == NULL_KEY) return; integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6)) + (integer)wasKeyValueGet("session", llGetObjectDesc()); llListen(comChannel, "", mav, ""); llDialog(mav, "Please select an option from the list below or click the back button to return to the previous menu.", menuList, comChannel); } touch_start(integer num) { mav = llDetectedKey(0); // locked to owner, bail out if(mav != llGetOwner()) state default; integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6)) + (integer)wasKeyValueGet("session", llGetObjectDesc()); llListen(comChannel, "", mav, ""); llDialog(mav, "Please select an option from the list below or click the back button to return to the previous menu.", menuList, comChannel); } listen(integer channel, string name, key id, string message) { if(message == "⏏ Exit") { menuList = []; state default; } if(message == "⌠ Textures ⌡") { menuList = []; state textures; } if(message == "⌠ Mode ⌡") state mode; llDialog(id, "Please select an option from the list below or click the back button to return to the previous menu.", menuList, channel); } on_rez(integer num) { llSetObjectDesc(wasKeyValueSet("session", "0", llGetObjectDesc())); llResetScript(); } } // locked to owner state mode { state_entry() { menuList = [ "⏏ Exit", "☀ PG", "♥ Mature", "☯ Adult"]; if(mav == NULL_KEY) return; integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6)) + (integer)wasKeyValueGet("session", llGetObjectDesc()); llListen(comChannel, "", mav, ""); llDialog(mav, "The chaise lounge can operate in two different modes. Please select an operating mode from the available options below:\n\nPG - general audience with adult entertainment poses hidden.\n\nAdult - both general audience and adult entertainment poses shown.", menuList, comChannel); } touch_start(integer num) { mav = llDetectedKey(0); // locked to owner, bail out if(mav != llGetOwner()) state default; integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6)) + (integer)wasKeyValueGet("session", llGetObjectDesc()); llListen(comChannel, "", mav, ""); llDialog(mav, "The chaise lounge can operate in two different modes. Please select an operating mode from the available options below:\n\nPG - general audience with adult entertainment poses hidden.\n\nAdult - both general audience and adult entertainment poses shown.", menuList, comChannel); } listen(integer channel, string name, key id, string message) { if(message == "☀ PG") { llSetObjectDesc(wasKeyValueSet("mode", "pg", llGetObjectDesc())); jump settings; } if(message == "♥ Mature") { llSetObjectDesc(wasKeyValueSet("mode", "mature", llGetObjectDesc())); jump settings; } if(message == "☯ Adult") { llSetObjectDesc(wasKeyValueSet("mode", "adult", llGetObjectDesc())); jump settings; } @settings; menuList = []; state settings; } on_rez(integer num) { llSetObjectDesc(wasKeyValueSet("session", "0", llGetObjectDesc())); llResetScript(); } } // locked to owner state textures { state_entry() { nLine = llGetInventoryNumber(INVENTORY_TEXTURE)-1; do { menuList += llGetInventoryName(INVENTORY_TEXTURE, nLine); } while(--nLine>-1); if(mav == NULL_KEY) return; integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6)) + (integer)wasKeyValueGet("session", llGetObjectDesc()); llListen(comChannel, "", mav, ""); llSetObjectDesc(wasKeyValueSet("index", "0", llGetObjectDesc())); llDialog(mav, "Please select an option from the list below or click the exit button to return to the previous menu.", wasDialogMenu(menuList, ["⏏ Exit", "⟻ Back", "Next ⟼"], ""), comChannel); } touch_start(integer num) { mav = llDetectedKey(0); // locked to owner, bail out if(mav != llGetOwner()) state default; integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6)) + (integer)wasKeyValueGet("session", llGetObjectDesc()); llListen(comChannel, "", mav, ""); llDialog(mav, "Please select an option from the list below or click the exit button to return to the previous menu.", wasDialogMenu(menuList, ["⏏ Exit", "⟻ Back", "Next ⟼"], ""), comChannel); } listen(integer channel, string name, key id, string message) { if(message == "⏏ Exit") { menuList = []; state settings; } if(message == "⟻ Back") { llDialog(id, "Please select a texture from the list below:\n", wasDialogMenu(menuList, ["⏏ Exit", "⟻ Back", "Next ⟼"], "<"), channel); return; } if(message == "Next ⟼") { llDialog(id, "Please select a texture from the list below:\n", wasDialogMenu(menuList, ["⏏ Exit", "⟻ Back", "Next ⟼"], ">"), channel); return; } llSetLinkTexture(2, message, ALL_SIDES); llDialog(id, "Please select a texture from the list below:\n", wasDialogMenu(menuList, ["⏏ Exit", "⟻ Back", "Next ⟼"], ""), channel); } on_rez(integer num) { llSetObjectDesc(wasKeyValueSet("session", "0", llGetObjectDesc())); llResetScript(); } } state count { state_entry() { llGetNumberOfNotecardLines(set); } dataserver(key id, string data) { lines = (integer)data; state read; } on_rez(integer num) { llSetObjectDesc(wasKeyValueSet("session", "0", llGetObjectDesc())); llResetScript(); } } state read { state_entry() { nLine = llGetInventoryNumber(INVENTORY_NOTECARD)-1; do { if(llGetInventoryName(INVENTORY_NOTECARD, nLine) == set) jump found_notecard; } while(--nLine>-1); llSay(DEBUG_CHANNEL, "Failed to find notecard for chosen set."); return; @found_notecard; nLine = 0; llGetNotecardLine(set, nLine); } dataserver(key id, string data) { if(data == EOF) { llSetText("", <1,1,1>, 1); state menu; } if(data == "") jump continue; animations += data; integer percent = (integer)(100.0*(float)nLine/(float)lines); 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); @continue; llGetNotecardLine(set, ++nLine); } on_rez(integer num) { llSetObjectDesc(wasKeyValueSet("session", "0", llGetObjectDesc())); llResetScript(); } } state menu { state_entry() { nLine = llGetListLength(animations)-1; do { string animation = wasKeyValueGet("n", llList2String(animations, nLine)); if(llListFindList(menuList, (list)animation) != -1) jump continue; menuList += animation; @continue; } while(--nLine>-1); if(mav == NULL_KEY) return; integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6)) + (integer)wasKeyValueGet("session", llGetObjectDesc()); llListen(comChannel, "", mav, ""); llSetObjectDesc(wasKeyValueSet("index", "0", llGetObjectDesc())); llDialog(mav, "Please select an animation from the list below:\n", wasDialogMenu(menuList, ["⏏ Exit", "⟻ Back", "Next ⟼", "⟺ Swap"], ""), comChannel); } touch_start(integer num) { mav = llDetectedKey(0); integer comChannel = (integer)("0x8" + llGetSubString(llGetOwner(), 0, 6)) + (integer)wasKeyValueGet("session", llGetObjectDesc()); llListen(comChannel, "", mav, ""); llDialog(mav, "Please select an animation from the list below:\n", wasDialogMenu(menuList, ["⏏ Exit", "⟻ Back", "Next ⟼", "⟺ Swap"], ""), comChannel); } listen(integer channel, string name, key id, string message) { if(message == "⏏ Exit") { animations = []; menuList = []; state default; } if(message == "⟻ Back") { llDialog(id, "Please select an animation from the list below:\n", wasDialogMenu(menuList, ["⏏ Exit", "⟻ Back", "Next ⟼", "⟺ Swap"], "<"), channel); return; } if(message == "Next ⟼") { llDialog(id, "Please select an animation from the list below:\n", wasDialogMenu(menuList, ["⏏ Exit", "⟻ Back", "Next ⟼", "⟺ Swap"], ">"), channel); return; } list swap = []; if(message == "⟺ Swap") { swap = llCSV2List(wasKeyValueGet("swap", llGetObjectDesc())); set = llList2String(swap, 0); swap = llDeleteSubList(swap, 0, 0); swap += set; llSetObjectDesc(wasKeyValueSet("swap", llList2CSV(swap), llGetObjectDesc())); jump process; } llSetObjectDesc(wasKeyValueSet("select", message, llGetObjectDesc())); @process; string select = wasKeyValueGet("select", llGetObjectDesc()); list sex = []; list pos = []; list rot = []; nLine = llGetListLength(animations)-1; do { string kvp = llList2String(animations, nLine); string animation = wasKeyValueGet("n", kvp); if(animation != select) jump continue_processing; sex += wasKeyValueGet("sex", kvp); pos += wasKeyValueGet("p", kvp); rot += wasKeyValueGet("r", kvp); @continue_processing; } while(--nLine>-1); swap = llCSV2List(wasKeyValueGet("swap", llGetObjectDesc())); nLine = llGetListLength(swap)-1; do { set = llList2String(swap, nLine); if(llListFindList(sex, (list)set) != -1) jump continue_derez; llWhisper(channel, wasKeyValueEncode(["sex", set, "die", set])); llSetObjectDesc(wasKeyValueSet(set, "off", llGetObjectDesc())); swap = llDeleteSubList(swap, nLine, nLine); @continue_derez; } while(--nLine>-1); nLine = llGetListLength(swap)-1; do { set = llList2String(swap, nLine); if(wasKeyValueGet(set, llGetObjectDesc()) == "off") { llRezObject(set, llGetPos()+<0,0,1>, ZERO_VECTOR, ZERO_ROTATION, (integer)wasKeyValueGet("session", llGetObjectDesc())); llSetObjectDesc(wasKeyValueSet(set, "on", llGetObjectDesc())); llSleep(1); } llWhisper(channel, wasKeyValueEncode(["n", select, "sex", set, "swap", llList2String(sex, nLine), "p", llList2String(pos, nLine), "r", llList2String(rot, nLine), "rp", (string)llGetRootPosition(), "rr", (string)llGetRootRotation()])); @continue_messages; } while(--nLine>-1); swap = []; sex = []; pos = []; rot = []; } on_rez(integer num) { llSetObjectDesc(wasKeyValueSet("session", "0", llGetObjectDesc())); llResetScript(); } }