Recalling A Menu Question [SOLVED]

Hello!

I wasn't quite sure how to recall a menu with options if it isn't based around a function. If it's a function, after choosing something you can just recall the function again but when a function isn't involved how do you go about recalling a menu?

objecthere.menuhere  ??

Anyone know?

Anonynn.

EDIT:
This is a StringList Menu on an Object too if that helps.


You need to run the code again, so putting it in a function is the most obvious way.
If you don't want to do that, you can still call the same menu in more than one place.

To avoid having to type multiple copies of the same script, you can put the menu response script into a script attribute.
For example:
ShowMenu ("What colour is your hair?", Split("blond;brown;black;red", true, player.haircolour_menu_callback))
That assumes that the player has a script attribute haircolour_menu_callback which will be called (with a result variable) when a menu option is chosen.

Hope I'm making sense here :p

Or you could grab my Tomb of the Dead demo and yank some of the functions out of it. Question acts like ShowMenu but will wait until the previous menu is answered if you call it multiple times in the same turn; and RedoThis() lets you repeat the last question. This is powered by the WhenReady function (which is like "on ready" but also waits for menus), and whenready turnscript. Not sure if there's any more of the functions required to support those ones.


So that would work with an object's menu too? Trying to see if I understand correctly.

Like for example...

npcname.blahmenu

    }
    case ("Option 1") {
   npcname.blahmenu_callback
    }
    case ("Option 2") {
    }
    case ("Option 3") {
    }
  }

Anonynn.


Not sure what you mean by an object's menu here.

If you mean that one of the options in the menu calls the same menu again, you could do that like:

// Create a script attribute (or do it in the attributes tab if you prefer)
npcname.blahmenu_callback => {
  switch (result) {
    case ("Option 1") {
      ShowMenu ("Try again:", Split ("Option 2;Option 3;Option 4"), true, npcname.blahmenu_callback)
    }
    case ("Option 2") {
      // Other stuff here
    }
    case ("Option 3") {
      // Other stuff here
    }
    case ("Option 4") {
      // Just as an example of what you can do,
      //    this option can only be chosen if the player tried option 1 first
    }
  }
}

// And then actually call the menu using that callback:
ShowMenu ("Which option would you like?", Split ("Option 1;Option 2;Option 3"), true, npcname.blahmenu_callback)

So basically what I want to do is instead of having a menu that's tied to a function (where prompting the menu would be just calling the function again after each choice has been chosen), I have a menu that's tied to an object. So after the player picks a choice in the menu on this object, it'll recall the entire menu again. If I can do that with the scripts above....I think we're golden!

I'm confused though.

So when you have a menu with a function, you recall it by doing this...

FUNCTION NAME: Blahblah.

ShowMenu ("", game.blargh, true) {
switch (result) {
  case ("Build A Fire") {
Blahblah
}
case ("Roast Marshmellows") {
Blahblah
}
}

^--- so I'm wondering if I do this for a menu on an object to recall it...

OBJECT NAME: Blahblah.
STRING LIST blahblahmenu

ShowMenu ("", npcobject.blahblahmenu, true) {
switch (result) {
  case ("Build A Fire") {
Blahblah.blahblahmenu
}
case ("Roast Marshmellows") {
Blahblah.blahblahmenu
}
}

Anonynn.


Unless you already explained that and I'm a goofus and didn't understand it lol.

Anonynn.


(filler for getting my edited post, updated/posted)
(again, filler for getting my edited post, updated/posted)


to do/run/execute/activate/re-do/loop/re-run/re-execute/re-activate an Object's Script Attribute:

invoke (NAME_OF_OBJECT.NAME_OF_SCRIPT_ATTRIBUTE)
or
do (NAME_OF_OBJECT, "NAME_OF_SCRIPT_ATTRIBUTE")


for an example:

(the 'game' is an Object, a special Object, but it's still an Object, and its 'start' Script Attribute, while a special Script Attribute, is still a Script Attribute, lol)

<game name="example_game">

  <attr name="count" type="int">0</attr>

  <attr name="start" type="script">
    game.count = game.count + 1
    msg ("Count: " + game.count)
    if (not game.count = 5) {
      invoke (game.start) // or: do (game, "start")
    }
  </attr>

</game>

complete/full examples (Functions, Object's Script Attributes, and Delegates + Object Script Attributes):

<include ref="English.aslx" />
<include ref="Core.aslx" />

<delegate name="example_delegate_1" parameters="example_parameter_1"/>

<delegate name="example_delegate_2" type="string"/>

<delegate name="example_delegate_3" parameters="example_parameter_3" type="string" />

<game name="example_game">

  <attr name="count" type="int">0</attr>
  <attr name="count_0" type="int">0</attr>
  <attr name="count_1" type="int">0</attr>
  <attr name="count_2" type="int">0</attr>
  <attr name="count_3" type="int">0</attr>
  <attr name="count_4" type="int">0</attr>

  <attr name="start" type="script">

    game.count = game.count + 1
    msg ("Count: " + game.count)
    if (not game.count = 5) {
      invoke (game.count) // or: do (game, "count")
    }

    invoke (example_object.example_script_attribute_0) // or: do (example_object, "example_script_attribute_0")

    rundelegate (example_object, "example_script_attribute_1", "ep1")

    string_variable = "Example Return 2: " + RunDelegateFunction (example_object, "example_script_attribute_2")
    msg (string_variable)

    string_variable = "Example Return 3: " + RunDelegateFunction (example_object, "example_script_attribute_3", "ep3")
    msg (string_variable)

    example_function

  </attr>

</game>

<object name="example_object">

  <attr name="example_script_attribute_0" type="script">
    game.count_0 = game.count_0 + 1
    msg ("Count 0: " + game.count_0)
    if (not game.count_0 = 5) {
      invoke (example_object.example_script_attribute) // or: do (example_object, "example_script_attribute")
    }
  </attr>

  <attr name="example_script_attribute_1" type="example_delegate_1">
    game.count_1 = game.count_1 + 1
    msg ("Count 1: " + game.count_1)
    msg ("Example Parameter 1: " + example_parameter_1)
    if (not game.count_1 = 5) {
      rundelegate (example_object, "example_script_attribute_1", "ep1")
    }
  </attr>

  <attr name="example_script_attribute_2" type="example_delegate_2">
    game.count_2 = game.count_2 + 1
    msg ("Count 2: " + game.count_2)
    if (not game.count_1 = 5) {
      string_variable = RunDelegateFunction (example_object, "example_script_attribute_2")
    } else {
      return ("example_return_string_2")
    }
  </attr>

  <attr name="example_script_attribute_3" type="example_delegate_3">
    game.count_3 = game.count_3 + 1
    msg ("Count 3: " + game.count_3)
    msg ("Example Parameter 3: " + example_parameter_3)
    if (not game.count_3 = 5) {
      string_variable = RunDelegateFunction (example_object, "example_script_attribute_3", "ep3")
    } else {
      return ("example_return_string_3")
    }
  </attr>

</object>

<function name="example_function">
  game.count_4 = game.count_4 + 1
  msg ("Count 4: " + game.count_4)
  if (not game.count_4 = 5) {
    example_function
  }
</function>

<!--
Functions can of course also have return values, parameters, or both (return values and parameters) -- was too lazy to show them

(the Delegate usage basically makes an Object's Script Attribute be the same as a Function: able to have parameters, return values, and/or both: parameters and return values)
-->

If you just want to have a function that's specific to an object, you'd structure it exacly like a function, but put it in a script attribute.

Rather than

FunctionName()

you invoke it by:

do (objectname,"attributename")

The example in my previous post shows a different way of structuring it (I think slightly more efficient).


Hola Hk!

I'm not sure how your post pertains to my question/and I'm having trouble deciphering all that!

xD I just need a non-function menu to repeat.

Anonynn.


Oh, so ....

I would go...

do (objectname, "blahblahmenu")

?

Anonynn


(sorry about the confusion)


almost...

your scripting (menu + etc code) has to be within an Object's Script Attribute

<game name="example">

  <attr name="start" type="script">
    do (Blahblah, "blah") // or: invoke (Blahblah.blah)
  </attr>

</game>

<object name="npcobject">

  <blahblahmenu type="stringlist">

    <value>Build A Fire</value>
    <value>Roast Marshmellows</value>

  </blahblahmenu>

</object>

<object name="Blahblah">

  <attr name="blah" type="script">
    ShowMenu ("Select choice", npcobject.blahblahmenu, true) {
      switch (result) {
        case ("Build A Fire") {
          // blah scripting
        }
        case ("Roast Marshmellows") {
          // blah scripting
        }
      }
      on ready {
        ask ("Repeat?") {
          if (result) {
            msg ("You chose to repeat the menu selection")
            do (Blahblah, "blah") // or: invoke (Blahblah.blah)
          } else {
            msg ("You chose NOT to repeat the menu selection")
          }
        }
      }
    }
  </attr>

</object>

So I was finally able to test this...

do (objectname,"attributename")

Applying at it after each choice. But it didn't repeat the menu. Any advice?

Anonynn.


is 'objectname' the name of the Object (or is it a variable that is holding/pointing-to the Object) that has the Script Attribute that has the menu code?

is 'attributename' the name of the Script Attribute that has the menu code?


or, is your menu code within a Command? (and thus not within an Object's Script Attribute)

example (could be a bit different in how your Command's scripting is done):

<command name="example_command">
  <pattern>example</pattern>
  <script>
    show menu ("blah", Split ("blah1;blah2;blah3", ";"), false) {
      switch (result) {
        case ("blah1") {
          // I'm just using the 'ask' Function, so to prevent it from being an endless/infinite loop should you only choose 'blah1' repeatedly:
          ask ("again?") {
            if (result) {
              do (example_command, "script") // or: invoke (example_command.script) // or: do (this, "script") // or: invoke (this.script)
            } else {
              msg ("blah 1")
            }
          }
        }
        case ("blah2") {
          msg ("blah 2")
        }
        case ("blah3") {
          msg ("blah 3")
        }
    }
  </script>
</command>

The objectname is the name of the object that the menu is nested in.

The attribute name is the String List on the object's attribute list which is the menu I'm trying to repeat.

And nope, it would be easy if the menu were on a function or a command cause you would just recall the function or the command to bring up the menu. Since this menu I'm working on is on an object, I have no idea how to recall it.

Anonynn.


ah, "The attribute name is the String List on the object's attribute list (Anonynn)", there's your problem!

this needs to be the name of the Script Attribute (the Verb) itself, as you're looping the whole script, which includes the displayment menu within it

<game name="example_game">

  <attr name="start" type="script">

    do (example_object, "example_script_attribute")

  </attr>

</game>

<object name="example_object">

  <example_stringlist_attribute type="stringlist">

    <value>red</value>
    <value>blue</value>
    <value>yellow</value>

  </example_stringlist_attribute>

  <attr name="example_script_attribute" type="script">

    show menu ("Color?", example_object.example_stringlist_attribute, false) {
      switch (result) {
        case ("red") {
          ask ("Again?") {
            if (result) {
              do (example_object, "example_script_attribute")
            } else {
              msg ("Color: " + result)
            }
          }
        }
        case ("blue") {
          ask ("Again?") {
            if (result) {
              do (example_object, "example_script_attribute")
            } else {
              msg ("Color: " + result)
            }
          }
        }
        case ("yellow") {
          ask ("Again?") {
            if (result) {
              do (example_object, "example_script_attribute")
            } else {
              msg ("Color: " + result)
            }
          }
        }
      }
    }

  </attr>

</object>

if you only want to loop the menu displayment... that's a bit more tricky (as you got to use another Function or Script Attribute within that Script Attribute, to hold the menu displayment code, so you can only loop that menu displayment script instead of the full script/code of stuff)


I know little to nothing about object attributes. I do this with my menus. This is in my Pokemon game.

First room.

SetTimeout (3) {
}
msg ("Hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii!!!<br/>....<br/>Righto.<br/><br/>Now, the Pokémon... They are... magical creatures. Sometimes they are animals, and sometimes they are objects (such as Pokéballs) that come to life.<br/><br/><br/>You are.... um... in your room.<br/>Commands you should know; Heal Oran Berry me, Heal Sitrus Berry me, Rest me, Access object, Egress object, Look at object, x object, Check object, Scan object<br/><br/>Equip Pokemon.<br/>Save often. I recommend saving every 30 minutes.<br/><br/>Do you need any other help?")
a show menu
msg ("Testing. 1. 2. 3.")

The function
a show menu

options = Split("Pokemon;The Game;The Anime;Card Game;Combat;Items;Finish Game;Item Limit", ";")
ShowMenu ("Pokémon Information", options, true) {
  switch (result) {
    case ("Pokemon") {
      msg ("")
      msg ("Depending on whether you've watched the anime, played the game, read the manga, etc., Pokemon are either magical animals so overpowered you enslave them, or they are magical animals that are your friends, who, for some reason, follow you because you've beat them in battle, I assume that's Greek or anime logic, or something.<br/>This is satire, and parody. Be prepared for drunk old men, and intoxicated Slowpoke.<br/><br/>Pokemon is an RPG game.<br/>The name is short for \"Pocket Monsters.\" The Japanese developers thought  the name wouldn't catch on in the West, so they renamed it \"Pokemon.\" Don't ask me why, I think Pocket Monsters is better.")
      a show menu
    }
    case ("The Game") {
      msg ("")
      msg ("Ah yes, the game. The original game is a simple RPG. The original games were Pokemon Green in Blue, released in Japan in 1995. They were released as Red and Blue in the US and more in 1997. It can be summed up as follows: 20 minutes story, 300 hours grinding, 5 minutes x 8 gym leaders = 40 minutes for gym leaders, 5 minutes x 5 bosses = 25 minutes for the Elite Four, 200 hours trading/completing the Pokedex, and an optional 200 hours battling. Most casual/novice players stop after they've caught the final legendary, believing they completed the final game. The actual fun parts of the game are all online, and if you can't do that (and you don't have a friend/buy multiple games) you basically have an un-glorified Pokédex. Pokemon Diamond sucks in particular since you can't connect online anymore, and you can't get Spiritomb... sorry, I'm just complaining...")
      a show menu
    }
    case ("The Anime") {
      msg ("")
      msg ("Ah yes, the anime. The anime has run from 1998 (or 1997 JP), onward until today. And who knows if it will stop? There are actually multiple anime series based on the games, but there is one that is very famous: the one with Ash Ketchum and his Pikachu. The anime can be summed up as follows: Funny but awkward first season with a noticably lacking budget, a second season without Brock, and Ash actually won a league, the Johto series which was 90% filler and went on forever, an okay Advanced Series, an Awesome Battle Frontier series with major improvement past all former series, a decent Sinnoh series, and all the other series so far were just 'meh.' Currently, they are having a series where Ash Ketchum goes to school. Seriously. Pokemon Sun and Moon. Look it up. Also, Ketchum is an actual English last name. Wikipedia. https://en.wikipedia.org/wiki/Ketchum_(surname) There are also various other small episodes shows, mainly written for new games. An example: The Pokémon Mystery Dungeon Series. I also recommend Pokémon Generations and Pokémon Origins.")
      a show menu
    }
    case ("c") {
      msg ("")
      msg ("Ohhh.... yeah, the Card game. This is different since I don't play the card game. I only collect them... for fun. And I like to look at them. As far as I know, the card game can be bought at any Walmart, usually for around $4-$5 per pack. The inside usually contains one good card, some okay cards, and if you're unlucky you'll get a Caterpie card. The game is played in a Magic the Gathering type fashion. Each 'Trainer' has 20 HP points. You try to 'faint' (but everyone says kill) the other Pokemon/trainer. There are energy cards. You get the gist of it. The good part about this game, is at least you don't have to blurt out \"I activate my Voltorb... now I use my Electroshock for 30 damage on your active Pokemon.\" ...Usually.")
      a show menu
    }
    case ("d") {
      msg ("")
      msg ("Combat coming soon. Just set the Pokémon. Remember to save!")
      a show menu
    }
    case ("e") {
      msg ("")
      msg ("The berries heal health, and heal other status ailments. Oran Berries and Sitrus Berries heal health. Full restore heals health and heal all status conditions. Pecha Berries heal poison. More about items soon to come.")
      a show menu
    }
    case ("l") {
      msg ("")
      msg ("There is no ending. It's an open world RPG. To win the game, you will need to get 8 badges, and then defeat the Elite Four. I'm not even done editing the game yet...")
      a show menu
    }
    case ("f") {
      msg ("")
      msg ("You have an inventory limit of 50 items. You have a Pokémon team limit of 8 Pokémon.")
      a show menu
    }
    case (g) {
      msg ("Explaining Pokemon Catching Morality:")
    }
  }
}

The menu currently doesn't work because the cases currently don't match, but you should be able to copy it fine. Just call the funcrion name again.


Yeah, I don't need the entire verb to repeat, just the menu itself. Sorry about the confusion @_@

So you're saying I need to create a function anyway and recall the menu from there like I've been doing with all the other normal menus?

UPDATE: jmnevil54
That's what I'm trying to do I think, my code looks similar to yours. Lemme try just using the menu phrase itself.

Anonynn.


(filler for getting my edited post, updated/posted)


ah, okay... you want just the menu to be displayed again, no wonder you're having trouble, as this is a bit more tricky than just repeating the entire script/verb again

here's an example for you (using another Script Attribute, instead of using a Function):

the code has both repeating the entire script and repeating the menu displayment only within the entire script

(there's quite a few methods/designs... this is just one... might need to tailor/match the right method/design to your game/code design needs)

<game name="example_game">

  <attr name="start" type="script">

    ClearScreen

    msg ("Color? (Type in the number of/for your selection)")

    do (example_object, "menu_displayment_script_attribute")

    do (example_object, "menu_handling_script_attribute")

  </attr>

</game>

<object name="example_object">

  <example_stringlist_attribute type="stringlist">

    <value>red</value>
    <value>blue</value>
    <value>yellow</value>

  </example_stringlist_attribute>

  <attr name="menu_displayment_script_attribute" type="script">

    DisplayList (example_object.example_stringlist_attribute, true)

  </attr>

  <attr name="menu_handling_script_attribute" type="script">

    get input {
      switch (result) {
        case ("1") {
          ask ("Again?") {
            if (result) {
              ClearScreen
              msg ("Color? (Type in the number of/for your selection)")
              do (example_object, "menu_displayment_script_attribute")
              do (example_object, "menu_handling_script_attribute")
            } else {
              msg ("Color: " + result)
            }
          }
        }
        case ("2") {
          ask ("Again?") {
            if (result) {
              ClearScreen
              msg ("Color? (Type in the number of/for your selection)")
              do (example_object, "menu_displayment_script_attribute")
              do (example_object, "menu_handling_script_attribute")
            } else {
              msg ("Color: " + result)
            }
          }
        }
        case ("3") {
          ask ("Again?") {
            if (result) {
              ClearScreen
              msg ("Color? (Type in the number of/for your selection)")
              do (example_object, "menu_displayment_script_attribute")
              do (example_object, "menu_handling_script_attribute")
            } else {
              msg ("Color: " + result)
            }
          }
        } default {
          msg ("wrong input, try again")
          wait {
            ClearScreen
            msg ("Color? (Type in the number of/for your selection)")
            do (example_object, "menu_displayment_script_attribute")
            do (example_object, "menu_handling_script_attribute")
          }
        }
      }
    }

  </attr>

</object>

the above code can be improved by putting/running/nesting the two Script Attributes within another Script Attribute and adjusting some of the code around to match up with it

so you got:

the 'main' script attribute (let's call it 'main_script_attribute' for example here)
-> sub script attribute 1 (in the example above, this would be the 'menu displayment' script attribute)
-> sub script attribute 2 (in the example above, this would be the 'menu handling' script attribute)

which allows you to selectively repeat any of them or any combination of them (the main script attribute which does the entire operations/code/scripting, just the sub script attribute 1, jsut the sub script attribute 2, just the sub script attributes 1 and 2, etc etc etc whatever combinations)

(too lazy to show an example of it, at least for now... if you want an example, ask, and I'll post/write up an example, jsut not right now, lol)


yes, as mrangel said, its the same as having functions (or multiple functions) within functions, as that allows you to call whatever functions and/or combinations of functions, you want

except its with Objects and Script Attributes instead

(and if you use Delegates with Objects and Script Attributes, then its exactly the same as Functions: being able to return values and take data/inputs/arguments/parameters)


You can create a function, or you can create a script attribute. If you don't pass parameters to it, the two are equivalent; it's just how you prefer it to be organised.

There are two ways to use a script attribute for a menu. One way (which I prefer), you have the script that handles the menu response in a script attribute. Then you just call ShowMenu each time you want to repeat it.

The other way, you treat the script attribute like a function: it contains the ShowMenu command, and you call it using do() each time it's needed.


P.S.

this stuff is getting close to matching my own menu system/organization that I'm still working on for my game (for the character creation and anything else within the game that uses menus)... lol


I tried...

do() 

at the end of the menu and it didn't repeat it.

See the menu is a string list inside of a verb.

I don't want the entire verb to repeat. I just want the menu itself to repeat. But so far nothing is really working. This is the type of menu I'm using...

ShowMenu ("", game.menunamehere, true) {
switch (result) {
  case ("Build A Fire") {
  do ()
}
}
}

Anonynn.


(filler for getting my edited post, updated/posted)
(again, filler for getting my edited post, updated/posted)


with the usage of 'do (XXX)' Function, mrangel is referring to doing it similar to:

(see my big code post above, I have example of it there, except I made the String List an Attribute instead of a temporary String List Variable, they're the same thing though, aside from Attributes being able to be used/re-used anywhere, whereas your 'options' String List Variable can't be used outside of its Script Attribute or Function or Command or whatever parent Element that can do scripting)


the concept is like this:

(forgive my cooking ignorance, if I'm missing anything and/or have it wrong, lol)

lets say you're making chocolate chip cookies

you are the main operation/task (A Script Attribute), doing these sub tasks/operations (scripting):

  1. putting the cookie dough and chocolate chips into the mixer
  2. baking the cookie dough + chocolate chips
  3. telling your spouse to go buy more cookie dough and/or chocolate chips should you run out or need more
  4. making even more chocolate chip cookies, if you get requests for making more of them

your spouse is a sub operation/task (Another Script Attribute), with the sub sub tasks/operations (scripting) of:

  1. get cookie dough
    and/or
  2. chocolate chips

your spouse going to get the ingredients is a separate sub operation, as you can tell him/her what to get and while he/she is going to get the stuff, you're able to keep working at your tasks: you can tell him/her to get more and more ingredients over and over again, without disrupting/repeating your own operations/tasks


I think I see what you mean. I've done that before with something else.

Thanks for the help everyone. I'll try something and see if it works :D :D

Got it! Appreciate everyone. Thank you so much for your help!

Anonynn.


the problem is if you want to be able to just/only repeat the menu displayment coding (via putting the menu displayment coding into a sub Script Attribute) (and meaning NO usage of the 'show menu / ShowMenu' Functions: you got to display your menu another way), then for your main script attribute (or another sub Script Attribute within your main Script Attribute), you're going to have to use the 'get input' for handling/getting the menu selection and doing whatever with it, which takes a bit more coding to do that (as can see by my big code post)


the 'show menu / ShowMenu' Functions do two operations:

  1. menu displayment
  2. menu selection handling

so, if you want to separate out the menu displayment, so you can just repeat it as needed, then you can't use these built-in Functions, as we need to separate their two operations by putting each into their own Script Attribute

and thus why you're going to need to use the 'get input' Function


either using one Script Attribute (or Function) that does both operations via using the 'show menu / ShowMenu' Functions, or separating them into two Script Attributes (or Functions): one script attribute (or function) for displaying the menu and the other script attribute (or function) for getting the input/selection and doing whatever with it

essentially, you're just splitting the 'show menu / ShowMenu' Function's two operations (menu displayment and menu selection handling) into their own Script Attributes (or Functions), as that way, you can then repeat whichever one/operation (menu displayment or menu selection handling) you want or you can repeat both of them (menu displayment and menu selection handling), as well


to do/call and also to re-do/re-call/repeat/loop Script Attributes:

do (OBJECT, "SCRIPT_ATTRIBUTE")

// or

invoke (OBJECT.SCRIPT_ATTRIBUTE)

to do/call and also to re-do/re-call/repeat/loop Functions:

FUNCTION

// or, if got/using Parameters:

FUNCTION (XXX)

see how they're nearly the same... the only difference is that Script Attributes are contained by specific Objects, so you got to tell what Object has the Script Attribute that you want to use, as well as what Script Attribute, you want to be using... whereas, that's not the case with Functions as they're their own "objects" (if you will) that ONLY contain scripting itself (no need for a Script Attribute for holding the scripting)


nevermind, delete post

(is there a way to delete your posts yet?)


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

Support

Forums