A different way to do menus

Just 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.


I 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.


thank 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


I tried it. I'm not sure how this works.


This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums