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