How to customize the Default Load Save

Started by Ghostlady, Mon 22/07/2024 00:44:29

Previous topic - Next topic

Ghostlady

Is there a way to customize the default Load/Save window with different colors and font?  Also, were does it reside?  I can't find code for it.
My Games:

Hauntings Of Mystery Manor
Intrigue At Oakhaven Plantation
Haunting at Cliffhouse

Crimson Wizard

Are you referring to windows that are called using SaveGameDialog()/RestoreGameDialog(), or user-made guis found in the project tree?

If former, then you cannot customize them, and you should just create your own guis and script their behavior.

If latter, then find these GUIs in the project and change their properties.

Ghostlady

#2
I am referencing the windows that are called using SaveGameDialog()/RestoreGameDialog()
See attached image - When clicking on the buttons they will execute the above, which pulls up a gray box and that's what I would like to replace and also would like to see the code to replicate saving, loading, etc.
https://mysterymanor.net/images/samples/Interface.png
My Games:

Hauntings Of Mystery Manor
Intrigue At Oakhaven Plantation
Haunting at Cliffhouse

Crimson Wizard

#3
You could use one of the default templates for the reference of the saving/loading code.
Either create a dummy game from Sierra-style template (for example), or download this template's source project from here:
https://github.com/adventuregamestudio/ags-template-source/tree/master/Sierra-style

Specifically save / load dialog code is this part:
https://github.com/adventuregamestudio/ags-template-source/blob/f6deb48a8d205fb996b81b4319350637016161ee/Sierra-style/GlobalScript.asc#L271-L359

Ghostlady

My Games:

Hauntings Of Mystery Manor
Intrigue At Oakhaven Plantation
Haunting at Cliffhouse

Ghostlady

#5
Can you tell me where "lstSaveGamesList.FillSaveGameList" is being initialized?  I am getting an Undefined token '1stSaveGamesList'

Also, should I be clicking on the link (BASS, Sierra, Verb Coin: updated find_save_slot(), fix going over limit) and use that code?

Code: ags
Sierra-style/function show_save_game_dialog()
{
  // 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
  {
    // no save games yet, so default to empty text
    txtNewSaveName.Text = "";
  }
  open_gui(gSaveGame);
}
function show_restore_game_dialog()
{
  lstRestoreGamesList.FillSaveGameList();
  open_gui(gRestoreGame);
}
My Games:

Hauntings Of Mystery Manor
Intrigue At Oakhaven Plantation
Haunting at Cliffhouse

Crimson Wizard

lstSaveGamesList is the name of the ListBox control, which you want to fill with names of saves.

If you're using this code, then you're supposed to create a GUI with certain controls on them.

Of course you may adjust this to suit your needs. You do not have to use this code as it is.

QuoteAlso, should I be clicking on the link (BASS, Sierra, Verb Coin: updated find_save_slot(), fix going over limit) and use that code?

No, the version of the code that I linked above already has this fix.

Ghostlady

My Games:

Hauntings Of Mystery Manor
Intrigue At Oakhaven Plantation
Haunting at Cliffhouse

Eon_Star

Hello.

I used a mod and made a tutorial regarding the subject. You may take a look:

https://www.youtube.com/watch?v=oeQ0biGxVyY&list=PLdlsMVDmowzSkFXAwnV_dOXjrSqYsjU15&index=41

I hope to be of help.

 :-D

Ghostlady

This is wonderful!  I came upon it too late though.  How unfortunate for me.
My Games:

Hauntings Of Mystery Manor
Intrigue At Oakhaven Plantation
Haunting at Cliffhouse

Ghostlady

Quote from: Eon_Star on Sat 10/08/2024 01:07:55Hello.

I used a mod and made a tutorial regarding the subject. You may take a look:

https://www.youtube.com/watch?v=oeQ0biGxVyY&list=PLdlsMVDmowzSkFXAwnV_dOXjrSqYsjU15&index=41

I hope to be of help.

 :-D

Do you have the code, only to plop the screenshot into a place on a Save or Restore Gui? Here are both guis I am referring to.  Early stages with no graphics yet. The screenshot would be above the buttons.

My Games:

Hauntings Of Mystery Manor
Intrigue At Oakhaven Plantation
Haunting at Cliffhouse

Snarky

#11
The function you need is DynamicSprite.CreateFromSaveGame, and there is an example of how to use it in the manual.

You would put a button where you want to display the screenshot, and call that code in the OnSelectionChanged event handler for the listbox. (You need to get the SaveGameSlot of the selected savegame, and set the width and height to the size of the button.)

This works for the savegames that are already stored. If you want to display a screenshot for the Save dialog before saving the game, you need to grab that screenshot before you display the dialog, using DynamicSprite.CreateFromScreenShot.

Eon_Star

Hi,

I used the "A.S.S Module" and made a sample of the Save&Load Menu. The module allows you to save your games with screenshots. The tutorial video I made is very detailed.

Ghostlady, I recommend you watch the tutorial to see how I made it.  :)

Thanks.

Rik_Vargard

Quote from: Eon_Star on Sun 11/08/2024 22:04:31Hi,

I used the "A.S.S Module" and made a sample of the Save&Load Menu. The module allows you to save your games with screenshots. The tutorial video I made is very detailed.

Ghostlady, I recommend you watch the tutorial to see how I made it.  :)

Thanks.

A link to the tutorial would be cool :P   ;)


Ghostlady

I uderstand the button on the gui and adding this code to the OnSelectionChanged event handler. But where do I add the code where it reads "at the top of the script outside event functions"  Does this mean the global script?  If so I added at the top and I get an error.

Code: ags
// at top of script, outside event functions
DynamicSprite *buttonSprite;

// inside an event function
buttonSprite = DynamicSprite.CreateFromSaveGame(1, 50, 50);
if (buttonSprite != null) {
    btnScrnshot.NormalGraphic = buttonSprite.Graphic;
}

Secondly where do I put this code for the Saved Game Slots:
Code: ags
int index = lstSaveGames.SelectedIndex;
RestoreGameSlot(lstSaveGames.SaveGameSlots[index]);

Just a little confused how to piece this all together.
My Games:

Hauntings Of Mystery Manor
Intrigue At Oakhaven Plantation
Haunting at Cliffhouse

Snarky

Quote from: Ghostlady on Mon 12/08/2024 02:01:56But where do I add the code where it reads "at the top of the script outside event functions"  Does this mean the global script?

Yes, it means in the same script as the function (i.e. the global script), by itself (not inside of any function), somewhere above the function where you use it.

Quote from: Ghostlady on Mon 12/08/2024 02:01:56If so I added at the top and I get an error.

What error, pointing to what part of the script?

Quote from: Ghostlady on Mon 12/08/2024 02:01:56Secondly where do I put this code for the Saved Game Slots:
Code: ags
int index = lstSaveGames.SelectedIndex;
RestoreGameSlot(lstSaveGames.SaveGameSlots[index]);

Well, this is the code that restores a game from a save (by calling "RestoreGameSlot"). So when do you want that to happen? When the player clicks on the Restore button, no? So it needs to go in the Button.OnClick event handler for that button. (Which you create by going into the GUI editor and the event panel for the button.)

Ghostlady

I've included the code for Saving and Restoring.  The error message I am getting on "DynamicSprite *buttonSprite;" is Attributes of identifier do not match prototype

Code: ags
//=============================================================================
// SAVE / LOAD DIALOGS
//=============================================================================

int find_save_slot(String name)
{
  bool slots[] = new bool[999];
  int slots_used = 0;

  // record which slots are occupied already, 
  // if the types save name matches any existing one, then use that
  for (int i = 0; i < lstSaveGamesList.ItemCount; i++)
  {
    if (lstSaveGamesList.Items[i] == name)
    {
      // found existing save with matching name
      return lstSaveGamesList.SaveGameSlots[i];
    }

    // remember which slots are already taken
    slots[lstSaveGamesList.SaveGameSlots[i]] = true;
    slots_used++;
  }
  
  // current version of AGS has a limit of 50 save slots
  // that may be displayed in the ListBox at the same time
  if (slots_used >= 50)
  {
    return -1;
  }

  // find first free save slot, starting with slot 1 (for "cosmetic" purposes)
  for (int i = 1; i < 999; i++)
  {
    if (!slots[i])
    {
      return i;
    }
  }

  // no free slots found
  return -1;
}

function btnSaveGame_OnClick(GUIControl *control, MouseButton button)
{
  int gameSlotToSaveInto = find_save_slot(txtNewSaveName.Text);

  if (gameSlotToSaveInto < 0)
  {
    Display("Save slots limit of 50 is reached, delete some of the existing saves first!");
  }
  else
  {
    SaveGameSlot(gameSlotToSaveInto, txtNewSaveName.Text);
    close_owning_gui(control);
  }
}
function btnRestoreGame_OnClick(GUIControl *control, MouseButton button)
{
  if (lstRestoreGamesList.SelectedIndex >= 0)
  {
    RestoreGameSlot(lstRestoreGamesList.SaveGameSlots[lstRestoreGamesList.SelectedIndex]);
  }

  close_owning_gui(control);
}
DynamicSprite *buttonSprite;

function lstSaveGamesList_OnSelectionChanged(GUIControl *control)
{
  txtNewSaveName.Text = lstSaveGamesList.Items[lstSaveGamesList.SelectedIndex];
  buttonSprite = DynamicSprite.CreateFromSaveGame(1, 78, 78);
  if (buttonSprite != null) {
    btnScrnshot.NormalGraphic = buttonSprite.Graphic; }
}

function lstSaveGamesList_OnSelectionCh(GUIControl *control)
{
  txtNewSaveName.Text = lstSaveGamesList.Items[lstSaveGamesList.SelectedIndex];
}

function txtNewSaveName_OnActivate(GUIControl *control)
{
  // pressing Return in the text box simulates clicking the save button
  btnSaveGame_OnClick(control, eMouseLeft);
}

function btnDeleteSave_OnClick(GUIControl *control, MouseButton button)
{
  if (lstSaveGamesList.SelectedIndex >= 0)
  {
    DeleteSaveSlot(lstSaveGamesList.SaveGameSlots[lstSaveGamesList.SelectedIndex]);
    lstSaveGamesList.FillSaveGameList();
  }
}

function gReset_OnClick(GUI *theGui, MouseButton button)
{
SetGlobalInt(420,1);
}
My Games:

Hauntings Of Mystery Manor
Intrigue At Oakhaven Plantation
Haunting at Cliffhouse

Snarky

#18
Looking at other reports of this error message (here, here or here, for example), it seems like it most likely means that you've already used the name buttonSprite some other place in the script, perhaps in an import statement. Or you might have used it as the script name for some game entity (such as a GUI Control). Basically, it's telling you that the name is already in use.

There's also a mistake in line 73 in the code (going by the numbering in the forum post), since you're hardcoding it to use SaveGameSlot 1. You need to use lstSaveGamesList.SaveGameSlots[lstSaveGamesList.SelectedIndex] to show the currently selected savegame. (You may need to wrap it in a check so you don't get an "array index out of bounds" exception if nothing is selected in the listbox.)

Other than that, I find it a little weird that there's a bunch of code to ensure that if the player uses the same description as an existing savegame, it will overwrite it rather than save it as a separate savegame. That would really piss me off as a player.

Crimson Wizard

Quote from: Snarky on Mon 12/08/2024 17:35:04Other than that, I find it a little weird that there's a bunch of code to ensure that if the player uses the same description as an existing savegame, it will overwrite it rather than save it as a separate savegame. That would really piss me off as a player.

The existing templates provide no clear way of telling whether to create a new save or overwrite an existing one.
Instead they fill the description text box whenever player clicks on a existing item. That's why they use the description to match the existing save.

SMF spam blocked by CleanTalk