yes/no question function

I got a game here that I don't want to write the same yes/no prompt every time. I'm finding there is no global variables, and people are saying to use attributes instead. But I can't figure out how to call an attribute from another object to make a yes/no prompt. So I think "well I should just write a function" right? The problem is if/else expressions try to evaluate immediately so if the function doesn't evaluate immediately then the whole thing falls apart. Is there a way to make this work without having to write the same line of code every time I want to make a yes/no prompt?

if (yesnoF() = "yes") {
msg ("Yes placeholder")
}
else {
msg ("No placeholder")
}

alt text

alt text


You can't do that, because it's asynchronous. Your function yesnoF finishes as soon as the menu has been displayed, it doesn't wait for an answer.

What you probably want is something like the core function Ask.
So you can do something like:

Ask ("Some question here") {
  if (result) {
    msg ("Yes placeholder")
  }
  else {
    msg ("No placeholder")
  }
}

So thats how ask works, thanks for that. But this is going to be annoying when I want to ask anything repeatedly that's not a yes or no question. What if I use await?


You could use a switch/case?


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


the 'ask/Ask' is a built-in Function for asking a 'yes/no' question


for a normal question, you can use the built-in 'show menu / ShowMenu' Functions:

(in example below, I use a 'ask' Function for whether to re-do/loop/repeat the race selection or not)

(you need some form of check in whether to loop or not, else you've got an endless/infinite loop, which crashes quest, as the computer's resources/memory isn't infinite, whereas the endless/infinite loop uses infinite resources/memory)

<game name="NAME_OF_GAME">

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

    create ("character_data_object")

    character_data_object.race_stringlist_attribute = NewStringList ()
    list add (character_data_object.race_stringlist_attribute, "human")
    list add (character_data_object.race_stringlist_attribute, "dwarf")
    list add (character_data_object.race_stringlist_attribute, "elf")
    list add (character_data_object.race_stringlist_attribute, "gnome")
    list add (character_data_object.race_stringlist_attribute, "halfling")
    list add (character_data_object.race_stringlist_attribute, "giant")

    race_function

  </attr>

</game>

<function name="race_function">

  ClearScreen
  show menu ("Race?", character_data_object.race_stringlist_attribute, false) {
    player.race_string_attribute = result
    msg ("Your selected race: " + player.race_string_attribute)
    ask ("Correct?") {
      if (not result) {
        race_function
      }
    }
  }

</function>

example of an infinite/endless loop:

(there's no displayment/output for you to see, so all you'll experience is quest crashing "without warning")

<game name="NAME_OF_GAME">

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

    infinite_loop_function

  </attr>

</game>

<function name="infinite_loop_function">

  infinite_loop_function

</function>

example of an infinite/endless loop:

(this time I've added in displayment/output/tracking, so you can see it in action, and not just experience quest crashing on you with "no warning" like above in the previous example)

<game name="NAME_OF_GAME">

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

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

    infinite_loop_function

  </attr>

</game>

<function name="infinite_loop_function">

  msg ("Counter: " + game.counter)
  game.counter = game.counter + 1
  infinite_loop_function

</function>

What if I use await?

No, wait just waits for the game engine to not be doing anything.

The Ask and ShowMenu functions display a menu, and make a note of some code to be run when the player clicks on that menu. As far as Quest's concerned, it isn't "doing" anything.

But this is going to be annoying when I want to ask anything repeatedly that's not a yes or no question.

You could make a function that works the same way Ask does: its parameter is a callback script.
For example, I create a function called "RockPaperScissors", with a parameter named script.
I give it the contents:

options = Split("Rock;Paper;Scissors")
game.rpscallback = script
ShowMenu ("", options, false) {
  NPCthrows = PickOneString (Split ("Rock;Paper;Scissors"))
  if (NPCthrows = result) {
    msg ("You both picked "+result+"! Go again?")
    Ask ("Play again?") {
      if (result) {
        RockPaperScissors (game.rpscallback)
      }
      else {
        msg ("You resign")
        params = QuickParams ("playerthrow", result, "npcthrow", NPCthrows, "win", false)
        do (game, "rpscallback", params)
      }
    }
  }
  else {
    msg ("You say "+result+" and the other guy says "+NPCthrows+".")
    params = QuickParams ("playerthrow", result, "npcthrow", NPCthrows)
    switch (result + NPCthrows) {
      case ("RockPaper", "PaperScissors", "ScissorsRock") {
        msg ("You lose!")
        dictionary add (params, "win", false)
      }
      case ("PaperRock", "ScissorsPaper", "RockScissors") {
        msg ("You win!")
        dictionary add (params, "win", true)
      }
    }
    do (game, "rpscallback", params)
  }
}

This is a bit more complex than the Ask example; but in this case the function is doing a little more than just asking a question.
If you're just asking the same question lots of times, then checking the result from a function you've written is about as complex as checking the result from ShowMenu, so there's little time saving.

The function above could be used like:

msg ("Bob challenges you to play rock/paper/scissors to decide who gets the treasure chest.")
RockPaperScissors() {
  if (win) {
    msg ("“Awww,” Bob sulks. “Fine, you take it!”")
    AddToInventory (TreasureChest)
  }
  else {
    msg ("“Heh,” Bob sneers. “You got a tell!”")
  }
}

@hegemonkhan Thanks, that was really helpful. Now I understand how to reference attributes of other objects, which is what I couldn't figure out. Truth be told I'm using the visual editor rather than script but the only help given out is for scripting. But I've realized something that probably should have been obvious. In the future I'm gonna just start using the quest docs and copy pasting the scripts from examples to see how they translate when switching to the visual editor.

@mrangel I was referring to javascript "await" which pauses asynchronous functions. Though maybe I'm misunderstanding how await works. But the script you posted is helpful, I'll use it as a reference going forward thanks!

With this my problems are solved, thanks again for all the help both of you.


There is no await or equivalent in Quest script.

You could maybe use await to make your javascript code pause until it gets a response from Quest (although this would be difficult, as I don't think Quest provides promises for its state changes in any useful way); but there is no corresponding way to make the backend code on the Quest side wait for a response from your javascript.


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

Support

Forums