[SOLVED] Command pattern #text# means players get stuck in room forever!

The code below *********was ok if the player had got the safe excessable and wanted to remain in the room and eventually typed in the correct six digit code. HOWEVER !...If the player has accessed the safe and tries to guess the code, then gives up and wants to leave the room, he cannot. Because typing ANYTHING, even a direction gets a response..."incorrect code" or "the safe is not accessible" etc.

How do I allow the player to leave the room by typing "south" or "s" when ALL text is controlled by this script #text# ?

Is there not a #numbers# command structure that only deals with numbers typed and this would allow players to type "south" or "s" and leave the room easily?


if (GetBoolean(mirror, "mirrorup")) {
if (not IsInt(text)) {
play sound ("FFBuzz.wav", true, false)
msg ("You need to type ONLY six numbers!")
}
if (LengthOf(text) < 6) {
play sound ("FFBuzz.wav", true, false)
msg ("You need to type six numbers.")
}
if (LengthOf(text) = 6) {
play sound ("wrong6.wav", true, false)
msg ("That is not the correct 6 digit code.")
}
else if (GetBoolean(, "safeopen")) {
msg ("The safe is already open!")
}
}
else if (not GetBoolean(mirror, "mirrorup")) {
msg ("There is nowhere to type that code at the moment!")
}


There are a few patterns you could use to make this command work as desired; but I think they're mostly regular expressions. Regular expressions are more powerful than simple patterns, but also harder to understand.

My first choice would be ^(?<text>(?<text2>.+))$ - this is effectively the same as #text# except that it has a lower priority, so it will only be used if no other command matches the player's input.

You could alternatively use ^(?<text>.*\d.*)$ - which only matches if the player's input has a number in it.

Why this works:
Some Quest commands have the same words in them. For example use #object# and use #object1# on #object2#.
When the player types "use spanner on machine", Quest sees two commands that match. It could be use, with #object# matching the words "spanner on machine", or it could useon, with #object1# being "spanner" and #object2# being "machine".

To solve this situation, Quest looks for the most specific command. That is, the one with fewest characters mapping onto object names.
So in this example:
For the command useon (pattern "use #object1# on #object2#"), the variable object1 would be "spanner" (7 letters), and object2 would be "machine" (7 characters). This matches 7+7 = 14 characters in variables.
The command use (pattern "use #object#") would have the variable object being "spanner on machine", which is 18 characters.
It looks to see which number of characters is less. In this case, useon (14) has fewer characters in variables than use (18), so it selects the useon command.

This means that you can change which command is chosen by changing their patterns.

If the player types "east" then the command go acts as if its pattern was: #exit#. The variable exit gets the whole string, "east" (4 characters).
Your pattern #text# gives the variable text the whole string "east" (4 characters).
As these are both 4 characters, the tiebreaker is that the last command checked wins. So user-created commands override built-in ones.
The alternate pattern ^(?<text>(?<text2>.+))$ matches 2 variables: text, which gets the entire string "east" (4 characters), and text2 which also gets the entire string "east" (4 characters). That's 8 characters total, so Quest thinks that the go command is a closer match.


Could you please show me how ^(?

Instead of Command pattern : #text# do I put in Command patter : n ^(?

if (GetBoolean(mirror, "mirrorup")) {
if (not IsInt(text)) {
play sound ("FFBuzz.wav", true, false)
msg ("You need to type ONLY six numbers!")
}
if (LengthOf(text) < 6) {
play sound ("FFBuzz.wav", true, false)
msg ("You need to type six numbers.")
}
if (LengthOf(text) = 6) {
play sound ("wrong6.wav", true, false)
msg ("That is not the correct 6 digit code.")
}
else if (GetBoolean(, "safeopen")) {
msg ("The safe is already open!")
}
}
else if (not GetBoolean(mirror, "mirrorup")) {
msg ("There is nowhere to type that code at the moment!")
}


There is a drop down on a command, with the options "Command pattern" and "Regular expression".

Change the drop down to "regular expression, and then enter ^(?<text>(?<text2>.+))$ in the pattern box instead of #text#.
Or you could use ^(enter *|code *|(?=\S*\d\S*$))+(?<text>.+)$, or ^(?<text>.*\d.*)$ in the same way. They all have their advantages and disadvantages.

Incidentally, when you're pasting code or error messages in a forum post, you can put a backtick (`) before and after it to stop the forum messing it up. If you're pasting multiple lines of code, put a line of 3 backticks above and below it.


I tried the "regular expression" ^(?

Both don't allow thewrong six digit , under 6 digit or any other digits : Still get usual default "I dont understand reply"


That's strange; which expression are you trying?
(to paste it in the forum, put a backtick (`) before and after it, so that the forum doesn't try to treat the named group as HTML)

I've tested all of them now. It seems that ^(?<text>(?<text2>.+))$ doesn't work in Quest, but I can't figure out why. ^(?<text>.*(?<text2>.))$ seems to be fine.
Edit: a little more digging around in the code reveals that there's been some changes in the parser since last time I tried this. It turns out that it will ignore any command whose parameters are more than one character longer than the command entered. So there needs to be exactly 1 character in text2 in order to make this trick work now.


Cheers, The code works for text and or numbers.
However, Players may leave room, re enter room and the script is still active and therefore a word typed may replay the expected code safe question script and give a reply "incorrect code" with a sound.

There seems to be no way to stop this script from running forever. It can't be switched off!


If you want to disable a command permanently, you can destroy it. However, in most circumstances it's easier to just put it in a container. (Global commands have their parent attribute set to null. Local commands have the same parent as the player. Neither of these can be true if the command is inside an object that the player can't enter.

You can move commands around the same way you would any other object; although they aren't on the list of objects in the GUI, so you'll need to use code view to do this, or type the command's name in as an "expression".


Thanks. I sussed out that I simply had to add an if statement at the very start of the script (if safe has flag safeopen) then give an if statement (if safe does not have flag safeopen) at the very end.

Wonderful satisfaction when achieving a FIX to sometimes the smallest of problems. Took me 1 hr of fiddling and getting my brain working!

I decided to put in a response of "I don't understand you....Yet!" to when players may stumble into accidentally typing random stuff in the room where the safe has not been discovered. I think this will suffice.

Thanks for all your help, I would never have known how to code this the way you explained on my own. CHEERS.


Log in to post a reply.

Support

Forums