changeset 17750:f90707971eda draft

(svn r22534) -Fix [FS#4631] (r21250): doing rescan_ai in a game with running AIs caused a crash
author yexo <yexo@openttd.org>
date Fri, 03 Jun 2011 19:18:39 +0000
parents da329398c88a
children 66f3b5387d6d
files src/ai/ai_config.cpp src/ai/ai_config.hpp src/ai/ai_core.cpp
diffstat 3 files changed, 18 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/ai/ai_config.cpp
+++ b/src/ai/ai_config.cpp
@@ -75,9 +75,9 @@
 	return this->info;
 }
 
-bool AIConfig::ResetInfo()
+bool AIConfig::ResetInfo(bool force_exact_match)
 {
-	this->info = AI::FindInfo(this->name, -1, false);
+	this->info = AI::FindInfo(this->name, force_exact_match ? this->version : -1, force_exact_match);
 	return this->info != NULL;
 }
 
--- a/src/ai/ai_config.hpp
+++ b/src/ai/ai_config.hpp
@@ -57,10 +57,12 @@
 	/**
 	 * When ever the AI Scanner is reloaded, all infos become invalid. This
 	 *  function tells AIConfig about this.
+	 * @param force_exact_match If true try to find the exact same version
+	 *   as specified. If false any version is ok.
 	 * @return \c true if the reset was successful, \c false if the AI was no longer
 	 *  found.
 	 */
-	bool ResetInfo();
+	bool ResetInfo(bool force_exact_match);
 
 	/**
 	 * Get the AIInfo linked to this AIConfig.
--- a/src/ai/ai_core.cpp
+++ b/src/ai/ai_core.cpp
@@ -170,13 +170,24 @@
 	 *  a random new AI on reload). */
 	for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
 		if (_settings_game.ai_config[c] != NULL && _settings_game.ai_config[c]->HasAI()) {
-			if (!_settings_game.ai_config[c]->ResetInfo()) {
+			if (!_settings_game.ai_config[c]->ResetInfo(true)) {
 				DEBUG(ai, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_game.ai_config[c]->GetName());
 				_settings_game.ai_config[c]->ChangeAI(NULL);
+				if (Company::IsValidAiID(c)) {
+					/* 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
+					 * like what would happen if the AI was missing during loading. */
+					AI::Stop(c);
+					AI::StartNew(c, false);
+				}
+			} else if (Company::IsValidAiID(c)) {
+				/* Update the reference in the Company struct. */
+				Company::Get(c)->ai_info = _settings_game.ai_config[c]->GetInfo();
 			}
 		}
 		if (_settings_newgame.ai_config[c] != NULL && _settings_newgame.ai_config[c]->HasAI()) {
-			if (!_settings_newgame.ai_config[c]->ResetInfo()) {
+			if (!_settings_newgame.ai_config[c]->ResetInfo(false)) {
 				DEBUG(ai, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_newgame.ai_config[c]->GetName());
 				_settings_newgame.ai_config[c]->ChangeAI(NULL);
 			}