diff --git a/src/ai/ai.hpp b/src/ai/ai.hpp --- a/src/ai/ai.hpp +++ b/src/ai/ai.hpp @@ -114,7 +114,7 @@ public: static char *GetConsoleList(char *p, const char *last); static const AIInfoList *GetInfoList(); static const AIInfoList *GetUniqueInfoList(); - static AIInfo *FindInfo(const char *name, int version); + static AIInfo *FindInfo(const char *name, int version, bool force_exact_match); static bool ImportLibrary(const char *library, const char *class_name, int version, HSQUIRRELVM vm); static void Rescan(); #if defined(ENABLE_NETWORK) diff --git a/src/ai/ai_config.cpp b/src/ai/ai_config.cpp --- a/src/ai/ai_config.cpp +++ b/src/ai/ai_config.cpp @@ -16,11 +16,11 @@ #include "ai.hpp" #include "ai_config.hpp" -void AIConfig::ChangeAI(const char *name, int version, bool is_random_ai) +void AIConfig::ChangeAI(const char *name, int version, bool force_exact_match, bool is_random_ai) { free((void *)this->name); this->name = (name == NULL) ? NULL : strdup(name); - this->info = (name == NULL) ? NULL : AI::FindInfo(this->name, version); + this->info = (name == NULL) ? NULL : AI::FindInfo(this->name, version, force_exact_match); this->version = (info == NULL) ? -1 : info->GetVersion(); this->is_random_ai = is_random_ai; if (this->config_list != NULL) delete this->config_list; @@ -79,7 +79,7 @@ AIInfo *AIConfig::GetInfo() const bool AIConfig::ResetInfo() { - this->info = AI::FindInfo(this->name, -1); + this->info = AI::FindInfo(this->name, -1, false); return this->info != NULL; } diff --git a/src/ai/ai_config.hpp b/src/ai/ai_config.hpp --- a/src/ai/ai_config.hpp +++ b/src/ai/ai_config.hpp @@ -36,9 +36,11 @@ public: * Set another AI to be loaded in this slot. * @param name The name of the AI. * @param version The version of the AI to load, or -1 of latest. + * @param force_exact_match If true try to find the exact same version + * as specified. If false any compatible version is ok. * @param is_random Is the AI chosen randomly? */ - void ChangeAI(const char *name, int version = -1, bool is_random = false); + void ChangeAI(const char *name, int version = -1, bool force_exact_match = false, bool is_random = false); /** * When ever the AI Scanner is reloaded, all infos become invalid. This diff --git a/src/ai/ai_core.cpp b/src/ai/ai_core.cpp --- a/src/ai/ai_core.cpp +++ b/src/ai/ai_core.cpp @@ -44,7 +44,7 @@ info = AI::ai_scanner->SelectRandomAI(); assert(info != NULL); /* Load default data and store the name in the settings */ - config->ChangeAI(info->GetName(), -1, true); + config->ChangeAI(info->GetName(), -1, false, true); } _current_company = company; @@ -288,9 +288,9 @@ void CcAI(const CommandCost &result, Til return AI::ai_scanner->GetUniqueAIInfoList(); } -/* static */ AIInfo *AI::FindInfo(const char *name, int version) +/* static */ AIInfo *AI::FindInfo(const char *name, int version, bool force_exact_match) { - return AI::ai_scanner->FindInfo(name, version); + return AI::ai_scanner->FindInfo(name, version, force_exact_match); } /* static */ bool AI::ImportLibrary(const char *library, const char *class_name, int version, HSQUIRRELVM vm) diff --git a/src/ai/ai_scanner.cpp b/src/ai/ai_scanner.cpp --- a/src/ai/ai_scanner.cpp +++ b/src/ai/ai_scanner.cpp @@ -274,7 +274,7 @@ AIInfo *AIScanner::SelectRandomAI() cons return (*it).second; } -AIInfo *AIScanner::FindInfo(const char *nameParam, int versionParam) +AIInfo *AIScanner::FindInfo(const char *nameParam, int versionParam, bool force_exact_match) { if (this->info_list.size() == 0) return NULL; if (nameParam == NULL) return NULL; @@ -299,21 +299,19 @@ AIInfo *AIScanner::FindInfo(const char * /* Fall-through, like we were calling this function with a version */ } - /* Try to find a direct 'name.version' match */ - char ai_name_tmp[1024]; - snprintf(ai_name_tmp, sizeof(ai_name_tmp), "%s.%d", ai_name, versionParam); - strtolower(ai_name_tmp); - if (this->info_list.find(ai_name_tmp) != this->info_list.end()) return this->info_list[ai_name_tmp]; + if (force_exact_match) { + /* Try to find a direct 'name.version' match */ + char ai_name_tmp[1024]; + snprintf(ai_name_tmp, sizeof(ai_name_tmp), "%s.%d", ai_name, versionParam); + strtolower(ai_name_tmp); + if (this->info_list.find(ai_name_tmp) != this->info_list.end()) return this->info_list[ai_name_tmp]; + } /* See if there is a compatible AI which goes by that name, with the highest * version which allows loading the requested version */ AIInfoList::iterator it = this->info_list.begin(); for (; it != this->info_list.end(); it++) { - char ai_name_compare[1024]; - snprintf(ai_name_compare, sizeof(ai_name_compare), "%s", (*it).second->GetName()); - strtolower(ai_name_compare); - - if (strcasecmp(ai_name, ai_name_compare) == 0 && (*it).second->CanLoadFromVersion(versionParam) && (version == -1 || (*it).second->GetVersion() > version)) { + if (strcasecmp(ai_name, (*it).second->GetName()) == 0 && (*it).second->CanLoadFromVersion(versionParam) && (version == -1 || (*it).second->GetVersion() > version)) { version = (*it).second->GetVersion(); info = (*it).second; } diff --git a/src/ai/ai_scanner.hpp b/src/ai/ai_scanner.hpp --- a/src/ai/ai_scanner.hpp +++ b/src/ai/ai_scanner.hpp @@ -48,7 +48,7 @@ public: /** * Find an AI by name. */ - class AIInfo *FindInfo(const char *name, int version); + class AIInfo *FindInfo(const char *name, int version, bool force_exact_match); /** * Get the list of available AIs for the console. diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -1052,7 +1052,7 @@ DEF_CONSOLE_CMD(ConStartAI) AIConfig *config = AIConfig::GetConfig((CompanyID)n); if (argc >= 2) { - config->ChangeAI(argv[1]); + config->ChangeAI(argv[1], -1, true); if (!config->HasAI()) { IConsoleWarning("Failed to load the specified AI"); return true; 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 @@ -75,13 +75,13 @@ static void Load_AIPL() AIConfig *config = AIConfig::GetConfig(index); if (StrEmpty(_ai_saveload_name)) { /* A random AI. */ - config->ChangeAI(NULL, -1, true); + config->ChangeAI(NULL, -1, false, true); } else { - config->ChangeAI(_ai_saveload_name, _ai_saveload_version, _ai_saveload_is_random); + config->ChangeAI(_ai_saveload_name, _ai_saveload_version, false, _ai_saveload_is_random); if (!config->HasAI()) { /* No version of the AI available that can load the data. Try to load the * latest version of the AI instead. */ - config->ChangeAI(_ai_saveload_name, -1, _ai_saveload_is_random); + config->ChangeAI(_ai_saveload_name, -1, false, _ai_saveload_is_random); if (!config->HasAI()) { if (strcmp(_ai_saveload_name, "%_dummy") != 0) { DEBUG(ai, 0, "The savegame has an AI by the name '%s', version %d which is no longer available.", _ai_saveload_name, _ai_saveload_version);