diff --git a/src/ai/ai_core.cpp b/src/ai/ai_core.cpp index 0283b38f66..ae2e104bf6 100644 --- a/src/ai/ai_core.cpp +++ b/src/ai/ai_core.cpp @@ -203,21 +203,21 @@ for (CompanyID c = CompanyID::Begin(); c < MAX_COMPANIES; ++c) { if (_settings_game.script_config.ai[c] != nullptr && _settings_game.script_config.ai[c]->HasScript()) { if (!_settings_game.script_config.ai[c]->ResetInfo(true)) { - Debug(script, 0, "After a reload, the AI by the name '{}' was no longer found, and removed from the list.", _settings_game.script_config.ai[c]->GetName()); + Debug(script, 0, "After a reload, the AI by the name '{}' with version {} was no longer found, and removed from the list.", _settings_game.script_config.ai[c]->GetName(), _settings_game.script_config.ai[c]->GetVersion()); _settings_game.script_config.ai[c]->Change(std::nullopt); } } if (_settings_newgame.script_config.ai[c] != nullptr && _settings_newgame.script_config.ai[c]->HasScript()) { - if (!_settings_newgame.script_config.ai[c]->ResetInfo(false)) { - Debug(script, 0, "After a reload, the AI by the name '{}' was no longer found, and removed from the list.", _settings_newgame.script_config.ai[c]->GetName()); + if (!_settings_newgame.script_config.ai[c]->ResetInfo(_settings_newgame.script_config.ai[c]->GetForceExactMatch())) { + Debug(script, 0, "After a reload, the AI by the name '{}' with version {} was no longer found, and removed from the list.", _settings_newgame.script_config.ai[c]->GetName(), _settings_game.script_config.ai[c]->GetVersion()); _settings_newgame.script_config.ai[c]->Change(std::nullopt); } } if (Company::IsValidAiID(c) && Company::Get(c)->ai_config != nullptr) { AIConfig *config = Company::Get(c)->ai_config.get(); - if (!config->ResetInfo(true)) { + if (!config->ResetInfo(_settings_newgame.script_config.ai[c]->GetForceExactMatch())) { /* The code belonging to an already running AI was deleted. We can only do * one thing here to keep everything sane and that is kill the AI. After * killing the offending AI we start a random other one in it's place, just diff --git a/src/game/game_core.cpp b/src/game/game_core.cpp index 14ebcd9ab9..0054945b1e 100644 --- a/src/game/game_core.cpp +++ b/src/game/game_core.cpp @@ -159,7 +159,7 @@ * the GameConfig. If not, remove the Game from the list. */ if (_settings_game.script_config.game != nullptr && _settings_game.script_config.game->HasScript()) { if (!_settings_game.script_config.game->ResetInfo(true)) { - Debug(script, 0, "After a reload, the GameScript by the name '{}' was no longer found, and removed from the list.", _settings_game.script_config.game->GetName()); + Debug(script, 0, "After a reload, the GameScript by the name '{}' with version {} was no longer found, and removed from the list.", _settings_game.script_config.game->GetName(), _settings_newgame.script_config.game->GetVersion()); _settings_game.script_config.game->Change(std::nullopt); if (Game::instance != nullptr) Game::ResetInstance(); } else if (Game::instance != nullptr) { @@ -167,8 +167,8 @@ } } if (_settings_newgame.script_config.game != nullptr && _settings_newgame.script_config.game->HasScript()) { - if (!_settings_newgame.script_config.game->ResetInfo(false)) { - Debug(script, 0, "After a reload, the GameScript by the name '{}' was no longer found, and removed from the list.", _settings_newgame.script_config.game->GetName()); + if (!_settings_newgame.script_config.game->ResetInfo(_settings_newgame.script_config.game->GetForceExactMatch())) { + Debug(script, 0, "After a reload, the GameScript by the name '{}' with version {} was no longer found, and removed from the list.", _settings_newgame.script_config.game->GetName(), _settings_newgame.script_config.game->GetVersion()); _settings_newgame.script_config.game->Change(std::nullopt); } } diff --git a/src/settings.cpp b/src/settings.cpp index 9efb21a057..ed6f2923cf 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -948,6 +948,21 @@ static void ValidateSettings() } } +static std::pair TryReadScriptNameWithVersion(std::string_view item_name) +{ + StringConsumer consumer{item_name}; + auto name = consumer.ReadUntilChar('.', StringConsumer::SKIP_ONE_SEPARATOR); + + if (consumer.AnyBytesLeft()) { + auto version = consumer.TryReadIntegerBase(10); + if (version.has_value()) { + return { name, *version }; + } + } + + return { name, -1 }; +} + static void AILoadConfig(const IniFile &ini, std::string_view grpname) { const IniGroup *group = ini.GetGroup(grpname); @@ -966,9 +981,14 @@ static void AILoadConfig(const IniFile &ini, std::string_view grpname) config->Change(item.name); if (!config->HasScript()) { - if (item.name != "none") { - Debug(script, 0, "The AI by the name '{}' was no longer found, and removed from the list.", item.name); - continue; + auto [name, version] = TryReadScriptNameWithVersion(item.name); + config->Change(name, version, version != -1); + + if (!config->HasScript()) { + if (name != "none") { + Debug(script, 0, "The AI by the name '{}' was no longer found, and removed from the list.", name); + continue; + } } } if (item.value.has_value()) config->StringToSettings(*item.value); @@ -993,9 +1013,14 @@ static void GameLoadConfig(const IniFile &ini, std::string_view grpname) config->Change(item.name); if (!config->HasScript()) { - if (item.name != "none") { - Debug(script, 0, "The GameScript by the name '{}' was no longer found, and removed from the list.", item.name); - return; + auto [name, version] = TryReadScriptNameWithVersion(item.name); + config->Change(name, version, version != -1); + + if (!config->HasScript()) { + if (name != "none") { + Debug(script, 0, "The GameScript by the name '{}' was no longer found, and removed from the list.", name); + return; + } } } if (item.value.has_value()) config->StringToSettings(*item.value); @@ -1184,13 +1209,12 @@ static void AISaveConfig(IniFile &ini, std::string_view grpname) for (CompanyID c = CompanyID::Begin(); c < MAX_COMPANIES; ++c) { AIConfig *config = AIConfig::GetConfig(c, AIConfig::SSS_FORCE_NEWGAME); - std::string name; + std::string name = "none"; std::string value = config->SettingsToString(); if (config->HasScript()) { name = config->GetName(); - } else { - name = "none"; + if (config->GetForceExactMatch()) name = fmt::format("{}.{}", name, config->GetVersion()); } group.CreateItem(name).SetValue(value); @@ -1203,13 +1227,12 @@ static void GameSaveConfig(IniFile &ini, std::string_view grpname) group.Clear(); GameConfig *config = GameConfig::GetConfig(AIConfig::SSS_FORCE_NEWGAME); - std::string name; + std::string name = "none"; std::string value = config->SettingsToString(); if (config->HasScript()) { name = config->GetName(); - } else { - name = "none"; + if (config->GetForceExactMatch()) name = fmt::format("{}.{}", name, config->GetVersion()); } group.CreateItem(name).SetValue(value);