Files @ r11049:6eb2c87ed64a
Branch filter:

Location: cpp/openttd-patchpack/source/src/ai/ai_config.cpp - annotation

peter1138
(svn r15389) -Feature: Add ability to select which base graphics set is used from the Game Options window. The change takes effect when the window is closed. This option can only be used from the intro menu, as reloading graphics during a game may cause issues.
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10723:2143de457ff9
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10713:ba92067a4b49
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10713:ba92067a4b49
r10712:3ee31720391b
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10696:8dfe83e30d01
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10723:2143de457ff9
r10730:c4f9653e3345
r10730:c4f9653e3345
r10723:2143de457ff9
r10723:2143de457ff9
r10723:2143de457ff9
r10723:2143de457ff9
r10723:2143de457ff9
r10723:2143de457ff9
r10723:2143de457ff9
r10723:2143de457ff9
r10730:c4f9653e3345
r10723:2143de457ff9
r10723:2143de457ff9
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10712:3ee31720391b
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10712:3ee31720391b
r10840:7a608f4ad153
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10730:c4f9653e3345
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10788:e413614a4b4e
r10840:7a608f4ad153
r10840:7a608f4ad153
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10849:8e532db71075
r10849:8e532db71075
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10730:c4f9653e3345
r10724:cec22216aab8
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10724:cec22216aab8
r10730:c4f9653e3345
r10730:c4f9653e3345
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10840:7a608f4ad153
r10730:c4f9653e3345
r10730:c4f9653e3345
r10840:7a608f4ad153
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10730:c4f9653e3345
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10712:3ee31720391b
r10712:3ee31720391b
r10712:3ee31720391b
r10712:3ee31720391b
r10712:3ee31720391b
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10880:f94c832ac1e6
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10696:8dfe83e30d01
r10836:2daa1e2f98f5
r10836:2daa1e2f98f5
r10836:2daa1e2f98f5
r10696:8dfe83e30d01
/* $Id$ */

/** @file ai_config.cpp Implementation of AIConfig. */

#include "../stdafx.h"
#include "../openttd.h"
#include "../settings_type.h"
#include "../core/random_func.hpp"
#include "ai.hpp"
#include "ai_config.hpp"

void AIConfig::ChangeAI(const char *name, int version)
{
	free((void *)this->name);
	this->name = (name == NULL) ? NULL : strdup(name);
	this->info = (name == NULL) ? NULL : AI::FindInfo(this->name, version);
	this->version = (info == NULL) ? -1 : info->GetVersion();
	if (this->config_list != NULL) delete this->config_list;
	this->config_list = (info == NULL) ? NULL : new AIConfigItemList();
	if (this->config_list != NULL) this->config_list->push_back(_start_date_config);

	/* The special casing for start_date is here to ensure that the
	 *  start_date setting won't change even if you chose another AI. */
	int start_date = this->GetSetting("start_date");

	for (SettingValueList::iterator it = this->settings.begin(); it != this->settings.end(); it++) {
		free((void*)(*it).first);
	}
	this->settings.clear();

	this->SetSetting("start_date", start_date);

	if (_game_mode == GM_NORMAL && this->info != NULL) {
		/* If we're in an existing game and the AI is changed, set all settings
		 *  for the AI that have the random flag to a random value. */
		for (AIConfigItemList::const_iterator it = this->info->GetConfigList()->begin(); it != this->info->GetConfigList()->end(); it++) {
			if ((*it).flags & AICONFIG_RANDOM) {
				this->SetSetting((*it).name, InteractiveRandomRange((*it).max_value - (*it).min_value) + (*it).min_value);
			}
		}
		this->AddRandomDeviation();
	}

}

AIConfig::AIConfig(const AIConfig *config)
{
	this->name = (config->name == NULL) ? NULL : strdup(config->name);
	this->info = config->info;
	this->version = config->version;
	this->config_list = NULL;

	for (SettingValueList::const_iterator it = config->settings.begin(); it != config->settings.end(); it++) {
		this->settings[strdup((*it).first)] = (*it).second;
	}
	this->AddRandomDeviation();
}

AIConfig::~AIConfig()
{
	free((void *)this->name);
	this->ResetSettings();
	if (this->config_list != NULL) delete this->config_list;
}

AIInfo *AIConfig::GetInfo()
{
	return this->info;
}

bool AIConfig::ResetInfo()
{
	this->info = AI::FindInfo(this->name, -1);
	return this->info != NULL;
}

const AIConfigItemList *AIConfig::GetConfigList()
{
	if (this->info != NULL) return this->info->GetConfigList();
	if (this->config_list == NULL) {
		this->config_list = new AIConfigItemList();
		this->config_list->push_back(_start_date_config);
	}
	return this->config_list;
}

AIConfig *AIConfig::GetConfig(CompanyID company, bool forceNewgameSetting)
{
	AIConfig **config;
	if (!forceNewgameSetting) {
		config = (_game_mode == GM_MENU) ? &_settings_newgame.ai_config[company] : &_settings_game.ai_config[company];
	} else {
		config = &_settings_newgame.ai_config[company];
	}
	if (*config == NULL) *config = new AIConfig();
	return *config;
}

int AIConfig::GetSetting(const char *name)
{
	SettingValueList::iterator it = this->settings.find(name);
	/* Return the default value if the setting is not set, or if we are in a not-custom difficult level */
	if (it == this->settings.end() || ((_game_mode == GM_MENU) ? _settings_newgame.difficulty.diff_level : _settings_game.difficulty.diff_level) != 3) {
		if (this->info == NULL) {
			assert(strcmp("start_date", name) == 0);
			switch ((_game_mode == GM_MENU) ? _settings_newgame.difficulty.diff_level : _settings_game.difficulty.diff_level) {
				case 0: return AI::START_NEXT_EASY;
				case 1: return AI::START_NEXT_MEDIUM;
				case 2: return AI::START_NEXT_HARD;
				case 3: return AI::START_NEXT_MEDIUM;
				default: NOT_REACHED();
			}
		}
		return this->info->GetSettingDefaultValue(name);
	}
	return (*it).second;
}

void AIConfig::SetSetting(const char *name, int value)
{
	/* You can only set ai specific settings if an AI is selected. */
	if (this->info == NULL && strcmp("start_date", name) != 0) return;

	if (this->info == NULL && strcmp("start_date", name) == 0) {
		value = Clamp(value, AI::START_NEXT_MIN, AI::START_NEXT_MAX);
	} else {
		const AIConfigItem *config_item = this->info->GetConfigItem(name);
		if (config_item == NULL) return;

		value = Clamp(value, config_item->min_value, config_item->max_value);
	}

	SettingValueList::iterator it = this->settings.find(name);
	if (it != this->settings.end()) {
		(*it).second = value;
	} else {
		this->settings[strdup(name)] = value;
	}
}

void AIConfig::ResetSettings()
{
	for (SettingValueList::iterator it = this->settings.begin(); it != this->settings.end(); it++) {
		free((void*)(*it).first);
	}
	this->settings.clear();
}

void AIConfig::AddRandomDeviation()
{
	for (AIConfigItemList::const_iterator it = this->GetConfigList()->begin(); it != this->GetConfigList()->end(); it++) {
		if ((*it).random_deviation != 0) {
			this->SetSetting((*it).name, InteractiveRandomRange((*it).random_deviation * 2) - (*it).random_deviation + this->GetSetting((*it).name));
		}
	}
}

bool AIConfig::HasAI()
{
	return this->info != NULL;
}

const char *AIConfig::GetName()
{
	return this->name;
}

int AIConfig::GetVersion()
{
	return this->version;
}

void AIConfig::StringToSettings(const char *value)
{
	char *value_copy = strdup(value);
	char *s = value_copy;

	while (s != NULL) {
		/* Analyze the string ('name=value,name=value\0') */
		char *item_name = s;
		s = strchr(s, '=');
		if (s == NULL) break;
		if (*s == '\0') break;
		*s = '\0';
		s++;

		char *item_value = s;
		s = strchr(s, ',');
		if (s != NULL) {
			*s = '\0';
			s++;
		}

		this->SetSetting(item_name, atoi(item_value));
	}
	free(value_copy);
}

void AIConfig::SettingsToString(char *string, size_t size)
{
	string[0] = '\0';
	for (SettingValueList::iterator it = this->settings.begin(); it != this->settings.end(); it++) {
		char no[10];
		snprintf(no, sizeof(no), "%d", (*it).second);

		/* Check if the string would fit in the destination */
		size -= strlen((*it).first) - 1 - strlen(no) - 1;
		/* If it doesn't fit, skip the next settings */
		if (size <= 0) return;

		strcat(string, (*it).first);
		strcat(string, "=");
		strcat(string, no);
		strcat(string, ",");
	}
	/* Remove the last ',', but only if at least one setting was saved. */
	size_t len = strlen(string);
	if (len > 0) string[len - 1] = '\0';
}