Difference between revisions of "User:Kephra Nurmi/lsDialog"
Kephra Nurmi (talk | contribs) |
m (<lsl> tag to <source>) |
||
(5 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
{{LSL Header}} | |||
== lsDialog == | == lsDialog == | ||
Line 4: | Line 6: | ||
== Script: .lsDialog 09124 == | == Script: .lsDialog 09124 == | ||
< | <source lang="lsl2"> | ||
// .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 249: | ||
} | } | ||
} | } | ||
</ | </source> | ||
== Notecard: .lsDialog == | == Notecard: .lsDialog == | ||
Line 253: | Line 255: | ||
The .lsDialog notecard defines the menu dialog tree. A typical simple notecard could look like: | The .lsDialog notecard defines the menu dialog tree. A typical simple notecard could look like: | ||
< | <source lang="ini"> | ||
# default is to ask repeating ... remove comment if | # default is to ask repeating ... remove comment if | ||
#Dialog=Once | #Dialog=Once | ||
Line 281: | Line 283: | ||
Ivory=link 0 glass,color,Ivory | Ivory=link 0 glass,color,Ivory | ||
Cyan=link 0 glass,color,Cyan | Cyan=link 0 glass,color,Cyan | ||
</ | </source> | ||
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. | 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. | ||
Line 296: | Line 298: | ||
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. | 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. | ||
{{LSLC|Library}} |
Latest revision as of 23:44, 24 January 2015
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
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
// .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);
}
}
}
}
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.