Difference between revisions of "Options Menu"
imported>JustinOther m (→Examples: Grammar) |
imported>JustinOther m (Drat! More grammar...) |
||
Line 16: | Line 16: | ||
Int iButton = OptionsMESG.Show() ; Shows your menu. iButton == -1 until input | Int iButton = OptionsMESG.Show() ; Shows your menu. iButton == -1 until input | ||
If (iButton != =-1) | If (iButton != =-1) | ||
akNewContainer.RemoveItem(GetBaseObject(), 1, True) ; Silently remove token | |||
If (iButton == 1) ; Mage | If (iButton == 1) ; Mage | ||
Debug.Notification("Mage selected") | Debug.Notification("Mage selected") | ||
Line 23: | Line 24: | ||
Debug.Notification("Warrior selected") | Debug.Notification("Warrior selected") | ||
EndIf | EndIf | ||
EndIf | EndIf | ||
EndIf | EndIf | ||
EndEvent</source> | EndEvent</source> | ||
*For the next example, we'll offer sub-options for each main selection. For a multilevel menu, a function works well. Keep in mind each button can have conditions, so you could hide "Lunch" and "Dinner" if it's time for breakfast or hide "Lobster" if it's not currently available. In this case, to make it repeatable, we'll use a playable apparel item so the menu will show each time it is equipped | *For the next example, we'll offer sub-options for each main selection. For a multilevel menu, a function works well. Keep in mind each button can have conditions, so you could hide "Lunch" and "Dinner" if it's time for breakfast or hide "Lobster" if it's not currently available. In this case, to make it repeatable, we'll use a playable apparel item so the menu will show each time it is equipped. | ||
<source lang="papyrus">ScriptName OptionsMenuScript extends ObjectReference | <source lang="papyrus">ScriptName OptionsMenuScript extends ObjectReference |
Revision as of 16:01, 12 April 2012
Overview
Using Show - Message, it is possible to make an options menu with any number of buttons and/or levels. This is enabling as one can maintain but a single plugin with an options menu offering multiple configuration setting rather than necessitating multiple versions. In these examples, we'll use apparel items, but a menu can be prompted and managed in a number of ways. First off, create a message(s) form and add/fill in its buttons. Note that no more than ten buttons can be offered by any given message box and that the button indices are offset by one such that the first option's index is 0 and not 1. If offering a lot of options, it's best to think ahead regarding how you want to organize your options, making the message forms first, then plugging them into the script.
Examples
- For the first example, we'll have only three options: Mage, Thief, and Warrior. The token should be unplayable in this case. When the item is added to the player, the menu will be prompted and will exit as soon as a button is selected, executing the appropriate code.
ScriptName OptionsMenuScript extends ObjectReference
Message Property OptionsMESG Auto
Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
If akNewContainer == Game.GetPlayer() ; Only the player
Int iButton = OptionsMESG.Show() ; Shows your menu. iButton == -1 until input
If (iButton != =-1)
akNewContainer.RemoveItem(GetBaseObject(), 1, True) ; Silently remove token
If (iButton == 1) ; Mage
Debug.Notification("Mage selected")
ElseIf (iButton == 1) ; Thief
Debug.Notification("Thief selected")
ElseIf (iButton == 2) ; Warrior
Debug.Notification("Warrior selected")
EndIf
EndIf
EndIf
EndEvent
- For the next example, we'll offer sub-options for each main selection. For a multilevel menu, a function works well. Keep in mind each button can have conditions, so you could hide "Lunch" and "Dinner" if it's time for breakfast or hide "Lobster" if it's not currently available. In this case, to make it repeatable, we'll use a playable apparel item so the menu will show each time it is equipped.
ScriptName OptionsMenuScript extends ObjectReference
Message Property MainMenuMESG Auto
Message Property BreakfastMESG Auto
Message Property LunchMESG Auto
Message Property DinnerMESG Auto
Event OnEquipped(Actor akActor)
If akActor == Game.GetPlayer()
Game.DisablePlayerControls(False, False, False, False, False, True) ; Momentarily disable other menus
Game.GetPlayer().EquipItem(GetBaseObject(), True, True) ; Prevent unequip/reequip in favorites until the current menu is resolved
Utility.Wait(0.01) ; This ensures equipping the token from the favorites menu works
Game.GetPlayer().UnequipItem(GetBaseObject(), False, True) ; Silently unequip item
Game.EnablePlayerControls(False, False, False, False, False, True) ; Undo DisablePlayerControls
Menu()
EndIf
EndEvent
Function Menu(Bool abMenu = True, Int aiButton = 0)
While abMenu
If (aiButton != -1) ; Wait for input
aiButton = MainMenuMESG.Show() ; Main Menu
abMenu = False
If (aiButton == 0) ; Breakfast
aiButton = BreakfastMESG.Show()
If (aiButton == 0) ; Sweet Roll
ElseIf (aiButton == 1) ; Pancakes
ElseIf (aiButton == 2) ; Bacon & Eggs
EndIf
ElseIf (aiButton == 1) ; Lunch
aiButton = LunchMESG.Show()
If (aiButton == 0) ; Turkey Sandwich
ElseIf (aiButton == 1) ; Ham Sandwich
ElseIf (aiButton == 2) ; BLT
EndIf
ElseIf (aiButton == 2) ; Dinner
aiButton = DinnerMESG.Show()
If (aiButton == 0) ; Filet Mignon
ElseIf (aiButton == 1) ; Lobster
ElseIf (aiButton == 2) ; Fried Chicken
EndIf
EndIf
EndIf
EndWhile
EndFunction
- To make a multilevel, looping menu that will not close until a "Done" button is pressed, use the above method but with the Menu() function altered. Note that you can jump to a given message by specifying the aiMessage argument when calling the function. Sub-options as described in the previous example can be added to the below in the same manner. Theoretically, any number of options can be added with the below.
Function Menu(Int aiMessage = 0, Int aiButton = 0, Bool abMenu = True)
While abMenu
If (aiButton == -1)
ElseIf (aiMessage == 0)
aiButton = OptionsMenu00MESG.Show()
If (aiButton == 0)
ElseIf (aiButton == 1)
ElseIf (aiButton == 2)
ElseIf (aiButton == 3)
ElseIf (aiButton == 4)
ElseIf (aiButton == 5)
ElseIf (aiButton == 6)
ElseIf (aiButton == 7)
ElseIf (aiButton == 8) ; More
aiMessage = 1
ElseIf (aiButton == 9) ; Done
abMenu = False
EndIf
ElseIf (aiMessage == 1)
aiButton = OptionsMenu01MESG.Show()
If (aiButton == 0)
ElseIf (aiButton == 1)
ElseIf (aiButton == 2)
ElseIf (aiButton == 3)
ElseIf (aiButton == 4)
ElseIf (aiButton == 5)
ElseIf (aiButton == 6)
ElseIf (aiButton == 7) ; Back
aiMessage = 0
ElseIf (aiButton == 8) ; More
aiMessage = 2
ElseIf (aiButton == 9) ; Done
abMenu = False
EndIf
ElseIf (aiMessage == 2)
aiButton = OptionsMenu02MESG.Show()
If (aiButton == 0)
ElseIf (aiButton == 1)
ElseIf (aiButton == 2)
ElseIf (aiButton == 3)
ElseIf (aiButton == 4)
ElseIf (aiButton == 5)
ElseIf (aiButton == 6)
ElseIf (aiButton == 7)
ElseIf (aiButton == 8) ; Back
aiMessage = 1
ElseIf (aiButton == 9) ; Done
abMenu = False
EndIf
EndIf
EndWhile
EndFunction
Notes
- Given the buttons in Skyrim are listed from side to side, it is easy to spill over the edges of the user's monitor, particularly if it's a 4:3, in the event either the options are too verbose or there are too many options presented by a single message form. Currently, there's no way to list them from top to bottom as they were in previous Bethesda games. To mitigate this, keep the button text to a minimum and/or make sure to always set up conditions on mutually exclusive buttons to ensure only applicable options are presented.