Save game, Saving double of name.(Solved)

Started by Construed, Fri 27/12/2013 04:19:31

Previous topic - Next topic

Construed

Hey, I've been working on this save game function for a long time and don't really understand its flow completely.
When I save 1 character it works fine to save and restore.
But when I go to save a second character it saves over the first save game and has 2 of the same savegame name.

Code: ags

/////savegame function
function btnSaveGame_OnClick(GUIControl *control, MouseButton button)
{ 

  int gameSlotToSaveInto = lstSaveGamesList.ItemCount;
  int i = 0;
  while (i < lstSaveGamesList.ItemCount)
  {
    if (lstSaveGamesList.Items[i] == txtNewSaveName.Text)
    {
      gameSlotToSaveInto = lstSaveGamesList.SaveGameSlots[i];
    }
    i++;
  }
  txtNewSaveName.Text = nick;
  SaveGameSlot(gameSlotToSaveInto, txtNewSaveName.Text);
   
  close_save_game_dialog();
}
//////other part of save game function
function btnIconSave_OnClick(GUIControl *control, MouseButton button)
{

  
  gSaveGame.Visible = true;
  // Get the list of save games
  lstSaveGamesList.FillSaveGameList();
  if (lstSaveGamesList.ItemCount > 0)
  {
   //If there is at least one, set the default text
   //to be the first game's name
  
  txtNewSaveName.Text = lstSaveGamesList.Items[0];

  }
  else
  {
  txtNewSaveName.Text = "";
  }
 

 }


Thanks for reading, I hope someone can help me figure this pesky problem out :(

-Edited description of problem.
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Crimson Wizard

The function you are using is the same as the one in Default template, except one thing: you are assinging the "nick" variable to the savegame description. What is this variable's value, is it really different for each different player? You may check what's going on by adding an output:
Code: ags

Display("Saving game for %s", nick);
txtNewSaveName.Text = nick;


What bothers me also is that you are overriding the text that player could have typed in the text box (txtNewSaveName). Is that textbox enabled for editing or not? If yes, then why do you need it, if you are replacing what user typed by predefined variable?

Construed

Well, I'm trying to change the whole save process.
Nick = the players name that he registered with on the server.

Instead of the save game name being any name, it is actually they're characters name, basically making the list a list of characters rather than save game name's.
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Crimson Wizard

Can you explain what savedgame system you have in mind? Do you mean that every character has only one save? Depending on this you may even simplify the saving script. For example, you may completely get rid of the "save" menu (because player won't need to select/type save name).

Construed

Yes sir, I already did, the saving is automatically done when the player presses quit.
Basically when the player quits it automatically saves their nickname, which is the name they choose when they first create the character.

Everything works fine, but when the player creates a second character it saves over the current slot and the previous one.
So if a player makes a character named mike, he can quit/autosave and come back and it works fine.

But if he creates another character named charley it saves over both mike and charley for some strange reason and then there is  2 charley save games.
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Khris

I didn't completely think this through, but maybe try this:
Move this line
Code: ags
 txtNewSaveName.Text = nick;

to the start of the function so the loop will choose the correct slot.

Construed

Well, That seems to work much better but, It only allows me to have 2 different save games, on the third one it overwrites the first.
But at least not making double of the same name.
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Construed

I made a 4th one for the sake of testing, then it allowed me to have 3, but after restoring then quitting on it, made the darn double name again and saved over the first one.

This thing is a mess :(
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Crimson Wizard

#8
If there can be only one save per character, then there's no need for saves list box, nor text box to type in, nor the save menu at all; you can leave only "save now" button which should share the same script as autosaving (call same saving function).
Also, you may as well store save slot index along with character's name, so that you won't have to look up for correct slot every time.

Speaking of the lookup, in the worst case you may use this kind of algorythm instead:
Code: ags

// max savable characters (NOTE: AGS supports up to 999 free saves + 1 slot for autosave)
#define MAX_CHARACTER_SAVES 50

function SaveGameForCurrentCharacter()
{ 
  String description;
  int slot_index = 0;
  int character_save_index = -1;
  // Search for existing saved games in the game's folder
  bool stop_search = false;
  while (slot_index < MAX_CHARACTER_SAVES && !stop_search)
  {
     description = Game.GetSaveSlotDescription(slot_index);
     if (description == null)
     {
        // no more saves found, stop
        stop_search = true;  // so to break out of the loop early
     }
     else if (description == nick)
     {
        // found character's save, stop
        character_save_index = slot_index;
        stop_search = true; // so to break out of the loop early
     }
     slot_index++;
  }

  if (character_save_index < 0)
  {
     // no existing save found, write to the new one
     // use slot_index, it is equal to (last existing index + 1) at this point
     character_save_index = slot_index;
  }
  SaveGameSlot(character_save_index, nick);
}


Construed

I'm not sure where I would put that code?

Also I forgot to add this to the code above, where those 2 functions are automatically executed via the quit button.

Code: ags

//////Quit button set to execute entire save function automatically.
function btnQuit_OnClick(GUIControl *control, MouseButton button)
{
btnSaveGame_OnClick(btnSaveGame, eMouseLeft);
btnIconSave_OnClick(btnIconSave, eMouseLeft);
gGui12.Visible=true; 
}


Also I'm very tired after being up very late so please forgive me if I'm missing an obvious point or if I pass out, If I do I will continue working on this as soon as I wake.
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Crimson Wizard

I say try this:
Code: ags

function btnQuit_OnClick(GUIControl *control, MouseButton button)
{
   SaveGameForCurrentCharacter();
   gGui12.Visible=true; 
}


What is gGui12 (I guess that might be confirmation dialog)?

Construed

Yes, I had a problem with the game quitting before it saved and also needed something to cause the password entry gui appear when restored.

OK, I tried that but it only allows for one slot to be saved?
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Crimson Wizard

#12
Quote from: Construed on Sat 28/12/2013 19:30:24
OK, I tried that but it only allows for one slot to be saved?
Wait... is not that what you wanted? Can you elaborate again: do you want one or any number of saves per character?
If you want many saves per character, then how are you going to distinct them if you are setting every description to player name?

Construed

Basically I want the player to be able to have as many characters"savegames with nicks" as possible

The players name when he registers is the savegame name so like if he makes 3 chars it would appear in the save list like this:

Billybob
Fabio
Chimpow

and no matter which character he restores, the save function will automatically save over the nick he choose to restore.
So there is basically 1 save per character, but multiple characters allowed.


I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Crimson Wizard

#14
Well, that's what I thought. So, does not it work now?

Construed

No, it works for one character slot, but when I save a second one it writes over the first.
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Crimson Wizard

Uh, sorry, fixed the code:

Code: ags

// max savable characters (NOTE: AGS supports up to 999 free saves + 1 slot for autosave)
#define MAX_CHARACTER_SAVES 50

function SaveGameForCurrentCharacter()
{ 
  String description;
  int slot_index = 1;
  int character_save_index = -1;
  // Search for existing saved games in the game's folder
  bool stop_search = false;
  while (slot_index < MAX_CHARACTER_SAVES && !stop_search)
  {
     description = Game.GetSaveSlotDescription(slot_index);
     if (description == null)
     {
        // no more saves found, stop
        stop_search = true;  // so to break out of the loop early
     }
     else if (description == nick)
     {
        // found character's save, stop
        character_save_index = slot_index;
        stop_search = true; // so to break out of the loop early
     }
     else
       slot_index++;
  }

  if (character_save_index < 0)
  {
     // no existing save found, write to the new one
     // use slot_index, it is equal to (last existing index + 1) at this point
     character_save_index = slot_index;
  }
  SaveGameSlot(character_save_index, nick);
}

Construed

Ah, I can't thank you enough Crimson, it works like a charm!
I'm so glad to finally have this behind me so that I can start to work on other areas of the game!
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Crimson Wizard

Ok, sorry again, I wanted to test this code prior to posting, but was distracted by something and forgot :).

BTW, I made another change, this will let you delete games in the middle of the list, and the new character will be saved on the first free slot:

Code: ags

function SaveGameForCurrentCharacter()
{ 
  String description;
  int slot_index = 1;
  int character_save_index = -1;
  int first_free_slot = -1;
  // Search for existing saved games in the game's folder
  bool stop_search = false;
  while (slot_index < MAX_CHARACTER_SAVES && !stop_search)
  {
     description = Game.GetSaveSlotDescription(slot_index);
     if (description == null && first_free_slot < 0)
     {
        // remember the first free slot found and continue searching
        first_free_slot = slot_index;
     }
     else if (description != null && description == nick)
     {
        // found character's save, stop
        character_save_index = slot_index;
        stop_search = true; // so to break out of the loop early
     }
     else
       slot_index++;
  }
 
  if (character_save_index < 0)
  {
     // no existing save found, write to the new one
     if (first_free_slot >= 1)
       // if there was a free slot somewhere in the middle, use that
       character_save_index = first_free_slot;
     else
       // use slot_index, it is equal to (last existing index + 1) at this point
       character_save_index = slot_index;
  }
  SaveGameSlot(character_save_index, nick);
}


Also, why are you using variable "nick", and not player.Name?

Construed

Ah, Thank you kind sir!
"nick" is the name chosen at the beginning of the game to log in to the IRC chat.
I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

Crimson Wizard

Quote from: Construed on Sat 28/12/2013 20:32:51
"nick" is the name chosen at the beginning of the game to log in to the IRC chat.
I mean, you can set player.Name to that name, instead of adding new variable (nick).

Construed

I felt sorry for myself because I had no shoes.
Then I met the man with no feet.

SMF spam blocked by CleanTalk