Waiting for a popup

Started by SSH, Thu 10/02/2005 08:45:28

Previous topic - Next topic

SSH

Sometimes, I'd liek to ask the user a Yes/No or OK/Cancel kind of question, and I don't thin there's an easy way to script this. What I mean is, it woul dbe nice to have a function (builtin or user-defined) like:

if (AskYesNo("Overwrite savegame")) {
  // Do Yes
} else {
  // Do No
}

As it is , I can write a function that brings up a popup modal GUI and sets the label in it, but using the same function to wait for a reply from that GUI is not possible. Even using rep_ex_always, I can't get it to work. If you have a solution, please tell me, but if it means CJ needs to add something to AGS, then please coutn this as a  SUGGESTION!

Edit:

I've answered my own question: For a customisable confirm box, try my new DialogBox module.
12

Radiant

What I've done in the past is using 'callbacks'. What you do is initialize some variables that tell the interpreter which function to call once the player presses yes or no. That would commonly mean running some kind of interaction, or calling the room script.

for instance,
Code: ags

function hotspot_3_a () {
  if (action == MODE_USE) {
    CallYesNoBox (some text here, 3 /* hotspot number */)
  } else if (action == YES) {
     // do something
  } else if (action == NO) {
     display ("aborted");
  }
}


SSH

Now, if only we could pass function pointers as arguments.... we could do callbacks nicely! As it it you have to hardcode your fucntion names in somewhere, and I'm trying to make a generic module...

AskYesNo(string question, function *yesfn, function *nofn) would be nice;

Also, I notice that if you move gui control clcik functions into a module they don't work, even if you export/import them...  :'(
12

Ashen

#3
O.K. so I was meant to be cleaning out the garage, instead I've come up with this:

In the header:
Code: ags

	enum AnsyesNo { No, Yes, Ask};
	enum Question { Overwrite, Quit, //etc};
	import function AskYesNo (Question quest, AnsYesNo response);


2. In the script:
Code: ags

	int asked;

	function AskYesNo (Question quest, AnsYesNo response) {
	Ã,  asked = quest; // Stores question for Answer run
	Ã,  if (quest == Quit) { // For example
	Ã,  Ã,  if (response == Ask) {
	Ã,  Ã,  Ã,  LblAsk.SetText ("Are you sure you want to quit?");
	Ã,  Ã,  Ã,  BtnAskYes.SetText ("Quit");
	Ã,  Ã,  Ã,  BtnAskNo.SetText ("Play");
	Ã,  Ã,  Ã,  gAskgui.Visible = true;
	Ã,  }
	Ã,  Ã,  if (response == Yes) {
	Ã,  Ã,  Ã,  QuitGame (0);
	Ã,  Ã,  }
	Ã,  Ã,  if (response == No) {
	Ã,  Ã,  Ã,  gAskgui.Visible = false;
	Ã,  Ã,  }
	Ã,  }
	}


3. In interface_click (object 0 = the label 'LblAsk', object 1 = yes button 'BtnAskYes', object 2 = no button 'BtnAskNo'):
Code: ags

	if (interface == ASKGUI) {
	Ã,  if (button == 1) AskYesNo (asked, Yes);
	Ã,  if (button == 2) AskyesNo (asked, No);
	}



A little explanation:
The function is in two parts - question and answer. If AnsyesNo is passed as 'Ask', the function sets up the ASKGUI - sets the label text and Yes/No button text (Quit/Play, Overwrite/Cancel, etc), and turns the GUI on. If AnsYesNo is passed as Yes or No (i.e. by the GUI buttons) it responds accordingly.

For convenience, I've enum-ed the possible questions and answers (Yes/No/Ask), and I've used the OO scripting style, but it should be easy to reverse engineer, if anyone wants to.

It's probably a little clunky, but it works (for me, anyway). Feel free to modify, or to ask if anything doesn't make sense.

(EDIT: Corrected interface_click script)
I know what you're thinking ... Don't think that.

TheMagician

As I have not yet looked into OO scripting and I want to stay updated (pretty hard these daysÃ,  ;) ) I'd like to ask you a few questions, Ashen, regarding your code.
I get the general idea but there are some details which I don't understand:

Quote
enum AnsyesNo { No, Yes, Ask};
enum Question { Overwrite, Quit, //etc};
import function AskYesNo (Question quest, AnsYesNo response);

the first two lines set up the enums. I get that. But what does the last line do?
Does it create a function which stores the value of the "Question enum" in a varibale called "quest" and the value of "AnsYesNo enum" in a variable called "response"?

Quote
int asked;
function AskYesNo (Question quest, AnsYesNo response) {
Ã,  asked = quest; // Stores question for Answer run
Ã,  if (quest == Quit) { // For example
Ã,  Ã,  if (response == Ask) {

So, the "asked" int is for another function called "Answer" which is called at a later time to respond to the players click?
When is "response" set to "Ask"?Ã,  Is that the default value?

Quote
if (interface == ASKGUI) {
Ã,  if (button == 1) Answer (asked, Yes);
Ã,  if (button == 2) Answer (asked, No);

Ok, I don't get that part. Right now the "asked" int is set to "quest", isn't it?
Now if I klick on the Yes button (button 1) a new function "Answer" is called with two parameters .... naa ... I think I just don't understand it.

Ashen, if you would be so kind and make the code a little clearer to a noob. That would be really great!

Ashen

#5
TheMagician:
No problem, I figured there'd be a few bits I didn't explain properly.

1.
No, it imports the AskYesNo () function (as created in the global script, in your second quote) so it can be used anywhere in game, e.g. on hotspots, objects, etc. If you're only likely to use the function in GUIs, I don't think you even need this line.

2.
Ask is one of the options for the AnsYesNo enum. When you set response to Ask (e.g. AskYesNo (Quit, Ask);), you're telling the function that it's asking the question, rather than replying.
The 'Answer run' refers to the second time the function is called, by the GUI buttons. 'asked' is a global int storing the question that had been asked, to pass in the 'Answer run' (see below).

3.
Eeep! That's what you get for working across AGS and 2 instances of Notepad. The 'Answer' function was an earlier way I had this working, which doesn't exist any more. That bit should be:
Code: ags

if (interface == ASKGUI) {
Ã,  if (button == 1) AskYesNo (asked, Yes);
Ã,  if (button == 2) AskYesNo (asked, No);

Thanks for pointing that out! I'll edit my first post in a minute.
Yes, asked is set to quest - it's the only way I could think of to track which question had been asked.

Would it be usefull to you, if I worked out and posted the non-OO version of the script? Obviously, you wouldn't be able to use enums, but the rest of it should work, and it might give you a better idea what's going on.

EDIT: Got bored, made something else.
AskYesNo Module
Zip contains:
Ã,  Ã,  Ã,  - Importable AskYesNo module.
Ã,  Ã,  Ã,  - Documentation. Really bad documentation.
Ã,  Ã,  Ã,  - Non-OO Script, with equally bad documentation.
Enjoy.
I know what you're thinking ... Don't think that.

TheMagician

Aha!  :D  I read through it now another three times ... and now I completely understand it!

So all you have to do is ... in your local room script write for example  "AskYesNo (Quit, Ask);"  ... the function in the global script (which was imported by the header) is called and executed according to the "question" int (i.e. "Quit")  .... then you click on one of the buttons "Yes" or "no" on the GUI ... the function "AskYesNo" gets run again with the same "question" int as before but now with the according action for the button.

I feel really good now  ;)   Many thanks for explaining it to me!

btw, Ashen you will be in the "special thanks" credits of my soon-to-be-released-three-years-in-the-making game (hehe ridiculous ... 3 years for 20 rooms ...and it even uses the Roger character  :P ) for helping me with many scripting problems! ... Now it's your turn to feel really good  ;D

Pumaman

Quote from: SSH on Thu 10/02/2005 08:45:28
Sometimes, I'd liek to ask the user a Yes/No or OK/Cancel kind of question, and I don't thin there's an easy way to script this.

Yeah, the problem is because if you had a blocking pop-up GUI function, then the interface_click wouldn't get called since the script was blocked, so the GUI would never get removed, and it would all lock up.

This would be a handy use for function pointers, and I will consider them for a future version.

SMF spam blocked by CleanTalk