A different way to do menus
mrangel
08 Oct 2018, 09:18Just something I've been thinking about. A couple of functions:
<function name="ScriptDictMenu" parameters="title, options, allowCancel">
optionslist = NewStringList()
foreach (opt, options) {
list add (optionslist, opt)
}
game.menudictcallbacks = options
ShowMenu (title, optionslist, allowCancel) {
dict = game.menudictcallbacks
if (not DictionaryContains (dict, result)) {
error ("Unexpected menu callback: \""+result+"\".")
}
callback = DictionaryItem (dict, result)
if (TypeOf (callback) = "string") callback = eval (callback)
if (TypeOf (callback) = "script") invoke (callback)
if (not HasScript (game, "menucallback")) {
game.menudictcallbacks = null
}
}
</function>
<function name="RedoMenu" parameters="title, options, allowCancel">
dict = game.menudictcallbacks
switch (TypeOf (options)) {
case ("scriptdictionary", "dictionary", "stringdictionary") {
foreach (key, options) {
if (DictionaryContains (dict, key)) dictionary remove (dict, key)
value = DictionaryItem(options, key)
dictionary add (dict, key, value)
}
}
case ("stringlist", "list") {
filtered = NewDictionary()
foreach (key, options) {
if (not DictionaryContains (filtered, key)) dictionary add (filtered, key, DictionaryItem (dict, key))
}
dict = filtered
}
}
ScriptDictMenu (title, dict, allowCancel)
game.menudictcallbacks = dict
</function>
With this, instead of the usual pattern of having a switch
statement inside the menu, you pass the menu a scriptdictionary - the keys are the text the player sees on the menu, and the script that matches their choice is run.
(Note - it doesn't have to be a scriptdictionary. If you want, you can make it a stringdictionary whose keys will be evaluated. So your options list could be: QuickParams ("red", "SetPlayerHairColor(\"red\")", "green", "SetPlayerHairColor(\"green\")", "none", "player.makebald_scriptattribute")
)
RedoMenu
can be called from within the menu callback to run the menu again. Its options
parameter can either be a scriptdictionary (which is added to the existing options, so it's easy to modify a menu on the fly), or a stringlist, which is taken as a list of options to display (with those options keeping the same scripts they did last time; so you can display a subset of the options without having to create a new dictionary). If options
is null, it will just use the same options as last time.

Svarii
08 Oct 2018, 17:46I don't need this yet. But it looks like something I will need later.
Thanks for sharing.
I'm sure this will come in handy in the future.
hegemonkhan
08 Oct 2018, 21:50thank you mrangel!
I've been working on figuring out a menu system, so this is of great help for me to study and learn more, as I've been struggling with crafting a good menu system, so this code design is again of great help for me to learn more about coding design and the logic involved
jmnevil54
09 Oct 2018, 02:03I tried it. I'm not sure how this works.