# ai_sl.cpp

Go to the documentation of this file.

    00001 /* $Id: ai_sl.cpp 17693 2009-10-04 17:16:41Z rubidium $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    00008  */
    00009
    00012 #include "../stdafx.h"
    00013 #include "../company_base.h"
    00014 #include "../debug.h"
    00015 #include "saveload.h"
    00016 #include "../string_func.h"
    00017 #include "../ai/ai.hpp"
    00018 #include "../ai/ai_config.hpp"
    00019 #include "../network/network.h"
    00020 #include "../ai/ai_instance.hpp"
    00021
    00022 static char _ai_saveload_name[64];
    00023 static int  _ai_saveload_version;
    00024 static char _ai_saveload_settings[1024];
    00025
    00026 static const SaveLoad _ai_company[] = {
    00027   SLEG_STR(_ai_saveload_name,        SLE_STRB),
    00028   SLEG_STR(_ai_saveload_settings,    SLE_STRB),
    00029   SLEG_CONDVAR(_ai_saveload_version, SLE_UINT32, 108, SL_MAX_VERSION),
    00030   SLE_END()
    00031 };
    00032
    00033 static void SaveReal_AIPL(int *index_ptr)
    00034 {
    00035   CompanyID index = (CompanyID)*index_ptr;
    00036   AIConfig *config = AIConfig::GetConfig(index);
    00037
    00038   if (config->HasAI()) {
    00039     ttd_strlcpy(_ai_saveload_name, config->GetName(), lengthof(_ai_saveload_name));
    00040     _ai_saveload_version = config->GetVersion();
    00041   } else {
    00042     /* No AI is configured for this so store an empty string as name. */
    00043     _ai_saveload_name[0] = '\0';
    00044     _ai_saveload_version = -1;
    00045   }
    00046
    00047   _ai_saveload_settings[0] = '\0';
    00048   config->SettingsToString(_ai_saveload_settings, lengthof(_ai_saveload_settings));
    00049
    00050   SlObject(NULL, _ai_company);
    00051   /* If the AI was active, store his data too */
    00052   if (Company::IsValidAiID(index)) AI::Save(index);
    00053 }
    00054
    00055 static void Load_AIPL()
    00056 {
    00057   /* Free all current data */
    00058   for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
    00059     AIConfig::GetConfig(c)->ChangeAI(NULL);
    00060   }
    00061
    00062   CompanyID index;
    00063   while ((index = (CompanyID)SlIterateArray()) != (CompanyID)-1) {
    00064     _ai_saveload_version = -1;
    00065     SlObject(NULL, _ai_company);
    00066
    00067     if (_networking && !_network_server) {
    00068       if (Company::IsValidAiID(index)) AIInstance::LoadEmpty();
    00069       continue;
    00070     }
    00071
    00072     AIConfig *config = AIConfig::GetConfig(index);
    00073     if (StrEmpty(_ai_saveload_name)) {
    00074       /* A random AI. */
    00075       config->ChangeAI(NULL);
    00076     } else {
    00077       config->ChangeAI(_ai_saveload_name, _ai_saveload_version);
    00078       if (!config->HasAI()) {
    00079         /* No version of the AI available that can load the data. Try to load the
    00080          * latest version of the AI instead. */
    00081         config->ChangeAI(_ai_saveload_name, -1);
    00082         if (!config->HasAI()) {
    00083           if (strcmp(_ai_saveload_name, "%_dummy") != 0) {
    00084             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);
    00085             DEBUG(ai, 0, "A random other AI will be loaded in its place.");
    00086           } else {
    00087             DEBUG(ai, 0, "The savegame had no AIs available at the time of saving.");
    00088             DEBUG(ai, 0, "A random available AI will be loaded now.");
    00089           }
    00090         } else {
    00091           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);
    00092           DEBUG(ai, 0, "The latest version of that AI has been loaded instead, but it'll not get the savegame data as it's incompatible.");
    00093         }
    00094         /* Make sure the AI doesn't get the saveload data, as he was not the
    00095          *  writer of the saveload data in the first place */
    00096         _ai_saveload_version = -1;
    00097       }
    00098     }
    00099
    00100     config->StringToSettings(_ai_saveload_settings);
    00101
    00102     /* Start the AI directly if it was active in the savegame */
    00103     if (Company::IsValidAiID(index)) {
    00104       AI::StartNew(index);
    00105       AI::Load(index, _ai_saveload_version);
    00106     }
    00107   }
    00108 }
    00109
    00110 static void Save_AIPL()
    00111 {
    00112   for (int i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
    00113     SlSetArrayIndex(i);
    00114     SlAutolength((AutolengthProc *)SaveReal_AIPL, &i);
    00115   }
    00116 }
    00117
    00118 extern const ChunkHandler _ai_chunk_handlers[] = {
    00119   { 'AIPL', Save_AIPL, Load_AIPL, NULL, CH_ARRAY | CH_LAST},
    00120 };