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.
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.
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
(https://mysteyrmanor.net/images/samples/Interface.png)
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
Very good, that's what I am needing.
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?
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);
}
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.
Thanks.
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
This is wonderful! I came upon it too late though. How unfortunate for me.
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.
(http://mysterymanor.net/images/samples/RestoreLoadGui.png)
(http://mysterymanor.net/images/samples/SaveLoadGui.png)
The function you need is DynamicSprite.CreateFromSaveGame, and there is an example of how to use it in the manual (https://adventuregamestudio.github.io/ags-manual/DynamicSprite.html#dynamicspritecreatefromsavegame).
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 (https://adventuregamestudio.github.io/ags-manual/ListBox.html#listboxsavegameslots) 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.
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.
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 ;)
Hello,
Check my post from yesterday. You can find it.
Here is the link again:
https://www.youtube.com/watch?v=oeQ0biGxVyY&list=PLdlsMVDmowzSkFXAwnV_dOXjrSqYsjU15&index=41
;)
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.
// 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: int index = lstSaveGames.SelectedIndex;
RestoreGameSlot(lstSaveGames.SaveGameSlots[index]);
Just a little confused how to piece this all together.
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:
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.)
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
//=============================================================================
// 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);
}
Looking at other reports of this error message (here (https://www.adventuregamestudio.co.uk/forums/advanced-technical-forum/solved-directional-arrows-when-over-regions/msg636640450/#msg636640450), here (https://www.adventuregamestudio.co.uk/forums/beginners-technical-questions/odd-struct-error-message-solved/msg525865/#msg525865) or here (https://www.adventuregamestudio.co.uk/forums/beginners-technical-questions/screenshots-in-game-saves/msg636635411/#msg636635411), 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.
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.
I checked both global scripts and do not find any verbiage using buttonsprite in either, other than what is shown above.
Can you show me how to code this check so player would not get an "array index out of bounds" exception if nothing is selected in the listbox?
Quote from: Ghostlady on Mon 12/08/2024 18:11:04I checked both global scripts and do not find any verbiage using buttonsprite in either, other than what is shown above.
I assume you mean the script and the header? Well, as said it might also be the script name of a game entity. Or a global variable. But the simplest fix is just to rename the variable.
Quote from: Ghostlady on Mon 12/08/2024 18:11:04Can you show me how to code this check so player would not get an "array index out of bounds" exception if nothing is selected in the listbox?
Well, test it without a safety check first. I'm not sure it's necessary; I don't recall if there's any way for players to make it so nothing is selected. But something like this should work:
if(lstSaveGamesList.SelectedIndex >= 0) // Savegame selected in list
{
txtNewSaveName.Text = lstSaveGamesList.Items[lstSaveGamesList.SelectedIndex];
buttonSprite = DynamicSprite.CreateFromSaveGame(lstSaveGamesList.SaveGameSlots[lstSaveGamesList.SelectedIndex], 78, 78);
if (buttonSprite != null) // If there's a screenshot saved, display it
{
btnScrnshot.Visible = true;
btnScrnshot.NormalGraphic = buttonSprite.Graphic;
}
else
btnScrnshot.Visible = false;
}
else // No savegame selected, so hide the screenshot button
{
txtNewSaveName.Text = "";
btnScrnshot.Visible = false;
}
Hi, Ok, I got this working, sort of. The screenshot that displays is the correct room but it is filling up the whole area where the buttons are. So I can't use the Save, Delete, or Cancel buttons.
First, pick a suitable size for the screenshot. Like an eighth of the game resolution for instance. The size doesn't matter so much as the aspect ratio, obviously. Now resize the button to that, if you haven't already.
Now replace
buttonSprite = DynamicSprite.CreateFromSaveGame(lstSaveGamesList.SaveGameSlots[lstSaveGamesList.SelectedIndex], 78, 78);
with
int slot = lstSaveGamesList.SaveGameSlots[lstSaveGamesList.SelectedIndex];
buttonSprite = DynamicSprite.CreateFromSaveGame(slot, btnScrnshot.Width, btnScrnshot.Height);
(Assigning a larger sprite to a button will not clip it by default. You can turn this on in the button properties but that will simply crop the screenshot. The fix is shrinking the image.)
Hi, that code definitely corrected the size of the screenshot.
I am seeing the Save Gui showing up in the screenshot. How do I eliminate that?
Also, the screenshot shows that you can save with a blank name. (Not sure if this really matters)
(https://mysterymanor.net/images/samples/SampleSaveGui.png)
The screenshot will show the screen as it looks right when you save the game (by calling SaveGameSlot), so you have to hide the GUI (and wait for the screen to update) before you do that. In the A.S.S. module, this is done by:
gSave.Visible = false;
mouse.Mode = eModeWalkTo;
Wait(1);
SaveGameSlot(totalsaves+1, SL_TEXT);
Your code will likely be a bit different (different text in the SaveGameSlot, for one thing), but apart from perhaps the mouse.Mode line, it should be essentially equivalent.
That works perfect for removing the gui on the screenshot.
I notice that if I save with a screenshot, for example, Dom at letter (see example), then I play some more and save again, Dom at front of house. When I come into Save again, the screenshot displays the last screen that was selected/highlighted on the gui as opposed to the last save. So anytime I am in the Save function, it will always show the screenshot of the last item I highlighted in the gui. Should it be working like this?
(https://mysterymanor.net/images/samples/SampleSaveGui2.png)
Quote from: Ghostlady on Wed 21/08/2024 20:46:31Should it be working like this?
??? It's your game. How do you want it to work?
I see two potential purposes of the little screenshot thumbnail on this GUI. One is to show a thumbnail of the slot you will overwrite if you save now. The other is to give a preview of what the thumbnail will look like if you save now.
So showing the thumbnail of the highlighted save makes sense if that's the slot your game will be saved in (and therefore overwrite). To me that would be the intuitive behavior, and is how the A.S.S. module works. But as already discussed, the find_save_slot() function doesn't do that, so showing the selected item's thumbnail arguably makes it even more misleading.
Since I have separate guis for Save & Load (or restore) can I do something like this for the restore button? I think it makes more sense to see a screenshot of the save you want to restore. This seems to be working but I had to comment out the first line because there is no txtNewRestoreName.Text like there is for the save. Is it ok to leave this out?
function lstRestoreGamesList_OnSelectionChanged(GUIControl *control)
{
// txtNewRestoreName.Text = lstRestoreGamesList.Items[lstRestoreGamesList.SelectedIndex];
int slot = lstRestoreGamesList.SaveGameSlots[lstRestoreGamesList.SelectedIndex];
buttonSprite = DynamicSprite.CreateFromSaveGame(slot, btnScrshotR.Width, btnScrshotR.Height);
if (buttonSprite != null) {
btnScrshotR.NormalGraphic = buttonSprite.Graphic; }
}