This is a bit complicated, so I posted it here.
I made a custom Yes/No dialog GUI. One example of its usage is when the player clicks on the "Quit Game" button. This calls the following script:
bool bConfirmed = Prompt("Are you sure you want to QUIT? All unsaved progress will be lost.");
if (bConfirmed) {
QuitGame(0);
}
And here is the custom global "Prompt" function I have created:
function Prompt(String sMessage)
{
iYesNoResponse = -1;
lblDialog.Text = sMessage;
gYesNo.Transparency = 100;
gYesNo.Visible = true;
gYesNo.TweenTransparency(0.4, 0, eEaseInEaseOutTween, eBlockTween);
while (gYesNo.Visible) {
Wait(1);
}
if (iYesNoResponse == 1) {
return true;
} else {
return false;
}
}
I have a global variable iYesNoResponse that stores -1 when waiting for a response, 0 for "no", and 1 for "yes". The GUI itself is named gYesNo. And I'm using Edmundito's custom Tween module, which works perfectly.
The problem is, whenever gYesNo is called up, everything halts. I know it has to do with the Wait(1) command halting all scripts indefinitely... but how else should I do this? I want the gYesNo GUI to pop up, and I want the custom Prompt(...) function to return a boolean value depending upon the player's response.
Is there another, perhaps better, way to go about doing this? I can't seem to figure out the "right" way to do this.
Well having the Wait(1) is not exactly ideal but I'm not sure there's another way you could actually get the result returned from the same function...
One question I have is how exactly is your gYesNo GUI set up. Does it have yes and no as GUI buttons? Do you have a script in on_key_press to capture the keypresses for 'Y' and "N'? Perhaps a rep_ex_always script to capture the same?
Obviously if your condition depends on the visible state of the gYesNo GUI then you're updating that at the same time you are accepting the user input. The only thing I can really think of right now would be to have something like this:
if (gYesNo.Visible) {
if (IsKeyPressed('Y')) {
gYesNo.Visible = false;
iYesNoResponse = 1;
}
else if (IsKeyPressed('N')) {
gYesNo.Visible = false;
iYesNoResponse = 0;
}
}
Inside of repeatedly_execute_always. Of course that then only works with keypresses for the user-input, not button clicks (if that's how you were wanting to do it). Of course then you could check the raw state of the mouse buttons against the result of GUIControl.GetAtScreenXY...
It's a bit messy trying to get the delayed response result all within a single function...but definitely doable.
The Yes/No buttons do two things each: set the iYesNoResponse variable, and hide the gYesNo GUI.
Perhaps if the on_mouse_click() event were involved somehow... I'll have to look into that. Any other help would be greatly appreciated.
Are you going to use the YesNo GUI for five or so different questions, or more like 50?
Because if the former is the case, you could use an enum, like this:
// header
enum Question {
eQuit,
eRestart,
...
};
// global script
int _q;
function Prompt(String sMessage, Question q) {
lblDialog.Text = sMessage;
_q = q;
gYesNo.Transparency = 100;
gYesNo.Visible = true;
gYesNo.TweenTransparency(0.4, 0, eEaseInEaseOutTween, eBlockTween);
}
function btnYes_OnClick(...) {
if (_q == eQuit) QuitGame(0);
...
}
Ah, I see... have the Yes button do the real action. I was considering using enums instead.. even if there were 50, it would be doable.
I was just hoping that this could be modular... that I could use it in future projects without must tinkering. But I guess this works too. :)
EDIT:
Now there's a second issue, though it's not that big a deal... whenever a GUI fades in/out (by altering its Transparency) the buttons on all GUIs are greyed out. Is there a setting to change this?
There a setting in General settings to set the appearance of GUIs during blocking code.