Difference between revisions of "LlDialog"

From Second Life Wiki
Jump to navigation Jump to search
Line 14: Line 14:
*If the distance between the root prim of the [[listen]]ing object and the dialog generating prim is greater than 20 meters when a button is pressed, the response will not be heard. See [[#Limits]].
*If the distance between the root prim of the [[listen]]ing object and the dialog generating prim is greater than 20 meters when a button is pressed, the response will not be heard. See [[#Limits]].
**This limitation affects attachments too if the wearer moves more than 20 meters from where the listener is located. See [[#Limits]].
**This limitation affects attachments too if the wearer moves more than 20 meters from where the listener is located. See [[#Limits]].
**In one very specific circumstance the dialog button press is heard sim-wide: If the [[listen]]er resides in the same script that created the dialog and if the dialog's user is the owner of the prim that spawns, and listens to the dialog.


===<tt>message</tt> limits===
===<tt>message</tt> limits===

Revision as of 01:47, 23 October 2011

Summary

Function: llDialog( key avatar, string message, list buttons, integer chat_channel );
1.0 Forced Delay
10.0 Energy

Shows a dialog box in the lower right corner of the avatar's screen (upper right in Viewer 1.x) with a message and choice buttons, as well as an ignore button. This has many uses ranging from simple message delivery to complex menu systems.

• key avatar avatar UUID that is in the same region
• string message message to be displayed
• list buttons button labels
• integer chat_channel output chat channel, any integer value

When a button is pressed, the avatar says the text of the button label on chat_channel.
The position where the chat is generated is where the root prim of the dialog generating object was when the dialog button was pressed.

Button Order
9   10 11
6 7 8  
3 4 5
0 1 2

Caveats

  • This function causes the script to sleep for 1.0 seconds.
  • Messages sent on channel zero[1] and DEBUG_CHANNEL are throttled to a rate of <200/10sec, per region, per owner/user.
    • Once the rate is exceeded, all following messages on channel zero or DEBUG_CHANNEL will be dropped until the send rate is again below 200/10sec for the previous 10 sec. Dropped messages, despite being dropped still count against the limit.
  • There is no way by script to kill a dialog box.
  • There is no way for the script to detect if the user clicked the small "Ignore" button (no chat is generated as a result of pressing this button).
  • There is no way to distinguish the input from a dialog box and regular chat made by the same user.
    • It is important to expect that the response may not be one of the buttons.
  • If the distance between the root prim of the listening object and the dialog generating prim is greater than 20 meters when a button is pressed, the response will not be heard. See #Limits.
    • This limitation affects attachments too if the wearer moves more than 20 meters from where the listener is located. See #Limits.
    • In one very specific circumstance the dialog button press is heard sim-wide: If the listener resides in the same script that created the dialog and if the dialog's user is the owner of the prim that spawns, and listens to the dialog.

message limits

  • message must be fewer than 512 bytes in length and be not empty. If it is empty, llDialog will shout "llDialog: must supply a message" on the DEBUG_CHANNEL. If it is greater than or equal to 512 bytes, it shouts (again on the debug channel): "llDialog: message too long, must be less than 512 characters"; in both instances, the dialog box will not be created for avatar.
  • The client only displays 8 lines of message. If it is longer, the dialog has a scroll bar. See #Appearance.

Note: this should be 7 lines in message; one of the 8 lines is the owner and name of the object.

buttons limits

  • If buttons is an empty list, it will default to as if it were ["OK"]
  • If a button is named "Ignore", it will behave like the small "Ignore" button of the menu (i.e. pressing it will *not* get "Ignore" sent to the menu channel). If you need an "Ignore" button in your menu and wish to have its name sent back to the script when you press it, then use spaces in the button name (e.g. " Ignore ").
  • An error will be shouted on DEBUG_CHANNEL, if...
    • there are more than 12 buttons.
    • any list item is not a string.
    • any list item string length (measured in bytes, using UTF-8 encoding) is zero or greater than 24.
      • In other words, a button's text when encoded as UTF-8 cannot be longer than 24 bytes or a empty string.
  • The client will not display all the characters of a button if the text is wider than the text space of the button. See #Appearance.
  • If the script generates button labels from outside sources like inventory or object names, take care to avoid the special string "!!llTextBox!!". This text, in button 0, will cause llDialog to behave as llTextBox instead.

Examples

<lsl>integer channel = 1000;

default {

   state_entry()
   {
       llListen(channel,"", "","");
   }
   touch_start(integer count)
   {
       llDialog(llDetectedKey(0), "This is a test dialog.\n\nPlease choose one of the below options.",
                ["Yes", "No", "0", "1"], channel);
   }
   
   listen(integer chan, string name, key id, string mes)
   {
       if(id == llGetOwnerKey(id))//won't listen to objects unless they aren't in the region.
           llSay(0,name + " (" + (string)llGetObjectDetails(id, (list)OBJECT_POS) + ") chose option " + mes);
   }

}</lsl> A simple way to alphabetically or numerically arrange the buttons in a "commonly" logical way. <lsl>list a_list;

key owner;

list n_list;

default {

   state_entry()
   {
       a_list = ["e", "h", "g", "a", "c", "d", "b", "f", "i"];          // Shows dialog as
       owner = llGetOwner();                                            // [a] [b] [c]
   }                                                                    // [d] [e] [f]
   touch_start(integer total_number)                                    // [g] [h] [i]
   {                                                                    //    (ignore)
       n_list = llListSort(llListSort(a_list, 1, TRUE), 3, FALSE);
       llDialog(owner, "\nWha!!?", n_list, 0);
   } // This will only work for 3, 6, 9 & 12 buttons. Insert spacers to even out if list is not a multiple of 3.
}</lsl>

Useful Snippets

<lsl>//Compact function to put buttons in "correct" human-readable order integer channel;

list order_buttons(list buttons) {

   return llList2List(buttons, -3, -1) + llList2List(buttons, -6, -4)
        + llList2List(buttons, -9, -7) + llList2List(buttons, -12, -10);

}

default {

   state_entry()
   {   // Create random channel within range [-1000000000,-2000000000]

channel = (integer)(llFrand(-1000000000.0) - 1000000000.0);

llListen(channel,"", "","");

   }
   touch_start(integer total_number)
   {
       llDialog(llDetectedKey(0),"\nPlease choose an option:\n",

order_buttons(["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]),channel);

   }
   listen(integer _chan, string _name, key _id, string _option)
   {
       llSay(0, _name + " chose option " + _option);
   }

}</lsl>

Notes

To use dialog boxes to make menu systems, see Dialog Menus: A step by step guide (aimed at learners).

Tips

It is a good idea to use a very negative channel (if never more negative than the most negative 32-bit integer that is -2,147,483,648), e.g., <lsl>// Create random channel within range [-1000000000,-2000000000] integer channel = (integer)(llFrand(-1000000000.0) - 1000000000.0);

llDialog(llDetectedKey(0), "Please choose one of the below options:",

   ["Yes", "No", "0", "1"], channel);</lsl>

Negative channels are popular for script communications because the client is unable to chat directly on those channels ("/-xxxx message" won't chat "message" on channel "-xxxx", it will chat "/-xxxx message" on channel zero). The only way to do so prior to llTextBox was to use llDialog which was limited to 24 bytes.

You can be reasonably confident that all of your scripted objects have a unique chat channel with this small function:

<lsl>integer dialog_channel; // top of script in variables

integer channel() { // top of script in functions

   return (integer)("0x"+llGetSubString((string)llGetKey(),-8,-1));

}

dialog_channel = channel(); // somewhere in actual script execution, such as state_entry()</lsl> Note: Since this function uses public information to generate the channel number it should by no means considered secret.

This is an alternate version, as the version above uses positive channels and may in rare cases, intersect with channel 0, the DEBUG_CHANNEL, and other such channels. This version returns a channel number between -1073741823 (0xBFFFFFFF) and -2147483648 (0x80000000). It is also only one line of code. <lsl>privchan = ((integer)("0x"+llGetSubString((string)llGetKey(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;</lsl>

Appearance

If message requires more than 8 lines, a vertical scroll bar will appear in the dialog.

The message text can be formatted somewhat using "\n" (for newline) and "\t" (for tab). If URLs are in the text, they will appear as clickable links, and some viewer application URLs will receive special formatting. (Clickable links were not available before Viewer 2.) You can do nothing though to influence the font face, size or weight.

There is no way to change the actual size of the dialog, nor change its color.

The average number of characters that can be displayed on a dialog line is about 35 characters per line in ASCII7 characters. It depends upon the width of the characters, the viewer version, and font settings.

The number of characters that can be displayed in a button depends upon the width of the characters. You should expect around 10 chars, give or take, not the full 24 in the button definition. The full button definition IS said, up to 24 chars, into the chat channel even though fewer characters may be displayed in the button itself.


Limits

My testing shows the a Dialog box now works anywhere in the same Region as the object OR any region it hands you off to (e.g. the region you teleport to). It will not work for any subsequent hand offs. I have tested this with teleport only, I haven't tested it walking between regions.

See Also

Events

•  listen

Functions

•  llListen
•  llTextBox
•  llRegionSay
•  llWhisper Sends chat limited to 10 meters
•  llSay Sends chat limited to 20 meters
•  llShout Sends chat limited to 100 meters
•  llInstantMessage Sends chat to the specified user
•  llOwnerSay Sends chat to the owner only

Articles

•  Dialog Menus: A step by step guide A walk through of the entire dialog menu process (aimed at learners).

Deep Notes

Footnotes

  1. ^ Channel zero is also known as: PUBLIC_CHANNEL, open chat, local chat and public chat

Signature

function void llDialog( key avatar, string message, list buttons, integer chat_channel );