How to deal with riddles questions and answers (SOLVED)

NecroDeath
17 Feb 2017, 18:58

Hi,

I have an NPC, I want them to ask the player three riddles, if they get all three right they get to pick up an item. What's the easiest way to deal with giving the question and checking the answer?


XanMag
17 Feb 2017, 20:28

Does the player answer a riddle and is immediately asked another one?

Or, does the player speak to NPC, get asked a riddle, offer answer, and then must speak to them again?


NecroDeath
17 Feb 2017, 20:33

They get asked the second one, once they have answered the first one correctly. The NPC asks the first riddle when you first meet him - doesn't need to be triggered by speech. Thanks!


XanMag
17 Feb 2017, 21:09

I went ahead and wrote a quick scenario. =) I was bored! Ugh. Just saw you are using the online version... If at all possible, work with the downloaded version. It is MUCH better!

<!--Saved by Quest 5.6.6108.15891-->
<asl version="550">
  <include ref="English.aslx" />
  <include ref="Core.aslx" />
  <game name="riddle me thrice example">
    <gameid>b6f5ceed-c669-4d52-ab32-a0bf72601c56</gameid>
    <version>1.0</version>
    <firstpublished>2017</firstpublished>
    <start type="script">
      SetObjectFlagOn (Riddler, "one")
    </start>
  </game>
  <object name="room">
    <inherit name="editor_room" />
    <object name="player">
      <inherit name="editor_object" />
      <inherit name="editor_player" />
    </object>
    <object name="Riddler">
      <inherit name="editor_object" />
      <speak type="script"><![CDATA[
        if (GetBoolean(Riddler, "one")) {
          msg ("The riddler speaks,<br/><br/>\"Riddle three times, I shall ask,<br/>answer all three, it is your task.<br/>If you're right then I shall gift,<br/>I treat so great.  Magnificent.<br/><br/>It is time that I  begin<br/>and see if this game you shall win.<br/>Riddle one you now shall hear,<br/>So here we go, loudly and clear.<br/><br/>\"A sword's no match for this here tool,<br/>A porcupine, don't touch, You fool!<br/>Pluck a \"hair\" from that fearsome beast,<br/>Dip in the well, blue, black at least.<br/><br/><b>\"What am I?\"</b><br/>")
          SetObjectFlagOn (Riddler, "two")
          get input {
            switch (LCase(result)) {
              case ("pen", "a pen") {
                msg ("That's a great guess and we shall see.<br/>If your answer is right for me,<br/>We move on to the next riddle,<br/>Don't mess 'round or faddle fiddle.")
                Riddler.RiddleCount = Riddler.RiddleCount + 1
              }
              default {
                msg ("That's a great guess and we shall see.<br/>If your answer is right for me,<br/>We move on to the next riddle,<br/>Don't mess 'round or faddle fiddle.")
              }
            }
          }
          SetObjectFlagOff (Riddler, "one")
        }
        else if (GetBoolean(Riddler, "two")) {
          msg ("The riddler speaks,<br/><br/>\"Riddle one I've already posed,<br/>So here is two that I propose.<br/>Get ready now I do advise, <br/>And let me know that you are wise.<br/><br/>\"I'm quick and strike with rapier speed,<br/>And all but just a tongue I need,<br/>A good one and laughs you'll see,<br/>'Brevity is the soul of me.\"<br/><br/><b>\"What am I?\"</b><br/>")
          SetObjectFlagOn (Riddler, "three")
          get input {
            switch (LCase(result)) {
              case ("wit") {
                msg ("That's a great guess and we shall see.<br/>If your answer is right for me,<br/>We move on to the next riddle,<br/>Don't mess 'round or faddle fiddle.")
                Riddler.RiddleCount = Riddler.RiddleCount + 1
              }
              default {
                msg ("That's a great guess and we shall see.<br/>If your answer is right for me,<br/>We move on to the next riddle,<br/>Don't mess 'round or faddle fiddle.")
              }
            }
          }
          SetObjectFlagOff (Riddler, "two")
        }
        else if (GetBoolean(Riddler, "three")) {
          msg ("The riddler speaks,<br/><br/>\"My last riddle I now shall speak,<br/>Is your mind so strong or so weak?<br/>Please answer after three I say.<br/>If wrong you be, you shall dismay.<br/><br/>\"Best friend I am to man or child,<br/>My frequency by tame, not wild.<br/>Quadraped I am no doubting,<br/>No words I speak when I'm shouting.\"<br/><br/><b>\"What am I?\"</b><br/>")
          SetObjectFlagOn (Riddler, "three")
          get input {
            switch (LCase(result)) {
              case ("dog","a dog") {
                msg ("That's a great guess and we shall see.<br/>If your answer is right for me,<br/>We move on to the next riddle,<br/>Don't mess 'round or faddle fiddle.")
                Riddler.RiddleCount = Riddler.RiddleCount + 1
              }
              default {
                msg ("That's a great guess and we shall see.<br/>If your answer is right for me,<br/>We move on to the next riddle,<br/>Don't mess 'round or faddle fiddle.")
              }
            }
          }
          SetObjectFlagOff (Riddler, "three")
        }
        else {
          firsttime {
            if (Riddler.RiddleCount = 0) {
              msg ("You have answered all three wrong, so I will not gift to wrong.")
            }
            else if (Riddler.RiddleCount = 1) {
              msg ("You have answered just one right, so I give you nothing this here night.")
            }
            else if (Riddler.RiddleCount = 2) {
              msg ("You have answered two riddles well, but not enough so no gifts I sell.")
            }
            else if (Riddler.RiddleCount = 3) {
              msg ("All three you've answered right, oh me.  A gift I give so look and see!")
              MakeObjectVisible (sword)
            }
          }
          otherwise {
            msg ("You've had your chance to win the I say, so now you must just go away.")
          }
        }
      ]]></speak>
      <RiddleCount type="int">0</RiddleCount>
      <changedRiddleCount type="script">
      </changedRiddleCount>
      <look>Speak to the Riddler to hear a riddle!</look>
    </object>
    <object name="sword">
      <inherit name="editor_object" />
      <look>Greatest sword EVER!</look>
      <visible type="boolean">false</visible>
      <take />
    </object>
  </object>
</asl>

I based the above on:
Speak to Riddler and get first riddle. Give answer. Speak again and get second riddle. Give answer. Speak again and get last riddle. Give answer. Speak again to see if you are correct. This allows for levels of gifts to be awarded based on the number of riddles being answered correctly (if you want to do that).
You can copy-paste what I did, or... for your scenario....

  1. Instead of automatically moving on regardless of the first answer being right or wrong, you only change the flag settings on the right answer ONLY.
  2. You would also NOT need to add an attribute and adjust it as I did. Simply ask the appropriate riddle based on which flag is set.

I do things a bit... awkward I think and there might be an easier way to do this, but this is how I have learned it.
I think it would be most helpful to open a brand new game and copy-paste everything I have in there and then you can kind of use it as a template.

Ask if you have questions. Sorry if I'm confusing!

Good luck!


XanMag
17 Feb 2017, 21:18

So... (again, just saw you are working on-line... not sure how applicable this is, but I hope it helps!)

  1. Add verb speak to, etc on NPC.
  2. Go to game script tab and set a flag on your NPC. I named mine one.
  3. Add to the 'speak to' verb on the NPC an 'If' script.
  4. If object NPC has flag name one, then ask first riddle.
  5. Add a 'Get Input' script and add a switch script to it. In the switch box, type LCase(result). In the case box, add a string of acceptable answers IN QUOTES and SEPARATED BY COMMAS. In the default section under the case box, add a message indicating the player got it wrong.
  6. Add a script to this to unset NPC flag one and also add a script to set NPC flag two.
  7. Go back to the If script and click on an 'Else If' and add object NPC has flag two. Add here the second riddle and repeat step 5.
  8. Repeat steps 7 for the third riddle.
  9. After the third riddle is answered correctly, unset flag three on NPC.
  10. In the Else section of talking to the NPC add whatever you want for communicating/rewarding the player for answering all three correctly.

Let me know if that helps.


NecroDeath
17 Feb 2017, 21:25

Wow! Many thanks for this, really appreciate the effort and detail, I would never have figured this out on my own. Will try it now.


NecroDeath
17 Feb 2017, 21:30

Also I love the rhymes and riddles!


NecroDeath
17 Feb 2017, 21:35

Sorry one question, is there a reason why you suggest using object flags to count the riddles asked instead of object counters?


XanMag
18 Feb 2017, 01:59

Lol. I've never used object counters. So, I can't advise there! I'll mess with it when I get home.


NecroDeath
18 Feb 2017, 14:43

Thanks, also what does LCase mean? Lowercase? List cases?


XanMag
18 Feb 2017, 14:46

Yes. That means whatever the player types will be matched to lowercase only. So you don't have to worry about accounting for case sensitivity.


NecroDeath
18 Feb 2017, 14:59

thanks. Just finished coding it, about to test.


XanMag
18 Feb 2017, 15:03

Let me know!


NecroDeath
18 Feb 2017, 15:17

Getting the following error when responding to the NPC

Error running script: Error compiling expression 'LCase': Unknown object or variable 'LCase'


TinFoilMkIV
18 Feb 2017, 15:23

Can you post the section of code that's giving you the error, it sounds like something is either misplaced or a typo is throwing off the code.


NecroDeath
18 Feb 2017, 15:29

msg (""Greetings traveller" says the Bat (in an outrageous Transylvanian accent), "It's many moons since this cave saw light", "I hope you've not come to steal my treasure!" the Bat points one of its large curved fingers at the pile of droppings. "Only the wise deserve such a reward." "Answer these riddles three and the guano yours will be." "Are you ready?"")
get input {
switch (LCase) {
case ('yes', 'Yes', 'YES') {
msg (""I have several faces but I’m not a crowd
I’m covered in spots but I don’t have acne
I’m sometimes blown on but I’m not hot.

What Am I?"
")
get input {
switch (LCase) {
case ('dice', 'die', 'a dice', 'a die') {
msg (""Correct! Wiser than you appear it seems", 'Speak to me again when you are ready for the second riddle"")
IncreaseObjectCounter (Bat, "riddle")
}
default {
msg (""No, that's not right", "Speak to me when you are ready to try again."")
}
}
}
}
default {
msg (""Speak to me again when you are ready"")
}
}
}


NecroDeath
18 Feb 2017, 15:30

I'm using the GUI so have pasted from code view, apologies if bad form, I'm a noob.


XanMag
18 Feb 2017, 15:48

It needs to read:
LCase(result)
in the GUI

or

switch (LCase(result))

in code

And your cases need to be double quotes:
"die","a die","dice"


NecroDeath
18 Feb 2017, 15:50

Thanks, will try again.


NecroDeath
18 Feb 2017, 15:55

Seen your update, thanks, just trying it now


TinFoilMkIV
18 Feb 2017, 15:56

XanMag is correct.

LCase () is a function that says make everything inside of it lowercase, so putting it by itself doesn't mean anything. The error was because you didn't have the perentesis after it which tells Quest that LCase is the name of a function, a word just by itself tells Quest to look for an object which is what your error was about.


NecroDeath
18 Feb 2017, 16:06

My good lord, it works! Thanks so much.


XanMag
18 Feb 2017, 16:19

Excellent!


hegemonkhan
18 Feb 2017, 22:47

FUNCTION (ARGUMENTS/PARAMETERS: inputs/data/values to be used by the Function's scripting)

msg ("hi")

input: "hi" String Value
returned value/ouput: hi


<function name="integer_addition_function" parameters="integer_1_parameter, integer_2_parameter" type="int">
  if (TypeOf (integer_1_parameter) = "int" and TypeOf (integer_2_parameter) = "int") {
    return (integer_1_parameter + integer_2_parameter)
  } else {
     msg ("Wrong attribute/data/value type of inputs, try again")
  }
</function>

the, type="xxx", in the Function's header/signature, specifies what value the Function will return (via using the 'return (xxx)' within its scripting), so your returned value must match up with what you specify via the 'type' in the Function's signature/header line

Functions do NOT have to have arguments/parameters and/or nor have to have a return type, they're both individually optional


example of using the Function:

integer_1_variable = 67
integer_2_variable = 23
integer_3_variable = integer_addition_function (integer_1_variable, integer_2_variable)
msg ("Your new integer value is: " + integer_3_variable)
// output: Your new integer value is: 90

vs wrongly using it (giving it the wrong data/attribute/value types for its arguments/input/data):

string_1_variable = "hi"
string_2_variable = "bye"
integer_3_variable = integer_addition_function (string_1_variable, string_2_variable)
// output: Wrong attribute/data/value type of inputs, try again