Menu System 2 (Second Life)
From Grigbertz
Menu System 2 is a note-card-configured system for making easily interchangeable and configurable menu trees in second Life objects.
Contents |
Note Card Format
The note card may contain the following type of lines:
- Blank lines
- Comments
- Configuration Variable Settings
- Menu Definitions.
Blank lines and comment lines are ignored when reading the notecard, and not stored in memory.
The name of the note card to be read is taken from the name of the menu system script itself, so to change what card is used, just change the name of the script and reset it. The note card name is appended to the script name after a colon, like this:
MenySystem:MenuConfig
This enables more than one menu system to be used in the same object, running side-by-side.
Comment Lines
Comment lines starts with '#' in the first position.
Configuration Varables
Configuration Variable lines are defined as name '=' value. Names are case independent.
The following variables are currently defined:
- defaultanimation
- animationclientname
Configuration variables are for the menu system itself, not for its contents, so they should not be confused with the display variables defined later.
Menu Definitions
Menu Definitions consist of:
- Menu Name
- Description
- Button Definitions
Menu Name
The definition starts with the menu name surrounded by triple hyphens, like this:
---main---
The definition ends with the start of the next menu definition, or by just three hyphens on their own:
---
Menu Names and Roles
When a menu has a special definion for only a given role of users, that role can be given after the menu name itself, like this:
---main operator---
When the user has a specific role, the system first looks for menu name with role, and if it cannot find it, it looks for just the menu name.
The following roles are defined:
- owner
- operator
- other
Description
Description lines start with an asterisk, like this:
* This is a * multi-line * description
Newlines are significant, so the three lines above will show as three lines in the dialog box.
Descriptions and variable substitution
Descriptions can have display variables in them. These variables are sent to the menu system by the other scripts in the object as link messages. When the menu dialog box is to be shown, the variables are looked up and inserted into the description.
Variables are written into the description as dollar-brace name brace-dollar, like this:
${name}$
A short number of variables are predefined, and not sent by other scripts. Those are:
- owner - object owner name
- object - object name
Like this:
* ${object}$ is owned by ${owner}$
Button definitions
Buttons are defined by first a single button line, followed by any number of command lines.
The button line consists of the button label within brackets, followed by a number of modifiers separated by vertical bar:
[Lock] ifnot locked | hideinactive | keepmenu
The command lines consist of a command, followed by a list of arguments, separated by vertical bars.
regionsay | 0 | Hello World!
Both button lines and command lines can have any number of spaces surrounding the vertical bars.
Button Modifiers
Button modifiers consists of an optional condition expression, an optional "endmenu", and/or an optional "hideinactive". These may come in any order.
Button Condition Expression Modifier
The button condition expression governs whether the button should be displayed in the menu. The other scripts in the onject can send named conditions to the menu system, indicating any state of the object that should reflect in the buttons. The condition expression combines these named conditions, and use that combination to choose if the button is shown.
The possible expressions are:
- if condition
- ifnot condition
- ifanyof condition condition ... condition
- ifallof condition condition ... condition
- ifnoneof condition condition ... condition
If any more complex logical combination is needed than those above, the state-maintaining script better define that combination as a single new condition and send that one.
Hide Inactive Modifier
This modifier chooses how a button whose condition is not met is displayed.
If the "hideinactive" modifier is given, then the menu system totally removes the button. If it is not there, a blank button is instead shown when the condition is not met.
End Menu Modifier
The "endmenu" modifier governs the menu persistence. If it is present, the menu will not be re-displayed after after the button is pressed.
Commands
The following commands are available:
Name | Argument 1 | Argument 2 | Function |
menu | menu name | Replaces this menu with the named one (optionally modified by the user role, see menu name above) | |
none | A no-op. | ||
animateuser | animation name | Animates the agent using the menu. | |
animatesitter | animation name | Animates the agent sitting on this object. | |
stopanimation | Stops the latest animation this object activated on the agent using the menu. | ||
stopallanimations | Stops the all animations on the agent using the menu. | ||
messagelinkset | message | Send a message to all scripts in all prims in the same objects. | |
messagelinkthis | message | Send a message to all scripts in the same prim in the same objects. | |
regionsay | channel | message | Shout a message all over the region. |
say | channel | message | Say a message in the local area. |
rlv | rlv string | Send a RLV string to the client of the object's owner, if RLV is activated. |
Animation helpers
Communication
Channels Listened to
The Menu system sets up a random channel to listen to for each menu definition. This makes it able to separate buttons with the same label, but in different menus, from each other.
Touch
The Menu System does not itself listen to touch events. Other scripts in the object must send a linked message (see below) to display the first menu.
Linked Messages Listened to
The menu system listens to a number of linked messages
Name | Argument(s) | Function | Example Call |
menu | menuname | Display the given menu | llMessageLinked(LINK_THIS, 0, "menu " + menuName, agentKey); llMessageLinked(LINK_THIS, 0, "menu main", agentKey); |
setSitter | Set the key of the agent sitting on this object. | llMessageLinked(LINK_THIS, 0, "setSitter", agentKey); | |
removeSitter | Remove the key of the agent sitting on this object. | llMessageLinked(LINK_THIS, 0, "removeSitter", NULL_KEY); | |
setConditions | space-separated list of conditions | Set all conditions that apply. | llMessageLinked(LINK_THIS, 0, "setConditions " + llDumpList2String(conditionList, " "), NULL_KEY); llMessageLinked(LINK_THIS, 0, "setConditions locked seated muted", NULL_KEY); |
addConditions | space-separated list of conditions | Add these conditions to those that apply. | llMessageLinked(LINK_THIS, 0, "addConditions " + llDumpList2String(conditionList, " "), NULL_KEY); llMessageLinked(LINK_THIS, 0, "addConditions bound hogtied", NULL_KEY); |
removeConditions | space-separated list of conditions | Remove these conditions from those that apply. | llMessageLinked(LINK_THIS, 0, "removeConditions " + llDumpList2String(conditionList, " "), NULL_KEY); llMessageLinked(LINK_THIS, 0, "removeConditions bound locked", NULL_KEY); |
setVariableValue | name and URL-encoded value, separated by space. | Set this display variable for inclusion in menu descriptions. | llMessageLinked(LINK_THIS, 0, "setVariableValue" + name + " " + llEscapeURL(value), NULL_KEY); llMessageLinked(LINK_THIS, 0, "setVariableValue region Lugubris", NULL_KEY); |
useDefaultAnimation | Use the animation configured as default on the supplied avatar. | llMessageLinked(LINK_THIS, 0, "useDefaultAnimation", avatarKey); | |
addOperator | givenname familyname | Gives the named avatar the operator role. | llMessageLinked(LINK_THIS, 0, "addOperator " + name, NULL_KEY); llMessageLinked(LINK_THIS, 0, "addOperator Tuft Meili", NULL_KEY); |
removeOperator | givenname familyname | Revokes the operator role from the named avatar. | llMessageLinked(LINK_THIS, 0, "removeOperator " + name, NULL_KEY); llMessageLinked(LINK_THIS, 0, "removeOperator Tuft Meili", NULL_KEY); |
deleteOperators | Revokes all operator roles. | llMessageLinked(LINK_THIS, 0, "deleteOperators", NULL_KEY);< |
Examples
Handing over to another instance
You can have several instances of the menu system running in the same object, handling different branches of the menu tree.
Normally, you hand over to another submenu with:
[button] menu | newmenu
To call another menu system, instead use linked message:
[button] endmenu mesagelinkset | menu newmenu
Sinde we want this menu system to stop its menus, we use the button modifier "endmenu".