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?
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:
if (IsGamePaused())
return;
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)?
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:
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)
}
}
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.
Difficulty Easy is just a variable that should be active in the new blank room.
Could you show full contents of your on_key_press function?
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;
}
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:
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.
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.
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"
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
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);
}
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.
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.
Sorry, I do want the player to move once the GUI has closed. Is there a way I can do this?
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
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...
// 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);
}
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.
if (player.Room==1) player.Walk(180, 170, eBlock, eAnywhere); // or whatever room you which it to run
Better?
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.
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(..);
}
}
Sorry, I'm new to programming. Could you explain that a little simpler? :P
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.
I think I understand. I'm using a key press rather than a button but I assume it will still work.