Hey guys, I'm setting up a custom save/load system for my game in AGS 3.0.2 SP1.
It's based off that 'ole 'Save/load with screenshots' tutorial from way back when, and I had it working fine in AGS 2.62. But since I didn't understand the code 100%, I had to do a bit of guessing when translating it to the new scripting language. It seems to have worked out pretty well though, since the overall system works, but there's just some peculiar things going on with the GUI itself.
1. When I open the save gui, it takes a screenshot and puts it on a button. However, the first time the screenshot does not load. Only when I close the GUI and open it again does it show up. If I moved in the meantime though, I have to close the GUI again and reopen to see THAT screenshot. So the display is always lagging behind.
2. Additionally, the tempsave I make to create that screenshot never gets deleted, even though it says so in the code.
3. When I open the load GUI, I cannot get the screenshot of the top slot to display. If there are multiple savegames in the list, all their screenshots display correctly, except for the top slot. It just returns null on that one.
Here's the relevant code:
The function definitions (@ top of the global script)
//--------------------------------------------------------------------------------------------------------------
// Savegames with screenshots
//--------------------------------------------------------------------------------------------------------------
// Definitions
// Define screenshot width - 320/5, aka 128 real pixels in 640x480
#define SL_WIDTH 64
// Define screenshot height - 240/5, aka 96 real pixels in 640x480
#define SL_HEIGHT 48
// Substitute "139" with the sprite number of your choosing
#define SL_EMPTY_SPRITE 70
// Variables
String text; // Stores the typed text
int saveslot = 0; // Stores the selected savegame slot
int saves = 0; // Stores the total number of savegames
DynamicSprite *screenshot; // Stores the screenshot
// Functions
function sl_save() {
Wait(1);
SaveGameSlot(100, "temp"); // Save current game in temp slot
screenshot = DynamicSprite.CreateFromSaveGame(100, SL_WIDTH, SL_HEIGHT);// Retrieve screenshot from save
DeleteSaveSlot(100); // Delete temporary slot
if (screenshot != null) {
btnSaveScreen.NormalGraphic = screenshot.Graphic; // Display current screenshot
}
txtSaveName.Text = ""; // Clear Text box
lstSaveGames.FillSaveGameList(); // Fill List Box with saved games
lstSaveGames.SelectedIndex = -1; // Deselect savegame slots
saves = lstSaveGames.ItemCount; // Count how many saved games there are
if (saves > 19){ // If saved games 20 (maximum)
Display("All save slots are full. Please overwrite a previous save.");// Display warning
}
gSave.Visible = true; // Opens the save GUI
gSave.Centre(); // Centres the save GUI
mouse.Mode = eModePointer; // Set the pointer cursor
}
function sl_load() {
lstLoadGames.FillSaveGameList(); // Fill List Box with saved games
lstLoadGames.SelectedIndex = -1; // Deselect savegame slots
gLoad.Visible = true; // Opens the load GUI
gLoad.Centre(); // Centres the load GUI
mouse.Mode = eModePointer; // Set the pointer cursor
}
//--------------------------------------------------------------------------------------------------------------
The GUI interactions (@ bottom of the global script).
// Save GUI
function btnSaveOK_OnClick(GUIControl *control, MouseButton button) {
saves = lstSaveGames.ItemCount; // Count saved games
if (saves < 20) { // If less than 50
text = txtSaveName.Text; // Get the typed text
if (screenshot != null) {
btnSaveScreen.NormalGraphic = SL_EMPTY_SPRITE; // Resets the screenshot
screenshot.Delete();
}
gSave.Visible = false;
mouse.Mode = eModeWalkto;
Wait(1);
SaveGameSlot(saves+1,text); // Save game (text as description)
}
else { // If saved games are maxed out (50)
saveslot = lstSaveGames.SelectedIndex; // Get the selected save game
text = txtSaveName.Text; // Get the typed text
if (screenshot != null) {
screenshot.Delete();
btnSaveScreen.NormalGraphic = SL_EMPTY_SPRITE; // Resets the screenshot
}
gSave.Visible = false;
mouse.Mode = eModeWalkto;
Wait(1);
SaveGameSlot(savegameindex[saveslot],text); // Overwrite the selected game
}
}
function btnSaveCancel_OnClick(GUIControl *control, MouseButton button) {
gSave.Visible = false;
mouse.Mode = eModeWalkto;
if (screenshot != null) {
screenshot.Delete();
btnSaveScreen.NormalGraphic = SL_EMPTY_SPRITE; // Resets the screenshot
}
}
// Load GUI
function btnLoadOK_OnClick(GUIControl *control, MouseButton button) {
saveslot = lstLoadGames.SelectedIndex; // Gets the selected slot
gLoad.Visible = false;
mouse.Mode = eModeWalkto;
if (screenshot != null) {
screenshot.Delete();
btnLoadScreen.NormalGraphic = SL_EMPTY_SPRITE; // Resets the screenshot
}
RestoreGameSlot(savegameindex[saveslot]); // Restores the selected slot
}
function btnLoadCancel_OnClick(GUIControl *control, MouseButton button) {
gLoad.Visible = false;
mouse.Mode = eModeWalkto;
if (screenshot != null) {
screenshot.Delete();
btnLoadScreen.NormalGraphic = SL_EMPTY_SPRITE; // Resets the screenshot
}
}
function lstLoadGames_OnSelectionChange(GUIControl *control) {
// Updates screenshot display when selecting a different slot
saveslot = lstLoadGames.SelectedIndex; // Gets the selected slot
screenshot = DynamicSprite.CreateFromSaveGame(saveslot, SL_WIDTH, SL_HEIGHT);
if (screenshot != null) {
btnLoadScreen.NormalGraphic = screenshot.Graphic; // Updates the screenshot
}
}
Any thoughts?
[UPDATE]
I've done a bit of further tweaking, and I've discovered some things.
When I delete the tempsave after clicking OK or Cancel on the save GUI instead of right away, it succesfully gets deleted. Side-effect: Now the GUI never shows a screenshot.
Also, something strange happens on the load GUI. I've noticed that the screenshots are sorted in ascending order, with the first one at the top, but the savegames themselves are listed descending, so the most recent one is at the top. So if you save a few times, it sticks the wrong screenshots on the slots.
I think your main problem here is that you're not using the SaveGameSlots array (http://www.adventuregamestudio.co.uk/manual/ListBox.SaveGameSlots.htm) to map between the SelectedIndex and the actual save game number.
For example, this code:
saveslot = lstLoadGames.SelectedIndex; // Gets the selected slot
screenshot = DynamicSprite.CreateFromSaveGame(saveslot, SL_WIDTH, SL_HEIGHT);
will get the screenshot for the wrong save game without that mapping.
You do have a couple of references to savegameindex[saveslot] which is the old 2.62 equivalent, but you should replace those with the equivalent lstLoadGAmes.SaveGAmeSlots mapping instead.
Ooh thanks, I was wondering about that because I couldn't find savegameindex in the manual. I replaced those references like you said, and in the load GUI SelectionChange I changed:
screenshot = DynamicSprite.CreateFromSaveGame(saveslot, SL_WIDTH, SL_HEIGHT);
to:
screenshot = DynamicSprite.CreateFromSaveGame(lstLoadGames.SaveGameSlots[saveslot], SL_WIDTH, SL_HEIGHT);
Which solved the screenshots displaying wrong. :)
Now to just figure out how to get the screenshot to display right away on the save GUI and I'm all set.
Well, at the moment your code to display the screenshot is in the list box's OnSelectionChange event, so it doesn't get triggered when you first open the GUI.
The easiest thing to do is move the code from your lstLoadGames_OnSelectionChange function into a new function called sl_show_screenshot or something, and then call that new function from OnSelectionChange and also from sl_load.
EDIT: sorry thought you meant Load, not Save GUI.
For the Save GUI the problem is that SaveGameSlot doesn't run immediately, it only runs after the rest of the script finishes. So the save game is from the last time the code ran.
Instead of using SaveGameSlot -> CreateFromSaveGame -> DeleteGameSlot, just to DynamicSprite.CreateFromScreenSHot instead.
Excellent, thanks CJ. I thought that was what the problem was. Didn't occur to me I can now actually create a screenshot right away without having to save it first. Appreciate the speedy help man.
I've scripted my own savegame gui and well I had the same thing, then replacing that thing fixed it all. Also, I came to notice that if you have screenshots and you haven't enabled screenshots in savegames as a setting, you can still save and occasionally view screenshots but it's weirder since you have the option off.