diff --git a/src/saveload/ai_sl.cpp b/src/saveload/ai_sl.cpp --- a/src/saveload/ai_sl.cpp +++ b/src/saveload/ai_sl.cpp @@ -32,13 +32,19 @@ static const SaveLoad _ai_company_desc[] SLEG_SSTR("name", _ai_saveload_name, SLE_STR), SLEG_SSTR("settings", _ai_saveload_settings, SLE_STR), SLEG_CONDVAR("version", _ai_saveload_version, SLE_UINT32, SLV_108, SL_MAX_VERSION), - SLEG_CONDVAR("is_random", _ai_saveload_is_random, SLE_BOOL, SLV_136, SL_MAX_VERSION), + SLEG_CONDVAR("is_random", _ai_saveload_is_random, SLE_BOOL, SLV_136, SLV_AI_LOCAL_CONFIG), +}; + +static const SaveLoad _ai_running_desc[] = { + SLEG_CONDSSTR("running_name", _ai_saveload_name, SLE_STR, SLV_AI_LOCAL_CONFIG, SL_MAX_VERSION), + SLEG_CONDSSTR("running_settings", _ai_saveload_settings, SLE_STR, SLV_AI_LOCAL_CONFIG, SL_MAX_VERSION), + SLEG_CONDVAR("running_version", _ai_saveload_version, SLE_UINT32, SLV_AI_LOCAL_CONFIG, SL_MAX_VERSION), }; static void SaveReal_AIPL(int *index_ptr) { CompanyID index = (CompanyID)*index_ptr; - AIConfig *config = AIConfig::GetConfig(index); + AIConfig *config = AIConfig::GetConfig(index, AIConfig::SSS_FORCE_GAME); if (config->HasScript()) { _ai_saveload_name = config->GetName(); @@ -49,12 +55,21 @@ static void SaveReal_AIPL(int *index_ptr _ai_saveload_version = -1; } - _ai_saveload_is_random = config->IsRandom(); _ai_saveload_settings = config->SettingsToString(); SlObject(nullptr, _ai_company_desc); + + if (!Company::IsValidAiID(index)) return; + /* If the AI was active, store its data too */ - if (Company::IsValidAiID(index)) AI::Save(index); + config = AIConfig::GetConfig(index); + _ai_saveload_name = config->GetName(); + _ai_saveload_version = config->GetVersion(); + _ai_saveload_settings = config->SettingsToString(); + + SlObject(nullptr, _ai_running_desc); + AI::Save(index); + } struct AIPLChunkHandler : ChunkHandler { @@ -78,42 +93,66 @@ struct AIPLChunkHandler : ChunkHandler { SlObject(nullptr, slt); if (_game_mode == GM_MENU || (_networking && !_network_server)) { - if (Company::IsValidAiID(index)) AIInstance::LoadEmpty(); + if (Company::IsValidAiID(index)) { + SlObject(nullptr, _ai_running_desc); + AIInstance::LoadEmpty(); + } continue; } AIConfig *config = AIConfig::GetConfig(index, AIConfig::SSS_FORCE_GAME); - if (_ai_saveload_name.empty()) { + if (_ai_saveload_name.empty() || _ai_saveload_is_random) { /* A random AI. */ - config->Change(std::nullopt, -1, false, true); + config->Change(std::nullopt, -1, false); } else { - config->Change(_ai_saveload_name, _ai_saveload_version, false, _ai_saveload_is_random); + config->Change(_ai_saveload_name, _ai_saveload_version, false); if (!config->HasScript()) { - /* No version of the AI available that can load the data. Try to load the + /* No version of the AI available. Try to configure the * latest version of the AI instead. */ - config->Change(_ai_saveload_name, -1, false, _ai_saveload_is_random); + config->Change(_ai_saveload_name, -1, false); if (!config->HasScript()) { if (_ai_saveload_name.compare("%_dummy") != 0) { Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version); - Debug(script, 0, "A random other AI will be loaded in its place."); - } else { - Debug(script, 0, "The savegame had no AIs available at the time of saving."); - Debug(script, 0, "A random available AI will be loaded now."); + Debug(script, 0, "Configuration switched to Random AI."); } } else { Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version); - Debug(script, 0, "The latest version of that AI has been loaded instead, but it'll not get the savegame data as it's incompatible."); + Debug(script, 0, "The latest version of that AI has been configured instead"); } - /* Make sure the AI doesn't get the saveload data, as it was not the - * writer of the saveload data in the first place */ - _ai_saveload_version = -1; } } - config->StringToSettings(_ai_saveload_settings); + if (!Company::IsValidAiID(index)) continue; + /* Load the AI saved data */ - if (Company::IsValidAiID(index)) config->SetToLoadData(AIInstance::Load(_ai_saveload_version)); + SlObject(nullptr, _ai_running_desc); + + Company::Get(index)->ai_config = std::make_unique(); + config = Company::Get(index)->ai_config.get(); + config->Change(_ai_saveload_name, _ai_saveload_version, false); + if (!config->HasScript()) { + /* No version of the AI available that can load the data. Try to load the + * latest version of the AI instead. */ + config->Change(_ai_saveload_name, -1, false); + if (!config->HasScript()) { + if (_ai_saveload_name.compare("%_dummy") != 0) { + Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version); + Debug(script, 0, "A random other AI will be loaded in its place."); + } else { + Debug(script, 0, "The savegame had no AIs available at the time of saving."); + Debug(script, 0, "A random available AI will be loaded now."); + } + } else { + Debug(script, 0, "The savegame has an AI by the name '{}', version {} which is no longer available.", _ai_saveload_name, _ai_saveload_version); + Debug(script, 0, "The latest version of that AI has been loaded instead, but it'll not get the savegame data as it's incompatible."); + } + /* Make sure the AI doesn't get the saveload data, as it was not the + * writer of the saveload data in the first place */ + _ai_saveload_version = -1; + } + config->StringToSettings(_ai_saveload_settings); + config->SetToLoadData(AIInstance::Load(_ai_saveload_version)); } }