OpenTTD
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 
61 {
62  free(this->name);
63  this->ResetSettings();
64  if (this->config_list != NULL) delete this->config_list;
65 }
66 
68 {
69  return this->info;
70 }
71 
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 
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 
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 
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 
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 
142 {
143  return this->info != NULL;
144 }
145 
147 {
148  return this->is_random;
149 }
150 
151 const char *ScriptConfig::GetName() const
152 {
153  return this->name;
154 }
155 
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 }
int GetVersion() const
Get the version of the script.
Definition: script_info.hpp:74
static char * strecat(char *dst, const char *src, const char *last)
Appends characters from one string to another.
Definition: depend.cpp:99
const char * GetTextfile(TextfileType type, CompanyID slot) const
Search a textfile file next to this script.
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Definition: string.cpp:398
const ScriptConfigItemList * GetConfigList()
Get the config list for this ScriptConfig.
const ScriptConfigItemList * GetConfigList() const
Get the config list for this Script.
int min_value
The minimal value this configuration setting can have.
std::list< ScriptConfigItem > ScriptConfigItemList
List of ScriptConfig items.
void Change(const char *name, int version=-1, bool force_exact_match=false, bool is_random=false)
Set another Script to be loaded in this slot.
SettingValueList settings
List with all setting=>value pairs that are configure for this Script.
Subdirectory for all game scripts.
Definition: fileio_type.h:123
int max_value
The maximal value this configuration setting can have.
int GetSettingDefaultValue(const char *name) const
Get the default value for a setting.
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:50
Script settings.
void AddRandomDeviation()
Randomize all settings the Script requested to be randomized.
bool is_random
True if the AI in this slot was randomly chosen.
ScriptConfigItemList * config_list
List with all settings defined by this Script.
const char * GetName() const
Get the name of the Script.
The object is owned by a superuser / goal script.
Definition: company_type.h:29
bool IsRandom() const
Is the current Script a randomly chosen Script?
virtual void ClearConfigList()
Routine that clears the config list.
class ScriptInfo * GetInfo() const
Get the ScriptInfo linked to this ScriptConfig.
virtual ScriptInfo * FindInfo(const char *name, int version, bool force_exact_match)=0
This function should call back to the Scanner in charge of this Config, to find the ScriptInfo belong...
bool HasScript() const
Is this config attached to an Script? In other words, is there a Script that is assigned to this slot...
All static information from an Script like name, version, etc.
Definition: script_info.hpp:32
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Definition: string.cpp:126
When randomizing the Script, pick any value between min_value and max_value when on custom difficulty...
TextfileType
Additional text files accompanying Tar archives.
Definition: textfile_type.h:16
const ScriptConfigItem * GetConfigItem(const char *name) const
Get the description of a certain Script config option.
virtual void SetSetting(const char *name, int value)
Set the value of a setting for this config.
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:139
Info about a single Script setting.
int version
Version of the Script.
Subdirectory for all AI files.
Definition: fileio_type.h:121
void AnchorUnchangeableSettings()
As long as the default of a setting has not been changed, the value of the setting is not stored...
This setting can be changed while the Script is running.
class ScriptInfo * info
ScriptInfo object for related to this Script version.
void ResetSettings()
Reset all settings to their default value.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:114
virtual int GetSetting(const char *name) const
Get the value of a setting for this config.
virtual ~ScriptConfig()
Delete an Script configuration.
const char * name
Name of the Script.
Owner
Enum for all companies/owners.
Definition: company_type.h:20
const char * GetTextfile(TextfileType type, Subdirectory dir, const char *filename)
Search a textfile file next to the given content.
void StringToSettings(const char *value)
Convert a string which is stored in the config file or savegames to custom settings of this Script...
void SettingsToString(char *string, const char *last) const
Convert the custom settings to a string that can be stored in the config file or savegames.
virtual void PushExtraConfigList()
In case you have mandatory non-Script-definable config entries in your list, add them to this functio...
An invalid company.
Definition: company_type.h:32
ScriptInfo keeps track of all information of a script, like Author, Description, ...
int GetVersion() const
Get the version of the Script.