Complete more functionality of the Next Engine for dialogs
This commit is contained in:
parent
6e28878b6a
commit
aa26ff7406
1 changed files with 197 additions and 21 deletions
218
Next Engine.lsl
218
Next Engine.lsl
|
@ -37,6 +37,43 @@ string EXIT_MENU = "-exit-";
|
|||
string NEXT_MENU = "-->";
|
||||
|
||||
|
||||
string SLURL(key kID){
|
||||
return "secondlife:///app/agent/"+(string)kID+"/about";
|
||||
}
|
||||
|
||||
integer IsLikelyUUID(string sID)
|
||||
{
|
||||
if(sID == (string)NULL_KEY)return TRUE;
|
||||
if(llStringLength(sID)==32)return TRUE;
|
||||
key kID = (key)sID;
|
||||
if(kID)return TRUE;
|
||||
if(llStringLength(sID) >25){
|
||||
if(llGetSubString(sID,8,8)=="-" && llGetSubString(sID, 13,13) == "-" && llGetSubString(sID,18,18) == "-" && llGetSubString(sID,23,23)=="-") return TRUE;
|
||||
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
integer IsLikelyAvatarID(key kID)
|
||||
{
|
||||
if(!IsLikelyUUID(kID))return FALSE;
|
||||
// Avatar UUIDs always have the 15th digit set to a 4
|
||||
if(llGetSubString(kID,8,8) == "-" && llGetSubString(kID,14,14)=="4")return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
integer IsListOfIDs(list lIDs)
|
||||
{
|
||||
integer i=0;
|
||||
integer end = llGetListLength(lIDs);
|
||||
for(i=0;i<end;i++){
|
||||
if(IsLikelyUUID(llList2String(lIDs,i)))return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
integer generateChannel(integer iPositive) {
|
||||
integer iRand = llRound(llFrand(0xFFFF));
|
||||
|
@ -70,38 +107,78 @@ string readMenu(string sName) {
|
|||
return sMenu;
|
||||
}
|
||||
|
||||
list g_lListeners = [];
|
||||
integer STRIDE = 7;
|
||||
integer STRIDE_ID = 0;
|
||||
integer STRIDE_PATH = 1;
|
||||
integer STRIDE_CHANNEL = 2;
|
||||
integer STRIDE_TEXT = 3;
|
||||
integer STRIDE_PAGE = 4;
|
||||
integer STRIDE_HANDLE = 5;
|
||||
integer STRIDE_TIMER = 6;
|
||||
|
||||
startListen(key kAv, integer iChannel, string sMenuName, string sMenuText) {
|
||||
list g_lListeners = [];
|
||||
integer MENU_TIMER = 30;
|
||||
integer GENERAL_TIMER = 120;
|
||||
|
||||
startListen(key kAv, integer iChannel, string sMenuName, string sMenuText, integer iTimer) {
|
||||
integer iIndex=llListFindList(g_lListeners, [kAv]);
|
||||
if(iIndex == -1) {
|
||||
integer iListener = llListen(iChannel, "", kAv, "");
|
||||
g_lListeners += [kAv, sMenuName, iChannel, sMenuText, 0, iListener];
|
||||
g_lListeners += [kAv, sMenuName, iChannel, sMenuText, 0, iListener, llGetUnixTime() + iTimer];
|
||||
}else {
|
||||
stopListen(kAv);
|
||||
|
||||
startListen(kAv, iChannel, sMenuName, sMenuText);
|
||||
startListen(kAv, iChannel, sMenuName, sMenuText, iTimer);
|
||||
}
|
||||
}
|
||||
|
||||
stopListen(key kAv) {
|
||||
integer iIndex = llListFindList(g_lListeners, [kAv]);
|
||||
if(iIndex != -1) {
|
||||
g_lListeners = llDeleteSubList(g_lListeners, iIndex, iIndex+5); // Stride is 6 - ID, path, channel, text, page, listen handle
|
||||
g_lListeners = llDeleteSubList(g_lListeners, iIndex, iIndex+STRIDE-1); // Stride is 6 - ID, path, channel, text, page, listen handle
|
||||
}
|
||||
}
|
||||
|
||||
updatePage(key kID, integer iPage) {
|
||||
integer iIndex = llListFindList(g_lListeners, [kID]);
|
||||
if(iIndex!=-1) {
|
||||
g_lListeners = llListReplaceList(g_lListeners, [iPage], iIndex+4, iIndex+4);
|
||||
g_lListeners = llListReplaceList(g_lListeners, [iPage], iIndex+STRIDE_PAGE, iIndex+STRIDE_PAGE);
|
||||
}
|
||||
}
|
||||
|
||||
integer getListenTimer(key kID) {
|
||||
integer iIndex = llListFindList(g_lListeners, [kID]);
|
||||
if(iIndex != -1) {
|
||||
integer iVal = llList2Integer(g_lListeners, iIndex+STRIDE_TIMER);
|
||||
return iVal;
|
||||
}else return -1;
|
||||
}
|
||||
|
||||
integer getPageNumber(key kID) {
|
||||
integer iIndex = llListFindList(g_lListeners, [kID]);
|
||||
if(iIndex != -1) {
|
||||
return llList2Integer(g_lListeners, iIndex + STRIDE_PAGE);
|
||||
} else return -1;
|
||||
}
|
||||
|
||||
updateTimer(key kID, integer iNewTimer) {
|
||||
integer iIndex = llListFindList(g_lListeners, [kID]);
|
||||
if(iIndex != -1) {
|
||||
g_lListeners = llListReplaceList(g_lListeners, [llGetUnixTime() + iNewTimer], iIndex + STRIDE_TIMER, iIndex + STRIDE_TIMER);
|
||||
}
|
||||
}
|
||||
|
||||
string getMenuID(key kID) {
|
||||
integer iIndex = llListFindList(g_lListeners, [kID]);
|
||||
if(iIndex != -1) {
|
||||
return llList2String(g_lListeners, iIndex + STRIDE_PATH);
|
||||
} else return "";
|
||||
}
|
||||
|
||||
integer getChannel(key kID) {
|
||||
integer iIndex = llListFindList(g_lListeners, [kID]);
|
||||
if(iIndex!=-1) {
|
||||
return llList2Integer(g_lListeners, iIndex+2);
|
||||
return llList2Integer(g_lListeners, iIndex+STRIDE_CHANNEL);
|
||||
} else return -1;
|
||||
}
|
||||
|
||||
|
@ -180,7 +257,7 @@ integer calcMaxPages(string sMenu) {
|
|||
}
|
||||
}
|
||||
|
||||
list getPage(string sMenu, integer iPage) {
|
||||
string getPage(string sMenu, integer iPage, integer iCheckUUID) {
|
||||
// Retrieve buttons and utility lists from JSON
|
||||
list lButtons = llJson2List(llJsonGetValue(sMenu, ["buttons"]));
|
||||
list lUtility = llJson2List(llJsonGetValue(sMenu, ["utility"]));
|
||||
|
@ -216,7 +293,31 @@ list getPage(string sMenu, integer iPage) {
|
|||
// Add navigation buttons
|
||||
lPageButtons = getNavigatorButtons(iPage, totalPages) + lPageButtons;
|
||||
|
||||
return lPageButtons;
|
||||
// Loop over the buttons, check if UUID, replace with a number instead if UUID
|
||||
if(!iCheckUUID) jump returnMenu;
|
||||
i =0;
|
||||
integer end = llGetListLength(lPageButtons);
|
||||
integer idNum = 0;
|
||||
string sExtraText = "";
|
||||
for(i=0;i<end;i++) {
|
||||
string sButton = llList2String(lPageButtons, i);
|
||||
if(IsLikelyAvatarID(sButton)) {
|
||||
lPageButtons = llListReplaceList(lPageButtons, [(string)idNum], i,i);
|
||||
idNum++;
|
||||
|
||||
sExtraText += SLURL(sButton) + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@returnMenu;
|
||||
return llList2Json(JSON_OBJECT, ["text", sExtraText, "buttons", "~!~" + llDumpList2String(lPageButtons, "~!~") + "~!~"]);
|
||||
}
|
||||
|
||||
AppendMenuButton(string sMenu, string sButton) {
|
||||
string json = readMenu(sMenu);
|
||||
AddMenuButton(json, sButton);
|
||||
|
||||
updateMenu(sMenu, json);
|
||||
}
|
||||
|
||||
default
|
||||
|
@ -224,14 +325,24 @@ default
|
|||
state_entry() {
|
||||
llLinksetDataDeleteFound("menus", "");
|
||||
llMessageLinked(LINK_SET, LINK_SIGNAL_QUERY_MENU, "root", "");
|
||||
|
||||
llLinksetDataDeleteFound("colors", "");
|
||||
// Query color menu buttons and color pairs. Stride 3 instead of 2
|
||||
}
|
||||
|
||||
timer() {
|
||||
integer iTimerActive=0;
|
||||
integer i = 0;
|
||||
integer end = llGetListLength(g_lListeners);
|
||||
for(i=0;i<end;i+=STRIDE) {
|
||||
key kID = llList2Key(g_lListeners, i + STRIDE_ID);
|
||||
|
||||
integer iTimer = getListenTimer(kID);
|
||||
if(llGetUnixTime() > iTimer) {
|
||||
stopListen(kID);
|
||||
|
||||
if(!iTimerActive){
|
||||
llSetTimerEvent(0);
|
||||
llRegionSayTo(kID, 0, "Listener Timed Out");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,23 +354,83 @@ default
|
|||
}
|
||||
|
||||
listen(integer c,string n,key i,string m) {
|
||||
integer iIndex = llListFindList(g_lListeners, [i]);
|
||||
// Get the listener handle
|
||||
integer iListener = llList2Integer(g_lListeners, iIndex+5);
|
||||
llListenRemove(iListener);
|
||||
// Get the menu path
|
||||
string sMenuID = getMenuID(i);
|
||||
|
||||
// Get the current page number
|
||||
integer iPage = getPageNumber(i);
|
||||
|
||||
string sMenu = "";
|
||||
|
||||
if(sMenuID != "") readMenu(sMenuID);
|
||||
integer iMaxPages = calcMaxPages(sMenu);
|
||||
|
||||
if(m == PREVIOUS_MENU) {
|
||||
// Update the time remaining
|
||||
updateTimer(i, MENU_TIMER);
|
||||
|
||||
iPage--;
|
||||
|
||||
if(iPage < 0) iPage=0;
|
||||
|
||||
string sPage = getPage(sMenuID, iPage, TRUE);
|
||||
|
||||
list lPageButtons = llParseString2List(llJsonGetValue(sPage, ["buttons"]), ["~!~"], []);
|
||||
|
||||
updatePage(i, iPage);
|
||||
string sAppend = llJsonGetValue(sPage, ["text"]);
|
||||
|
||||
if(iMaxPages > 1) sAppend += "\n\nPage " + (string)iPage + "/" + (string)(iMaxPages-1);
|
||||
llDialog(i, llJsonGetValue(sMenu, ["prompt"]) + sAppend, lPageButtons, getChannel(i));
|
||||
} else if(m == NEXT_MENU) {
|
||||
// Update the time remaining
|
||||
updateTimer(i, MENU_TIMER);
|
||||
|
||||
iPage++;
|
||||
|
||||
if(iPage < iMaxPages-1) iPage=iMaxPages-1;
|
||||
|
||||
string sPage = getPage(sMenuID, iPage, TRUE);
|
||||
|
||||
list lPageButtons = llParseString2List(llJsonGetValue(sPage, ["buttons"]), ["~!~"], []);
|
||||
|
||||
updatePage(i, iPage);
|
||||
string sAppend = llJsonGetValue(sPage, ["text"]);
|
||||
|
||||
if(iMaxPages > 1) sAppend += "\n\nPage " + (string)iPage + "/" + (string)(iMaxPages-1);
|
||||
llDialog(i, llJsonGetValue(sMenu, ["prompt"]) + sAppend, lPageButtons, getChannel(i));
|
||||
} else if(m == " ") {
|
||||
// Update the time remaining
|
||||
updateTimer(i, MENU_TIMER);
|
||||
|
||||
string sPage = getPage(sMenuID, iPage, TRUE);
|
||||
|
||||
list lPageButtons = llParseString2List(llJsonGetValue(sPage, ["buttons"]), ["~!~"], []);
|
||||
|
||||
updatePage(i, iPage);
|
||||
string sAppend = llJsonGetValue(sPage, ["text"]);
|
||||
|
||||
if(iMaxPages > 1) sAppend += "\n\nPage " + (string)iPage + "/" + (string)(iMaxPages-1);
|
||||
llDialog(i, llJsonGetValue(sMenu, ["prompt"]) + sAppend, lPageButtons, getChannel(i));
|
||||
} else if(m == EXIT_MENU) {
|
||||
stopListen(i);
|
||||
} else {
|
||||
// Stop listening, and send a signal
|
||||
string sPage = getPage(sMenuID, iPage, FALSE);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
link_message(integer s,integer n,string m,key i) {
|
||||
if(n == LINK_SIGNAL_GEN_CHANNEL) {
|
||||
integer iChan = generateChannel((integer)m);
|
||||
startListen(i, iChan, "", "");
|
||||
startListen(i, iChan, "", "", GENERAL_TIMER);
|
||||
llMessageLinked(LINK_SET, LINK_SIGNAL_CHANNEL_BACK, (string)iChan, "");
|
||||
} else if(n == LINK_SIGNAL_SHOW_MENU) {
|
||||
string sMenu = readMenu(llJsonGetValue(m,["menu"]));
|
||||
integer iChan = generateChannel(FALSE);
|
||||
|
||||
startListen(i, iChan, m, llJsonGetValue(sMenu, ["prompt"]));
|
||||
startListen(i, iChan, m, llJsonGetValue(sMenu, ["prompt"]), MENU_TIMER);
|
||||
|
||||
// Show the dialog window now after constructing pages if needed.
|
||||
integer maxPages = calcMaxPages(sMenu);
|
||||
|
@ -267,12 +438,17 @@ default
|
|||
integer iPage = 1;
|
||||
if(jsonValueExists(m, ["page"])) iPage = (integer)llJsonGetValue(m,["page"]);
|
||||
|
||||
list lPageButtons = getPage(sMenu, iPage);
|
||||
string sPage = getPage(sMenu, iPage, TRUE);
|
||||
list lPageButtons = llParseString2List(llJsonGetValue(sPage, ["buttons"]), ["~!~"], []);
|
||||
|
||||
updatePage(i, iPage);
|
||||
string sAppend = "";
|
||||
string sAppend = llJsonGetValue(sPage, ["text"]);
|
||||
|
||||
if(maxPages>1) sAppend += "\n\nPage " + (string)iPage+"/" + (string)(maxPages-1);
|
||||
|
||||
//llOwnerSay("DEBUG\n" + llJsonGetValue(sMenu, ["prompt"]) + sAppend + "\n\n" + llJsonGetValue(sPage, ["buttons"]));
|
||||
|
||||
|
||||
if(maxPages>1) sAppend = "\n\nPage " + (string)iPage+"/" + (string)maxPages;
|
||||
llDialog(i, llJsonGetValue(sMenu, ["prompt"])+sAppend, lPageButtons, getChannel(i));
|
||||
} else if(n == LINK_SIGNAL_REGISTER_MENU) {
|
||||
string sMenuJson = llLinksetDataRead("menus." + (string)i);
|
||||
|
|
Loading…
Reference in a new issue