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/>.
8 /** @file script_text.hpp Everything to handle text which can be translated. */
10 #ifndef SCRIPT_TEXT_HPP
11 #define SCRIPT_TEXT_HPP
13 #include "script_object.hpp"
18 * Internal parent object of all Text-like objects.
21 class Text
: public ScriptObject
{
24 * Convert a ScriptText to a normal string.
28 virtual std::string
GetEncodedText() = 0;
31 * Convert a #ScriptText into a decoded normal string.
35 const std::string
GetDecodedText();
39 * Internally used class to create a raw text in a Text object.
42 class RawText
: public Text
{
44 RawText(const std::string
&text
) : text(text
) {}
46 std::string
GetEncodedText() override
{ return this->text
; }
48 const std::string text
;
52 * Class that handles all text related functions. You can define a language
53 * file in lang/english.txt, in the same format as OpenTTD does, including
54 * tags like {BLACK}, {STRING1} etc. The name given to this string is made
55 * available to you in ScriptText, for example: ScriptText.STR_NEWS, if your
56 * english.txt contains: STR_NEWS :{BLACK}Welcome {COMPANY}!
58 * In translation files like lang/dutch.txt you can then translate such
59 * strings, like: STR_NEWS :{BLACK}Hallo {COMPANY}!
60 * When the user has the dutch language selected, it will automatically use
61 * the translated string when available. The fallback language is always
62 * the english language.
64 * If you use parameters in your strings, you will have to define those
65 * parameters, for example like this:
66 * \code local text = ScriptText(ScriptText.STR_NEWS);
67 * text.AddParam(1); \endcode
68 * This will set the {COMPANY} to the name of Company 1. Alternatively you
69 * can directly give those arguments to the ScriptText constructor, like this:
70 * \code local text = ScriptText(ScriptText.STR_NEWS, 1); \endcode
74 class ScriptText
: public Text
{
76 static const int SCRIPT_TEXT_MAX_PARAMETERS
= 20; ///< The maximum amount of parameters you can give to one object.
80 * The constructor wrapper from Squirrel.
82 ScriptText(HSQUIRRELVM vm
);
85 * Generate a text from string. You can set parameters to the instance which
86 * can be required for the string.
87 * @param string The string of the text.
88 * @param ... Optional arguments for this string.
90 ScriptText(StringID string
, ...);
91 #endif /* DOXYGEN_API */
95 * Used for .param_N and [] set from Squirrel.
97 SQInteger
_set(HSQUIRRELVM vm
);
102 SQInteger
SetParam(HSQUIRRELVM vm
);
107 SQInteger
AddParam(HSQUIRRELVM vm
);
110 * Set the parameter to a value.
111 * @param parameter Which parameter to set.
112 * @param value The value of the parameter. Has to be string, integer or an instance of the class ScriptText.
114 void SetParam(int parameter
, object value
);
117 * Add a value as parameter (appending it).
118 * @param value The value of the parameter. Has to be string, integer or an instance of the class ScriptText.
119 * @return The same object as on which this is called, so you can chain.
121 ScriptText
*AddParam(object value
);
122 #endif /* DOXYGEN_API */
127 std::string
GetEncodedText() override
;
130 using ScriptTextRef
= ScriptObjectRef
<ScriptText
>;
131 using ScriptTextList
= std::vector
<ScriptText
*>;
132 using Param
= std::variant
<SQInteger
, std::string
, ScriptTextRef
>;
135 StringIndexInTab owner
;
139 const char *cmd
= nullptr;
141 ParamCheck(StringIndexInTab owner
, int idx
, Param
*param
) : owner(owner
), idx(idx
), param(param
) {}
143 void Encode(std::back_insert_iterator
<std::string
> &output
, const char *cmd
);
146 using ParamList
= std::vector
<ParamCheck
>;
147 using ParamSpan
= std::span
<ParamCheck
>;
149 StringIndexInTab string
;
150 std::array
<Param
, SCRIPT_TEXT_MAX_PARAMETERS
> param
= {};
154 * Internal function to recursively fill a list of parameters.
155 * The parameters are added as _GetEncodedText used to encode them
156 * before the addition of parameter validation.
157 * @param params The list of parameters to fill.
158 * @param seen_texts The list of seen ScriptText.
160 void _FillParamList(ParamList
¶ms
, ScriptTextList
&seen_texts
);
163 * Internal function for recursive calling this function over multiple
164 * instances, while writing in the same buffer.
165 * @param output The output to write the encoded text to.
166 * @param param_count The number of parameters that are consumed by the string.
167 * @param args The parameters to be consumed.
168 * @param first Whether it's the first call in the recursion.
170 void _GetEncodedText(std::back_insert_iterator
<std::string
> &output
, int ¶m_count
, ParamSpan args
, bool first
);
173 * Set a parameter, where the value is the first item on the stack.
175 SQInteger
_SetParam(int k
, HSQUIRRELVM vm
);
178 #endif /* SCRIPT_TEXT_HPP */