get input inside a while loop

vegas
I am trying to simulate my character typing commands into a computer terminal and have the following code:

while (true) {
msg ("Type your command.")
get input {
switch (result) {
case ("open") {
msg ("opening door")
UnlockExit (room00exit)
}
}
}
}

Unfortunately, when I run it I get the following error:

Error running script: Only one 'get input' can be in progress at a time



I kind of understand why the error is happening, but can't think of a way to structure my code to stop it. Does anyone know of a way around this?

XanMag
Here is how I structured my computer program...

msg ("<br/>The screen clears and a single prompt appears in green.<br/><br/>Please type the last name of the person you would like to search or type 'stop' to quit using the computer or type 'return' to return to the program selection screen:<br/>")
get input {
switch (result) {
case ("Dingo", "dingo") {
play sound ("alarm.mp3", false, false)
msg ("CLASSIFIED...<br/><br/>CLASSIFIED...<br/><br/>ACCESS DENIED.<br/><br/>CLASSIFIED...<br/><br/>CLASSIFIED...<br/><br/>ACCESS DENIED.")
wait {
computer loop
}
}
case ("Magoo","magoo") {
msg ("<b><u>Name:</b></u> Xanadu Magoo<br/><br/><b><u>General Appearance:</b></u> Serious dork. Early thirties. 5'8\". 105 pounds. Light brown hair, hazel eyes, pasty white complexion.<br/><br/><b><u>Occupation:</b></u> Science Teacher at the Holy Moly Incapables<br/><b><u>Ethnicity:</b></u> Caucasian, American<br/><br/><b><u>Specialties:</b></u> Above average knowledge in science, especially physics and chemisty<br/><br/><b><u>Notes:</b></u> Escaped several assassination attempts in the desert. In doing so, killed two desert patrol guards, one via electrocution and one died of complication with an unknown biotic factor. Infiltrated our compound for unknown reasons. Was forced into unconsciousness by Dr. Dingo himself upon arrival. Assassination was to immediately follow, but Dr. Dingo would not allow it. Instead, Xanadu Magoo is currently being help captive in prison cell one by orders of Dr. Dingo.")
wait {
computer loop
case ("stop") {
msg ("You type quit and hit enter. You back away from the computer and look for better things to do.")
}
default {
default to program
}
case ("stop") {
msg ("You stop using the computer and you look for better things to do.")
wait {
MoveObject (Xanadu, sarlashkars office)
}
case ("return") {
msg ("<br/>You type in 'return' and you return to the program option screen.<br/>")
wait {
msg ("<br/>Which program would you like to run (type 'stop' to stop using the computer)?<br/>1 - Dingo Database<br/>2 - Compound Information<br/>Stop - quit using computer<br/>")
get input {
switch (result) {
case ("1") {
computer loop
}
case ("2") {
computer loop 2
}
case ("stop") {
msg ("You type quit and hit enter. You back away from the computer and look for better things to do.")
}
default {
default to program
}
}


Obviously, I have a LOT more than just that, but I didn't want to post spoilers to my soon to be released game! :lol:

Pardon if the brackets are messed up... I copy-pasted only relevant stuff. As far as you getting the error message... I'm not sure. It looks fine to me, but someone will probably come along and give you better info in that regard.

Good luck.

The Pixie
It is not trivial.
while (true) {
msg ("Type your command.")
get input {
switch (result) {
case ("open") {
msg ("opening door")
UnlockExit (room00exit)
}
}
}
}

The problem, as you perhaps realised, is that the get input is waiting for the player to type something, but the script continues, going to the next cycle, and then gets to a second get input, and hence the error. This will get the same error:
  get input {
msg("You said: " + result)
}
get input {
msg("You said: " + result)
}

The trick, in general, is to put the second get input inside the block, like this:
  get input {
msg("You said: " + result)
get input {
msg("You said: " + result)
}
}

Doing that in a loop is not possible, so you need to look at recursion, which I did here (and good luck working out how that works!):
viewtopic.php?f=18&t=5492

Did I say it is not trivial?

An alternative is to subvert the Quest command system, so instead of using get input, you handle regular commands as though they were instructions to the computer. You can change the prompt to make this apparent to the player. Whether that is easier or better is debatable.

vegas
Interesting. I'll try recursion first, seeing as that wouldn't require restructuring my game. But yeah, my other option was to have the computer terminal as another room and feed commands into it that way, while hiding as best I can the fact that it is a room. I'll post again if I find a good solution

TinFoilMkIV
As The Pixie said, not anywhere near as simple as it may sound. I ran into this problem myself a while back, and the issue is as he said above, the code still runs, so when you do a get input attempting a loop this is basically what happens
get input {
//do input stuff
//this section only happens after the input is resolved
}
//this stuff is still happening while the game is waiting for your input

//attempt to loop back to input

//error because the game is still waiting for your input while trying to rerun the get input again


Basically you have to have the overall script end with the get input, you need everything that occurs after the input to be inside the get input results if it is still going to be part of the same script.

One of the tricks I personally use it to have the looping section of code stored outside of the main code block. This can be done by storing as a function, or as a script attribute of an object. I personally prefer script attributes since in most cases that I use this it's not something that will be called very often outside of one or two specific situations, and I don't want to clutter up my functions with things that aren't common use.

Then you call the attribute script to run when you want the get input to happen, and as part of the results you can have it call itself again in the case that it loops, and in the case that it proceeds to something else you call a different script to achieve that. You don't actually have to break the results into a separate script but I tend to do that for organizational purposes as well as being able to pull different script results in different ways without re-writing code a bunch of times.

So it might look something like this
//computer terminal activation and whatever text goes here before the input
msg ("Type your command.")
do (computer, "command prompt")
//this calls the "command prompt" script from the object 'computer'

//command prompt script
getinput {
switch (result) {
case ("open") {
//do open stuff here
}
default { //this is the equivalent of an 'else' for a switch, no matching cases will execute this code
do (computer, "command prompt")
//this causes the command prompt to repeat on an invalid command
}
}
}

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

Support

Forums