ai_config.cpp
Go to the documentation of this file.00001
00002
00005 #include "../stdafx.h"
00006 #include "../openttd.h"
00007 #include "../settings_type.h"
00008 #include "../core/random_func.hpp"
00009 #include "ai.hpp"
00010 #include "ai_config.hpp"
00011
00012 void AIConfig::ChangeAI(const char *name, int version)
00013 {
00014 free((void *)this->name);
00015 this->name = (name == NULL) ? NULL : strdup(name);
00016 this->info = (name == NULL) ? NULL : AI::FindInfo(this->name, version);
00017 this->version = (info == NULL) ? -1 : info->GetVersion();
00018 if (this->config_list != NULL) delete this->config_list;
00019 this->config_list = (info == NULL) ? NULL : new AIConfigItemList();
00020 if (this->config_list != NULL) this->config_list->push_back(_start_date_config);
00021
00022
00023
00024 int start_date = this->GetSetting("start_date");
00025
00026 for (SettingValueList::iterator it = this->settings.begin(); it != this->settings.end(); it++) {
00027 free((void*)(*it).first);
00028 }
00029 this->settings.clear();
00030
00031 this->SetSetting("start_date", start_date);
00032
00033 if (_game_mode == GM_NORMAL && this->info != NULL) {
00034
00035
00036 for (AIConfigItemList::const_iterator it = this->info->GetConfigList()->begin(); it != this->info->GetConfigList()->end(); it++) {
00037 if ((*it).flags & AICONFIG_RANDOM) {
00038 this->SetSetting((*it).name, InteractiveRandomRange((*it).max_value - (*it).min_value) + (*it).min_value);
00039 }
00040 }
00041 this->AddRandomDeviation();
00042 }
00043
00044 }
00045
00046 AIConfig::AIConfig(const AIConfig *config)
00047 {
00048 this->name = (config->name == NULL) ? NULL : strdup(config->name);
00049 this->info = config->info;
00050 this->version = config->version;
00051 this->config_list = NULL;
00052
00053 for (SettingValueList::const_iterator it = config->settings.begin(); it != config->settings.end(); it++) {
00054 this->settings[strdup((*it).first)] = (*it).second;
00055 }
00056 this->AddRandomDeviation();
00057 }
00058
00059 AIConfig::~AIConfig()
00060 {
00061 free((void *)this->name);
00062 this->ResetSettings();
00063 if (this->config_list != NULL) delete this->config_list;
00064 }
00065
00066 AIInfo *AIConfig::GetInfo()
00067 {
00068 return this->info;
00069 }
00070
00071 bool AIConfig::ResetInfo()
00072 {
00073 this->info = AI::FindInfo(this->name, -1);
00074 return this->info != NULL;
00075 }
00076
00077 const AIConfigItemList *AIConfig::GetConfigList()
00078 {
00079 if (this->info != NULL) return this->info->GetConfigList();
00080 if (this->config_list == NULL) {
00081 this->config_list = new AIConfigItemList();
00082 this->config_list->push_back(_start_date_config);
00083 }
00084 return this->config_list;
00085 }
00086
00087 AIConfig *AIConfig::GetConfig(CompanyID company, bool forceNewgameSetting)
00088 {
00089 AIConfig **config;
00090 if (!forceNewgameSetting) {
00091 config = (_game_mode == GM_MENU) ? &_settings_newgame.ai_config[company] : &_settings_game.ai_config[company];
00092 } else {
00093 config = &_settings_newgame.ai_config[company];
00094 }
00095 if (*config == NULL) *config = new AIConfig();
00096 return *config;
00097 }
00098
00099 int AIConfig::GetSetting(const char *name)
00100 {
00101 SettingValueList::iterator it = this->settings.find(name);
00102
00103 if (it == this->settings.end() || ((_game_mode == GM_MENU) ? _settings_newgame.difficulty.diff_level : _settings_game.difficulty.diff_level) != 3) {
00104 if (this->info == NULL) {
00105 assert(strcmp("start_date", name) == 0);
00106 switch ((_game_mode == GM_MENU) ? _settings_newgame.difficulty.diff_level : _settings_game.difficulty.diff_level) {
00107 case 0: return AI::START_NEXT_EASY;
00108 case 1: return AI::START_NEXT_MEDIUM;
00109 case 2: return AI::START_NEXT_HARD;
00110 case 3: return AI::START_NEXT_MEDIUM;
00111 default: NOT_REACHED();
00112 }
00113 }
00114 return this->info->GetSettingDefaultValue(name);
00115 }
00116 return (*it).second;
00117 }
00118
00119 void AIConfig::SetSetting(const char *name, int value)
00120 {
00121
00122 if (this->info == NULL && strcmp("start_date", name) != 0) return;
00123
00124 if (this->info == NULL && strcmp("start_date", name) == 0) {
00125 value = Clamp(value, AI::START_NEXT_MIN, AI::START_NEXT_MAX);
00126 } else {
00127 const AIConfigItem *config_item = this->info->GetConfigItem(name);
00128 if (config_item == NULL) return;
00129
00130 value = Clamp(value, config_item->min_value, config_item->max_value);
00131 }
00132
00133 SettingValueList::iterator it = this->settings.find(name);
00134 if (it != this->settings.end()) {
00135 (*it).second = value;
00136 } else {
00137 this->settings[strdup(name)] = value;
00138 }
00139 }
00140
00141 void AIConfig::ResetSettings()
00142 {
00143 for (SettingValueList::iterator it = this->settings.begin(); it != this->settings.end(); it++) {
00144 free((void*)(*it).first);
00145 }
00146 this->settings.clear();
00147 }
00148
00149 void AIConfig::AddRandomDeviation()
00150 {
00151 for (AIConfigItemList::const_iterator it = this->GetConfigList()->begin(); it != this->GetConfigList()->end(); it++) {
00152 if ((*it).random_deviation != 0) {
00153 this->SetSetting((*it).name, InteractiveRandomRange((*it).random_deviation * 2) - (*it).random_deviation + this->GetSetting((*it).name));
00154 }
00155 }
00156 }
00157
00158 bool AIConfig::HasAI()
00159 {
00160 return this->info != NULL;
00161 }
00162
00163 const char *AIConfig::GetName()
00164 {
00165 return this->name;
00166 }
00167
00168 int AIConfig::GetVersion()
00169 {
00170 return this->version;
00171 }
00172
00173 void AIConfig::StringToSettings(const char *value)
00174 {
00175 char *value_copy = strdup(value);
00176 char *s = value_copy;
00177
00178 while (s != NULL) {
00179
00180 char *item_name = s;
00181 s = strchr(s, '=');
00182 if (s == NULL) break;
00183 if (*s == '\0') break;
00184 *s = '\0';
00185 s++;
00186
00187 char *item_value = s;
00188 s = strchr(s, ',');
00189 if (s != NULL) {
00190 *s = '\0';
00191 s++;
00192 }
00193
00194 this->SetSetting(item_name, atoi(item_value));
00195 }
00196 free(value_copy);
00197 }
00198
00199 void AIConfig::SettingsToString(char *string, size_t size)
00200 {
00201 string[0] = '\0';
00202 for (SettingValueList::iterator it = this->settings.begin(); it != this->settings.end(); it++) {
00203 char no[10];
00204 snprintf(no, sizeof(no), "%d", (*it).second);
00205
00206
00207 size_t needed_size = strlen((*it).first) + 1 + strlen(no) + 1;
00208
00209 if (size <= needed_size) break;
00210 size -= needed_size;
00211
00212 strcat(string, (*it).first);
00213 strcat(string, "=");
00214 strcat(string, no);
00215 strcat(string, ",");
00216 }
00217
00218 size_t len = strlen(string);
00219 if (len > 0) string[len - 1] = '\0';
00220 }