Standard Menu UI/Number Setting Example
From The Elder Scrolls Construction Set Wiki
Below is the code for the Wrye Leveling options command token. This is fairly compact code for presenting several menus and handling the selected options. The point of this page is to demonstrate some techniques and standards for arranging hierachical menu code, and handling menu selections.
Background (Cobl Option Token handling):
- This short section is a bit OT. Just FYI, explains the part of the code that's concerned with physical movement of the option tokens.
- Option tokens are stored in a special options container. The player can then select options from the container, which then triggers the corresponding menu.
- To prevent the player from using the container as free storage, all container contents are removed to the player when the container is closed.
- Hence, each token, when added to the player will: 1) add a new copy of itself back into the options container, 2) (if not in cleanup mode), show the the options menu, and 3) self-destruct (removeMe).
- Because of the way this is structured, it's guaranteed that everything that is menu display/handling related will all occure while in menu mode.
Menu Display/Handling:
- Note that the menu display code is actually the last thing that happens. Even the onAdd block doesn't show a menu.
- The current menu is indicated by menu variable. If this variable is negative, it means "Skip the menu handling section." So to trigger the top menu the first time, I set menu to -1; that gets inverted at the top of the handling section, and then falls through to the menu display section.
- Menu handling is together, separate and above menu display. This means that menu handling can carry out operations and then change the current menu number as necessary. I'm starting to use the standard "menu == 100" means exit.
Button Handling Check out the menu handling section beginning with "elseif menu == 4 ;--Final Limits". There are a couple of things I need to do here:
- Recognize the Back button.
- Allow numbers to be incremented up or down.
- Set restrictions on how much numbers can be incremented up or down.
- Set different increment amounts for different buttons. Level goes up/down by 5 units at a time, while attrs and skill limit goes up/down by 10 units at a time.
So, what I do is:
- First determine whether increment is up or down. Delta is thus set to 1 or -1 depending on whether shift key is pressed.
- Set temp local variables to what value for each button will be if change is applied to it.
- Finally, do the if block which:
- Handles buttons and upper/lower limits for each item.
- Handles back button.
- Displays "Can't go up." or "Can't go down." message if the above blocks fail.
Note that there's a lot of similarity in the lines of the code. Coding was speeded by writing first example of a set of lines, then duplicating that several times, then doing search and replace.
scn wrLevOptOS
;--Wrye Levling: Options
short button
short menu
;--Temp values
long key
long delta
long costBase ;--Levelup cost = costBase + nextLevel*costPerLevel
long costPerLevel
long attrPoints ;--Attribute points available per levelup
long skillPoints ;--Skill points available per levelup
long maxLevel ;--Maximum level player is allowed to reach
long maxAttr ;--Maximum value an attribute can have
long maxSkill ;--Maximum value a skill can have
long maxAttrGain ;--Maximum attribute increase per levelup
long maxLuckGain ;--Maximum luck increase per levelup
long maxSkillGain;--Maximum skill increase per levelup
long daysBetween ;--Minimum days between levelups
begin onAdd player;-----------------------------------------------------------
;--Restock the options box
cobOptChestRef.addItem wrLevOpt 1
;--Ignore if added by optionsbox purge.
if cobOptChestRef.state != 20
removeMe
endif
set menu to -1
end;onAdd
begin menuMode;---------------------------------------------------------------
;--Quick return if not in menu displaying mode.
if menu == 0
return
endif
set button to getButtonPressed
if menu < 0
set menu to -menu
elseif button == -1
return
elseif menu == 1;--Main Menu
if button < 3
set menu to button + 2
else
set menu to 100
endif
elseif menu == 2;--Cost
set key to getKeyPress 0
set delta to 1 - 2 * (key == 42 || key == 54)
set costBase to wrLevZ.costBase + 25*delta
set costPerLevel to wrLevZ.costPerLevel + 25*delta
if button == 0 && costBase >= 0 && costBase <= 10000
set wrLevZ.costBase to costBase
elseif button == 1 && costPerLevel >= 50 && costPerLevel <= 10000
set wrLevZ.costPerLevel to costPerLevel
elseif button > 1
set menu to 1
elseif delta > 0
message "That cannot be raised further."
else
message "That cannot be lowered further."
endif
elseif menu == 3;--Round Limits
set key to getKeyPress 0
set delta to 1 - 2 * (key == 42 || key == 54)
set attrPoints to wrLevZ.attrPoints + delta
set skillPoints to wrLevZ.skillPoints + delta
set maxAttrGain to wrLevZ.maxAttrGain + delta
set maxLuckGain to wrLevZ.maxLuckGain + delta
set maxSkillGain to wrLevZ.maxSkillGain + delta
set daysBetween to wrLevZ.daysBetween + delta
if button == 0 && attrPoints >= 3 && attrPoints <= 15
set wrLevZ.attrPoints to attrPoints
elseif button == 1 && skillPoints >= 10 && skillPoints <= 20
set wrLevZ.skillPoints to skillPoints
elseif button == 2 && maxAttrGain >= 3 && maxAttrGain <= 15
set wrLevZ.maxAttrGain to maxAttrGain
elseif button == 3 && maxLuckGain >= 1 && maxLuckGain <= 5
set wrLevZ.maxLuckGain to maxLuckGain
elseif button == 4 && maxSkillGain >= 5 && maxSkillGain <= 20
set wrLevZ.maxSkillGain to maxSkillGain
elseif button == 5 && daysBetween >= 0 && daysBetween <= 90
set wrLevZ.daysBetween to daysBetween
elseif button > 5
set menu to 1
elseif delta > 0
message "That cannot be raised further."
else
message "That cannot be lowered further."
endif
elseif menu == 4;--Final Limits
set key to getKeyPress 0
set delta to 1 - 2 * (key == 42 || key == 54)
set maxLevel to wrLevZ.maxLevel + 5*delta
set maxAttr to wrLevZ.maxAttr + 10*delta
set maxSkill to wrLevZ.maxSkill + 10*delta
if button == 0 && maxLevel >= 30 && maxLevel <= 100
set wrLevZ.maxLevel to maxLevel
elseif button == 1 && maxAttr >= 50 && maxAttr <= 250
set wrLevZ.maxAttr to maxAttr
elseif button == 2 && maxSkill >= 50 && maxSkill <= 250
set wrLevZ.maxSkill to maxSkill
elseif button > 2
set menu to 1
elseif delta > 0
message "That cannot be raised further."
else
message "That cannot be lowered further."
endif
endif
;--Menus ------------------------------------------------------------------
if menu == 1;--Main Menu
messageBoxEx "Wrye Leveling configuration.|Cost >|Round Limits >|Final Limits >|Done"
elseif menu == 2
messageBoxEx "Cost = CostBase + level*CostPerLevel. Click or shift-click to modify.|CostBase %g|CostPerLevel %g|< Back" wrLevZ.costBase wrLevZ.costPerLevel
elseif menu == 3
messageBoxEx "Configure levelup round limits. Click or shift-click to modify.|Attr Points %g|Skill Points %g|Max Attr Gain %g|Max Luck Gain %g|Max Skill Gain %g|Days Between %g|< Back" wrLevZ.attrPoints wrLevZ.skillPoints wrLevZ.maxAttrGain wrLevZ.maxLuckGain wrLevZ.maxSkillGain wrLevZ.daysBetween
elseif menu == 4
messageBoxEx "Configure level, attribute and skills limits. Click or shift-click to modify.|Level Max %g|Attr Max %g|Skill Max %g|< Back" wrLevZ.maxLevel wrLevZ.maxAttr wrLevz.maxSkill
elseif menu == 100;--Done
removeMe
endif
end;--menuMode

