Difference between revisions of "User:Kephra Nurmi/lsDialog"
Kephra Nurmi (talk | contribs) |
|||
Line 4: | Line 4: | ||
== Script: .lsDialog 09124 == | == Script: .lsDialog 09124 == | ||
< | <lsl> | ||
// .lsDialog 09124 (c) 2007-2009 by Kephra Nurmi under Creative Commons Attribution-Share Alike 3.0 License | // .lsDialog 09124 (c) 2007-2009 by Kephra Nurmi under Creative Commons Attribution-Share Alike 3.0 License | ||
Line 247: | Line 247: | ||
} | } | ||
} | } | ||
</ | </lsl> | ||
== Notecard: .lsDialog == | == Notecard: .lsDialog == |
Revision as of 17:19, 3 May 2009
lsDialog
lsDialog is an universal notecard driven menu dialog system. lsDialog could be used in a HUD or rezzed objects, providing one prim dialog trees or multi prim button dialogs. You can restrict usage to owner, group, named avatars or everybody. lsDialog is using llSay or llMessageLinked to comunicate with other scripts.
Script: .lsDialog 09124
<lsl> // .lsDialog 09124 (c) 2007-2009 by Kephra Nurmi under Creative Commons Attribution-Share Alike 3.0 License
string configName = ".lsDialog"; string configKey = NULL_KEY; integer configLine = 0; key configReq = NULL_KEY; integer avChannel;
list dialogNames = []; list dialogLines = []; string currentName = ""; string currentLines = "";
string currentMenu = ""; list currentOptions = []; list currentValues = []; list simpleOptions = []; list simpleActions = [];
integer djChannel = 0; integer djListen = 0; key djKey = NULL_KEY; string djName = ""; list guests = [ ]; integer everybody = FALSE; integer samegroup = FALSE; integer again = TRUE; integer linked = FALSE;
integer permissions(key id) {
return (everybody || (samegroup && llSameGroup(id)) || (llGetOwner() == id) || ((NULL_KEY != djKey) && (djKey == id)) || (llListFindList(guests, [ llKey2Name(id) ])>=0));
}
configRestart() {
configName = ".lsDialog"; key conf = llGetInventoryKey(configName); if ((string)conf == configKey) return; if ((NULL_KEY != configKey) && (llGetFreeMemory() < 6000)) llResetScript(); dialogNames = []; dialogLines = []; simpleOptions = []; simpleActions = []; currentName = ""; currentLines = ""; djChannel = 0; djKey = NULL_KEY; djName = ""; guests = [ ]; everybody = FALSE; samegroup = FALSE; if (conf == NULL_KEY) return; configKey = conf; configLine = 0; configReq = llGetNotecardLine(configName,configLine);
}
flushDialog() {
if ("" == currentName) return; if ("" == currentLines) return; integer i = llListFindList(dialogNames,[ currentName ]); if (i>=0) { dialogNames = llDeleteSubList(dialogNames,i,i); dialogLines = llDeleteSubList(dialogLines,i,i); } dialogNames = dialogNames + [ currentName ]; dialogLines = dialogLines + [ currentLines ]; currentName = ""; currentLines = "";
}
parseDialogRC(string data) {
if (llStringLength(data) == 0) return; if (llGetSubString(data,0,0) == "#") return; if ((llGetSubString(data,0,0) == "[") && (llSubStringIndex(data,"]") >= 0)) { flushDialog(); currentName = llGetSubString(data,1,llSubStringIndex(data,"]")-1); return; } if ("" == currentName) { if ("Allow=Owner" == data) { everybody = FALSE; samegroup = FALSE; } else if ("Allow=Group" == data) { everybody = FALSE; samegroup = TRUE; } else if ("Allow=All" == data) { everybody = TRUE; samegroup = FALSE; } else if ("Allow=" == llGetSubString(data,0,5)) { guests = guests + [ llGetSubString(data,6,-1) ]; } else if ("LSDJ=" == llGetSubString(data,0,4)) { djChannel = (integer)llGetSubString(data,5,-1); } else if ("Dialog=Again" == data) { again = TRUE; } else if ("Dialog=Once" == data) { again = FALSE; } else if ("Dialog=Link" == data) { linked = TRUE; } } else if ("*" == currentName) { integer p = llSubStringIndex(data,"="); if (0 < p) { simpleOptions = simpleOptions + [ llGetSubString(data, 0, p-1) ]; simpleActions = simpleActions + [ llGetSubString(data, p+1, -1) ]; } } else if (llSubStringIndex(data,"=") >= 0) { if ("" == currentLines) currentLines = data; else currentLines = currentLines+"\n"+data; }
}
parseDialogLines(string menu) {
currentMenu = menu; currentOptions = []; currentValues = []; integer i = llListFindList(dialogNames, [ menu ]); if (i < 0) return; list l = llParseString2List(llList2String(dialogLines,i),[ "\n" ], []); integer n = llGetListLength(l); integer k; string s; for (i = 0; i<n; i++) { s = llList2String(l, i); k = llSubStringIndex(s,"="); if (k>0) { currentOptions = currentOptions + [ llGetSubString(s,0,k-1) ]; currentValues = currentValues + [ llGetSubString(s,k+1,-1) ]; } }
}
action(string s, key id) {
integer q = -1; integer r = -1; q = llSubStringIndex(s," "); if (0 < q) { r = q+llSubStringIndex(llGetSubString(s,q+1,-1)," ")+1; } if (q < r) { string cmd = llGetSubString(s,0,q-1); integer ch = (integer)llGetSubString(s,q+1,r-1); string val = llGetSubString(s,r+1,-1); if ("say" == cmd) llSay(ch,val); if ("shout" == cmd) llShout(ch,val); if ("whisper" == cmd) llWhisper(ch,val); if ("region" == cmd) llRegionSay(ch,val); if ("root" == cmd) llMessageLinked(LINK_ROOT,ch,val,id); if ("link" == cmd) llMessageLinked(LINK_SET,ch,val,id); if ("this" == cmd) llMessageLinked(LINK_THIS,ch,val,id); }
}
default {
state_entry() { configRestart(); avChannel = 1000+(integer)llFrand(3000.0); llListen( avChannel, "", NULL_KEY, "" ); } changed(integer type) { if (type & CHANGED_OWNER) llResetScript(); if (type & CHANGED_INVENTORY) configRestart(); } dataserver(key queryId, string data) { if (queryId != configReq) return; if (data != EOF) { llSetText("parsing line "+(string)configLine,<1,0,0>,1); parseDialogRC(data); configReq = llGetNotecardLine(configName,++configLine); } else { if (0 != djListen) llListenRemove(djListen); if (0 != djChannel) djListen = llListen( djChannel, "", NULL_KEY, "" ); llSetText("",<1,0,0>,1); flushDialog(); llOwnerSay("ready, "+(string)llGetFreeMemory()+" free memory, listen on channel: "+(string)avChannel); } } touch_start(integer num) { key id = llDetectedKey(0); if (!permissions(id)) return; if (linked) { integer l = llDetectedLinkNumber(0); integer p = llListFindList(simpleOptions, [ llGetLinkName(l) ]); if (0 <= p) action(llList2String(simpleActions, p), id); else { p = llListFindList(dialogNames, [ llGetLinkName(l) ]); if (p >= 0) { parseDialogLines(llList2String(dialogNames,p)); llDialog(id,llList2String(dialogNames,p),currentOptions,avChannel); } } } else if ((llGetListLength(dialogNames) > 1) || (llGetListLength(simpleActions) > 0)) { currentMenu = ""; string s = llGetObjectDesc(); if ("" == s) s = "your command?"; llDialog(id,s,dialogNames+simpleOptions,avChannel); } else if (llGetListLength(dialogNames) == 1) { parseDialogLines(llList2String(dialogNames,0)); llDialog(id,llList2String(dialogNames,0),currentOptions,avChannel); } } listen(integer channel, string name, key id, string message) { if (djChannel == channel) { key k = id; if (llGetAgentInfo(id)<=0) k = llGetOwnerKey(k); if (k != llGetOwner()) return; list tmp = llCSV2List(message); if ("DJ" == llList2String(tmp,0)) djKey = llList2String(tmp,1); return; } if (!permissions(id)) return; if ("" == currentMenu) { integer i = llListFindList(simpleOptions,[ message ]); if (i>=0) action(llList2String(simpleActions, i), id); else { parseDialogLines(message); llDialog(id,currentMenu,currentOptions + [ "Back" ],avChannel); } } else if ("Back" == message) { currentMenu = ""; string s = llGetObjectDesc(); if ("" == s) s = "your command?"; llDialog(id,s,dialogNames+simpleOptions,avChannel); } else { integer i = llListFindList(currentOptions,[ message ]); if (i>=0) action(llList2String(currentValues, i), id); if (again) { if (llGetListLength(dialogNames) > 1) llDialog(id,currentMenu,currentOptions + [ "Back" ],avChannel); else llDialog(id,currentMenu,currentOptions,avChannel); } } }
} </lsl>
Notecard: .lsDialog
The .lsDialog notecard defines the menu dialog tree. A typical simple notecard could look like:
# default is to ask repeating ... remove comment if #Dialog=Once #Dialog=Link # allow only one of the following #Allow=Owner #Allow=Group #Allow=All # and in addition several named avatars #Allow=Kephra Nurmi #Allow=Alez Ember [*] Reset=link 0 reset [Size] 90%=link 0 *,size,90 95%=link 0 *,size,95 100%=link 0 *,size,100 105%=link 0 *,size,105 110%=link 0 *,size,110 [Color] Lime=link 0 glass,color,Lime Ivory=link 0 glass,color,Ivory Cyan=link 0 glass,color,Cyan
This notecard will define a single prim dialog system with one top menu called 'Reset' and two sub menus called 'Size' and 'Color' with link action on channel 0 and default permissions. The object description defines the name for the top menu dialog. Each menu starts with a section header in brackets followed lines to define the dialog entries. Each entry has a name equal to an action, a channel and a string.
Possible actions are:
- say - llSay(ch,val);
- shout - llShout(ch,val);
- whisper - llWhisper(ch,val);
- region - llRegionSay(ch,val);
- root - llMessageLinked(LINK_ROOT,ch,val,id);
- link - llMessageLinked(LINK_SET,ch,val,id);
- this - llMessageLinked(LINK_THIS,ch,val,id);
The top of the notecard, before any sections in brackets start, defines the permission and behavior. The hash marks lines as comments. Uncommenting Dialog=Once will cause to ask only one once, and not repeatingly. Dialog=Linked would need a 4 prim object, with buttons named 'Reset', 'Size' and 'Color'. The Allow= statements change the default permissions.