Feature: Purchase land multiple tiles at a time
[openttd-github.git] / src / settings_internal.h
blob75b520222c6239d96ad8a10a669b2a9f01718857
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 */
8 /** @file settings_internal.h Functions and types used internally for the settings configurations. */
10 #ifndef SETTINGS_INTERNAL_H
11 #define SETTINGS_INTERNAL_H
13 #include <variant>
14 #include "saveload/saveload.h"
16 enum SettingFlag : uint16 {
17 SF_NONE = 0,
18 SF_GUI_0_IS_SPECIAL = 1 << 0, ///< A value of zero is possible and has a custom string (the one after "strval").
19 SF_GUI_NEGATIVE_IS_SPECIAL = 1 << 1, ///< A negative value has another string (the one after "strval").
20 SF_GUI_DROPDOWN = 1 << 2, ///< The value represents a limited number of string-options (internally integer) presented as dropdown.
21 SF_GUI_CURRENCY = 1 << 3, ///< The number represents money, so when reading value multiply by exchange rate.
22 SF_NETWORK_ONLY = 1 << 4, ///< This setting only applies to network games.
23 SF_NO_NETWORK = 1 << 5, ///< This setting does not apply to network games; it may not be changed during the game.
24 SF_NEWGAME_ONLY = 1 << 6, ///< This setting cannot be changed in a game.
25 SF_SCENEDIT_TOO = 1 << 7, ///< This setting can be changed in the scenario editor (only makes sense when SF_NEWGAME_ONLY is set).
26 SF_SCENEDIT_ONLY = 1 << 8, ///< This setting can only be changed in the scenario editor.
27 SF_PER_COMPANY = 1 << 9, ///< This setting can be different for each company (saved in company struct).
28 SF_NOT_IN_SAVE = 1 << 10, ///< Do not save with savegame, basically client-based.
29 SF_NOT_IN_CONFIG = 1 << 11, ///< Do not save to config file.
30 SF_NO_NETWORK_SYNC = 1 << 12, ///< Do not synchronize over network (but it is saved if SF_NOT_IN_SAVE is not set).
32 DECLARE_ENUM_AS_BIT_SET(SettingFlag)
34 /**
35 * A SettingCategory defines a grouping of the settings.
36 * The group #SC_BASIC is intended for settings which also a novice player would like to change and is able to understand.
37 * The group #SC_ADVANCED is intended for settings which an experienced player would like to use. This is the case for most settings.
38 * Finally #SC_EXPERT settings only few people want to see in rare cases.
39 * The grouping is meant to be inclusive, i.e. all settings in #SC_BASIC also will be included
40 * in the set of settings in #SC_ADVANCED. The group #SC_EXPERT contains all settings.
42 enum SettingCategory {
43 SC_NONE = 0,
45 /* Filters for the list */
46 SC_BASIC_LIST = 1 << 0, ///< Settings displayed in the list of basic settings.
47 SC_ADVANCED_LIST = 1 << 1, ///< Settings displayed in the list of advanced settings.
48 SC_EXPERT_LIST = 1 << 2, ///< Settings displayed in the list of expert settings.
50 /* Setting classification */
51 SC_BASIC = SC_BASIC_LIST | SC_ADVANCED_LIST | SC_EXPERT_LIST, ///< Basic settings are part of all lists.
52 SC_ADVANCED = SC_ADVANCED_LIST | SC_EXPERT_LIST, ///< Advanced settings are part of advanced and expert list.
53 SC_EXPERT = SC_EXPERT_LIST, ///< Expert settings can only be seen in the expert list.
55 SC_END,
58 /**
59 * Type of settings for filtering.
61 enum SettingType {
62 ST_GAME, ///< Game setting.
63 ST_COMPANY, ///< Company setting.
64 ST_CLIENT, ///< Client setting.
66 ST_ALL, ///< Used in setting filter to match all types.
69 struct IniItem;
71 /** Properties of config file settings. */
72 struct SettingDesc {
73 SettingDesc(SaveLoad save, SettingFlag flags, bool startup) :
74 flags(flags), startup(startup), save(save) {}
75 virtual ~SettingDesc() {}
77 SettingFlag flags; ///< Handles how a setting would show up in the GUI (text/currency, etc.).
78 bool startup; ///< Setting has to be loaded directly at startup?.
79 SaveLoad save; ///< Internal structure (going to savegame, parts to config).
81 bool IsEditable(bool do_command = false) const;
82 SettingType GetType() const;
84 /**
85 * Get the name of this setting.
86 * @return The name of the setting.
88 constexpr const std::string &GetName() const
90 return this->save.name;
93 /**
94 * Check whether this setting is an integer type setting.
95 * @return True when the underlying type is an integer.
97 virtual bool IsIntSetting() const { return false; }
99 /**
100 * Check whether this setting is an string type setting.
101 * @return True when the underlying type is a string.
103 virtual bool IsStringSetting() const { return false; }
105 const struct IntSettingDesc *AsIntSetting() const;
106 const struct StringSettingDesc *AsStringSetting() const;
109 * Format the value of the setting associated with this object.
110 * @param buf The before of the buffer to format into.
111 * @param last The end of the buffer to format into.
112 * @param object The object the setting is in.
114 virtual void FormatValue(char *buf, const char *last, const void *object) const = 0;
117 * Parse/read the value from the Ini item into the setting associated with this object.
118 * @param item The Ini item with the content of this setting.
119 * @param object The object the setting is in.
121 virtual void ParseValue(const IniItem *item, void *object) const = 0;
124 * Check whether the value in the Ini item is the same as is saved in this setting in the object.
125 * It might be that determining whether the value is the same is way more expensive than just
126 * writing the value. In those cases this function may unconditionally return false even though
127 * the value might be the same as in the Ini item.
128 * @param item The Ini item with the content of this setting.
129 * @param object The object the setting is in.
130 * @return True if the value is definitely the same (might be false when the same).
132 virtual bool IsSameValue(const IniItem *item, void *object) const = 0;
135 /** Base integer type, including boolean, settings. Only these are shown in the settings UI. */
136 struct IntSettingDesc : SettingDesc {
138 * A check to be performed before the setting gets changed. The passed integer may be
139 * changed by the check if that is important, for example to remove some unwanted bit.
140 * The return value denotes whether the value, potentially after the changes,
141 * is allowed to be used/set in the configuration.
142 * @param value The prospective new value for the setting.
143 * @return True when the setting is accepted.
145 typedef bool PreChangeCheck(int32 &value);
147 * A callback to denote that a setting has been changed.
148 * @param The new value for the setting.
150 typedef void PostChangeCallback(int32 value);
152 IntSettingDesc(SaveLoad save, SettingFlag flags, bool startup, int32 def,
153 int32 min, uint32 max, int32 interval, StringID str, StringID str_help, StringID str_val,
154 SettingCategory cat, PreChangeCheck pre_check, PostChangeCallback post_callback) :
155 SettingDesc(save, flags, startup), def(def), min(min), max(max), interval(interval),
156 str(str), str_help(str_help), str_val(str_val), cat(cat), pre_check(pre_check),
157 post_callback(post_callback) {}
158 virtual ~IntSettingDesc() {}
160 int32 def; ///< default value given when none is present
161 int32 min; ///< minimum values
162 uint32 max; ///< maximum values
163 int32 interval; ///< the interval to use between settings in the 'settings' window. If interval is '0' the interval is dynamically determined
164 StringID str; ///< (translated) string with descriptive text; gui and console
165 StringID str_help; ///< (Translated) string with help text; gui only.
166 StringID str_val; ///< (Translated) first string describing the value.
167 SettingCategory cat; ///< assigned categories of the setting
168 PreChangeCheck *pre_check; ///< Callback to check for the validity of the setting.
169 PostChangeCallback *post_callback; ///< Callback when the setting has been changed.
172 * Check whether this setting is a boolean type setting.
173 * @return True when the underlying type is an integer.
175 virtual bool IsBoolSetting() const { return false; }
176 bool IsIntSetting() const override { return true; }
178 void ChangeValue(const void *object, int32 newvalue) const;
179 void MakeValueValidAndWrite(const void *object, int32 value) const;
181 virtual size_t ParseValue(const char *str) const;
182 void FormatValue(char *buf, const char *last, const void *object) const override;
183 void ParseValue(const IniItem *item, void *object) const override;
184 bool IsSameValue(const IniItem *item, void *object) const override;
185 int32 Read(const void *object) const;
187 private:
188 void MakeValueValid(int32 &value) const;
189 void Write(const void *object, int32 value) const;
192 /** Boolean setting. */
193 struct BoolSettingDesc : IntSettingDesc {
194 BoolSettingDesc(SaveLoad save, SettingFlag flags, bool startup, bool def,
195 StringID str, StringID str_help, StringID str_val, SettingCategory cat,
196 PreChangeCheck pre_check, PostChangeCallback post_callback) :
197 IntSettingDesc(save, flags, startup, def, 0, 1, 0, str, str_help, str_val, cat,
198 pre_check, post_callback) {}
199 virtual ~BoolSettingDesc() {}
201 bool IsBoolSetting() const override { return true; }
202 size_t ParseValue(const char *str) const override;
203 void FormatValue(char *buf, const char *last, const void *object) const override;
206 /** One of many setting. */
207 struct OneOfManySettingDesc : IntSettingDesc {
208 typedef size_t OnConvert(const char *value); ///< callback prototype for conversion error
210 OneOfManySettingDesc(SaveLoad save, SettingFlag flags, bool startup, int32 def,
211 int32 max, StringID str, StringID str_help, StringID str_val, SettingCategory cat,
212 PreChangeCheck pre_check, PostChangeCallback post_callback,
213 std::initializer_list<const char *> many, OnConvert *many_cnvt) :
214 IntSettingDesc(save, flags, startup, def, 0, max, 0, str, str_help, str_val, cat,
215 pre_check, post_callback), many_cnvt(many_cnvt)
217 for (auto one : many) this->many.push_back(one);
220 virtual ~OneOfManySettingDesc() {}
222 std::vector<std::string> many; ///< possible values for this type
223 OnConvert *many_cnvt; ///< callback procedure when loading value mechanism fails
225 static size_t ParseSingleValue(const char *str, size_t len, const std::vector<std::string> &many);
226 char *FormatSingleValue(char *buf, const char *last, uint id) const;
228 size_t ParseValue(const char *str) const override;
229 void FormatValue(char *buf, const char *last, const void *object) const override;
232 /** Many of many setting. */
233 struct ManyOfManySettingDesc : OneOfManySettingDesc {
234 ManyOfManySettingDesc(SaveLoad save, SettingFlag flags, bool startup,
235 int32 def, StringID str, StringID str_help, StringID str_val, SettingCategory cat,
236 PreChangeCheck pre_check, PostChangeCallback post_callback,
237 std::initializer_list<const char *> many, OnConvert *many_cnvt) :
238 OneOfManySettingDesc(save, flags, startup, def, (1 << many.size()) - 1, str, str_help,
239 str_val, cat, pre_check, post_callback, many, many_cnvt) {}
240 virtual ~ManyOfManySettingDesc() {}
242 size_t ParseValue(const char *str) const override;
243 void FormatValue(char *buf, const char *last, const void *object) const override;
246 /** String settings. */
247 struct StringSettingDesc : SettingDesc {
249 * A check to be performed before the setting gets changed. The passed string may be
250 * changed by the check if that is important, for example to remove unwanted white
251 * space. The return value denotes whether the value, potentially after the changes,
252 * is allowed to be used/set in the configuration.
253 * @param value The prospective new value for the setting.
254 * @return True when the setting is accepted.
256 typedef bool PreChangeCheck(std::string &value);
258 * A callback to denote that a setting has been changed.
259 * @param The new value for the setting.
261 typedef void PostChangeCallback(const std::string &value);
263 StringSettingDesc(SaveLoad save, SettingFlag flags, bool startup, const char *def,
264 uint32 max_length, PreChangeCheck pre_check, PostChangeCallback post_callback) :
265 SettingDesc(save, flags, startup), def(def == nullptr ? "" : def), max_length(max_length),
266 pre_check(pre_check), post_callback(post_callback) {}
267 virtual ~StringSettingDesc() {}
269 std::string def; ///< Default value given when none is present
270 uint32 max_length; ///< Maximum length of the string, 0 means no maximum length
271 PreChangeCheck *pre_check; ///< Callback to check for the validity of the setting.
272 PostChangeCallback *post_callback; ///< Callback when the setting has been changed.
274 bool IsStringSetting() const override { return true; }
275 void ChangeValue(const void *object, std::string &newval) const;
277 void FormatValue(char *buf, const char *last, const void *object) const override;
278 void ParseValue(const IniItem *item, void *object) const override;
279 bool IsSameValue(const IniItem *item, void *object) const override;
280 const std::string &Read(const void *object) const;
282 private:
283 void MakeValueValid(std::string &str) const;
284 void Write(const void *object, const std::string &str) const;
287 /** List/array settings. */
288 struct ListSettingDesc : SettingDesc {
289 ListSettingDesc(SaveLoad save, SettingFlag flags, bool startup, const char *def) :
290 SettingDesc(save, flags, startup), def(def) {}
291 virtual ~ListSettingDesc() {}
293 const char *def; ///< default value given when none is present
295 void FormatValue(char *buf, const char *last, const void *object) const override;
296 void ParseValue(const IniItem *item, void *object) const override;
297 bool IsSameValue(const IniItem *item, void *object) const override;
300 /** Placeholder for settings that have been removed, but might still linger in the savegame. */
301 struct NullSettingDesc : SettingDesc {
302 NullSettingDesc(SaveLoad save) :
303 SettingDesc(save, SF_NOT_IN_CONFIG, false) {}
304 virtual ~NullSettingDesc() {}
306 void FormatValue(char *buf, const char *last, const void *object) const override { NOT_REACHED(); }
307 void ParseValue(const IniItem *item, void *object) const override { NOT_REACHED(); }
308 bool IsSameValue(const IniItem *item, void *object) const override { NOT_REACHED(); }
311 typedef std::variant<IntSettingDesc, BoolSettingDesc, OneOfManySettingDesc, ManyOfManySettingDesc, StringSettingDesc, ListSettingDesc, NullSettingDesc> SettingVariant;
314 * Helper to convert the type of the iterated settings description to a pointer to it.
315 * @param desc The type of the iterator of the value in SettingTable.
316 * @return The actual pointer to SettingDesc.
318 static constexpr const SettingDesc *GetSettingDesc(const SettingVariant &desc)
320 return std::visit([](auto&& arg) -> const SettingDesc * { return &arg; }, desc);
323 typedef span<const SettingVariant> SettingTable;
325 const SettingDesc *GetSettingFromName(const std::string_view name);
326 void GetSaveLoadFromSettingTable(SettingTable settings, std::vector<SaveLoad> &saveloads);
327 bool SetSettingValue(const IntSettingDesc *sd, int32 value, bool force_newgame = false);
328 bool SetSettingValue(const StringSettingDesc *sd, const std::string value, bool force_newgame = false);
330 #endif /* SETTINGS_INTERNAL_H */