Network Telepad System
De DigiWiki.
This Networked Telepad system allows you to create teleport points throughout a region.
Its almost too easy to use.
1) Simply Rez a pad where you want a TP Point.
2) Edit the description (*not* the name) of the object to the name of the place (House, Pool, Skybox, etc...)
3) Click on the telepad, and choose "Reset" from the dialog box. Only the owner can do this. (this adds the telepad to the network)
Telepad system 2.0
// // Telepad Instructions // // This Networked Telepad system allows you to // create teleport points throughout a region. // Its almost too easy to use. // // 1) Simply Rez a pad where you want a TP Point. // 2) Edit the description (*not* the name) of // the object to the name of the place // (House, Pool, Skybox, etc...) // 3) Click on the telepad, and choose "Reset" // from the dialog box. Only the owner can do this. // (this adds the telepad to the network) // // InWorldz and OpenSim 0.6.9 (osgrid and others) Caviat! (fixed in 0.7.1) // Don't rotate the prim! Be sure it is set to Rotation 0,0,0 // There is a little bug that prevents the teleporter from dropping // you off in the right place. However, when the bug is fixed, this script // should work even with rotations, or child rotaions, unless rotations will // be working differently than the other place. Also, if it is inside a child // prim, it is likely to have rotation issues as well. // // **Important** if you move a telepad, or delete one, // you must use "Reset" to be sure all telepads receive // the changes. (Reset just the one you moved, not all of them) // // To use it, touch it, choose the destination, then right // click it and choose Teleport. // // ** advanced ** // If the description starts with a minus (for example -Beach) // then the telepad will serve as a direct telepad to that // // location. // // To use a special channel number for the network other // than the default.. add colon channel number to the description. // For example Beach:-99999 // integer network_channel = -23423432; // default integer dialog_channel = 0; integer same_owner = TRUE; integer directMode = FALSE; float timeout = 15.0; string myname; list pads; string destination; integer collecting = FALSE; //== dialog control stuff // ********** DIALOG FUNCTIONS ********** // Dialog constants integer lnkDialog = 14001; integer lnkDialogNotify = 14004; integer lnkDialogResponse = 14002; integer lnkDialogTimeOut = 14003; integer lnkDialogReshow = 14011; integer lnkDialogCancel = 14012; integer lnkMenuClear = 15001; integer lnkMenuAdd = 15002; integer lnkMenuShow = 15003; string seperator = "||"; integer dialogTimeOut = 0; string packDialogMessage(string message, list buttons, list returns){ string packed_message = message + seperator + (string)dialogTimeOut; integer i; integer count = llGetListLength(buttons); for(i=0; i<count; i++){ string button = llList2String(buttons, i); if(llStringLength(button) > 24) button = llGetSubString(button, 0, 23); packed_message += seperator + button + seperator + llList2String(returns, i); } return packed_message; } dialogReshow(){llMessageLinked(LINK_THIS, lnkDialogReshow, "", NULL_KEY);} dialogCancel(){ llMessageLinked(LINK_THIS, lnkDialogCancel, "", NULL_KEY); llSleep(1); } dialog(key id, string message, list buttons, list returns){ llMessageLinked(LINK_THIS, lnkDialog, packDialogMessage(message, buttons, returns), id); } dialogNotify(key id, string message){ list rows; llMessageLinked(LINK_THIS, lnkDialogNotify, message + seperator + (string)dialogTimeOut + seperator, id); } // ********** END DIALOG FUNCTIONS ********** dotext() { string tex = "Telepad\n"; if (directMode) { tex += "Direct Teleport to "+myname; llSetSitText("Teleport"); } else { if (destination != "") { tex += "Click to go to "+destination + "\n.\nRight-Click->Touch\nfor another Destination\n"; llSetSitText("Teleport"); } else { tex += "Click to choose Destination\n"; llSetSitText("."); } } llSetText(tex,<1.0,1.0,1.0>,1.0); } pinger() { if (directMode) return; llRegionSay(network_channel,llDumpList2String( [ myname, llGetPos(), llGetRot() ], ":")); } setupMenus() { llMessageLinked(LINK_THIS, lnkMenuClear, "", NULL_KEY); list b1; list b2; integer n; integer i; pads = llListSort(pads,3,TRUE); n = llGetListLength(pads); for (i = 0; i < n; i += 3) { b1 += [ llList2String(pads,i) ]; b2 += [ "pad," + llList2String(pads,i) ]; } //llOwnerSay(llDumpList2String(b1,":")); llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage( "[ Networked Telepad ]\n" + " Choose Destination", b1 + [ " " ], b2 + [ " " ] ), "MainMenu"); llMessageLinked(LINK_THIS, lnkMenuAdd, packDialogMessage( "[ Networked Telepad ]\n" + " Choose Destination", b1 + [ "Reset" ], b2 + [ "RESET" ] ), "OwnerMenu"); } default { state_entry() { //llSetRot(ZERO_ROTATION); llSetClickAction(CLICK_ACTION_TOUCH); dotext(); string mydesc = llGetObjectDesc(); list d = llParseString2List(mydesc,[ ":" ],[]); myname = llList2String(d,0); if (llGetSubString(myname,0,0) == "-") { directMode = TRUE; myname = llGetSubString(myname,1,-1); dotext(); } string altchan = llList2String(d,1); integer n = (integer)altchan; if (n != 0) { if (n > 0) n = - n; network_channel = n; } if ((float)llList2String(d,2) > 0) { timeout = (float)llList2String(d,2); } if (myname == "") { llOwnerSay("Please name this telepad by putting a name in the objects description"); return; } llListen(network_channel,"",NULL_KEY,""); llRegionSay(network_channel,"ping"); collecting = TRUE; llSleep(0.2 + llFrand(0.3)); llSetTimerEvent(2.0); pinger(); } on_rez(integer num) { llResetScript(); } listen(integer chan, string name, key id, string message) { if (same_owner) { key ok = llGetOwnerKey(id); if (ok != llGetOwner()) return; } if (message == "ping") { pads = []; llSetTimerEvent(2.0); collecting = TRUE; pinger(); return; } list v = llParseString2List(message,[ ":" ],[]); if (llGetListLength(v) != 3) return; string n = llList2String(v,0); if (directMode && n != myname) return; vector vec = (vector)llList2String(v,1); rotation rot = (rotation)llList2String(v,2); integer i = llListFindList(pads, [ n ]); if (i > -1) { pads = llListReplaceList(pads, [ n, vec, rot ], i, i+2); } else { pads += [ n, vec, rot ]; } if (directMode) { vec = ( vec - llGetPos() ) / llGetRot(); rot = rot / llGetRot(); vec.z += 1.5; llSitTarget(vec,rot); llSetClickAction(CLICK_ACTION_SIT); } else { collecting = TRUE; llSetTimerEvent(2.0); } } touch_start(integer num) { if (collecting) return; key toucher = llDetectedKey(0); if (toucher == llGetOwner()) { llMessageLinked(LINK_THIS, lnkMenuShow, "OwnerMenu", llDetectedKey(0)); } else { llMessageLinked(LINK_THIS, lnkMenuShow, "MainMenu", llDetectedKey(0)); } } timer() { if (collecting) { llSetTimerEvent(0.0); setupMenus(); collecting = FALSE; return; } llSitTarget(ZERO_VECTOR,ZERO_ROTATION); llSetClickAction(CLICK_ACTION_TOUCH); destination = ""; dotext(); } changed(integer change) { if (change & CHANGED_LINK) { llSleep(0.1); if (llAvatarOnSitTarget() != NULL_KEY) { llUnSit(llAvatarOnSitTarget()); if (!directMode) llSetTimerEvent(timeout); } } } link_message(integer sender, integer num, string message, key id) { if(num == lnkDialogResponse) { integer p = llSubStringIndex(message,","); integer s; string cmd; string rest; if (p > -1) { cmd = llToLower(llGetSubString(message,0,p-1)); rest = llGetSubString(message,p+1,-1); } else { cmd = llToLower(message); } if (id == llGetOwner() && message == "RESET") llResetScript(); if (cmd == "pad") { integer ii = llListFindList(pads, [ rest ]); if (ii > -1) { destination = rest; vector vv = llList2Vector(pads,ii+1); rotation rr = llList2Rot(pads,ii+2); vv = (vv - llGetPos()) / llGetRot(); rr = rr / llGetRot(); vv.z += 1.5; llSitTarget(vv,rr); llSetClickAction(CLICK_ACTION_SIT); if (!directMode) llSetTimerEvent(timeout); dotext(); } } } } }
Dialog control 1.8
// ********** SIMPLE DIALOG MODULE ********** // // By Nargus Asturias // Version 1.80 // // Support only one dialog at a time. DO NOT request multiple dialog at once! // Use of provided functions are recommented. Instruction here are for hardcore programmers only! // // Request: Send MessageLinked to the script. There are 3 dialog modes: // lnkDialog : Normal dialog with message and buttons // lnkDialogNumericAdjust : A dialog with buttons can be used to adjust numeric value // lnkDialogNotify : Just a simple notification dialog. No return value and no buttons. // // Send MessageLinked with code lnkDialogReshow to force active dialog to reappear. // Send MessageLinked with code lnkDialogCancel to force cancel active dialog // // If a lnkDialog is requested with more than 12 buttons, multi-pages dialog is used to show the buttons. // // [ For lnkDialog ] // MessageLinked Format: // String part: List dumped into string, each entry seperated by '||' // Field 1: Dialog message (512 bytes maximum) // Field 2: Time-out data (integer) // Field 3-4: Button#1 and return value pair // Field 5-6: Button#2 and return value pair // And go on... // Key part: Key of AV who attend this dialog // // Response: MessageLinked to the prim that requested dialog (but no where else) // num == lnkDialogResponse: AV click on a button. The buttons value returned as a string // num == lnkDialogTimeOut: Dialog timeout. // // [ For lnkDialogNumericAdjust ] // MessageLinked Format: // String part: List dumped into string, each entry seperated by '||' // Field 1: Dialog message (512 bytes maximum) // Put {VALUE} where you want the current value to be displayed) // Field 2: Time-out data (integer) // Field 3: Most significant value (ie. 100, for +/-100) // Field 4: String-casted numeric value to be adjusted // Field 5: 2nd most significant value (ie. 10, for +/-10) // Field 6: Use '1' to enable "+/-" button, '0' otherwise. // Field 7: 3nd significant value (ie. 1, for +/-1) // Field 8: Use '1' for integer, or '0' for float // Field 9: Least significant value (ie. 0.1, for +/-0.1) // Field 10: Reserved. Not used. // Key part: Key of AV who attend this dialog // // Response: MessageLinked to the prim that requested dialog (but no where else) // num == lnkDialogResponse: OK or Cancel button is clicked. The final value returned as string. // num == lnkDialogTimeOut: Dialog timeout. // // ******************************************* // // Constants integer lnkDialog = 14001; integer lnkDialogNumericAdjust = 14005; integer lnkDialogNotify = 14004; integer lnkDialogReshow = 14011; integer lnkDialogCancel = 14012; integer lnkDialogResponse = 14002; // A button is hit, or OK is hit for lnkDialogNumericAdjust integer lnkDialogCanceled = 14006; // Cancel is hit for lnkDialogNumericAdjust integer lnkDialogTimeOut = 14003; // No button is hit, or Ignore is hit integer lnkMenuClear = 15001; integer lnkMenuAdd = 15002; integer lnkMenuShow = 15003; integer lnkMenuNotFound = 15010; string seperator = "||"; // Menus variables list menuNames = []; // List of names of all menus list menus = []; // List of packed menus command, in order of menuNames integer lastMenuIndex = 0; // Latest called menu's index // Dialog variables integer dialogChannel; // Channel number used to spawn this dialog string message; // Message to be shown with the dialog integer timerOut; // Dialog time-out key keyId; // Key of user who attending this dialog integer requestedNum; // Link-number of the requested prim list buttons; // List of dialog buttons list returns; // List of results from dialog buttons float numericValue; integer useInteger; // Other variables integer buttonsCount; integer startItemNo; integer listenId; string redirectState; integer responseInt = -1; string responseStr; key responseKey; list order_buttons(list buttons) { return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4) + llList2List(buttons, -9, -7) + llList2List(buttons, -12, -10); } // ********** String Functions ********** string replaceString(string pattern, string replace, string source){ integer index = llSubStringIndex(source, pattern); if(index < 0) return source; source = llDeleteSubString(source, index, (index + llStringLength(pattern) - 1)); return llInsertString(source, index, replace); } // ********** Dialog Functions ********** // Function: createDialog // Create dialog with given message and buttons, direct to user with give id integer createDialog(key id, string message, list buttons){ integer channel = -((integer)llFrand(8388608))*(255) - (integer)llFrand(8388608) - 11; llListenRemove(listenId); listenId = llListen(channel, "", keyId, ""); llDialog(keyId, message, order_buttons(buttons), channel); return channel; } // Function: createMultiDialog // Create dialog with multiple pages. Each page has Back, Next, and a Close button. Otherwise same functionality as createDialog() function. integer createMultiDialog(key id, string message, list buttons, integer _startItemNo){ integer channel = -llRound(llFrand( llFabs(llSin(llGetGMTclock())) * 1000000 )) - 11; if(_startItemNo < 0) _startItemNo = 0; if(_startItemNo >= buttonsCount - 1) _startItemNo -= 9; startItemNo = _startItemNo; integer vButtonsCount = buttonsCount - 2; // Generate list of buttons to be shown string closeButton = llList2String(buttons, buttonsCount - 1); integer stopItemNo = startItemNo + 8; if(stopItemNo >= buttonsCount - 1) stopItemNo = vButtonsCount; list thisButtons = llList2List(buttons, startItemNo, stopItemNo); // Generate dialog navigation buttons integer i = stopItemNo - startItemNo + 1; i = i % 3; if(i > 0) { while(i < 3) { thisButtons += [" "]; i++; } } if(startItemNo > 0) thisButtons += ["<< BACK"]; else thisButtons += [" "]; thisButtons += [closeButton]; if(stopItemNo < vButtonsCount) thisButtons += ["NEXT >>"]; else thisButtons += [" "]; // Append page number to the message integer pageNumber = (integer)(stopItemNo / 9) + 1; integer pagesCount = llCeil(vButtonsCount / 9.0); string vMessage = "PAGE: " + (string)pageNumber + " of " + (string)pagesCount + "\n" + message; // Display dialog llListenRemove(listenId); listenId = llListen(channel, "", keyId, ""); llDialog(keyId, vMessage, order_buttons(thisButtons), channel); return channel; } // Function: generateNumericAdjustButtons // Generate numeric adjustment dialog which adjustment values are in given list. // If useNegative is TRUE, "+/-" button will be available. list generateNumericAdjustButtons(list adjustValues, integer useNegative){ list dialogControlButtons; list positiveButtons; list negativeButtons; list additionButtons; dialogControlButtons = ["OK", "Cancel"]; // Config adjustment buttons integer count = llGetListLength(adjustValues); integer index; for(index = 0; (index < count) && (index < 3); index++){ string sValue = llList2String(adjustValues, index); if((float)sValue != 0){ positiveButtons += ["+" + sValue]; negativeButtons += ["-" + sValue]; } } // Check positive/negative button if(useNegative) additionButtons = ["+/-"]; else additionButtons = []; // If there is fourth adjustment button if(count > 3){ if(llGetListLength(additionButtons) == 0) additionButtons = [" "]; string sValue = llList2String(adjustValues, index); additionButtons += ["+" + sValue, "-" + sValue]; }else if(additionButtons != []) additionButtons += [" ", " "]; // Return list dialog buttons return additionButtons + negativeButtons + positiveButtons + dialogControlButtons; } setResponse(integer int, string str, key id){ responseInt = int; responseStr = str; responseKey = id; } checkDialogRequest(integer sender_num, integer num, string str, key id){ if((num == lnkDialogNotify) || (num == lnkDialogNumericAdjust) || (num == lnkDialog)){ list data = llParseStringKeepNulls(str, [seperator], []); message = llList2String(data, 0); timerOut = llList2Integer(data, 1); keyId = id; requestedNum = sender_num; buttons = []; returns = []; if(message == "") message = " "; if(timerOut > 7200) timerOut = 7200; integer i; integer count; count = llGetListLength(data); for(i=2; i<count; i += 0){ buttons += [llList2String(data, i++)]; returns += [llList2String(data, i++)]; } buttonsCount = llGetListLength(buttons); if(num == lnkDialogNotify){ dialogChannel = -((integer)llFrand(8388608))*(255) - (integer)llFrand(8388608) - 11; llDialog(keyId, message, order_buttons(buttons), dialogChannel); return; }else if(num == lnkDialogNumericAdjust) redirectState = "NumericAdjustDialog"; else if(num == lnkDialog){ if(buttonsCount > 12) redirectState = "MultiDialog"; else redirectState = "Dialog"; } if(TRUE) state StartDialog; }else checkMenuRequest(sender_num, num, str, id); } // ********** Menu Functions ********** clearMenusList(){ menuNames = []; menus = []; lastMenuIndex = 0; } addMenu(string name, string message, list buttons, list returns){ // Reduced menu request time by packing request commands string packed_message = message + seperator + "0"; integer i; integer count = llGetListLength(buttons); for(i=0; i<count; i++) packed_message += seperator + llList2String(buttons, i) + seperator + llList2String(returns, i); // Add menu to the menus list integer index = llListFindList(menuNames, [name]); if(index >= 0) menus = llListReplaceList(menus, [packed_message], index, index); else{ menuNames += [name]; menus += [packed_message]; } } integer showMenu(string name, key id){ if(llGetListLength(menuNames) <= 0) return FALSE; integer index; if(name != ""){ index = llListFindList(menuNames, [name]); if(index < 0) return FALSE; }else index = lastMenuIndex; lastMenuIndex = index; // Load menu command and execute string packed_message = llList2String(menus, index); llMessageLinked(LINK_THIS, lnkDialog, packed_message, id); return TRUE; } checkMenuRequest(integer sender_num, integer num, string str, key id){ // Menu response commands if(num == lnkDialogResponse){ if(llGetSubString(str, 0, 4) == "MENU_"){ str = llDeleteSubString(str, 0, 4); showMenu(str, id); } } // Menu management commands else if(num == lnkMenuClear) clearMenusList(); else if(num == lnkMenuAdd){ list data = llParseString2List(str, [seperator], []); string message = llList2String(data, 0); list buttons = []; list returns = []; integer i; integer count = llGetListLength(data); for(i=2; i<count; i += 0){ buttons += [llList2String(data, i++)]; returns += [llList2String(data, i++)]; } addMenu((string)id, message, buttons, returns); }else if(num == lnkMenuShow){ if(!showMenu(str, id)) llMessageLinked(sender_num, lnkMenuNotFound, str, NULL_KEY); } } // ********** States ********** default{ state_entry(){ if(responseInt > 0) llMessageLinked(requestedNum, responseInt, responseStr, responseKey); } link_message(integer sender_num, integer num, string str, key id){ checkDialogRequest(sender_num, num, str, id); } } state StartDialog{ state_entry(){ if(redirectState == "Dialog") state Dialog; else if(redirectState == "MultiDialog") state MultiDialog; else if(redirectState == "NumericAdjustDialog") state NumericAdjustDialog; else state default; } } state Dialog{ state_entry(){ responseInt = -1; dialogChannel = createDialog(keyId, message, buttons); llSetTimerEvent(timerOut); } state_exit(){ llSetTimerEvent(0); } on_rez(integer start_param){ state default; } timer(){ setResponse(lnkDialogTimeOut, "", keyId); state default; } link_message(integer sender_num, integer num, string str, key id){ if(num == lnkDialogReshow){ dialogChannel = createDialog(keyId, message, buttons); llSetTimerEvent(timerOut); }else if(num == lnkDialogCancel) state default; else checkDialogRequest(sender_num, num, str, id); } listen(integer channel, string name, key id, string msg){ if((channel != dialogChannel) || (id != keyId)) return; integer index = llListFindList(buttons, [msg]); setResponse(lnkDialogResponse, llList2String(returns, index), keyId); state default; } } state MultiDialog { state_entry(){ responseInt = -1; startItemNo = 0; dialogChannel = createMultiDialog(keyId, message, buttons, startItemNo); llSetTimerEvent(timerOut); } state_exit(){ llSetTimerEvent(0); } on_rez(integer start_param){ state default; } timer(){ setResponse(lnkDialogTimeOut, "", keyId); state default; } link_message(integer sender_num, integer num, string str, key id){ if(num == lnkDialogReshow){ dialogChannel = createMultiDialog(keyId, message, buttons, startItemNo); llSetTimerEvent(timerOut); }else if(num == lnkDialogCancel) state default; else checkDialogRequest(sender_num, num, str, id); } listen(integer channel, string name, key id, string msg){ if((channel != dialogChannel) || (id != keyId)) return; // Dialog control buttons if(msg == "<< BACK"){ dialogChannel = createMultiDialog(keyId, message, buttons, startItemNo - 9); llSetTimerEvent(timerOut); }else if(msg == "NEXT >>"){ dialogChannel = createMultiDialog(keyId, message, buttons, startItemNo + 9); llSetTimerEvent(timerOut); }else if(msg == " "){ dialogChannel = createMultiDialog(keyId, message, buttons, startItemNo); llSetTimerEvent(timerOut); // Response buttons }else{ integer index = llListFindList(buttons, [msg]); setResponse(lnkDialogResponse, llList2String(returns, index), keyId); state default; } } } state NumericAdjustDialog { state_entry(){ responseInt = -1; numericValue = llList2Float(returns, 0); useInteger = llList2Integer(returns, 2); buttons = generateNumericAdjustButtons(buttons, llList2Integer(returns, 1)); string vMessage; if(useInteger) vMessage = replaceString("{VALUE}", (string)((integer)numericValue), message); else vMessage = replaceString("{VALUE}", (string)numericValue, message); dialogChannel = createDialog(keyId, vMessage, buttons); llSetTimerEvent(timerOut); } state_exit(){ llSetTimerEvent(0); } on_rez(integer start_param){ state default; } timer(){ setResponse(lnkDialogTimeOut, "", keyId); state default; } link_message(integer sender_num, integer num, string str, key id){ if(num == lnkDialogReshow){ dialogChannel = createDialog(keyId, message, buttons); llSetTimerEvent(timerOut); }else if(num == lnkDialogCancel) state default; else checkDialogRequest(sender_num, num, str, id); } listen(integer channel, string name, key id, string msg){ if((channel != dialogChannel) || (id != keyId)) return; // Dialog control button is hit if(msg == "OK"){ setResponse(lnkDialogResponse, (string)numericValue, keyId); state default; }else if(msg == "Cancel"){ setResponse(lnkDialogCanceled, (string)numericValue, keyId); llMessageLinked(requestedNum, lnkDialogCanceled, (string)numericValue, keyId); state default; // Value adjustment button is hit }else if(msg == "+/-") numericValue = -numericValue; else if(llSubStringIndex(msg, "+") == 0) numericValue += (float)llDeleteSubString(msg, 0, 0); else if(llSubStringIndex(msg, "-") == 0) numericValue -= (float)llDeleteSubString(msg, 0, 0); // Spawn another dialog if no OK nor Cancel is hit string vMessage; if(useInteger) vMessage = replaceString("{VALUE}", (string)((integer)numericValue), message); else vMessage = replaceString("{VALUE}", (string)numericValue, message); dialogChannel = createDialog(keyId, vMessage, buttons); llSetTimerEvent(timerOut); } }