Difference between revisions of "Options Menu"

From the CreationKit Wiki
Jump to navigation Jump to search
imported>Threedee
imported>Threedee
Line 12: Line 12:
Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
If akNewContainer == Game.GetPlayer(); Only the player
If akNewContainer == Game.GetPlayer(); Only the player
Int iButton = OptionsMESG.Show() ; Shows your menu.
Int iButton = OptionsMESG.Show() ; Shows your menu. Note that the menu will stay open until a menu button (0-9) is clicked on.
akNewContainer.RemoveItem(self, 1, True) ; Silently remove token from the player
akNewContainer.RemoveItem(self, 1, True) ; Silently remove token from the player
If iButton == 0  ; Mage
If iButton == 0  ; Mage
Line 21: Line 21:
Debug.Notification("Warrior selected")
Debug.Notification("Warrior selected")
EndIf
EndIf
; note that if iButton (for whatever reason) returns any value other than 0-2, the menu will simply exit cleanly.
EndIf
EndIf
EndEvent</source>
EndEvent</source>
Line 50: Line 51:


Function Menu()
Function Menu()
int aiButton = MainMenuMESG.Show() ; Main Menu
int iButton = MainMenuMESG.Show() ; Main Menu
If aiButton == 0 ; Breakfast
If iButton == 0 ; Breakfast
BreakfastMenu()
BreakfastMenu()
ElseIf aiButton == 1 ; Lunch
ElseIf iButton == 1 ; Lunch
LunchMenu()
LunchMenu()
ElseIf aiButton == 2 ; Dinner
ElseIf iButton == 2 ; Dinner
DinnerMenu()
DinnerMenu()
ElseIf aiButton == 3 ; Quit the menu
ElseIf iButton == 3 ; Quit the menu
Return
Return
EndIf
EndIf
; note: the menu will exit here unless we call Menu() again
; note: the menu will exit here unless we call Menu() again
; note that if iButton (for whatever reason) returns any value other than 0-3, the menu will simply exit cleanly.
EndFunction
EndFunction


Line 66: Line 69:


Function BreakfastMenu()
Function BreakfastMenu()
int aiButton = BreakfastMESG.Show()
int iButton = BreakfastMESG.Show()
If aiButton == 0
If iButton == 0
Debug.Notification("Choice = Sweet Roll & Coffee")
Debug.Notification("Choice = Sweet Roll & Coffee")
ElseIf aiButton == 1
ElseIf iButton == 1
Debug.Notification("Choice = Pancakes, Bacon & Eggs")
Debug.Notification("Choice = Pancakes, Bacon & Eggs")
ElseIf aiButton == 2
ElseIf iButton == 2
Debug.Notification("Choice = Chicken Fried Pony Steak")
Debug.Notification("Choice = Chicken Fried Pony Steak")
ElseIf aiButton == 3 ; Return to the main menu
ElseIf iButton == 3 ; Return to the main menu
Return
Return
EndIf
EndIf
; note: the submenu will exit back to main menu from here unless we call BreakfastMenu() again
; note: the submenu will exit back to main menu from here unless we call BreakfastMenu() again
; note that if iButton (for whatever reason) returns any value other than 0-2, the submenu will simply exit back to the main menu.
EndFunction
EndFunction


Line 82: Line 87:


Function LunchMenu()
Function LunchMenu()
int aiButton = LunchMESG.Show()
int iButton = LunchMESG.Show()
If aiButton == 0
If iButton == 0
Debug.Notification("Choice = Glazed Turkey Sandwich")
Debug.Notification("Choice = Glazed Turkey Sandwich")
ElseIf aiButton == 1
ElseIf iButton == 1
Debug.Notification("Choice = Grilled Ham Sandwich")
Debug.Notification("Choice = Grilled Ham Sandwich")
ElseIf aiButton == 2
ElseIf iButton == 2
Debug.Notification("Choice = Shredded Pony Sandwich")
Debug.Notification("Choice = Shredded Pony Sandwich")
ElseIf aiButton == 3 ; Return to the main menu
ElseIf iButton == 3 ; Return to the main menu
Return
Return
EndIf
EndIf
; note: the submenu will exit back to main menu from here unless we call LunchMenu() again
; note: the submenu will exit back to main menu from here unless we call LunchMenu() again
; note that if iButton (for whatever reason) returns any value other than 0-2, the submenu will simply exit back to the main menu.
EndFunction
EndFunction


Line 98: Line 105:


Function DinnerMenu()
Function DinnerMenu()
aiButton = DinnerMESG.Show()
iButton = DinnerMESG.Show()
If aiButton == 0
If iButton == 0
Debug.Notification("Choice = Filet Mignon")
Debug.Notification("Choice = Filet Mignon")
ElseIf aiButton == 1
ElseIf iButton == 1
Debug.Notification("Choice = Pony Fajitas")
Debug.Notification("Choice = Pony Fajitas")
ElseIf aiButton == 2
ElseIf iButton == 2
Debug.Notification("Choice = Lobster")
Debug.Notification("Choice = Lobster")
ElseIf aiButton == 3 ; Return to the main menu
ElseIf iButton == 3 ; Return to the main menu
Return
Return
EndIf
EndIf
; note: the submenu will exit back to main menu from here unless we call DinnerMenu() again
; note: the submenu will exit back to main menu from here unless we call DinnerMenu() again
; note that if iButton (for whatever reason) returns any value other than 0-2, the submenu will simply exit back to the main menu.
EndFunction
EndFunction


Line 147: Line 156:


While abMenu
While abMenu
int aiButton = MainMenuMESG.Show()
int iButton = MainMenuMESG.Show()


If aiButton == 0
If iButton == 0
Submenu00() ; goto submenu00
Submenu00() ; goto submenu00
ElseIf aiButton == 1
ElseIf iButton == 1
Submenu01() ; goto submenu01
Submenu01() ; goto submenu01
ElseIf aiButton == 2
ElseIf iButton == 2
Submenu02() ; goto submenu02
Submenu02() ; goto submenu02
ElseIf aiButton == 3 ; quit
ElseIf iButton == 3 ; quit
Return ; exits the menu function and while loop
Return ; exits the menu function and while loop
EndIf
EndIf


Menu() ; loops the main menu
Menu() ; loops the main menu
; note that if iButton (for whatever reason) returns any value other than 0-2, the menu will simply re-display.
EndWhile
EndWhile


Line 168: Line 179:
Function Submenu00()
Function Submenu00()


int aiButton = OptionsMenu00MESG.Show()
int iButton = OptionsMenu00MESG.Show()


If aiButton == 0
If iButton == 0
; do stuff here
; do stuff here
ElseIf aiButton == 1
ElseIf iButton == 1
; do stuff here
; do stuff here
ElseIf aiButton == 2
ElseIf iButton == 2
; do stuff here
; do stuff here
ElseIf aiButton == 3
ElseIf iButton == 3
; do stuff here
; do stuff here
ElseIf aiButton == 4
ElseIf iButton == 4
; do stuff here
; do stuff here
ElseIf aiButton == 5
ElseIf iButton == 5
; do stuff here
; do stuff here
ElseIf aiButton == 6
ElseIf iButton == 6
; do stuff here
; do stuff here
ElseIf aiButton == 7
ElseIf iButton == 7
Submenu01() ; More - goto submenu01
Submenu01() ; More - goto submenu01
ElseIf aiButton == 8 ; Return to main menu
ElseIf iButton == 8 ; Return to main menu
Menu()
Menu()
ElseIf aiButton == 9 ; Done - exit from all menus
ElseIf iButton == 9 ; Done - exit from all menus
abMenu = FALSE ; stop the while loop
abMenu = FALSE ; stop the while loop
Return
Return
Line 194: Line 205:


Submenu00() ; loops this submenu
Submenu00() ; loops this submenu
; note that if iButton (for whatever reason) returns any value other than 0-9, the submenu will simply re-display.


EndFunction
EndFunction
Line 201: Line 213:
Function Submenu01()
Function Submenu01()


int aiButton = OptionsMenu01MESG.Show()
int iButton = OptionsMenu01MESG.Show()


If aiButton == 0 ; Back - goto submenu00
If iButton == 0 ; Back - goto submenu00
Submenu00()
Submenu00()
ElseIf aiButton == 1
ElseIf iButton == 1
; do stuff here
; do stuff here
ElseIf aiButton == 2
ElseIf iButton == 2
; do stuff here
; do stuff here
ElseIf aiButton == 3
ElseIf iButton == 3
; do stuff here
; do stuff here
ElseIf aiButton == 4
ElseIf iButton == 4
; do stuff here
; do stuff here
ElseIf aiButton == 5
ElseIf iButton == 5
; do stuff here
; do stuff here
ElseIf aiButton == 6
ElseIf iButton == 6
; do stuff here
; do stuff here
ElseIf aiButton == 7
ElseIf iButton == 7
Submenu02() ; More - goto submenu02
Submenu02() ; More - goto submenu02
ElseIf aiButton == 8 ; Return to main menu
ElseIf iButton == 8 ; Return to main menu
Menu()
Menu()
ElseIf aiButton == 9 ; Done - exit from all menus
ElseIf iButton == 9 ; Done - exit from all menus
abMenu = FALSE ; stop the while loop
abMenu = FALSE ; stop the while loop
Return
Return
Line 227: Line 239:


Submenu01() ; loops this submenu
Submenu01() ; loops this submenu
; note that if iButton (for whatever reason) returns any value other than 0-9, the submenu will simply re-display.


EndFunction
EndFunction
Line 234: Line 247:
Function Submenu02()
Function Submenu02()


int aiButton = OptionsMenu02MESG.Show()
int iButton = OptionsMenu02MESG.Show()


If aiButton == 0 ; Back - goto submenu01
If iButton == 0 ; Back - goto submenu01
Submenu01()
Submenu01()
ElseIf aiButton == 1
ElseIf iButton == 1
; do stuff here
; do stuff here
ElseIf aiButton == 2
ElseIf iButton == 2
; do stuff here
; do stuff here
ElseIf aiButton == 3
ElseIf iButton == 3
; do stuff here
; do stuff here
ElseIf aiButton == 4
ElseIf iButton == 4
; do stuff here
; do stuff here
ElseIf aiButton == 5
ElseIf iButton == 5
; do stuff here
; do stuff here
ElseIf aiButton == 6
ElseIf iButton == 6
; do stuff here
; do stuff here
ElseIf aiButton == 7
ElseIf iButton == 7
; do stuff here
; do stuff here
ElseIf aiButton == 8 ; Return to main menu
ElseIf iButton == 8 ; Return to main menu
Menu()
Menu()
ElseIf aiButton == 9 ; Done - exit from all menus
ElseIf iButton == 9 ; Done - exit from all menus
abMenu = FALSE ; stop the while loop
abMenu = FALSE ; stop the while loop
Return
Return
Line 260: Line 273:


Submenu02() ; loops this submenu
Submenu02() ; loops this submenu
; note that if iButton (for whatever reason) returns any value other than 0-9, the submenu will simply re-display.


EndFunction
EndFunction
Line 295: Line 309:
Debug.Notification("Warrior selected")
Debug.Notification("Warrior selected")
EndIf
EndIf
; note that the menu will simply exit, no matter what value is returned by iButton.
EndFunction
EndFunction



Revision as of 21:31, 4 July 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 and a book, but a menu can be prompted and managed in a number of ways. First, create a message(s) form(s) and add/fill the buttons with the options you'd like to offer. Note that no more than ten buttons can be in a 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. Also note that if you use many buttons and if the button names are long, your menu might be too wide to fit on the screen, so keep the layout as compact as possible.

Examples

  • For the first example, we'll have only three options: "Mage", "Thief", and "Warrior". When the token is added to the player, the menu will be prompted and will exit as soon as a button is selected, executing the appropriate code right after the token is silently removed.


ScriptName OptionsMenuScript extends ObjectReference

Message Property OptionsMESG Auto ; The Message form that configures the menu buttons

Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
	If akNewContainer == Game.GetPlayer(); Only the player
		Int iButton = OptionsMESG.Show() ; Shows your menu. Note that the menu will stay open until a menu button (0-9) is clicked on.
		akNewContainer.RemoveItem(self, 1, True) ; Silently remove token from the player
		If iButton == 0  ; Mage
			Debug.Notification("Mage selected")
		ElseIf iButton == 1 ; Thief
			Debug.Notification("Thief selected")
		ElseIf iButton == 2 ; Warrior
			Debug.Notification("Warrior selected")
		EndIf
		; note that if iButton (for whatever reason) returns any value other than 0-2, the menu will simply exit cleanly.
	EndIf
EndEvent


  • For the next example, we'll offer sub-options for each main selection. For a multilevel menu, functions can be used to keep the menu well organized. Keep in mind that you can assign conditions to each button in the Message forms, 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 book so the menu will show each time it is read. A book cannot be favorited or hotkeyed, unlike an apparel item. A potion can be hotkeyed, but it will be consumed when used and not remain hotkeyed even if immediately replaced. This example will let the user choose breakfast, lunch, or dinner, then close after one meal is selected.


ScriptName OptionsMenuScript extends ObjectReference
{This script should be attached to a book.
It will open a menu with three submenu pages when the book is read}
;===================================================
 
Message Property MainMenuMESG Auto
Message Property BreakfastMESG Auto
Message Property LunchMESG Auto
Message Property DinnerMESG Auto
 
;===================================================

Event OnRead()
	Game.DisablePlayerControls(False, False, False, False, False, True) ; Temporarily disable other menus
	Menu()
	Game.EnablePlayerControls(False, False, False, False, False, True) ; Re-enable Player controls
EndEvent 
 
;===================================================

Function Menu()
	int iButton = MainMenuMESG.Show() ; Main Menu
	If iButton == 0 ; Breakfast
		BreakfastMenu()
	ElseIf iButton == 1 ; Lunch
		LunchMenu()
	ElseIf iButton == 2 ; Dinner
		DinnerMenu()
	ElseIf iButton == 3 ; Quit the menu
		Return
	EndIf
	; note: the menu will exit here unless we call Menu() again
	; note that if iButton (for whatever reason) returns any value other than 0-3, the menu will simply exit cleanly.

EndFunction

;===================================================

Function BreakfastMenu()
	int iButton = BreakfastMESG.Show()
	If iButton == 0
		Debug.Notification("Choice = Sweet Roll & Coffee")
	ElseIf iButton == 1
		Debug.Notification("Choice = Pancakes, Bacon & Eggs")
	ElseIf iButton == 2
		Debug.Notification("Choice = Chicken Fried Pony Steak")
	ElseIf iButton == 3 ; Return to the main menu
		Return
	EndIf
	; note: the submenu will exit back to main menu from here unless we call BreakfastMenu() again
	; note that if iButton (for whatever reason) returns any value other than 0-2, the submenu will simply exit back to the main menu.

EndFunction

;===================================================

Function LunchMenu()
	int iButton = LunchMESG.Show()
	If iButton == 0
		Debug.Notification("Choice = Glazed Turkey Sandwich")
	ElseIf iButton == 1
		Debug.Notification("Choice = Grilled Ham Sandwich")
	ElseIf iButton == 2
		Debug.Notification("Choice = Shredded Pony Sandwich")
	ElseIf iButton == 3 ; Return to the main menu
		Return
	EndIf
	; note: the submenu will exit back to main menu from here unless we call LunchMenu() again
	; note that if iButton (for whatever reason) returns any value other than 0-2, the submenu will simply exit back to the main menu.

EndFunction

;===================================================

Function DinnerMenu()
	iButton = DinnerMESG.Show()
	If iButton == 0
		Debug.Notification("Choice = Filet Mignon")
	ElseIf iButton == 1
		Debug.Notification("Choice = Pony Fajitas")
	ElseIf iButton == 2
		Debug.Notification("Choice = Lobster")
	ElseIf iButton == 3 ; Return to the main menu
		Return
	EndIf
	; note: the submenu will exit back to main menu from here unless we call DinnerMenu() again
	; note that if iButton (for whatever reason) returns any value other than 0-2, the submenu will simply exit back to the main menu.

EndFunction

;===================================================


  • To make a multilevel, looping menu with thirty buttons that will not close until a "Done" button is pressed, use the above method but with an altered Menu() function. Sub-options as described in the previous example can be added to the example below in the same manner. Theoretically, any number of options can be added with the below structure. By structuring each submenu as a separate function, you can easily jump from one submenu to another by calling the corresponding function.


ScriptName OptionsMenuScript extends ObjectReference
{Presents a multilevel looped menu when this item is equipped}
;===================================================

Message Property MainMenuMESG Auto	; main menu messagebox
Message Property OptionsMenu00MESG Auto	; submenu page 1 messagebox
Message Property OptionsMenu01MESG Auto	; submenu page 2 messagebox
Message Property OptionsMenu02MESG Auto	; submenu page 3 messagebox

bool abMenu
 
;===================================================

Event OnEquipped(Actor akActor)
	If akActor == Game.GetPlayer()
		Armor menuARMO = self as Armor ; cast self as Armor
		akActor.UnequipItem(menuARMO, False, True) ; Silently unequip this item
		abMenu = TRUE
		Game.DisablePlayerControls(False, False, False, False, False, True) ; Temporarily disable other menus
		Menu()
		Game.EnablePlayerControls(False, False, False, False, False, True) ; Re-enable Player controls
	EndIf
EndEvent
 
;===================================================

Function Menu()

	While abMenu
		int iButton = MainMenuMESG.Show()

		If iButton == 0
			Submenu00() ; goto submenu00
		ElseIf iButton == 1
			Submenu01() ; goto submenu01
		ElseIf iButton == 2
			Submenu02() ; goto submenu02
		ElseIf iButton == 3 ; quit
			Return ; exits the menu function and while loop
		EndIf

		Menu() ; loops the main menu
		; note that if iButton (for whatever reason) returns any value other than 0-2, the menu will simply re-display.

	EndWhile

EndFunction

;===================================================

Function Submenu00()

	int iButton = OptionsMenu00MESG.Show()

	If iButton == 0
		; do stuff here
	ElseIf iButton == 1
		; do stuff here
	ElseIf iButton == 2
		; do stuff here
	ElseIf iButton == 3
		; do stuff here
	ElseIf iButton == 4
		; do stuff here
	ElseIf iButton == 5
		; do stuff here
	ElseIf iButton == 6
		; do stuff here
	ElseIf iButton == 7
		Submenu01() ; More - goto submenu01
	ElseIf iButton == 8 ; Return to main menu
		Menu()
	ElseIf iButton == 9 ; Done - exit from all menus
		abMenu = FALSE ; stop the while loop
		Return
	EndIf

	Submenu00() ; loops this submenu
	; note that if iButton (for whatever reason) returns any value other than 0-9, the submenu will simply re-display.

EndFunction

;===================================================

Function Submenu01()

	int iButton = OptionsMenu01MESG.Show()

	If iButton == 0 ; Back - goto submenu00
		Submenu00()
	ElseIf iButton == 1
		; do stuff here
	ElseIf iButton == 2
		; do stuff here
	ElseIf iButton == 3
		; do stuff here
	ElseIf iButton == 4
		; do stuff here
	ElseIf iButton == 5
		; do stuff here
	ElseIf iButton == 6
		; do stuff here
	ElseIf iButton == 7
		Submenu02() ; More - goto submenu02
	ElseIf iButton == 8 ; Return to main menu
		Menu()
	ElseIf iButton == 9 ; Done - exit from all menus
		abMenu = FALSE ; stop the while loop
		Return
	EndIf

	Submenu01() ; loops this submenu
	; note that if iButton (for whatever reason) returns any value other than 0-9, the submenu will simply re-display.

EndFunction

;===================================================

Function Submenu02()

	int iButton = OptionsMenu02MESG.Show()

	If iButton == 0 ; Back - goto submenu01
		Submenu01()
	ElseIf iButton == 1
		; do stuff here
	ElseIf iButton == 2
		; do stuff here
	ElseIf iButton == 3
		; do stuff here
	ElseIf iButton == 4
		; do stuff here
	ElseIf iButton == 5
		; do stuff here
	ElseIf iButton == 6
		; do stuff here
	ElseIf iButton == 7
		; do stuff here
	ElseIf iButton == 8 ; Return to main menu
		Menu()
	ElseIf iButton == 9 ; Done - exit from all menus
		abMenu = FALSE ; stop the while loop
		Return
	EndIf

	Submenu02() ; loops this submenu
	; note that if iButton (for whatever reason) returns any value other than 0-9, the submenu will simply re-display.

EndFunction

;===================================================


  • This next example shows how you would open a simple menu using a script attached to a MagicEffect form used by a Spell:


ScriptName OptionsMenuScript extends ActiveMagicEffect
{ A template for a MagicEffect script that opens a simple menu.}

Message Property OptionsMESG Auto ; The Message form that configures the menu buttons

;==============================================================

Event OnEffectStart(Actor akTarget, Actor akCaster)
	If akCaster == Game.GetPlayer(); Only the player can open the menu
		Menu()
	EndIf
	Dispel()
EndEvent

Function Menu()
		Int iButton = OptionsMESG.Show() ; Shows your menu.

		If iButton == 0  ; Mage
			Debug.Notification("Mage selected")
		ElseIf iButton == 1 ; Thief
			Debug.Notification("Thief selected")
		ElseIf iButton == 2 ; Warrior
			Debug.Notification("Warrior selected")
		EndIf
		; note that the menu will simply exit, no matter what value is returned by iButton.
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.
  • To conditionalize buttons upon script/quest variables, use GetVMScriptVariable and GetVMQuestVariable.
  • To hide buttons you wish to fill in later, add an impossible condition like 'IsXBox == -1'.
  • Conditionalizing MessageBox buttons will not change their indices such that, for instance, button 9 will still execute the "Done" code in the last example even if buttons 0-8 are hidden.
  • To learn how to assign user-created messageboxes as values to the message box properties defined in the above scripts, see the Papyrus tutorial's page on Properties and Functions
  • If the Message property isn't filled in the CK the Show() will always return a 0.
  • If the Message is a Notification (without buttons) instead of a Message Box the Show() will return a -1.

See Also

Show - Message