diff --git a/src/saveload/game_sl.cpp b/src/saveload/game_sl.cpp --- a/src/saveload/game_sl.cpp +++ b/src/saveload/game_sl.cpp @@ -54,64 +54,68 @@ static void SaveReal_GSDT(int *index_ptr Game::Save(); } -static void Load_GSDT() -{ - const std::vector slt = SlCompatTableHeader(_game_script_desc, _game_script_sl_compat); +struct GSDTChunkHandler : ChunkHandler { + GSDTChunkHandler() : ChunkHandler('GSDT', CH_TABLE) {} + + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_game_script_desc, _game_script_sl_compat); + + /* Free all current data */ + GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME)->Change(nullptr); - /* Free all current data */ - GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME)->Change(nullptr); + if (SlIterateArray() == -1) return; + + _game_saveload_version = -1; + SlObject(nullptr, slt); + + if (_networking && !_network_server) { + GameInstance::LoadEmpty(); + if (SlIterateArray() != -1) SlErrorCorrupt("Too many GameScript configs"); + return; + } - if (SlIterateArray() == -1) return; - - _game_saveload_version = -1; - SlObject(nullptr, slt); + GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME); + if (!_game_saveload_name.empty()) { + config->Change(_game_saveload_name.c_str(), _game_saveload_version, false, _game_saveload_is_random); + if (!config->HasScript()) { + /* No version of the GameScript available that can load the data. Try to load the + * latest version of the GameScript instead. */ + config->Change(_game_saveload_name.c_str(), -1, false, _game_saveload_is_random); + if (!config->HasScript()) { + if (_game_saveload_name.compare("%_dummy") != 0) { + Debug(script, 0, "The savegame has an GameScript by the name '{}', version {} which is no longer available.", _game_saveload_name, _game_saveload_version); + Debug(script, 0, "This game will continue to run without GameScript."); + } else { + Debug(script, 0, "The savegame had no GameScript available at the time of saving."); + Debug(script, 0, "This game will continue to run without GameScript."); + } + } else { + Debug(script, 0, "The savegame has an GameScript by the name '{}', version {} which is no longer available.", _game_saveload_name, _game_saveload_version); + Debug(script, 0, "The latest version of that GameScript has been loaded instead, but it'll not get the savegame data as it's incompatible."); + } + /* Make sure the GameScript doesn't get the saveload data, as it was not the + * writer of the saveload data in the first place */ + _game_saveload_version = -1; + } + } - if (_networking && !_network_server) { - GameInstance::LoadEmpty(); + config->StringToSettings(_game_saveload_settings); + + /* Start the GameScript directly if it was active in the savegame */ + Game::StartNew(); + Game::Load(_game_saveload_version); + if (SlIterateArray() != -1) SlErrorCorrupt("Too many GameScript configs"); - return; } - GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME); - if (!_game_saveload_name.empty()) { - config->Change(_game_saveload_name.c_str(), _game_saveload_version, false, _game_saveload_is_random); - if (!config->HasScript()) { - /* No version of the GameScript available that can load the data. Try to load the - * latest version of the GameScript instead. */ - config->Change(_game_saveload_name.c_str(), -1, false, _game_saveload_is_random); - if (!config->HasScript()) { - if (_game_saveload_name.compare("%_dummy") != 0) { - Debug(script, 0, "The savegame has an GameScript by the name '{}', version {} which is no longer available.", _game_saveload_name, _game_saveload_version); - Debug(script, 0, "This game will continue to run without GameScript."); - } else { - Debug(script, 0, "The savegame had no GameScript available at the time of saving."); - Debug(script, 0, "This game will continue to run without GameScript."); - } - } else { - Debug(script, 0, "The savegame has an GameScript by the name '{}', version {} which is no longer available.", _game_saveload_name, _game_saveload_version); - Debug(script, 0, "The latest version of that GameScript has been loaded instead, but it'll not get the savegame data as it's incompatible."); - } - /* Make sure the GameScript doesn't get the saveload data, as it was not the - * writer of the saveload data in the first place */ - _game_saveload_version = -1; - } + void Save() const override + { + SlTableHeader(_game_script_desc); + SlSetArrayIndex(0); + SlAutolength((AutolengthProc *)SaveReal_GSDT, nullptr); } - - config->StringToSettings(_game_saveload_settings); - - /* Start the GameScript directly if it was active in the savegame */ - Game::StartNew(); - Game::Load(_game_saveload_version); - - if (SlIterateArray() != -1) SlErrorCorrupt("Too many GameScript configs"); -} - -static void Save_GSDT() -{ - SlTableHeader(_game_script_desc); - SlSetArrayIndex(0); - SlAutolength((AutolengthProc *)SaveReal_GSDT, nullptr); -} +}; extern GameStrings *_current_data; @@ -152,44 +156,48 @@ static const SaveLoad _game_language_des SLEG_STRUCTLIST("strings", SlGameLanguageString), }; -static void Load_GSTR() -{ - const std::vector slt = SlCompatTableHeader(_game_language_desc, _game_language_sl_compat); +struct GSTRChunkHandler : ChunkHandler { + GSTRChunkHandler() : ChunkHandler('GSTR', CH_TABLE) {} + + void Load() const override + { + const std::vector slt = SlCompatTableHeader(_game_language_desc, _game_language_sl_compat); + + delete _current_data; + _current_data = new GameStrings(); - delete _current_data; - _current_data = new GameStrings(); + while (SlIterateArray() != -1) { + LanguageStrings ls; + SlObject(&ls, slt); + _current_data->raw_strings.push_back(std::move(ls)); + } - while (SlIterateArray() != -1) { - LanguageStrings ls; - SlObject(&ls, slt); - _current_data->raw_strings.push_back(std::move(ls)); + /* If there were no strings in the savegame, set GameStrings to nullptr */ + if (_current_data->raw_strings.size() == 0) { + delete _current_data; + _current_data = nullptr; + return; + } + + _current_data->Compile(); + ReconsiderGameScriptLanguage(); } - /* If there were no strings in the savegame, set GameStrings to nullptr */ - if (_current_data->raw_strings.size() == 0) { - delete _current_data; - _current_data = nullptr; - return; - } + void Save() const override + { + SlTableHeader(_game_language_desc); - _current_data->Compile(); - ReconsiderGameScriptLanguage(); -} + if (_current_data == nullptr) return; -static void Save_GSTR() -{ - SlTableHeader(_game_language_desc); - - if (_current_data == nullptr) return; + for (uint i = 0; i < _current_data->raw_strings.size(); i++) { + SlSetArrayIndex(i); + SlObject(&_current_data->raw_strings[i], _game_language_desc); + } + } +}; - for (uint i = 0; i < _current_data->raw_strings.size(); i++) { - SlSetArrayIndex(i); - SlObject(&_current_data->raw_strings[i], _game_language_desc); - } -} - -static const ChunkHandler GSTR{ 'GSTR', Save_GSTR, Load_GSTR, nullptr, nullptr, CH_TABLE }; -static const ChunkHandler GSDT{ 'GSDT', Save_GSDT, Load_GSDT, nullptr, nullptr, CH_TABLE }; +static const GSTRChunkHandler GSTR; +static const GSDTChunkHandler GSDT; static const ChunkHandlerRef game_chunk_handlers[] = { GSTR, GSDT,