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 
8 /** @file script_text.hpp Everything to handle text which can be translated. */
9 
10 #ifndef SCRIPT_TEXT_HPP
11 #define SCRIPT_TEXT_HPP
12 
13 #include "script_object.hpp"
14 #include "../../core/alloc_type.hpp"
15 
16 /**
17  * Internal parent object of all Text-like objects.
18  * @api -all
19  */
20 class Text : public ScriptObject {
21 public:
22 	/**
23 	 * Convert a ScriptText to a normal string.
24 	 * @return A string (in a static buffer), or nullptr.
25 	 * @api -all
26 	 */
27 	virtual const char *GetEncodedText() = 0;
28 
29 	/**
30 	 * Convert a #ScriptText into a decoded normal string.
31 	 * @return A string (in a static buffer), or nullptr.
32 	 * @api -all
33 	 */
34 	const char *GetDecodedText();
35 };
36 
37 /**
38  * Internally used class to create a raw text in a Text object.
39  * @api -all
40  */
41 class RawText : public Text {
42 public:
43 	RawText(const char *text);
44 	~RawText();
45 
GetEncodedText()46 	const char *GetEncodedText() override { return this->text; }
47 private:
48 	const char *text;
49 };
50 
51 /**
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}!
57  *
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.
63  *
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
71  *
72  * @api game
73  */
74 class ScriptText : public Text , public ZeroedMemoryAllocator {
75 public:
76 	static const int SCRIPT_TEXT_MAX_PARAMETERS = 20; ///< The maximum amount of parameters you can give to one object.
77 
78 #ifndef DOXYGEN_API
79 	/**
80 	 * The constructor wrapper from Squirrel.
81 	 */
82 	ScriptText(HSQUIRRELVM vm);
83 #else
84 	/**
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.
89 	 */
90 	ScriptText(StringID string, ...);
91 #endif /* DOXYGEN_API */
92 	~ScriptText();
93 
94 #ifndef DOXYGEN_API
95 	/**
96 	 * Used for .param_N and [] set from Squirrel.
97 	 */
98 	SQInteger _set(HSQUIRRELVM vm);
99 
100 	/**
101 	 * Set the parameter.
102 	 */
103 	SQInteger SetParam(HSQUIRRELVM vm);
104 
105 	/**
106 	 * Add an parameter
107 	 */
108 	SQInteger AddParam(HSQUIRRELVM vm);
109 #else
110 	/**
111 	 * Set the parameter to a value.
112 	 * @param parameter Which parameter to set.
113 	 * @param value The value of the parameter. Has to be string, integer or an instance of the class ScriptText.
114 	 */
115 	void SetParam(int parameter, Object value);
116 
117 	/**
118 	 * Add a value as parameter (appending it).
119 	 * @param value The value of the parameter. Has to be string, integer or an instance of the class ScriptText.
120 	 * @return The same object as on which this is called, so you can chain.
121 	 */
122 	ScriptText *AddParam(Object value);
123 #endif /* DOXYGEN_API */
124 
125 	/**
126 	 * @api -all
127 	 */
128 	virtual const char *GetEncodedText();
129 
130 private:
131 	StringID string;
132 	char *params[SCRIPT_TEXT_MAX_PARAMETERS];
133 	int64 parami[SCRIPT_TEXT_MAX_PARAMETERS];
134 	ScriptText *paramt[SCRIPT_TEXT_MAX_PARAMETERS];
135 	int paramc;
136 
137 	/**
138 	 * Internal function for recursive calling this function over multiple
139 	 *  instances, while writing in the same buffer.
140 	 * @param p The current position in the buffer.
141 	 * @param lastofp The last position valid in the buffer.
142 	 * @param param_count The number of parameters that are in the string.
143 	 * @return The new current position in the buffer.
144 	 */
145 	char *_GetEncodedText(char *p, char *lastofp, int &param_count);
146 
147 	/**
148 	 * Set a parameter, where the value is the first item on the stack.
149 	 */
150 	SQInteger _SetParam(int k, HSQUIRRELVM vm);
151 };
152 
153 #endif /* SCRIPT_TEXT_HPP */
154