Yes/No Button blocking or delay problem

Started by rockitship, Mon 26/12/2011 09:25:36

Previous topic - Next topic

rockitship

Hello, I'm very new to AGS so I've been working very simply to get a feel for scripting. I am trying to create a yes no button for any situation. in this case giving the player the option to look closer or not, but really I want to use it for combining items and other interactions. I believe my problem has to do with something i don't understand about the blocking. The problem comes from the results trying to run simultaneously with the function bringing up the GUI.

First I created a GUI with two buttons, then made the yes or no function, imported the function, and made the global variable, and was able to get the question to appear at the appropriate time. Then I ran into a problem. At first clicking the button appeared to do nothing. clicking a second time would also result in nothing. When I take out the line that resets the variable back to neutral I get a different result. On the first try there is nothing, but on try to i get the original desired result at the same time as the GUI appears. Most likely because the variable was set from the first click.

so first the global script

function show_yes_no()
{
  vYon = -1; // this resets the variable back to neutral, and may be part of the problem
  gYON.Visible = true;
  mouse.UseModeGraphic(eModePointer);
}

function Yes_OnClick(GUIControl *control, MouseButton button)
{
vYon = 1;
gYON.Visible = false;
mouse.UseDefaultGraphic();
}

function No_OnClick(GUIControl *control, MouseButton button)
{
vYon = 0;
gYON.Visible = false;
mouse.UseDefaultGraphic();
}

then the room script

//sheets
function hsheets_Look()
{
  Display("A thread bare sheet that smells of mold.");
  Display("Look under the sheet?");
  show_yes_no();
  if (vYon == 1) Display("Eww");
  else if (vYon == 0) Display("Good idea.");
}

Thanks for taking a look.

Khris

The reason for why this doesn't work is that the hsheets_Look function continues to run, so when the value of vYon is tested, it is still -1.
Then when you click one of the buttons, it is changed, and the next time you look at the sheets, that choice is processed, again without waiting for you to click one of the buttons.

Using a loop to wait for the choice won't work either because the buttons are disabled during a loop.

What does work is process the choice separately:

Code: ags
int crs;  // CallRoomScript parameter

function show_yes_no(int p)           // import function show_yes_no(int p); in Global.ash
{
  vYon = -1;
  gYON.Centre();
  gYON.Visible = true;
  mouse.UseModeGraphic(eModePointer);
  crs = p;
}

function Yes_OnClick(GUIControl *control, MouseButton button)
{
  vYon = 1;
  gYON.Visible = false;
  mouse.UseDefaultGraphic();
  CallRoomScript(crs);
}

function No_OnClick(GUIControl *control, MouseButton button)
{
  vYon = 0;
  gYON.Visible = false;
  mouse.UseDefaultGraphic();
  CallRoomScript(crs);
}


In the room script, split the script like this:

Code: ags
//sheets
function hsheets_Look()
{
  Display("A thread bare sheet that smells of mold.");
  Display("Look under the sheet?");
  show_yes_no(1);
}

function on_call(int p) {           // called by CallRoomScript()
  if (p == 1) {
      if (vYon == 1) Display("Eww");
      else Display("Good idea.");
  }
}


Now if you want to implement a second confirmation in the same room, use show_yes_no(2); and add a if (p == 2) block to on_call.

To make the code more readable you can use an enum instead of numbers:
Code: ags
 // top of room script
enum YesNo {
  eYNSheets
  ...
};

  ...
  show_yes_no(eYNSheets);
  ...
  if (p == eYNSheets) {
  ...

rockitship

#2
Thanks, that works great for 90% of my functions. Is there a global equivalent of CallRoomScript, or would I have to make a separate global yes/no button?

The situation i'm still having trouble with is for inventory interactions. Since they occur in the global script the CRS won't reach them. For now I have just created a craft station and tied the combining functions to that room.


So this is my working item combining code
Code: ags

function iTGlove1_UseInv()
{
  if (cEgo.ActiveInventory == iBattery)
  {
    if (cEgo.Room == 1)
    {
      gInventory.Visible = false;
      show_yes_no(eYNTGlove1);
    }
    else
    {
      gInventory.Visible = false;
      Display ("'Note to self, make screwdriver gloves' For now you should go back to your craftbench.");
    }  
  }
}


and then this is in the rooms on_call function
but I'd like this to run in the global script.

Code: ags

else if (vP == eYNTGlove1)
  {
    if (vYon == 1)
    {
      cEgo.LoseInventory(iTGlove1);
      cEgo.LoseInventory(iBattery);
      cEgo.AddInventory(iTGlove2);
      Display("The glove powers up, your arm starts to tingle.");
      gInventory.Visible = true;
    }
    else
    {
      gInventory.Visible = true;
    }
  }


ideally i'd like to be able to combine items anywhere, i.e. screwdriver gloves. Thanks again for tipping me off to function on_call, when I read CallRoomScript in the manual I didn't really understand it. Now i see possibilities.

Khris

There's no global equivalent, but you can simply call a function in the global script directly, as long as it is defined further up in the script.

Code: ags
function ProcessYesNo(int p) {

  if (p == -1) {
    if (vYon == 1)
    {
      cEgo.LoseInventory(iTGlove1);
      cEgo.LoseInventory(iBattery);
      cEgo.AddInventory(iTGlove2);
      Display("The glove powers up, your arm starts to tingle.");
      gInventory.Visible = true;
    }
    else
    {
      gInventory.Visible = true;
    }
  }
  ...
}


And further down, inside the two button functions:

Code: ags
  if (crs > 0) CallRoomScript(crs);
  else ProcessYesNo(crs);


Now use negative numbers for global interactions i.e. with Characters and InvItems.

rockitship

Great! I figured it was something along those lines, thanks alot for the detailed explanation. Next up are dialog trees.

SMF spam blocked by CleanTalk