summaryrefslogtreecommitdiff
path: root/src/ai
diff options
context:
space:
mode:
authoryexo <yexo@openttd.org>2011-06-03 19:18:39 +0000
committeryexo <yexo@openttd.org>2011-06-03 19:18:39 +0000
commitcf11a1e98e4d5a4bfc6929b78a9fb28108f763a8 (patch)
tree92917d8ce904d002e0b034df3d0df6db2d27f49b /src/ai
parentb1812c9b02a3975f0d3f9a12e23f961717df22a0 (diff)
downloadopenttd-cf11a1e98e4d5a4bfc6929b78a9fb28108f763a8.tar.xz
(svn r22534) -Fix [FS#4631] (r21250): doing rescan_ai in a game with running AIs caused a crash
Diffstat (limited to 'src/ai')
-rw-r--r--src/ai/ai_config.cpp4
-rw-r--r--src/ai/ai_config.hpp4
-rw-r--r--src/ai/ai_core.cpp15
3 files changed, 18 insertions, 5 deletions
diff --git a/src/ai/ai_config.cpp b/src/ai/ai_config.cpp
index 8ec213cd8..a00cf4867 100644
--- a/src/ai/ai_config.cpp
+++ b/src/ai/ai_config.cpp
@@ -75,9 +75,9 @@ AIInfo *AIConfig::GetInfo() const
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;
}
diff --git a/src/ai/ai_config.hpp b/src/ai/ai_config.hpp
index ee6f8b416..3ed06d346 100644
--- a/src/ai/ai_config.hpp
+++ b/src/ai/ai_config.hpp
@@ -57,10 +57,12 @@ public:
/**
* 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.
diff --git a/src/ai/ai_core.cpp b/src/ai/ai_core.cpp
index 1c7005b74..f92d511c2 100644
--- 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);
}