Purposely Blocking Scripts

Started by PTefft, Thu 29/04/2010 17:51:07

Previous topic - Next topic

PTefft

Hello all,

So, I am writing a game where I am planning to occasionally bring up a GUI when the player interacts with an object, etc. for something a bit comparable to a quick time event.  The GUI asks the player to perform a task and then the game does *something* based on whether they succeed or fail.  Here's a little snippet that I wrote to test this feature.

Code:

function hHotspot2_Interact()
{
    bringUpCardMatch();
   
    //wait for the GUI to close somehow

    if(lastCheckPassed == true)
    {
      Display ("Pass!");
    }
    else
    {
      Display ("Fail!");
    }
}

Where bringUpCardMatch() brings up the GUI, which pauses the game while visible, and then adjusts lastCheckPassed accordingly.  However, the room script just keeps going (which is to be expected) and hits the if statement long before the GUI can adjust lastCheckPassed.

The obvious solution is this:

function hHotspot2_Interact()
{
    bringUpCardMatch();
   
    while(gCardCheck.Visible){}


    if(lastCheckPassed == true)
    {
      Display ("Pass!");
    }
    else
    {
      Display ("Fail!");
    }
}

However, AGS hates it when you put together what appears to be a hung loop, and crashes.

I could try delegating the responsibility to the GUI to do whatever it needs to do, but that could make things very complicated, considering that this would be used in a variety of situations.  So, ideally, I should find some way to block the room script until this is done, without crashing the game.

Calin Leafshade

try

Code: ags

while(gCardCheck.Visible){Wait(1)}

Khris

Either check if the user has passed in the script of the button that closes the GUI or use CallRoomScript() & on_call(int param).

Snarky

#3
Reviving this thread since I'm facing a similar problem. In order to have keyboard shortcuts for dialog selection I've scripted the dialog structure as a state machine, and I'm trying to process it with this function:

Code: ags

void CrossExamine(StateMachine testimony)
{
  while(testimony.CurrentState != "exit")
  {
      ShowTestimony(testimony);                     // A method that displays the right line of dialog depending on where we are in the testimony
      gCrossExamine.Visible = true;        // This GUI has buttons to move back and forward in the testimony, press and object
      while(gCrossExamine.Visible == true)
         Wait(1);
  }
}


This works pretty well, except that Wait() makes the cursor disappear (goes to the Wait mode, which is blank), which makes it hard to hit the right button. (The obvious workaround for this would be to temporarily set the Wait cursor to mimic the Interaction cursor.)

If I understand Khris's alternative suggestion correctly, it's to drop the inner while loop and change the outer loop to an if, then call the method from all the places where gCrossExamine is turned off. My issue with this is that I couldn't call CrossExamine() as a blocking function in the middle of a script any more. I'd have to break it up and do some voodoo (well, check testimony.CurrentState in the repexec, I suppose) to get the following commands to run once it exited. (I was also worried about CrossExamine essentially calling itself recursively, possibly causing a stack overflow if the testimony goes on for long enough, but when I look at it now I see that it's not actually calling itself, even indirectly.)

I don't suppose there's another way to block a script? In the choice of these two solutions, which is the better? - Or have I overlooked another alternative?

Edit: I must have been doing something else when I tested it, because the code I posted up there does not work. As far as I can tell, after pretty extensive testing, you can't interact with GUI buttons at all during Wait(), or even during WaitMouseKey().

I used Khris's method instead, and got it to work.

SMF spam blocked by CleanTalk