Save/Restore GUIs using version 2.7 (SOLVED)

Started by sloppy, Thu 02/02/2006 03:44:19

Previous topic - Next topic

sloppy

I'm making my own Save/Restore GUI's using several tutorials that are for earlier versions of AGS.   I'm making progress, I think I actually have the Save GUI done right.  But what I can't figure out is how to make a proper Restore GUI.  Specifically, how do you make it so that the saved games in the Saved GUI list box come up into the Restore GUI list box.
  The Save GUI:
Code: ags
                    
//Save Game
 if (interface==SAVEGUI) {   
if (button==0) {
bg_save_idx = save_listbox_chris.ItemCount;

if (bg_save_idx<20) {
  save_textbox_chris.GetText(input);
  save_listbox_chris.AddItem(input);
  SaveGameSlot(bg_save_idx+1, input);
  gSavegui.Visible=false;
  }
  }
  }  

That seems to save the games okay.  Although I don't really know unless I can get the Restore GUI to work.

Here's what I've tried for the Restore GUI:
Code: ags

//Restore Game
 int bg_restore_idx; 
 string  bg_restore_buf;
 
 if (interface==LOADGUI) {
  if (button==0) {
   bg_restore_idx= restore_listbox_chris.SelectedIndex;
 if (bg_restore_idx==-1) {
   Display("Please make a selection.");
 }
 else 
{
restore_listbox_chris.GetItemText(restore_listbox_chris.SelectedIndex, bg_restore_buf);
RestoreGameSlot(savegameindex[bg_restore_idx]);    
}
}
}
}

But when the Restore GUI comes up, there's no saved games to choose from. 
Has anybody tried this using version 2.7 that works?

Ashen

That seems OK, as far as it goes. Where do you turn the GUI on (F7 keypress, button on another GUI, both, somewhere else)?

Wherever, there should also be a ListBox.FillSaveGameList() command to, well, fill the list box with the save games, e.g.:
Code: ags

restore_listbox_chris.FillSaveGameList();
gLoadgui.Visible = true;

(There should also be something similar to fill the Save GUI list, when it turns on.)

Also, as a matter of good practice, since you're using 2.7 put the commands in individual control functions rather than the obsolete interface_click it looks like you're using. (But this isn't vital, as interface_clickstill works.)
I know what you're thinking ... Don't think that.

sloppy

#2
Thanks!  I should have thought of that.

One other question: is there a way to clear the text box in the Save GUI whether either the save or cancel button is pushed?  Right now, if you type anything there and hit save, the text stays and you have to back space it to clear it every time.

EDIT: Actually I'm thinking that might not be possible.  Perhaps I was thinking about the Cirque De Zale game where there's numbered slots in the save GUI to type in.  How would one accomplish that?

Ashen

#3
The second way is trickier, and I don't know it off the top of my head (not actually having played CdZ).
The first way, just use TextBox.SetText(...) in the Save/Cancel button scripts, e.g.:
Code: ags

save_textbox_chris.SetText("");


(In 2.7, anyway. 2.71 and the new string methods might be different).

Give the manual a look through (which you really should have already) - even if you don't need a particular function just now, knowing it exists will save you having to ask in the future.
I know what you're thinking ... Don't think that.

sloppy

Thanks again, Ashen.  I'll try this. 

Since any tutorials I've found are for older versions, I hope it's obvious that I've pored over the manual to figure this out for the newer version.  But sometimes even the manual doesn't help if you don't know what you're looking for.  (There's a lot of info there).  But at least you've put me in the right direction.

Ashen

Yes, it can be confusing to take in all at once.

I didn't mean it as a 'RTFM, n00b', just that you should take the time to familiarise yourself with it in general. Also - as you might've noticed - most of the obsolete functions (e.g. Get/SetTextBoxText(gui, object, string)) link to their current versions, which should help with updating most code.
I know what you're thinking ... Don't think that.

sloppy

Okay, just one more question regarding this and I think it's done.Ã,  It's overwriting a saved game slot if you type in the same name that's in the listbox or highlight an existing game name and then save.

I know you'd have to say something like
if (save_textbox_chris.GetText(input) ==save_listbox_chris.GetItemText(save_listbox_chris.SelectedIndex, input) {
overwrite what's in the listbox.Ã,  Something like that.Ã,  :-\

I'm just not able to get my head around it.  Can someone help?

Ashen

If you're using 2.7, you can't compare strings using the '==' operator - you need to use StrComp(string1, string2) or StrCaseComp(string1, string2) (StrComp() is case sensitive, StrCaseComp() isn't).

Also, you'd need to use a second string to store the item text for comparison, e.g.:
Code: ags

string input;
string item;
save_textbox_chris.GetText(input);
save_listbox_chris.GetItemText(save_listbox_chris.SelectedIndex, item);
if (StrComp (input, item) == 0) { // i.e. strings match
  // overwrite slot
}
else {
  // save new slot
}

(You should probably include a confirmation option, to stop people accidentally overwriting slots.)

In 2.71+, you can use '==', but I'd still recommend using different Strings for the TextBox and ListBox.

Another thing you might want to do (if you haven't already) is add something to the ListBox's SelectionChanged function, to set the TextBox text to the name of the selected save slot.
I know what you're thinking ... Don't think that.

sloppy

Is there an overwrite slot command?  From other posts, it looks like you would have to delete that same saved game and then save it again as new.  Or is there a simpler way in 2.7?  If not, how do you delete that exact saved game name?

Ashen

No need to delete, just save over it with SaveGameSlot(), e.g.:
Code: ags

SaveGameSlot (savegameindex[save_listbox_chris.SelectedIndex], input);
I know what you're thinking ... Don't think that.

sloppy

Great!  It works when I type in a name that is also in the list box.  But then about highlighting a name in the listbox and saving:
Quote
Another thing you might want to do (if you haven't already) is add something to the ListBox's SelectionChanged function, to set the TextBox text to the name of the selected save slot.

I'm not sure what you meant here.

Ashen

It seems, from the code you've posted, like you want it that if you select an existing slot in the ListBox, and type the same name into the TextBox, it overwrites the slot.
By double clicking on the ListBox in the editor, you can set code that runs every time the player changes the selection, just like you'd set the code for buttons (if you weren't using interface_click). If you added something like:
Code: ags

save_listbox_chris.GetItemText(save_listbox_chris.SelectedIndex, item);
save_textbox_chris.SetText(item);

You'd save the player having to type the existing save game name.

You can still do this with interface_click (I'd just forgotten you were using it), just do an if (button == .. condition for the ListBox's number, or use:
Code: ags

    if (button == save_listbox_chris.ID) {
      save_listbox_chris.GetItemText(save_listbox_chris.SelectedIndex, item);
      save_textbox_chris.SetText(item);
    }


It's not important - it's just something I think is neat.
I know what you're thinking ... Don't think that.

sloppy

Okay, I've put the code into the "save" control function like you suggested.
Here's what I put:
Code: ags

int bg_save_idx;
string input;
string item;

bg_save_idx = save_listbox_chris.ItemCount;

if (bg_save_idx<20) {
Ã,  save_textbox_chris.GetText(input);
Ã,  save_listbox_chris.AddItem(input);
Ã,  SaveGameSlot(bg_save_idx+1, input);
Ã,  gSavegui.Visible=false;
 
save_listbox_chris.GetItemText(save_listbox_chris.SelectedIndex, item);
if (StrComp (input, item) == 0) {
Ã,  SaveGameSlot (savegameindex[save_listbox_chris.SelectedIndex], input);
}
}
}


It looks right to me.Ã,  The funny thing is, it worked for a while.Ã,  It would overwrite a saved game that was already in the listbox.Ã,  Ã, But now it doesn't.Ã,  It'll repeat the same name into the listbox.Ã,  But isn't it correct?

Also in the saved GUI listbox control function I put this:
Code: ags

save_listbox_chris.GetItemText(save_listbox_chris.SelectedIndex, item);
save_textbox_chris.SetText(item);

Now that works in that it will put what I highlight from the listbox into the textbox, but then I can't make it overwrite that saved game.Ã,  I know I'm missing something there, but I can't figure out what.

Ashen

The way you've got it, it'll save to a new slot and turn the GUI off, before even checking the selected slot. AFAIK, closing the GUI 'resets' the selected index, meaning the match would be lost. Try:
Code: ags

int bg_save_idx;
string input;
string item;

bg_save_idx = save_listbox_chris.ItemCount;
save_textbox_chris.GetText(input);
save_listbox_chris.GetItemText(save_listbox_chris.SelectedIndex, item);
if (StrComp (input, item) == 0) {
  SaveGameSlot (savegameindex[save_listbox_chris.SelectedIndex], input);
  gSavegui.Visible=false;
} // i.e. Check if TextBox and ListBox match. If so , save ...

else if (bg_save_idx<20) { // And if not, AND you have less than 20 slots, save a new one
  save_listbox_chris.AddItem(input); // This line seems pointless to me
  SaveGameSlot(bg_save_idx+1, input);
  gSavegui.Visible=false;
}
 // You might want to include a 'No match, and already have 20 slots' condition here.
} // I guess this is the end of the button condition?


The 'pointless' line doesn't really serve a purpose, as the GUI is turned off before you'd notice the new item, and the ListBox is re-filled with the savegame list the next time you turn it on - so you don't need to manually add it here.
I know what you're thinking ... Don't think that.

sloppy

Almost there I think.Ã,  The only problem with this last scripting is this line:
Code: ags

save_listbox_chris.GetItemText(save_listbox_chris.SelectedIndex, item);


It works if there's already a saved game in the listbox, but if you're starting fresh, there's nothing in the listbox to get, and the game crashes.

Ashen

True. Add a check for save_listbox_chris.SelectedIndex != -1 when you get the ListBox text, i.e.:
Code: ags

 // blah blah
save_textbox_chris.GetText(input);
if (save_listbox_chris.SelectedIndex != -1) save_listbox_chris.GetItemText(save_listbox_chris.SelectedIndex, item);
if (StrComp (input, item) == 0) {
//blah blah


Now, the only problem would be if nothing is selected (or there's nothing TO select), and the player enters a blank name (it'll get a 'match' and try to save to slot -1). But, being able to save with a blank name is a bit of a problem anyway. To totally idiot-proof it, you might want to add something to abort if the TextBox was left blank, e.g.:
Code: ags

save_textbox_chris.GetText(input);
if (StrComp (input, "") == 0) {
  Display("You must enter a name for your save game!");
  return;
}
if (save_listbox_chris.SelectedIndex != -1) save_listbox_chris.GetItemText(save_listbox_chris.SelectedIndex, item);
// etc...
I know what you're thinking ... Don't think that.

sloppy

Just one more thing regarding if the listbox has more that 20 slots filled.Ã,  I've tried several things but they don't work and ends up messing other stuff up.

Maybe you could let me know if I'm close.

int bg_save_idx;
string input;
string item;

bg_save_idx = save_listbox_chris.ItemCount;
save_textbox_chris.GetText(input);
save_listbox_chris.GetItemText(save_listbox_chris.SelectedIndex, item);
if (StrComp (input, item) == 0) {
Ã,  SaveGameSlot (savegameindex[save_listbox_chris.SelectedIndex], input);
Ã,  gSavegui.Visible=false;
}

else if (bg_save_idx<20) {
Ã,  Ã,  SaveGameSlot(bg_save_idx+1, input);
Ã,  gSavegui.Visible=false;
}

else if (bg_save_idx>20) {
SaveGameSlot (savegameindex[save_listbox_chris.SelectedIndex], input);
Ã,  gSavegui.Visible=false;
}


But two "else if's" like this won't work.Ã,  And it doesn't overwrite any other way I try this.
How would you put that exactly?  (Once I get this part, I think I'm done with this.)

Ashen

Thatlooks almost exactly right, but you'll need to make it 'greater than or equal to 20' (bg_save_idx>=20), rather than just 'greater than' - which obviously won't run if there are EXACTLY 20 slots.

Also, you should add a check that a slot is selected or you'll get a crash (similar to the one you were getting with GetItemText and an empty ListBox):
Code: ags

else if (bg_save_idx>=20) {
  if (save_listbox_chris.SelectedIndex != -1) {
    SaveGameSlot (savegameindex[save_listbox_chris.SelectedIndex], input);
    gSavegui.Visible=false;
  }
  else Display ("Select a slot to overwrite.");
}


And again, you might want to add a confirmation to prevent accidental overwriting.
I know what you're thinking ... Don't think that.

sloppy

Just one final thing.Ã,  I made a new GUI that pops up for the confirmation.Ã, 
For the "Yes" button, I put this code:
Code: ags

string input;
Ã,  if (save_listbox_chris.SelectedIndex != -1) {
Ã,  Ã,  SaveGameSlot (savegameindex[save_listbox_chris.SelectedIndex], input);
Ã,  Ã,  gSavegui.Visible=false;
Ã,  Ã,  gConfirm.Visible=false;
Ã,  Ã,  }

But then instead of the save name, it puts this strange symbol in the save listbox slot.  I didn't think it would be complicated, probably just a small thing.

Ashen

Do you actually have another declaration of string input; in the button's condition? That would explain why it's not saving with the name (it's dealing with a new, blank instance of input), but not why it assigns it a random symbol.  It could be setting an ascii character for input - does the symbol change at all, or is it always the same one?

Whatever, you either need to make input accessable by all GUIs (put the declaration somewhere in the global script outside of and before interface_click, and delete all other string input; lines), or get the TextBox text again, before saving. Either of them should resolve this.
I know what you're thinking ... Don't think that.

SMF spam blocked by CleanTalk