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