Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: HillBilly on Thu 18/05/2006 22:21:31

Title: Help me out on my save/load GUI
Post by: HillBilly on Thu 18/05/2006 22:21:31
It's been ages since I've tried making my own save/load GUI, and I didn't really get it back then either. I've searched the forums alot today, looking for different solutions. I never managed to even get to the whole "testing" part, since it was always some error I did in the global script. I also found the link to Greek AGS Community's old save/load toturial, but it seems to be out of order.

I'm using AGS v. 2.62.509.0, by the way. Before the whole "code change" deal. I could really use a simple step-by-step toturial right now, or an importable gui I could snatch the code from. I really don't want anything fancy, I just want to change the graphics.

I feel bad about posting this, since I don't got anything to show for myself, but I don't know where else to turn. If anyone could help me out on a simple 3-5 slot save/load system, I'd be very grateful.
Title: Re: Help me out on my save/load GUI
Post by: GarageGothic on Thu 18/05/2006 22:40:57
Maybe you could use SSHs savegame with screenshots module: http://www.adventuregamestudio.co.uk/yabb/index.php?topic=23320.0

Not sure if it suits your purposes since I've never tried it.
Title: Re: Help me out on my save/load GUI
Post by: strazer on Thu 18/05/2006 23:10:51
GG, script modules are only supported since AGS v2.70.
Title: Re: Help me out on my save/load GUI
Post by: GarageGothic on Thu 18/05/2006 23:44:45
Oops, sorry didn't notice that. Would upgrading the game to 2.72 be a problem if you just unchecked the enforce oo-scripting and new strings boxes?

Otherwise, here's the code from the Greek AGS Community site. I can't get the link to work either, but I had it saved on my HD:

GUI 0 (Restore interface) :
Object 0 : List Box
Object 1 : Button (cancel)

GUI 1 (Save interface) :
Object 0 : Textbox
Object 1 : Label (Save game name)
Object 2 : Button (cancel)
Object 3 : ListBox

GLOBAL SCRIPT :


string text;

int index;



function on_key_press(int keycode) {



if (keycode==363) {
// Press F5

SetTextBoxText(1,0,"");
// Clear Text box

ListBoxSaveGameList(1,3);
// Fill List Box with saved games

index=ListBoxGetNumItems(1,3);
// Count how many saved games there are           

if (index>19){
// If saved games 20 (maximum)

Display("You must overwrite a previous saved game");
// Display warning

}

InterfaceOn(1);
// Bring Save interface on             

}



if (keycode==365) {
// Press F7

ListBoxSaveGameList(0,0);
// Fill List box with saved games 

InterfaceOn(0);
// Bring restore Interface on

}





function interface_click(int interface, int button) {

if (interface==0) {
// if Restore interface

if (button==1) {
// if cancel is pressed

InterfaceOff(0);
// Close interface

else { index=ListBoxGetSelected(0,0);
// else get the selected game

RestoreGameSlot(savegameindex[index]);}
// restore the game

}
}



if (interface==1) {
// if save interface

if (button==0) {
// if enter is pressed 

index=ListBoxGetNumItems(1,3);
// Count saved games 

if (index<20) {
// if less than 20

GetTextBoxText(1,0,text);
// Get the typed text

InterfaceOff(1);
// Close interface

SaveGameSlot(index+1,text); }
// Save game (text as description)

else {
// if saved games are 20

index=ListBoxGetSelected(1,3);
// Get the selected save game

GetTextBoxText(1,0,text);
// Get the typed text

InterfaceOff(1);
// Close the interface

SaveGameSlot(savegameindex[index],text); }
// Overwrite the selected game



}

if (button==2) InterfaceOff(1);
// if cancel is pressed close interface

Title: Re: Help me out on my save/load GUI
Post by: HillBilly on Fri 19/05/2006 12:57:08
Thanks, GG. I managed to code it in without much of a problem.

However, I still got three issues I need help with:

1. I can't overwrite save games. I've fiddled around, but I can't figure it out. I'm guessing I need another button? Here's the code(GUI 6 is LOAD, while GUI 7 is SAVE):

#sectionend repeatedly_execute  // DO NOT EDIT OR REMOVE THIS LINE

  string text;

int index;
function show_inventory_window () {
  // This demonstrates both types of inventory window - the first part is how to
  // show the built-in inventory window, the second part uses the custom one.
  // Un-comment one section or the other below.
 
  // ** DEFAULT INVENTORY WINDOW
  InventoryScreen();
/* 
  // ** CUSTOM INVENTORY WINDOW
  GUIOn (INVENTORY); 
  // switch to the Use cursor (to select items with)
  SetCursorMode (MODE_USE);
  // But, override the appearance to look like the arrow
  SetMouseCursor (6);
*/
}

#sectionstart on_key_press  // DO NOT EDIT OR REMOVE THIS LINE
function on_key_press(int keycode) {
  // called when a key is pressed. keycode holds the key's ASCII code
  if (IsGamePaused() == 1) keycode=0;  // game paused, so don't react to keypresses
  if (keycode==17)  QuitGame(1);   // Ctrl-Q
  if (keycode==367) RestartGame();  // F9
  if (keycode==434) SaveScreenShot("scrnshot.bmp");  // F12
  if (keycode==9)   show_inventory_window();  // Tab, show inventory

  if (keycode==19)  Debug(0,0);  // Ctrl-S, give all inventory
  if (keycode==22)  Debug(1,0);  // Ctrl-V, version
  if (keycode==1)   Debug(2,0);  // Ctrl-A, show walkable areas
  if (keycode==24)  Debug(3,0);  // Ctrl-X, teleport to room
  if (keycode==363) {
// Press F5

SetMouseCursor (6);
// Sets cursormode 6

PauseGame();
//Pauses the game

SetTextBoxText(7,0,"");
// Clear Text box

ListBoxSaveGameList(7,3);
// Fill List Box with saved games

index=ListBoxGetNumItems(7,3);
// Count how many saved games there are           

if (index>19){
// If saved games 20 (maximum)

Display("You must overwrite a previous saved game");
// Display warning

}

InterfaceOn(7);
// Bring Save interface on             

}



if (keycode==365) {
// Press F7

SetMouseCursor (6);
// Sets cursormode 6

PauseGame();
//Pauses the game

ListBoxSaveGameList(6,0);
// Fill List box with saved games

InterfaceOn(6);
// Bring restore Interface on

}
}
#sectionend on_key_press  // DO NOT EDIT OR REMOVE THIS LINE


#sectionstart on_mouse_click  // DO NOT EDIT OR REMOVE THIS LINE
function on_mouse_click(int button) {
  // called when a mouse button is clicked. button is either LEFT or RIGHT
  if (IsGamePaused() == 1) {
    // Game is paused, so do nothing (ie. don't allow mouse click)
  }
  else if (button==LEFT) {
    ProcessClick(mouse.x, mouse.y, GetCursorMode() );
  }
  else {   // right-click, so cycle cursor
    SetNextCursorMode();
  }
}
#sectionend on_mouse_click  // DO NOT EDIT OR REMOVE THIS LINE


#sectionstart interface_click  // DO NOT EDIT OR REMOVE THIS LINE
function interface_click(int interface, int button) {
  if (interface==6) {
// if Restore interface

if (button==1) {
// if cancel is pressed

UnPauseGame();
//Pauses the game

InterfaceOff(6);
// Close interface
}
else { index=ListBoxGetSelected(6,0);
// else get the selected game

RestoreGameSlot(savegameindex[index]);}
// restore the game

}


if (interface==7) {
// if save interface

if (button==0) {
// if enter is pressed

UnPauseGame();
//Pauses the game

index=ListBoxGetNumItems(7,3);
// Count saved games

if (index<20) {
// if less than 20

GetTextBoxText(7,0,text);
// Get the typed text

InterfaceOff(7);
// Close interface

SaveGameSlot(index+1,text); }
// Save game (text as description)

else {
// if saved games are 20

index=ListBoxGetSelected(7,3);
// Get the selected save game

GetTextBoxText(7,0,text);
// Get the typed text

InterfaceOff(7);
// Close the interface

SaveGameSlot(savegameindex[index],text); }
// Overwrite the selected game

UnPauseGame();
//Pauses the game

}
}

if (button==2) InterfaceOff(7);
// if cancel is pressed close interface
UnPauseGame();
//Pauses the game


2. I want the cursor to change to cursor 6 when SAVE/LOAD opens. I've managed to get it to change right after the window opens, but if you move the mouse over and away from e.g. the typing field, it changes back to walk-mode, look-mode or whatever it was before SAVE/LOAD was opened.

3. When I open save/load from the iconbar, the "quit" GUI opens behind it. I've tried playing with brackets and else's and if's, but I'm just not logical that way. This is just one of those annoying obvious bugs I couldn't solve to save my grandma. This is the code that follows right after the above one:

if (interface == ICONBAR) {
    if (button == 4) {  // show inventory
      show_inventory_window();
    }
    else if (button == 5) {   // use selected inventory
      if (character[ GetPlayerCharacter() ].activeinv >= 0)
        SetCursorMode(4);
    }
    else if (button == 0)    // save game
      GUIOn(7);
    else if (button == 1)   // load game
      GUIOn(6);
    else if (button == 2)   // quit
      SetCursorMode(6);
      PauseGame ();
      GUIOn(5);
  }  // end if interface ICONBAR

  if (interface == INVENTORY) {
    // They clicked a button on the Inventory GUI

    if (button == 1) {
      // They pressed SELECT, so switch to the Get cursor
      SetCursorMode (MODE_USE);
      // But, override the appearance to look like the arrow
      SetMouseCursor (6);
    }
   
    if (button == 2) {
      // They pressed LOOK, so switch to that mode
      SetActiveInventory(-1);
      SetCursorMode(MODE_LOOK); 
    }
    if (button == 3) {
      // They pressed the OK button, close the GUI
      GUIOff (INVENTORY);
      SetDefaultCursor();
    }

    if ((button == 4) && (game.top_inv_item < game.num_inv_items - game.num_inv_displayed)) {
      // scroll down
      game.top_inv_item = game.top_inv_item + game.items_per_line;
    }
    if ((button == 5) && (game.top_inv_item > 0)){
      // scroll up
      game.top_inv_item = game.top_inv_item - game.items_per_line;
}
}
   
   if (interface == 4) {
    if (button == 0) {  // show inventory
    SetCursorMode (MODE_USE);
    SetMouseCursor (6);
      GUIOn(2);
}
}

if (interface == EXIT) {
    if (button == 1) {  // Close Window
      SetCursorMode(0);
      UnPauseGame();
      GUIOff (EXIT);
    } 
    else if (button == 0)    // quit game
    QuitGame(0);
}   
}


This post was alot longer and pathetic than I hoped for. It'll be fun to see what problems I encounter when I change to AGS v2.7.
Title: Re: Help me out on my save/load GUI
Post by: Ashen on Fri 19/05/2006 13:26:03
1.
Yes, adding another button is the easiest way. You can use the 'more than 20 save games' code from the normal save condition.

index=ListBoxGetSelected(7,3);
// Get the selected save game

GetTextBoxText(7,0,text);
// Get the typed text

InterfaceOff(7);
// Close the interface

SaveGameSlot(savegameindex[index],text); }
// Overwrite the selected game

UnPauseGame();
//Pauses the game


Although you'll probably need to add a check (to the overwrite button, if not both) that there IS something selected first, e.g.:


index=ListBoxGetSelected(7,3);
// Get the selected save game
if (index == -1) Display("Please select a slot to overwrite"); // No selection
else { // Overwrite the selected game
  GetTextBoxText(7,0,text); // Get the typed text
  InterfaceOff(7); // Close the interface
  SaveGameSlot(savegameindex[index],text);
}


You could also make a condition for the list box, so that double clicking a game will overwrite it.

2. I don't know, sorry. It might be something in repeatedly_execute[/i, except that you call PauseGame().

3.
Looks like there's a problem with the conditions:

    else if (button == 2)   // quit
      SetCursorMode(6);
      PauseGame ();
      GUIOn(5);


SetCursorMode(6) will only be run if button 2 is pressed, the other lines (including the one which turns on GUI6, which I guess is the Quit GUI) will run for ANY button on ICONBAR. Try:

    else if (button == 2) {  // quit
      SetCursorMode(6);
      PauseGame ();
      GUIOn(5);
    } // end quit

Or (depending on what commands you actually want to run when)

    else if (button == 2)   // quit
      GUIOn(5); // Only runs on quit
    SetCursorMode(6); // Runs for all (Might solve question 2)
    PauseGame ();  // Runs for all


On a general note: change all the InterfaceOn/Offs to GUIOn/Off, as I'm fairly sure InterfaceOn/Off was already obsolete by 2.62 - it still works, but it makes sense to keep them all the same.
Also, since you originally asked for a 3-5 slot system, you might want to change all the references to if(index>19), to decrease the possible number of save games.
Title: Re: Help me out on my save/load GUI
Post by: HillBilly on Fri 19/05/2006 15:16:40
Quote from: Ashen on Fri 19/05/2006 13:26:03Yes, adding another button is the easiest way. You can use the 'more than 20 save games' code from the normal save condition.

Thanks for the quick answer! Here's what I've come up with this far:

#sectionstart interface_click  // DO NOT EDIT OR REMOVE THIS LINE
function interface_click(int interface, int button) {
  if (interface==6) {
// if Restore interface

if (button==1) {
// if cancel is pressed

UnPauseGame();
//Pauses the game

InterfaceOff(6);
// Close interface
}
else { index=ListBoxGetSelected(6,0);
// else get the selected game

RestoreGameSlot(savegameindex[index]);}
// restore the game

}


if (interface==7) {
// if save interface

if (button==0) {
// if enter is pressed

UnPauseGame();
//Pauses the game

index=ListBoxGetNumItems(7,3);
// Count saved games

if (index<20) {
// if less than 20

GetTextBoxText(7,0,text);
// Get the typed text

InterfaceOff(7);
// Close interface

SaveGameSlot(index+1,text); }
// Save game (text as description)

else {
// if saved games are 20

index=ListBoxGetSelected(7,3);
// Get the selected save game

GetTextBoxText(7,0,text);
// Get the typed text

InterfaceOff(7);
// Close the interface

SaveGameSlot(savegameindex[index],text); }
// Overwrite the selected game

UnPauseGame();
//Pauses the game

}
}

if (button==4) {
// if "save" is pressed

UnPauseGame();
//unPauses the game

index=ListBoxGetNumItems(7,3);
// Count saved games

if (index<20) {
// if less than 20

GetTextBoxText(7,0,text);
// Get the typed text

InterfaceOff(7);
// Close interface

SaveGameSlot(index+1,text); }
// Save game (text as description)

else {
// if saved games are 20

index=ListBoxGetSelected(7,3);
// Get the selected save game
if (index == -1) Display("Please select a slot to overwrite"); // No selection
else { // Overwrite the selected game
  GetTextBoxText(7,0,text); // Get the typed text
  InterfaceOff(7); // Close the interface
  SaveGameSlot(savegameindex[index],text);
}

}
}

if (button==2) InterfaceOff(7);
// if cancel is pressed close interface
UnPauseGame();
//Pauses the game


Button 4 is the new button. Here's the result I've got from this:

When I open the save GUI, I type in a name in the text field and press enter. The GUI closes, but don't save the game. Same result with pressing the new button. I've obviously done something wrong here.

Also, you mentioned something about making a condition for the list box, and making it overwrite a game by double clicking? Do you think you could give me a little step by step on how to do that? Or would it be easier to just fix the system I'm trying now?

Your solution for the quit code, pluss a little bracket, worked perfect. Thanks alot.
Title: Re: Help me out on my save/load GUI
Post by: Ashen on Fri 19/05/2006 15:50:53
I think there's a problem with your braces in there - the condition for GUI 7 ends right after the button 0 condition (the second '}' just before if (button == 4), meaning the following conditons will work on any GUI. However, that shouldn't be causing the problem since they should still be run. (I think, I'm a little rusty in 2.62 code, but that makes logical sense.)

Check the Compiled folder - are you sure it's not actually saving? I notice that when you turn the save/load GUIs on from the ICONBAR GUI, you only turn the GUIs on, and don't run the ListBoxSaveGameList(7,3); needed to display existing save games. Other than that, the code looks fine to me I can't see why it wouldn't save, especially if you've just copied the code GG posted. (Although, like I said - rusty in 2.62.)

Quoteyou mentioned something about making a condition for the list box, and making it overwrite a game by double clicking? Do you think you could give me a little step by step on how to do that?

In the if (interface == 7) condition:

if (button == 3) { // I THINK control 3 is your listbox? Check to be sure
  if (index != ListBoxGetSelected(7,3)) index != ListBoxGetSelected(7,3);
  // First click. If clicked item hasn't been selected before, remember it for next time.
  else { // Second click. (i.e. clicked item has already been selected.)
    GetTextBoxText(7,0,text); // Get the typed text
    GUIOff(7); // Close the interface
    SaveGameSlot(savegameindex[index],text);
  }
}


That should do it. However, it probably would make more sense to get normal saving working first, before getting into anything else.
   
Title: Re: Help me out on my save/load GUI
Post by: HillBilly on Sun 28/05/2006 13:07:44
Hey,

Sorry for not responding. I've been trying to work out a solution myself, among other things.

The saving works now, but not the overwriting. It's basically doomed to save in a new slot for every save. When I turn the GUI on, the top game is always marked. I guess it shouldn't, and only be marked when it's supposed to be saved over? Is this possible without re-organizing too much of the code?

if (interface==7) {
// if save interface

if (button==0) {
// if enter is pressed

UnPauseGame();
//Pauses the game

index=ListBoxGetNumItems(7,3);
// Count saved games

if (index<6) {
// if less than 20

GetTextBoxText(7,0,text);
// Get the typed text

InterfaceOff(7);
// Close interface

SaveGameSlot(index+1,text); }
// Save game (text as description)

else {
// if saved games are 20

index=ListBoxGetSelected(7,3);
// Get the selected save game

GetTextBoxText(7,0,text);
// Get the typed text

InterfaceOff(7);
// Close the interface

SaveGameSlot(savegameindex[index],text); }
// Overwrite the selected game

UnPauseGame();
//Pauses the game

}
}

if (button==4) {
// if "save" is pressed

UnPauseGame();
//unPauses the game

index=ListBoxGetNumItems(7,3);
// Count saved games

if (index<6) {
// if less than 20

GetTextBoxText(7,0,text);
// Get the typed text

InterfaceOff(7);
// Close interface

SaveGameSlot(index+1,text); }
// Save game (text as description)

else {
// if saved games are 20

index=ListBoxGetSelected(7,3);
// Get the selected save game
if (index == -1) Display("Please select a slot to overwrite"); // No selection
else { // Overwrite the selected game
  GetTextBoxText(7,0,text); // Get the typed text
  InterfaceOff(7); // Close the interface
  SaveGameSlot(savegameindex[index],text);
}

}
}

if (button==2) InterfaceOff(7);
// if cancel is pressed close interface
UnPauseGame();
//Pauses the game

Title: Re: Help me out on my save/load GUI
Post by: Ashen on Sun 28/05/2006 13:26:14
I take it button 4 is your Overwrite button?
You've still got the code set to check if there's less than 6 save games already, before it checks for a highlighted slot to save over. Try changing the code to:

if (button==4) { // if "save" is pressed
  UnPauseGame();   //unPauses the game
  index=ListBoxGetSelected(7,3);   // Get the selected save game
  if (index == -1) Display("Please select a slot to overwrite"); // No selection
  else { // Overwrite the selected game
    GetTextBoxText(7,0,text); // Get the typed text
    InterfaceOff(7); // Close the interface
    SaveGameSlot(savegameindex[index],text);
  }
}

This'll overwrite the slot that's selected when button 4 is pressed, however many existing games there are.
You'll need to add a line wherever you turn the GUI on to clear the selected item (ListBoxSetSelected, but I'm not sure of the useage).

If you mean it's creating new savegames over 6, then I can't see the problem, sorry.