OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

script_config.cpp
Go to the documentation of this file.
1 /* $Id: script_config.cpp 26509 2014-04-25 15:40:32Z rubidium $ */
2
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
9
12 #include "../stdafx.h"
13 #include "../settings_type.h"
14 #include "../core/random_func.hpp"
15 #include "script_info.hpp"
16 #include "../textfile_gui.h"
17 #include "../string_func.h"
18
19 #include "../safeguards.h"
20
21 void ScriptConfig::Change(const char *name, int version, bool force_exact_match, bool is_random)
22 {
23 free(this->name);
24 this->name = (name == NULL) ? NULL : stredup(name);
25 this->info = (name == NULL) ? NULL : this->FindInfo(this->name, version, force_exact_match);
26 this->version = (info == NULL) ? -1 : info->GetVersion();
27 this->is_random = is_random;
28 if (this->config_list != NULL) delete this->config_list;
29 this->config_list = (info == NULL) ? NULL : new ScriptConfigItemList();
30 if (this->config_list != NULL) this->PushExtraConfigList();
31
32 this->ClearConfigList();
33
34 if (_game_mode == GM_NORMAL && this->info != NULL) {
35 /* If we're in an existing game and the Script is changed, set all settings
36 * for the Script that have the random flag to a random value. */
37 for (ScriptConfigItemList::const_iterator it = this->info->GetConfigList()->begin(); it != this->info->GetConfigList()->end(); it++) {
38 if ((*it).flags & SCRIPTCONFIG_RANDOM) {
39 this->SetSetting((*it).name, InteractiveRandomRange((*it).max_value - (*it).min_value) + (*it).min_value);
40 }
41 }
42 this->AddRandomDeviation();
43 }
44 }
45
46 ScriptConfig::ScriptConfig(const ScriptConfig *config)
47 {
48 this->name = (config->name == NULL) ? NULL : stredup(config->name);
49 this->info = config->info;
50 this->version = config->version;
51 this->config_list = NULL;
52 this->is_random = config->is_random;
53
54 for (SettingValueList::const_iterator it = config->settings.begin(); it != config->settings.end(); it++) {
55 this->settings[stredup((*it).first)] = (*it).second;
56 }
57 this->AddRandomDeviation();
58 }
59
60 ScriptConfig::~ScriptConfig()
61 {
62 free(this->name);
63 this->ResetSettings();
64 if (this->config_list != NULL) delete this->config_list;
65 }
66
67 ScriptInfo *ScriptConfig::GetInfo() const
68 {
69 return this->info;
70 }
71
72 const ScriptConfigItemList *ScriptConfig::GetConfigList()
73 {
74 if (this->info != NULL) return this->info->GetConfigList();
75 if (this->config_list == NULL) {
76 this->config_list = new ScriptConfigItemList();
77 this->PushExtraConfigList();
78 }
79 return this->config_list;
80 }
81
82 void ScriptConfig::ClearConfigList()
83 {
84 for (SettingValueList::iterator it = this->settings.begin(); it != this->settings.end(); it++) {
85 free((*it).first);
86 }
87 this->settings.clear();
88 }
89
90 void ScriptConfig::AnchorUnchangeableSettings()
91 {
92 for (ScriptConfigItemList::const_iterator it = this->GetConfigList()->begin(); it != this->GetConfigList()->end(); it++) {
93 if (((*it).flags & SCRIPTCONFIG_INGAME) == 0) {
94 this->SetSetting((*it).name, this->GetSetting((*it).name));
95 }
96 }
97 }
98
99 int ScriptConfig::GetSetting(const char *name) const
100 {
101 SettingValueList::const_iterator it = this->settings.find(name);
102 if (it == this->settings.end()) return this->info->GetSettingDefaultValue(name);
103 return (*it).second;
104 }
105
106 void ScriptConfig::SetSetting(const char *name, int value)
107 {
108 /* You can only set Script specific settings if an Script is selected. */
109 if (this->info == NULL) return;
110
111 const ScriptConfigItem *config_item = this->info->GetConfigItem(name);
112 if (config_item == NULL) return;
113
114 value = Clamp(value, config_item->min_value, config_item->max_value);
115
116 SettingValueList::iterator it = this->settings.find(name);
117 if (it != this->settings.end()) {
118 (*it).second = value;
119 } else {
120 this->settings[stredup(name)] = value;
121 }
122 }
123
124 void ScriptConfig::ResetSettings()
125 {
126 for (SettingValueList::iterator it = this->settings.begin(); it != this->settings.end(); it++) {
127 free((*it).first);
128 }
129 this->settings.clear();
130 }
131
132 void ScriptConfig::AddRandomDeviation()
133 {
134 for (ScriptConfigItemList::const_iterator it = this->GetConfigList()->begin(); it != this->GetConfigList()->end(); it++) {
135 if ((*it).random_deviation != 0) {
136 this->SetSetting((*it).name, InteractiveRandomRange((*it).random_deviation * 2) - (*it).random_deviation + this->GetSetting((*it).name));
137 }
138 }
139 }
140
141 bool ScriptConfig::HasScript() const
142 {
143 return this->info != NULL;
144 }
145
146 bool ScriptConfig::IsRandom() const
147 {
148 return this->is_random;
149 }
150
151 const char *ScriptConfig::GetName() const
152 {
153 return this->name;
154 }
155
156 int ScriptConfig::GetVersion() const
157 {
158 return this->version;
159 }
160
161 void ScriptConfig::StringToSettings(const char *value)
162 {
163 char *value_copy = stredup(value);
164 char *s = value_copy;
165
166 while (s != NULL) {
167 /* Analyze the string ('name=value,name=value\0') */
168 char *item_name = s;
169 s = strchr(s, '=');
170 if (s == NULL) break;
171 if (*s == '\0') break;
172 *s = '\0';
173 s++;
174
175 char *item_value = s;
176 s = strchr(s, ',');
177 if (s != NULL) {
178 *s = '\0';
179 s++;
180 }
181
182 this->SetSetting(item_name, atoi(item_value));
183 }
184 free(value_copy);
185 }
186
187 void ScriptConfig::SettingsToString(char *string, const char *last) const
188 {
189 char *s = string;
190 *s = '\0';
191 for (SettingValueList::const_iterator it = this->settings.begin(); it != this->settings.end(); it++) {
192 char no[10];
193 seprintf(no, lastof(no), "%d", (*it).second);
194
195 /* Check if the string would fit in the destination */
196 size_t needed_size = strlen((*it).first) + 1 + strlen(no);
197 /* If it doesn't fit, skip the next settings */
198 if (string + needed_size > last) break;
199
200 s = strecat(s, (*it).first, last);
201 s = strecat(s, "=", last);
202 s = strecat(s, no, last);
203 s = strecat(s, ",", last);
204 }
205
206 /* Remove the last ',', but only if at least one setting was saved. */
207 if (s != string) s[-1] = '\0';
208 }
209
210 const char *ScriptConfig::GetTextfile(TextfileType type, CompanyID slot) const
211 {
212 if (slot == INVALID_COMPANY || this->GetInfo() == NULL) return NULL;
213
214 return ::GetTextfile(type, (slot == OWNER_DEITY) ? GAME_DIR : AI_DIR, this->GetInfo()->GetMainScript());
215 }