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_company.hpp Everything to query a company's financials and statistics or build company related buildings. */
9 
10 #ifndef SCRIPT_COMPANY_HPP
11 #define SCRIPT_COMPANY_HPP
12 
13 #include "script_text.hpp"
14 #include "../../economy_type.h"
15 #include "../../livery.h"
16 #include "../../gfx_type.h"
17 
18 /**
19  * Class that handles all company related functions.
20  * @api ai game
21  */
22 class ScriptCompany : public ScriptObject {
23 public:
24 	/** The range of possible quarters to get company information of. */
25 	enum Quarter {
26 		CURRENT_QUARTER  = 0,                      ///< The current quarter.
27 		EARLIEST_QUARTER = ::MAX_HISTORY_QUARTERS, ///< The earliest quarter company information is available for.
28 	};
29 
30 	/** Different constants related to CompanyID. */
31 	enum CompanyID {
32 		/* Note: these values represent part of the in-game Owner enum */
33 		COMPANY_FIRST     = ::COMPANY_FIRST,   ///< The first available company.
34 		COMPANY_LAST      = ::MAX_COMPANIES,   ///< The last available company.
35 
36 		/* Custom added value, only valid for this API */
37 		COMPANY_INVALID   = -1,                ///< An invalid company.
38 		COMPANY_SELF      = 254,               ///< Constant that gets resolved to the correct company index for your company.
39 		COMPANY_SPECTATOR = 255,               ///< Constant indicating that player is spectating (gets resolved to COMPANY_INVALID)
40 	};
41 
42 	/** Possible genders for company presidents. */
43 	enum Gender {
44 		GENDER_MALE,         ///< A male person.
45 		GENDER_FEMALE,       ///< A female person.
46 		GENDER_INVALID = -1, ///< An invalid gender.
47 	};
48 
49 	/** List of different livery schemes. */
50 	enum LiveryScheme {
51 		LS_DEFAULT,                  ///< Default scheme.
52 		LS_STEAM,                    ///< Steam engines.
53 		LS_DIESEL,                   ///< Diesel engines.
54 		LS_ELECTRIC,                 ///< Electric engines.
55 		LS_MONORAIL,                 ///< Monorail engines.
56 		LS_MAGLEV,                   ///< Maglev engines.
57 		LS_DMU,                      ///< DMUs and their passenger wagons.
58 		LS_EMU,                      ///< EMUs and their passenger wagons.
59 		LS_PASSENGER_WAGON_STEAM,    ///< Passenger wagons attached to steam engines.
60 		LS_PASSENGER_WAGON_DIESEL,   ///< Passenger wagons attached to diesel engines.
61 		LS_PASSENGER_WAGON_ELECTRIC, ///< Passenger wagons attached to electric engines.
62 		LS_PASSENGER_WAGON_MONORAIL, ///< Passenger wagons attached to monorail engines.
63 		LS_PASSENGER_WAGON_MAGLEV,   ///< Passenger wagons attached to maglev engines.
64 		LS_FREIGHT_WAGON,            ///< Freight wagons.
65 		LS_BUS,                      ///< Buses.
66 		LS_TRUCK,                    ///< Trucks.
67 		LS_PASSENGER_SHIP,           ///< Passenger ships.
68 		LS_FREIGHT_SHIP,             ///< Freight ships.
69 		LS_HELICOPTER,               ///< Helicopters.
70 		LS_SMALL_PLANE,              ///< Small aeroplanes.
71 		LS_LARGE_PLANE,              ///< Large aeroplanes.
72 		LS_PASSENGER_TRAM,           ///< Passenger trams.
73 		LS_FREIGHT_TRAM,             ///< Freight trams.
74 		LS_INVALID = -1,
75 	};
76 
77 	/** List of colours. */
78 	enum Colours {
79 		COLOUR_DARK_BLUE,
80 		COLOUR_PALE_GREEN,
81 		COLOUR_PINK,
82 		COLOUR_YELLOW,
83 		COLOUR_RED,
84 		COLOUR_LIGHT_BLUE,
85 		COLOUR_GREEN,
86 		COLOUR_DARK_GREEN,
87 		COLOUR_BLUE,
88 		COLOUR_CREAM,
89 		COLOUR_MAUVE,
90 		COLOUR_PURPLE,
91 		COLOUR_ORANGE,
92 		COLOUR_BROWN,
93 		COLOUR_GREY,
94 		COLOUR_WHITE,
95 		COLOUR_INVALID = ::INVALID_COLOUR
96 	};
97 
98 	/**
99 	 * Types of expenses.
100 	 * @api -ai
101 	 */
102 	enum ExpensesType : byte {
103 		EXPENSES_CONSTRUCTION = ::EXPENSES_CONSTRUCTION, ///< Construction costs.
104 		EXPENSES_NEW_VEHICLES = ::EXPENSES_NEW_VEHICLES, ///< New vehicles.
105 		EXPENSES_TRAIN_RUN    = ::EXPENSES_TRAIN_RUN,    ///< Running costs trains.
106 		EXPENSES_ROADVEH_RUN  = ::EXPENSES_ROADVEH_RUN,  ///< Running costs road vehicles.
107 		EXPENSES_AIRCRAFT_RUN = ::EXPENSES_AIRCRAFT_RUN, ///< Running costs aircraft.
108 		EXPENSES_SHIP_RUN     = ::EXPENSES_SHIP_RUN,     ///< Running costs ships.
109 		EXPENSES_PROPERTY     = ::EXPENSES_PROPERTY,     ///< Property costs.
110 		EXPENSES_TRAIN_INC    = ::EXPENSES_TRAIN_INC,    ///< Income from trains.
111 		EXPENSES_ROADVEH_INC  = ::EXPENSES_ROADVEH_INC,  ///< Income from road vehicles.
112 		EXPENSES_AIRCRAFT_INC = ::EXPENSES_AIRCRAFT_INC, ///< Income from aircraft.
113 		EXPENSES_SHIP_INC     = ::EXPENSES_SHIP_INC,     ///< Income from ships.
114 		EXPENSES_LOAN_INT     = ::EXPENSES_LOAN_INT,     ///< Interest payments over the loan.
115 		EXPENSES_OTHER        = ::EXPENSES_OTHER,        ///< Other expenses.
116 		EXPENSES_INVALID      = ::INVALID_EXPENSES,      ///< Invalid expense type.
117 	};
118 
119 	/**
120 	 * Resolved the given company index to the correct index for the company. If
121 	 *  the company index was COMPANY_SELF it will be resolved to the index of
122 	 *  your company. If the company with the given index does not exist it will
123 	 *  return COMPANY_INVALID.
124 	 * @param company The company index to resolve.
125 	 * @return The resolved company index.
126 	 */
127 	static CompanyID ResolveCompanyID(CompanyID company);
128 
129 	/**
130 	 * Check if a CompanyID is your CompanyID, to ease up checks.
131 	 * @param company The company index to check.
132 	 * @return True if and only if this company is your CompanyID.
133 	 * @api -game
134 	 */
135 	static bool IsMine(CompanyID company);
136 
137 	/**
138 	 * Set the name of your company.
139 	 * @param name The new name of the company (can be either a raw string, or a ScriptText object).
140 	 * @pre name != nullptr && len(name) != 0.
141 	 * @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE
142 	 * @return True if the name was changed.
143 	 */
144 	static bool SetName(Text *name);
145 
146 	/**
147 	 * Get the name of the given company.
148 	 * @param company The company to get the name for.
149 	 * @pre ResolveCompanyID(company) != COMPANY_INVALID.
150 	 * @return The name of the given company.
151 	 */
152 	static char *GetName(CompanyID company);
153 
154 	/**
155 	 * Set the name of your president.
156 	 * @param name The new name of the president (can be either a raw string, or a ScriptText object).
157 	 * @pre name != nullptr && len(name) != 0.
158 	 * @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE
159 	 * @return True if the name was changed.
160 	 */
161 	static bool SetPresidentName(Text *name);
162 
163 	/**
164 	 * Get the name of the president of the given company.
165 	 * @param company The company to get the president's name for.
166 	 * @pre ResolveCompanyID(company) != COMPANY_INVALID.
167 	 * @return The name of the president of the given company.
168 	 */
169 	static char *GetPresidentName(CompanyID company);
170 
171 	/**
172 	 * Set the gender of the president of your company.
173 	 * @param gender The new gender for your president.
174 	 * @pre GetPresidentGender(ScriptCompany.COMPANY_SELF) != gender.
175 	 * @return True if the gender was changed.
176 	 * @note When successful a random face will be created.
177 	 * @api -game
178 	 */
179 	static bool SetPresidentGender(Gender gender);
180 
181 	/**
182 	 * Get the gender of the president of the given company.
183 	 * @param company The company to get the presidents gender off.
184 	 * @return The gender of the president.
185 	 */
186 	static Gender GetPresidentGender(CompanyID company);
187 
188 	/**
189 	 * Sets the amount to loan.
190 	 * @param loan The amount to loan (multiplier of GetLoanInterval()).
191 	 * @pre 'loan' must be non-negative.
192 	 * @pre GetLoanInterval() must be a multiplier of 'loan'.
193 	 * @pre 'loan' must be below GetMaxLoanAmount().
194 	 * @pre 'loan' - GetLoanAmount() + GetBankBalance() must be non-negative.
195 	 * @game @pre Valid ScriptCompanyMode active in scope.
196 	 * @return True if the loan could be set to your requested amount.
197 	 */
198 	static bool SetLoanAmount(Money loan);
199 
200 	/**
201 	 * Sets the minimum amount to loan, i.e. the given amount of loan rounded up.
202 	 * @param loan The amount to loan (any positive number).
203 	 * @pre 'loan' must be non-negative.
204 	 * @pre 'loan' must be below GetMaxLoanAmount().
205 	 * @game @pre Valid ScriptCompanyMode active in scope.
206 	 * @return True if we could allocate a minimum of 'loan' loan.
207 	 */
208 	static bool SetMinimumLoanAmount(Money loan);
209 
210 	/**
211 	 * Gets the amount your company have loaned.
212 	 * @return The amount loaned money.
213 	 * @post GetLoanInterval() is always a multiplier of the return value.
214 	 */
215 	static Money GetLoanAmount();
216 
217 	/**
218 	 * Gets the maximum amount your company can loan.
219 	 * @return The maximum amount your company can loan.
220 	 * @post GetLoanInterval() is always a multiplier of the return value.
221 	 */
222 	static Money GetMaxLoanAmount();
223 
224 	/**
225 	 * Gets the interval/loan step.
226 	 * @return The loan step.
227 	 * @post Return value is always positive.
228 	 */
229 	static Money GetLoanInterval();
230 
231 	/**
232 	 * Gets the bank balance. In other words, the amount of money the given company can spent.
233 	 * @param company The company to get the bank balance of.
234 	 * @pre ResolveCompanyID(company) != COMPANY_INVALID.
235 	 * @return The actual bank balance.
236 	 */
237 	static Money GetBankBalance(CompanyID company);
238 
239 	/**
240 	 * Changes the bank balance by a delta value. This method does not affect the loan but instead
241 	 * allows a GS to give or take money from a company.
242 	 * @param company The company to change the bank balance of.
243 	 * @param delta Amount of money to give or take from the bank balance. A positive value adds money to the bank balance.
244 	 * @param expenses_type The account in the finances window that will register the cost.
245 	 * @param tile The tile to show text effect on or ScriptMap::TILE_INVALID
246 	 * @return True, if the bank balance was changed.
247 	 * @game @pre No ScriptCompanyMode active in scope.
248 	 * @pre ResolveCompanyID(company) != COMPANY_INVALID.
249 	 * @pre delta >= -2**31
250 	 * @pre delta <   2**31
251 	 * @note You need to create your own news message to inform about costs/gifts that you create using this command.
252 	 * @api -ai
253 	 */
254 	static bool ChangeBankBalance(CompanyID company, Money delta, ExpensesType expenses_type, TileIndex tile);
255 
256 	/**
257 	 * Get the income of the company in the given quarter.
258 	 * Note that this function only considers recurring income from vehicles;
259 	 * it does not include one-time income from selling stuff.
260 	 * @param company The company to get the quarterly income of.
261 	 * @param quarter The quarter to get the income of.
262 	 * @pre ResolveCompanyID(company) != COMPANY_INVALID.
263 	 * @pre quarter <= EARLIEST_QUARTER.
264 	 * @return The gross income of the company in the given quarter.
265 	 */
266 	static Money GetQuarterlyIncome(CompanyID company, uint32 quarter);
267 
268 	/**
269 	 * Get the expenses of the company in the given quarter.
270 	 * Note that this function only considers recurring expenses from vehicle
271 	 * running cost, maintenance and interests; it does not include one-time
272 	 * expenses from construction and buying stuff.
273 	 * @param company The company to get the quarterly expenses of.
274 	 * @param quarter The quarter to get the expenses of.
275 	 * @pre ResolveCompanyID(company) != COMPANY_INVALID.
276 	 * @pre quarter <= EARLIEST_QUARTER.
277 	 * @return The expenses of the company in the given quarter.
278 	 */
279 	static Money GetQuarterlyExpenses(CompanyID company, uint32 quarter);
280 
281 	/**
282 	 * Get the amount of cargo delivered by the given company in the given quarter.
283 	 * @param company The company to get the amount of delivered cargo of.
284 	 * @param quarter The quarter to get the amount of delivered cargo of.
285 	 * @pre ResolveCompanyID(company) != COMPANY_INVALID.
286 	 * @pre quarter <= EARLIEST_QUARTER.
287 	 * @return The amount of cargo delivered by the given company in the given quarter.
288 	 */
289 	static int32 GetQuarterlyCargoDelivered(CompanyID company, uint32 quarter);
290 
291 	/**
292 	 * Get the performance rating of the given company in the given quarter.
293 	 * @param company The company to get the performance rating of.
294 	 * @param quarter The quarter to get the performance rating of.
295 	 * @pre ResolveCompanyID(company) != COMPANY_INVALID.
296 	 * @pre quarter <= EARLIEST_QUARTER.
297 	 * @pre quarter != CURRENT_QUARTER.
298 	 * @note The performance rating is calculated after every quarter, so the value for CURRENT_QUARTER is undefined.
299 	 * @return The performance rating of the given company in the given quarter.
300 	 */
301 	static int32 GetQuarterlyPerformanceRating(CompanyID company, uint32 quarter);
302 
303 	/**
304 	 * Get the value of the company in the given quarter.
305 	 * @param company The company to get the value of.
306 	 * @param quarter The quarter to get the value of.
307 	 * @pre ResolveCompanyID(company) != COMPANY_INVALID.
308 	 * @pre quarter <= EARLIEST_QUARTER.
309 	 * @return The value of the company in the given quarter.
310 	 */
311 	static Money GetQuarterlyCompanyValue(CompanyID company, uint32 quarter);
312 
313 	/**
314 	 * Build your company's HQ on the given tile.
315 	 * @param tile The tile to build your HQ on, this tile is the most northern tile of your HQ.
316 	 * @pre ScriptMap::IsValidTile(tile).
317 	 * @game @pre Valid ScriptCompanyMode active in scope.
318 	 * @exception ScriptError::ERR_AREA_NOT_CLEAR
319 	 * @exception ScriptError::ERR_FLAT_LAND_REQUIRED
320 	 * @return True if the HQ could be build.
321 	 * @note An HQ can not be removed, only by water or rebuilding; If an HQ is
322 	 *  build again, the old one is removed.
323 	 */
324 	static bool BuildCompanyHQ(TileIndex tile);
325 
326 	/**
327 	 * Return the location of a company's HQ.
328 	 * @param company The company the get the HQ of.
329 	 * @pre ResolveCompanyID(company) != COMPANY_INVALID.
330 	 * @return The tile of the company's HQ, this tile is the most northern tile
331 	 *  of that HQ, or ScriptMap::TILE_INVALID if there is no HQ yet.
332 	 */
333 	static TileIndex GetCompanyHQ(CompanyID company);
334 
335 	/**
336 	 * Set whether autorenew is enabled for your company.
337 	 * @param autorenew The new autorenew status.
338 	 * @return True if autorenew status has been modified.
339 	 * @api -game
340 	 */
341 	static bool SetAutoRenewStatus(bool autorenew);
342 
343 	/**
344 	 * Return whether autorenew is enabled for a company.
345 	 * @param company The company to get the autorenew status of.
346 	 * @pre ResolveCompanyID(company) != COMPANY_INVALID.
347 	 * @return True if autorenew is enabled.
348 	 */
349 	static bool GetAutoRenewStatus(CompanyID company);
350 
351 	/**
352 	 * Set the number of months before/after max age to autorenew an engine for your company.
353 	 * @param months The new months between autorenew.
354 	 * @return True if autorenew months has been modified.
355 	 * @api -game
356 	 */
357 	static bool SetAutoRenewMonths(int16 months);
358 
359 	/**
360 	 * Return the number of months before/after max age to autorenew an engine for a company.
361 	 * @param company The company to get the autorenew months of.
362 	 * @pre ResolveCompanyID(company) != COMPANY_INVALID.
363 	 * @return The months before/after max age of engine.
364 	 */
365 	static int16 GetAutoRenewMonths(CompanyID company);
366 
367 	/**
368 	 * Set the minimum money needed to autorenew an engine for your company.
369 	 * @param money The new minimum required money for autorenew to work.
370 	 * @return True if autorenew money has been modified.
371 	 * @pre money >= 0
372 	 * @pre money <  2**32
373 	 * @api -game
374 	 */
375 	static bool SetAutoRenewMoney(Money money);
376 
377 	/**
378 	 * Return the minimum money needed to autorenew an engine for a company.
379 	 * @param company The company to get the autorenew money of.
380 	 * @pre ResolveCompanyID(company) != COMPANY_INVALID.
381 	 * @return The minimum required money for autorenew to work.
382 	 */
383 	static Money GetAutoRenewMoney(CompanyID company);
384 
385 	/**
386 	 * Set primary colour for your company.
387 	 * @param scheme Livery scheme to set.
388 	 * @param colour Colour to set.
389 	 * @return False if unable to set primary colour of the livery scheme (e.g. colour in use).
390 	 */
391 	static bool SetPrimaryLiveryColour(LiveryScheme scheme, Colours colour);
392 
393 	/**
394 	 * Set secondary colour for your company.
395 	 * @param scheme Livery scheme to set.
396 	 * @param colour Colour to set.
397 	 * @return False if unable to set secondary colour of the livery scheme.
398 	 */
399 	static bool SetSecondaryLiveryColour(LiveryScheme scheme, Colours colour);
400 
401 	/**
402 	 * Get primary colour of a livery for your company.
403 	 * @param scheme Livery scheme to get.
404 	 * @return Primary colour of livery.
405 	 */
406 	static ScriptCompany::Colours GetPrimaryLiveryColour(LiveryScheme scheme);
407 
408 	/**
409 	 * Get secondary colour of a livery for your company.
410 	 * @param scheme Livery scheme to get.
411 	 * @return Secondary colour of livery.
412 	 */
413 	static ScriptCompany::Colours GetSecondaryLiveryColour(LiveryScheme scheme);
414 };
415 
416 DECLARE_POSTFIX_INCREMENT(ScriptCompany::CompanyID)
417 
418 #endif /* SCRIPT_COMPANY_HPP */
419