Standard Menu UI/Number Setting Example
Jump to navigation
Jump to search
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