Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: TDBFW1 on Sun 15/10/2017 16:11:37

Title: GUI blocking keys
Post by: TDBFW1 on Sun 15/10/2017 16:11:37
I'm doing this in a new game in a default game for testing:


function room_AfterFadeIn()
{
gTest.Visible=true;
mouse.Mode=eModePointer;
}


In the Globalscript:


   if (keycode == eKeyN) gTest.Visible = !gTest.Visible;


However, the GUI doesn't close when I push "N". BTW, the GUI visibility is on pause game when shown. Any help?
Title: Re: GUI blocking keys
Post by: Crimson Wizard on Sun 15/10/2017 17:08:50
Quote from: TDBFW1 on Sun 15/10/2017 16:11:37
However, the GUI doesn't close when I push "N". BTW, the GUI visibility is on pause game when shown. Any help?

Actually I asked this in your previous forum thread, but you did not reply: http://www.adventuregamestudio.co.uk/forums/index.php?topic=55259.msg636571292#msg636571292

Check if you have something like this in on_key_press:

Code (ags) Select

if (IsGamePaused())
    return;
Title: Re: GUI blocking keys
Post by: TDBFW1 on Sun 15/10/2017 17:15:06
Yes I do, actually:

  if (IsGamePaused() || (IsInterfaceEnabled() == 0))
  {
    // If the game is paused with a modal GUI on the
    // screen, or the player interface is disabled in
    // a cut scene, ignore any keypresses.
    return;
  }

What should I do about it (It's in the default game)?
Title: Re: GUI blocking keys
Post by: Crimson Wizard on Sun 15/10/2017 17:22:40
This condition is there to disable certain key shortcuts that are only allowed to work when no blocking GUI is shown (such as toggling cursor modes, for example).

I suggest splitting this function in parts, each for possible state of your game, for example:
- When your GUI dialog is shown;
- When no blocking GUI is shown;
- other...

Something like:
Code (ags) Select

function on_key_press(eKeyCode keycode)
{
    if (gTest.Visible)
    {
        // Only check for keys that should work in gTest dialog
    }
    else if (IsGamePaused())
    {
        // Check for keys that should work when any other blocking GUI is shown
    }
    else
    {
        // Only check for keys that should work during regular gameplay (no blocking GUIs shown)
    }
}
Title: Re: GUI blocking keys
Post by: TDBFW1 on Mon 16/10/2017 19:28:09
I tried something like this, in my original game with a GUI called gNotebook:


  if ((keycode == eKeyN) &&
(DifficultyEasy))
{
  if ((gNotebook.Visible) &&
  (IsGamePaused()))
  {
    gNotebook.Visible=false;
  }
  else if (!gNotebook.Visible) gNotebook.Visible=true;
  else
  {
    gNotebook.Visible=false;
  }
}

It still doesn't work and I don't know why.
Title: Re: GUI blocking keys
Post by: TDBFW1 on Mon 16/10/2017 19:31:27
Difficulty Easy is just a variable that should be active in the new blank room.
Title: Re: GUI blocking keys
Post by: Crimson Wizard on Mon 16/10/2017 19:44:39
Could you show full contents of your on_key_press function?
Title: Re: GUI blocking keys
Post by: TDBFW1 on Mon 16/10/2017 19:52:58

function on_key_press(eKeyCode keycode) {
  // The following is called before "if game is paused keycode=0", so
  // it'll happen even when the game is paused.
 
  if ((keycode == eKeyEscape) && gRestartYN.Visible) {
    //Use ESC to cancel restart.
    gRestartYN.Visible = false;
    gIconbar.Visible = true;
    // If the panel's not ON, then the player must have gotten here by tapping F9,
    // therefore his cursor needs restoring. If the panel IS on, then it doesn't,
    // because it's already a pointer. Get used to thinking like this!!
    if (!gPanel.Visible) mouse.UseDefaultGraphic();
    return;
  }
  if ((keycode == eKeyEscape) && gPanel.Visible) {
    // Use ESC to turn the panel off.
    gPanel.Visible = false;
    mouse.UseDefaultGraphic();
    gIconbar.Visible = true;
    return;
  }
  if ((keycode == eKeyEscape) && (gSaveGame.Visible))
  {
    // Use ESC to close the save game dialog
    close_save_game_dialog();
    return;
  }
  if ((keycode == eKeyEscape) && (gRestoreGame.Visible))
  {
    // Use ESC to close the restore game dialog
    close_restore_game_dialog();
    return;
  }
 
  if (keycode == eKeyReturn) {
    // ENTER, in this case merely confirms restart
    if (gRestartYN.Visible) RestartGame();
  }

  if (IsGamePaused() || (IsInterfaceEnabled() == 0))
  {
    // If the game is paused with a modal GUI on the
    // screen, or the player interface is disabled in
    // a cut scene, ignore any keypresses.
    return;
  }

  // FUNCTION KEYS AND SYSTEM SHORTCUTS
  if (keycode == eKeyEscape) {
    // ESC
    gPanel.Visible = true;
    gIconbar.Visible = false;
    mouse.UseModeGraphic(eModePointer);
  }
  if (keycode == eKeyCtrlQ)  QuitGame(1);   // Ctrl-Q
  if (keycode == eKeyF5) show_save_game_dialog();   // F5
  if (keycode == eKeyF7) show_restore_game_dialog();  // F7
  if (keycode == eKeyF9) {
    // F9, asks the player to confirm restarting (so much better to always confirm first)
    gRestartYN.Visible = true; 
    gIconbar.Visible = false;
    mouse.UseModeGraphic(eModePointer);
  }
  if (keycode == eKeyF12) SaveScreenShot("scrnshot.bmp");  // F12
  if (keycode == eKeyTab)   show_inventory_window();  // Tab, show inventory

  if ((keycode == eKeyN) &&
(DifficultyEasy))
{
  if ((gNotebook.Visible) &&
  (IsGamePaused()))
  {
    gNotebook.Visible=false;
  }
  else if (!gNotebook.Visible) gNotebook.Visible=true;
  else
  {
    gNotebook.Visible=false;
  }
}

  // GAME COMMAND SHORTCUTS
  if (keycode == 'W') mouse.Mode=eModeWalkto; //Notice this alternate way to indicate keycodes.
  if (keycode == 'L') mouse.Mode=eModeLookat; //Note that all we do here is set modes.
  if (keycode == 'U') mouse.Mode=eModeInteract; //If you want something else to happen, such as GUI buttons highlighting,
  if (keycode == 'T') mouse.Mode=eModeTalkto; //you'll need some more scripting done.
  if (keycode == 'I') mouse.Mode=eModeUseinv; //But this will, as-is, give you some standard keyboard shortcuts your players will very much appreciate.

  // For extra cursor modes, such as pick up, feel free to add as you will.
  // Uncomment the line below if you use the "Pick Up" mode.
  //if (keycode == 'P' || keycode == 'G') mouse.Mode=eModePickup;

  // DEBUG FUNCTIONS
  if (keycode == eKeyCtrlS)  Debug(0,0);  // Ctrl-S, give all inventory
  if (keycode == eKeyCtrlV)  Debug(1,0);  // Ctrl-V, version
  if (keycode == eKeyCtrlA)  Debug(2,0);  // Ctrl-A, show walkable areas
  if (keycode == eKeyCtrlX)  Debug(3,0);  // Ctrl-X, teleport to room
  if (keycode == eKeyCtrlW && game.debug_mode)
    player.PlaceOnWalkableArea(); //Ctrl-W, move to walkable area

}


The code for the room is just this:

function room_AfterFadeIn()
{
gNotebook.Visible=true;
}

function room_Load()
{
DifficultyEasy=true;
}
Title: Re: GUI blocking keys
Post by: Crimson Wizard on Mon 16/10/2017 19:58:44
You still have IsGamePaused() check before checking for N key. This means that whenever game is paused it won't even get to 'N' key check (or anything else beyond IsGamePaused()).

I mean those lines:
Code (ags) Select

  if (IsGamePaused() || (IsInterfaceEnabled() == 0))
  {
    // If the game is paused with a modal GUI on the
    // screen, or the player interface is disabled in
    // a cut scene, ignore any keypresses.
    return;
  }


You could remove it, but the problem is that if you do, then all other keys will also work while gNotebook is visible (such as eKeyCtrlQ, eKeyF5, and so on).

For that reason, I suggest to split the function into logical if/else blocks, where each will be executed only in particular game mode, similar to an example I showed in my previous post.
Title: Re: GUI blocking keys
Post by: TDBFW1 on Mon 16/10/2017 20:11:30
This works:

function on_key_press(eKeyCode keycode)
{
    if (gNotebook.Visible)
    {
  if ((keycode == eKeyN) &&
  (DifficultyEasy))
  {
    gNotebook.Visible=false;
  }
  else
    {
  if ((keycode == eKeyEscape) && gRestartYN.Visible) {
    //Use ESC to cancel restart.
    gRestartYN.Visible = false;
    gIconbar.Visible = true;
    // If the panel's not ON, then the player must have gotten here by tapping F9,
    // therefore his cursor needs restoring. If the panel IS on, then it doesn't,
    // because it's already a pointer. Get used to thinking like this!!
    if (!gPanel.Visible) mouse.UseDefaultGraphic();
    return;
  }
  if ((keycode == eKeyEscape) && gPanel.Visible) {
    // Use ESC to turn the panel off.
    gPanel.Visible = false;
    mouse.UseDefaultGraphic();
    gIconbar.Visible = true;
    return;
  }
  if ((keycode == eKeyEscape) && (gSaveGame.Visible))
  {
    // Use ESC to close the save game dialog
    close_save_game_dialog();
    return;
  }
  if ((keycode == eKeyEscape) && (gRestoreGame.Visible))
  {
    // Use ESC to close the restore game dialog
    close_restore_game_dialog();
    return;
  }
 
  if (keycode == eKeyReturn) {
    // ENTER, in this case merely confirms restart
    if (gRestartYN.Visible) RestartGame();
  }

  // FUNCTION KEYS AND SYSTEM SHORTCUTS
  if (keycode == eKeyEscape) {
    // ESC
    gPanel.Visible = true;
    gIconbar.Visible = false;
    mouse.UseModeGraphic(eModePointer);
  }
  if (keycode == eKeyCtrlQ)  QuitGame(1);   // Ctrl-Q
  if (keycode == eKeyF5) show_save_game_dialog();   // F5
  if (keycode == eKeyF7) show_restore_game_dialog();  // F7
  if (keycode == eKeyF9) {
    // F9, asks the player to confirm restarting (so much better to always confirm first)
    gRestartYN.Visible = true; 
    gIconbar.Visible = false;
    mouse.UseModeGraphic(eModePointer);
  }
  if (keycode == eKeyF12) SaveScreenShot("scrnshot.bmp");  // F12
  if (keycode == eKeyTab)   show_inventory_window();  // Tab, show inventory
    }
  // GAME COMMAND SHORTCUTS
  if (keycode == 'W') mouse.Mode=eModeWalkto; //Notice this alternate way to indicate keycodes.
  if (keycode == 'L') mouse.Mode=eModeLookat; //Note that all we do here is set modes.
  if (keycode == 'U') mouse.Mode=eModeInteract; //If you want something else to happen, such as GUI buttons highlighting,
  if (keycode == 'T') mouse.Mode=eModeTalkto; //you'll need some more scripting done.
  if (keycode == 'I') mouse.Mode=eModeUseinv; //But this will, as-is, give you some standard keyboard shortcuts your players will very much appreciate.

  // For extra cursor modes, such as pick up, feel free to add as you will.
  // Uncomment the line below if you use the "Pick Up" mode.
  //if (keycode == 'P' || keycode == 'G') mouse.Mode=eModePickup;

  // DEBUG FUNCTIONS
  if (keycode == eKeyCtrlS)  Debug(0,0);  // Ctrl-S, give all inventory
  if (keycode == eKeyCtrlV)  Debug(1,0);  // Ctrl-V, version
  if (keycode == eKeyCtrlA)  Debug(2,0);  // Ctrl-A, show walkable areas
  if (keycode == eKeyCtrlX)  Debug(3,0);  // Ctrl-X, teleport to room
  if (keycode == eKeyCtrlW && game.debug_mode)
    player.PlaceOnWalkableArea(); //Ctrl-W, move to walkable area

}
}

But if I add this:

if ((keycode == eKeyN) &&
(DifficultyEasy))
{
gNotebook.Visible=!gNotebook.Visible;
}

at the end of the initial "else" statement (I.e. where all the other keycodes live), it doesn't work.
Title: Re: GUI blocking keys
Post by: Crimson Wizard on Mon 16/10/2017 21:05:40
I think you have a mistake at the first "else", you did not close the very first condition "if (gNotebook.Visible)", and now all other keys are checked only if notebook is open.
You need to add one more closing bracket "}" before first else, and remove one unnecessary bracket after line "if (keycode == eKeyTab)   show_inventory_window();  // Tab, show inventory"
Title: Re: GUI blocking keys
Post by: TDBFW1 on Tue 17/10/2017 20:40:17
Thanks so much! I had no idea why it wasn't working. Sorry for being a bit slow to realise what you were getting at, I'm a little late to coding.:-D
Title: Re: GUI blocking keys
Post by: TDBFW1 on Tue 17/10/2017 21:15:11
Sorry, but a related question: Why doesn't this work?

function room_AfterFadeIn()
{
mouse.Mode=eModePointer;
gNotebook.Visible=true;
if (!gNotebook.Visible) player.Walk(180, 170, eBlock, eAnywhere);
}
Title: Re: GUI blocking keys
Post by: Crimson Wizard on Tue 17/10/2017 21:34:58
Quote from: TDBFW1 on Tue 17/10/2017 21:15:11
Sorry, but a related question: Why doesn't this work?

If you mean why player is not walking, you are setting Notebook.Visible to true, and then immediately do player.Walk under condition if Notebook.Visible is false (which never happen at this point).
I cannot even guess what you were trying to do this way.
Title: Re: GUI blocking keys
Post by: Khris on Wed 18/10/2017 11:15:37
If the idea is to make the player Walk after the GUI was closed by the user, I don't think it'll work that way.
Even if gNotebook is a modal GUI, it won't stop execution mid-function.

Describe what you goal is, and we can provide solutions.
Title: Re: GUI blocking keys
Post by: TDBFW1 on Wed 18/10/2017 20:51:26
Sorry, I do want the player to move once the GUI has closed. Is there a way I can do this?
Title: Re: GUI blocking keys
Post by: Khris on Wed 18/10/2017 22:00:22
Here's one way:
// above and outside the functions mentioned below
bool playerWalked;

  // in room_Load
  playerWalked = false; // upon entering the room, reset variable

  // in room_Rep_Exec
  if (!playerWalked && !gNotebook.Visible) {
    player.Walk(180, 170, eBlock, eAnywhere);
    playerWalked = true;
  }


The variable makes sure this happens a) every time the room is visited but b) only once
Title: Re: GUI blocking keys
Post by: Cassiebsg on Thu 19/10/2017 11:58:16
Couldn't he just add the line to the close gNotebook function instead of using Rep_Exec?
And if it' only to happen once, then use Game.DoOnceOnly...

Code (ags) Select

// whatever your function is called
{
    // ... eventually other code
    gNotebook.Visible=false;
    if (Game.DoOnceOnly("Walk only the 1st time the gNotes closes")) player.Walk(180, 170, eBlock, eAnywhere);
}
Title: Re: GUI blocking keys
Post by: Khris on Thu 19/10/2017 12:05:14
Sure, but I'm assuming this code is specific to a single room. That's why I chose to keep it inside the room script.
As for using Game.DoOnceOnly, I'm also assuming this code is supposed to run each time the room is entered, given that TDBFW1 put it in room_AfterFadeIn(). Therefore it needs to run more than once total.
Title: Re: GUI blocking keys
Post by: Cassiebsg on Thu 19/10/2017 12:34:24

    if (player.Room==1) player.Walk(180, 170, eBlock, eAnywhere); // or whatever room you which it to run


Better?
Title: Re: GUI blocking keys
Post by: TDBFW1 on Thu 19/10/2017 20:19:57
Thanks a lot for the suggestions. However, in one of my rooms (Not the test room with the code given), it needs to run during room_Rep_exec. This stems from a workaround. As SetRestartPoint() only restarts the game after a non-blocking loop, and my room immediately starts with a blocking script (I.e, a cutscene), I've set up a timer for one loop (To restart the game) and put the rest in room_Rep_exec, something like this:


function room_FirstLoad()
{
SetRestartPoint();
SetTimer(1, 1);
}

function room_RepExec()
{
if (IsTimerExpired(1))
{
int ran=Random(3);
if (ran == 0)
{
  HallRan=true;
  aGrandfather_Clock.Play(eAudioPriorityLow, eRepeat);
  Wait(20);
  cMaid.Say("Looks like I don't have to wind up the grandfather clock.");
  ClockPlaying=true;
  Wait(20);
  blink();
  cMaid.Say("Now which cup did the chef ask for?");
  cMaid.Walk(140, 190, eBlock);
  cMaid.FaceDirection(eDirectionRight, eBlock);
  Wait(40);
  oPinkCup.Visible=false;
  cMaid.Say("That's the one!");
  Wait(20);
  cMaid.Say("Now isn't there another thing the chef asked for?");
  blink();
  oVase.Visible=false;
  Wait(20);
  cMaid.Walk(257, 195, eBlock);
  cMaid.Say("Now I'm ready to go to the chef.");
  if (DifficultyEasy)
  {
    mouse.Mode=eModePointer;
    gNotebook.Visible=true;
  }
}
etc.
Now I don't know where to put the code in my script. Is it better to put it in Globalscript? Is there a better way to restart a room? Or should I just put the code for when the notebook is closed at the end of my room_Rep_exec function?

Sorry for the long post, it's become a bit of a mess.

BTW, you can see where the notebook closed code is meant to slot in, in the DifficultyEasy section.
Title: Re: GUI blocking keys
Post by: Khris on Thu 19/10/2017 21:40:01
If you want to do something after the user closes the notebook in more than one room, you can use CallRoomScript().
In the button handler (I assume) in the global script, where you turn gNotebook back to invisible, add CallRoomScript(1);
Then add this to your room script:
function on_call(int param) {
  if (param == 1) {
    player.Walk(..);
  }
}
Title: Re: GUI blocking keys
Post by: TDBFW1 on Sat 21/10/2017 13:43:59
Sorry, I'm new to programming. Could you explain that a little simpler? :P
Title: Re: GUI blocking keys
Post by: Khris on Sat 21/10/2017 13:57:54
I assume you have a button on gNotebook that closes it? In that case you should have something like this in your GlobalScript:

function btnCloseNotebook_OnClick(GUIControl* control, MouseButton button) {
  gNotebook.Visible = false;
}


What you do is add a line to that:

function btnCloseNotebook_OnClick(GUIControl* control, MouseButton button) {
  gNotebook.Visible = false;
  CallRoomScript(1);
}


This line makes AGS call on_call(1); in the current room's script.
Which means you can use this to run commands right after the user closes the Notebook (or some other global event).

You do this by adding the on_call function to your room script. Consider it the room's "user closes notebook" event.

function on_call(int param) {
  if (param == 1) {
     player.Walk(180, 170, eBlock, eAnywhere);
  }
}


The parameter is there in case you want to also use this mechanism for other things. It's like with timers.
Title: Re: GUI blocking keys
Post by: TDBFW1 on Sat 21/10/2017 19:30:56
I think I understand. I'm using a key press rather than a button but I assume it will still work.