OpenTTD Source 20260208-master-g43af8e94d0
newgrf_act0_globalvar.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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#include "../stdafx.h"
11#include "../debug.h"
12#include "../currency.h"
13#include "../landscape.h"
14#include "../language.h"
15#include "../rev.h"
16#include "../string_func.h"
17#include "../core/utf8.hpp"
18#include "../newgrf.h"
19#include "../newgrf_badge.h"
21#include "../newgrf_cargo.h"
22#include "../newgrf_engine.h"
23#include "../newgrf_sound.h"
24#include "../vehicle_base.h"
25#include "../rail.h"
26#include "newgrf_bytereader.h"
28#include "newgrf_internal.h"
30
31#include "table/strings.h"
32
33#include "../safeguards.h"
34
44template <typename T, typename TGetTableFunc>
45static ChangeInfoResult LoadTranslationTable(uint first, uint last, ByteReader &buf, TGetTableFunc gettable, std::string_view name)
46{
47 if (first != 0) {
48 GrfMsg(1, "LoadTranslationTable: {} translation table must start at zero", name);
49 return CIR_INVALID_ID;
50 }
51
52 std::vector<T> &translation_table = gettable(*_cur_gps.grffile);
53 translation_table.clear();
54 translation_table.reserve(last);
55 for (uint id = first; id < last; ++id) {
56 translation_table.push_back(T(std::byteswap(buf.ReadDWord())));
57 }
58
59 GRFFile *grf_override = GetCurrentGRFOverride();
60 if (grf_override != nullptr) {
61 /* GRF override is present, copy the translation table to the overridden GRF as well. */
62 GrfMsg(1, "LoadTranslationTable: Copying {} translation table to override GRFID {:08X}", name, std::byteswap(grf_override->grfid));
63 std::vector<T> &override_table = gettable(*grf_override);
64 override_table = translation_table;
65 }
66
67 return CIR_SUCCESS;
68}
69
70static ChangeInfoResult LoadBadgeTranslationTable(uint first, uint last, ByteReader &buf, std::vector<BadgeID> &translation_table, std::string_view name)
71{
72 if (first != 0 && first != std::size(translation_table)) {
73 GrfMsg(1, "LoadBadgeTranslationTable: {} translation table must start at zero or {}", name, std::size(translation_table));
74 return CIR_INVALID_ID;
75 }
76
77 if (first == 0) translation_table.clear();
78 translation_table.reserve(last);
79 for (uint id = first; id < last; ++id) {
80 std::string_view label = buf.ReadString();
81 translation_table.push_back(GetOrCreateBadge(label).index);
82 }
83
84 return CIR_SUCCESS;
85}
86
93static std::string ReadDWordAsString(ByteReader &reader)
94{
95 std::string output;
96 for (int i = 0; i < 4; i++) output.push_back(reader.ReadByte());
97 return StrMakeValid(output);
98}
99
108static ChangeInfoResult GlobalVarChangeInfo(uint first, uint last, int prop, ByteReader &buf)
109{
110 /* Properties which are handled as a whole */
111 switch (prop) {
112 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
113 /* Explicitly defined cargo translation table means it's no longer a fallback list. LoadTranslationTable erases any existing list. */
114 _cur_gps.grffile->cargo_list_is_fallback = false;
115 return LoadTranslationTable<CargoLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<CargoLabel> & { return grf.cargo_list; }, "Cargo");
116
117 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
118 return LoadTranslationTable<RailTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RailTypeLabel> & { return grf.railtype_list; }, "Rail type");
119
120 case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined roadtypes)
121 return LoadTranslationTable<RoadTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RoadTypeLabel> & { return grf.roadtype_list; }, "Road type");
122
123 case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined tramtypes)
124 return LoadTranslationTable<RoadTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RoadTypeLabel> & { return grf.tramtype_list; }, "Tram type");
125
126 case 0x18: // Badge translation table
127 return LoadBadgeTranslationTable(first, last, buf, _cur_gps.grffile->badge_list, "Badge");
128
129 default:
130 break;
131 }
132
133 /* Properties which are handled per item */
135 for (uint id = first; id < last; ++id) {
136 switch (prop) {
137 case 0x08: { // Cost base factor
138 int factor = buf.ReadByte();
139
140 if (id < to_underlying(Price::End)) {
141 _cur_gps.grffile->price_base_multipliers[id] = std::min<int>(factor - 8, MAX_PRICE_MODIFIER);
142 } else {
143 GrfMsg(1, "GlobalVarChangeInfo: Price {} out of range, ignoring", id);
144 }
145 break;
146 }
147
148 case 0x0A: { // Currency display names
149 uint curidx = GetNewgrfCurrencyIdConverted(id);
150 if (curidx < CURRENCY_END) {
151 AddStringForMapping(GRFStringID{buf.ReadWord()}, [curidx](StringID str) {
152 _currency_specs[curidx].name = str;
153 _currency_specs[curidx].code.clear();
154 });
155 } else {
156 buf.ReadWord();
157 }
158 break;
159 }
160
161 case 0x0B: { // Currency multipliers
162 uint curidx = GetNewgrfCurrencyIdConverted(id);
163 uint32_t rate = buf.ReadDWord();
164
165 if (curidx < CURRENCY_END) {
166 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
167 * which OTTD does not. For this reason, divide grf value by 1000,
168 * to be compatible */
169 _currency_specs[curidx].rate = rate / 1000;
170 } else {
171 GrfMsg(1, "GlobalVarChangeInfo: Currency multipliers {} out of range, ignoring", curidx);
172 }
173 break;
174 }
175
176 case 0x0C: { // Currency options
177 uint curidx = GetNewgrfCurrencyIdConverted(id);
178 uint16_t options = buf.ReadWord();
179
180 if (curidx < CURRENCY_END) {
181 _currency_specs[curidx].separator.clear();
182 _currency_specs[curidx].separator.push_back(GB(options, 0, 8));
183 StrMakeValidInPlace(_currency_specs[curidx].separator);
184 /* By specifying only one bit, we prevent errors,
185 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
186 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
187 } else {
188 GrfMsg(1, "GlobalVarChangeInfo: Currency option {} out of range, ignoring", curidx);
189 }
190 break;
191 }
192
193 case 0x0D: { // Currency prefix symbol
194 uint curidx = GetNewgrfCurrencyIdConverted(id);
195 std::string prefix = ReadDWordAsString(buf);
196
197 if (curidx < CURRENCY_END) {
198 _currency_specs[curidx].prefix = std::move(prefix);
199 } else {
200 GrfMsg(1, "GlobalVarChangeInfo: Currency symbol {} out of range, ignoring", curidx);
201 }
202 break;
203 }
204
205 case 0x0E: { // Currency suffix symbol
206 uint curidx = GetNewgrfCurrencyIdConverted(id);
207 std::string suffix = ReadDWordAsString(buf);
208
209 if (curidx < CURRENCY_END) {
210 _currency_specs[curidx].suffix = std::move(suffix);
211 } else {
212 GrfMsg(1, "GlobalVarChangeInfo: Currency symbol {} out of range, ignoring", curidx);
213 }
214 break;
215 }
216
217 case 0x0F: { // Euro introduction dates
218 uint curidx = GetNewgrfCurrencyIdConverted(id);
219 TimerGameCalendar::Year year_euro{buf.ReadWord()};
220
221 if (curidx < CURRENCY_END) {
222 _currency_specs[curidx].to_euro = year_euro;
223 } else {
224 GrfMsg(1, "GlobalVarChangeInfo: Euro intro date {} out of range, ignoring", curidx);
225 }
226 break;
227 }
228
229 case 0x10: // Snow line height table
230 if (last > 1 || IsSnowLineSet()) {
231 GrfMsg(1, "GlobalVarChangeInfo: The snowline can only be set once ({})", last);
232 } else if (buf.Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
233 GrfMsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table ({})", buf.Remaining());
234 } else {
235 auto snow_line = std::make_unique<SnowLine>();
236
237 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
238 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
239 uint8_t &level = snow_line->table[i][j];
240 level = buf.ReadByte();
241 if (_cur_gps.grffile->grf_version >= 8) {
242 if (level != 0xFF) level = level * (1 + _settings_game.construction.map_height_limit) / 256;
243 } else {
244 if (level >= 128) {
245 /* no snow */
246 level = 0xFF;
247 } else {
248 level = level * (1 + _settings_game.construction.map_height_limit) / 128;
249 }
250 }
251
252 snow_line->highest_value = std::max(snow_line->highest_value, level);
253 snow_line->lowest_value = std::min(snow_line->lowest_value, level);
254 }
255 }
256 SetSnowLine(std::move(snow_line));
257 }
258 break;
259
260 case 0x11: // GRF match for engine allocation
261 /* This is loaded during the reservation stage, so just skip it here. */
262 /* Each entry is 8 bytes. */
263 buf.Skip(8);
264 break;
265
266 case 0x13: // Gender translation table
267 case 0x14: // Case translation table
268 case 0x15: { // Plural form translation
269 uint curidx = id; // The current index, i.e. language.
270 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : nullptr;
271 if (lang == nullptr) {
272 GrfMsg(1, "GlobalVarChangeInfo: Language {} is not known, ignoring", curidx);
273 /* Skip over the data. */
274 if (prop == 0x15) {
275 buf.ReadByte();
276 } else {
277 while (buf.ReadByte() != 0) {
278 buf.ReadString();
279 }
280 }
281 break;
282 }
283
284 if (prop == 0x15) {
285 uint plural_form = buf.ReadByte();
286 if (plural_form >= LANGUAGE_MAX_PLURAL) {
287 GrfMsg(1, "GlobalVarChanceInfo: Plural form {} is out of range, ignoring", plural_form);
288 } else {
289 _cur_gps.grffile->language_map[curidx].plural_form = plural_form;
290 }
291 break;
292 }
293
294 uint8_t newgrf_id = buf.ReadByte(); // The NewGRF (custom) identifier.
295 while (newgrf_id != 0) {
296 std::string_view name = buf.ReadString(); // The name for the OpenTTD identifier.
297
298 /* We'll just ignore the UTF8 identifier character. This is (fairly)
299 * safe as OpenTTD's strings gender/cases are usually in ASCII which
300 * is just a subset of UTF8, or they need the bigger UTF8 characters
301 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
302 auto [len, c] = DecodeUtf8(name);
303 if (c == NFO_UTF8_IDENTIFIER) name.remove_prefix(len);
304
306 map.newgrf_id = newgrf_id;
307 if (prop == 0x13) {
308 map.openttd_id = lang->GetGenderIndex(name);
309 if (map.openttd_id >= MAX_NUM_GENDERS) {
310 GrfMsg(1, "GlobalVarChangeInfo: Gender name {} is not known, ignoring", StrMakeValid(name));
311 } else {
312 _cur_gps.grffile->language_map[curidx].gender_map.push_back(map);
313 }
314 } else {
315 map.openttd_id = lang->GetCaseIndex(name);
316 if (map.openttd_id >= MAX_NUM_CASES) {
317 GrfMsg(1, "GlobalVarChangeInfo: Case name {} is not known, ignoring", StrMakeValid(name));
318 } else {
319 _cur_gps.grffile->language_map[curidx].case_map.push_back(map);
320 }
321 }
322 newgrf_id = buf.ReadByte();
323 }
324 break;
325 }
326
327 default:
328 ret = CIR_UNKNOWN;
329 break;
330 }
331 }
332
333 return ret;
334}
335
336static ChangeInfoResult GlobalVarReserveInfo(uint first, uint last, int prop, ByteReader &buf)
337{
338 /* Properties which are handled as a whole */
339 switch (prop) {
340 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
341 /* Explicitly defined cargo translation table means it's no longer a fallback list. LoadTranslationTable erases any existing list. */
342 _cur_gps.grffile->cargo_list_is_fallback = false;
343 return LoadTranslationTable<CargoLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<CargoLabel> & { return grf.cargo_list; }, "Cargo");
344
345 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
346 return LoadTranslationTable<RailTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RailTypeLabel> & { return grf.railtype_list; }, "Rail type");
347
348 case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined roadtypes)
349 return LoadTranslationTable<RoadTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RoadTypeLabel> & { return grf.roadtype_list; }, "Road type");
350
351 case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined tramtypes)
352 return LoadTranslationTable<RoadTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RoadTypeLabel> & { return grf.tramtype_list; }, "Tram type");
353
354 case 0x18: // Badge translation table
355 return LoadBadgeTranslationTable(first, last, buf, _cur_gps.grffile->badge_list, "Badge");
356
357 default:
358 break;
359 }
360
361 /* Properties which are handled per item */
363
364 for (uint id = first; id < last; ++id) {
365 switch (prop) {
366 case 0x08: // Cost base factor
367 case 0x15: // Plural form translation
368 buf.ReadByte();
369 break;
370
371 case 0x0A: // Currency display names
372 case 0x0C: // Currency options
373 case 0x0F: // Euro introduction dates
374 buf.ReadWord();
375 break;
376
377 case 0x0B: // Currency multipliers
378 case 0x0D: // Currency prefix symbol
379 case 0x0E: // Currency suffix symbol
380 buf.ReadDWord();
381 break;
382
383 case 0x10: // Snow line height table
385 break;
386
387 case 0x11: { // GRF match for engine allocation
388 uint32_t s = buf.ReadDWord();
389 uint32_t t = buf.ReadDWord();
390 SetNewGRFOverride(s, t);
391 break;
392 }
393
394 case 0x13: // Gender translation table
395 case 0x14: // Case translation table
396 while (buf.ReadByte() != 0) {
397 buf.ReadString();
398 }
399 break;
400
401 default:
402 ret = CIR_UNKNOWN;
403 break;
404 }
405 }
406
407 return ret;
408}
409
410
422bool GetGlobalVariable(uint8_t param, uint32_t *value, const GRFFile *grffile)
423{
424 switch (param) {
425 case 0x00: // current date
426 *value = std::max(TimerGameCalendar::date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::Date(0)).base();
427 return true;
428
429 case 0x01: // current year
431 return true;
432
433 case 0x02: { // detailed date information: month of year (bit 0-7), day of month (bit 8-12), leap year (bit 15), day of year (bit 16-24)
434 TimerGameCalendar::YearMonthDay ymd = TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date);
435 TimerGameCalendar::Date start_of_year = TimerGameCalendar::ConvertYMDToDate(ymd.year, 0, 1);
436 *value = ymd.month | (ymd.day - 1) << 8 | (TimerGameCalendar::IsLeapYear(ymd.year) ? 1 << 15 : 0) | (TimerGameCalendar::date - start_of_year).base() << 16;
437 return true;
438 }
439
440 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
441 *value = to_underlying(_settings_game.game_creation.landscape);
442 return true;
443
444 case 0x06: // road traffic side, bit 4 clear=left, set=right
445 *value = _settings_game.vehicle.road_side << 4;
446 return true;
447
448 case 0x09: // date fraction
449 *value = TimerGameCalendar::date_fract * 885;
450 return true;
451
452 case 0x0A: // animation counter
453 *value = GB(TimerGameTick::counter, 0, 16);
454 return true;
455
456 case 0x0B: { // TTDPatch version
457 uint major = 2;
458 uint minor = 6;
459 uint revision = 1; // special case: 2.0.1 is 2.0.10
460 uint build = 1382;
461 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
462 return true;
463 }
464
465 case 0x0D: // TTD Version, 00=DOS, 01=Windows
466 *value = GetGRFConfig(grffile->grfid)->palette & GRFP_USE_MASK;
467 return true;
468
469 case 0x0E: // Y-offset for train sprites
470 *value = grffile->traininfo_vehicle_pitch;
471 return true;
472
473 case 0x0F: // Rail track type cost factors
474 *value = 0;
475 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
476 if (_settings_game.vehicle.disable_elrails) {
477 /* skip elrail multiplier - disabled */
478 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
479 } else {
480 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electrified railway
481 /* Skip monorail multiplier - no space in result */
482 }
483 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
484 return true;
485
486 case 0x11: // current rail tool type
487 *value = 0; // constant fake value to avoid desync
488 return true;
489
490 case 0x12: // Game mode
491 *value = _game_mode;
492 return true;
493
494 /* case 0x13: // Tile refresh offset to left not implemented */
495 /* case 0x14: // Tile refresh offset to right not implemented */
496 /* case 0x15: // Tile refresh offset upwards not implemented */
497 /* case 0x16: // Tile refresh offset downwards not implemented */
498 /* case 0x17: // temperate snow line not implemented */
499
500 case 0x1A: // Always -1
501 *value = UINT_MAX;
502 return true;
503
504 case 0x1B: // Display options
505 *value = 0x3F; // constant fake value to avoid desync
506 return true;
507
508 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
509 *value = 1;
510 return true;
511
512 case 0x1E: { // Miscellaneous GRF features
513 GrfMiscBits bits = _misc_grf_features;
514
515 /* Add the local flags */
517 if (grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) bits.Set(GrfMiscBit::TrainWidth32Pixels);
518
519 *value = bits.base();
520 return true;
521 }
522
523 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
524
525 case 0x20: { // snow line height
526 uint8_t snowline = GetSnowLine();
527 if (_settings_game.game_creation.landscape == LandscapeType::Arctic && snowline <= _settings_game.construction.map_height_limit) {
528 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
529 } else {
530 /* No snow */
531 *value = 0xFF;
532 }
533 return true;
534 }
535
536 case 0x21: // OpenTTD version
537 *value = _openttd_newgrf_version;
538 return true;
539
540 case 0x22: // difficulty level
541 *value = SP_CUSTOM;
542 return true;
543
544 case 0x23: // long format date
545 *value = TimerGameCalendar::date.base();
546 return true;
547
548 case 0x24: // long format year
549 *value = TimerGameCalendar::year.base();
550 return true;
551
552 default: return false;
553 }
554}
555
556template <> ChangeInfoResult GrfChangeInfoHandler<GSF_GLOBALVAR>::Reserve(uint first, uint last, int prop, ByteReader &buf) { return GlobalVarReserveInfo(first, last, prop, buf); }
557template <> ChangeInfoResult GrfChangeInfoHandler<GSF_GLOBALVAR>::Activation(uint first, uint last, int prop, ByteReader &buf) { return GlobalVarChangeInfo(first, last, prop, buf); }
constexpr T SB(T &x, const uint8_t s, const uint8_t n, const U d)
Set n bits in x starting at bit s to d.
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr enable_if_t< is_integral_v< T >, T > byteswap(T x) noexcept
Custom implementation of std::byteswap; remove once we build with C++23.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Tstorage base() const noexcept
Retrieve the raw value behind this bit set.
constexpr Timpl & Set()
Set all bits.
Class to read from a NewGRF file.
uint32_t ReadDWord()
Read a single DWord (32 bits).
uint16_t ReadWord()
Read a single Word (16 bits).
std::string_view ReadString()
Read a NUL-terminated string.
uint8_t ReadByte()
Read a single byte (8 bits).
static Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
static YearMonthDay ConvertDateToYMD(Date date)
Converts a Date to a Year, Month & Day.
static Date date
Current date in days (day counter).
static Year year
Current year, starting at 0.
static DateFract date_fract
Fractional part of the day.
static constexpr TimerGame< struct Calendar >::Year ORIGINAL_MAX_YEAR
static constexpr TimerGame< struct Calendar >::Year ORIGINAL_BASE_YEAR
static constexpr TimerGame< struct Calendar >::Date DAYS_TILL_ORIGINAL_BASE_YEAR
static TickCounter counter
Monotonic counter, in ticks, since start of game.
static constexpr bool IsLeapYear(Year year)
std::pair< size_t, char32_t > DecodeUtf8(std::string_view buf)
Decode a character from UTF-8.
Definition utf8.cpp:46
uint8_t GetNewgrfCurrencyIdConverted(uint8_t grfcurr_id)
Will return the ottd's index correspondence to the ttdpatch's id.
Definition currency.cpp:119
std::array< CurrencySpec, CURRENCY_END > _currency_specs
Array of currencies used by the system.
Definition currency.cpp:80
Functions to handle different currencies.
@ CURRENCY_END
always the last item
Definition currency.h:73
Functions related to debugging.
@ End
Price base end marker.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:17
uint8_t GetSnowLine()
Get the current snow line, either variable or static.
bool IsSnowLineSet()
Has a snow line table already been loaded.
void SetSnowLine(std::unique_ptr< SnowLine > &&snow_line)
Set a variable snow line, as loaded from a newgrf file.
Functions related to OTTD's landscape.
static const uint SNOW_LINE_DAYS
Number of days in each month in the snow line table.
Definition landscape.h:17
static const uint SNOW_LINE_MONTHS
Number of months in the snow line table.
Definition landscape.h:16
@ Arctic
Landscape with snow levels.
Information about languages and their files.
static const uint8_t MAX_NUM_GENDERS
Maximum number of supported genders.
Definition language.h:20
const LanguageMetadata * GetLanguage(uint8_t newgrflangid)
Get the language with the given NewGRF language ID.
Definition strings.cpp:2190
static const uint8_t MAX_NUM_CASES
Maximum number of supported cases.
Definition language.h:21
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
GRFFile * GetCurrentGRFOverride()
Get overridden GRF for current GRF if present.
Definition newgrf.cpp:197
void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
Set the override for a NewGRF.
Definition newgrf.cpp:182
GrfMiscBits _misc_grf_features
Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E.
Definition newgrf.cpp:72
Base for the NewGRF implementation.
@ TrainWidth32Pixels
Use 32 pixels per train vehicle in depot gui and vehicle details. Never set in the global variable;.
Definition newgrf.h:63
bool GetGlobalVariable(uint8_t param, uint32_t *value, const GRFFile *grffile)
Reads a variable common to VarAction2 and Action7/9/D.
static ChangeInfoResult LoadTranslationTable(uint first, uint last, ByteReader &buf, TGetTableFunc gettable, std::string_view name)
Load a cargo- or railtype-translation table.
static ChangeInfoResult GlobalVarChangeInfo(uint first, uint last, int prop, ByteReader &buf)
Define properties for global variables.
static std::string ReadDWordAsString(ByteReader &reader)
Helper to read a DWord worth of bytes from the reader and to return it as a valid string.
Badge & GetOrCreateBadge(std::string_view label)
Register a badge label and return its global index.
Functions related to NewGRF badges.
Types related to NewGRF badges.
NewGRF buffer reader definition.
Cargo support for NewGRFs.
GRFConfig * GetGRFConfig(uint32_t grfid, uint32_t mask)
Retrieve a NewGRF from the current config by its grfid.
@ GRFP_USE_MASK
Bitmask to get only the use palette use states.
Functions for NewGRF engines.
NewGRF internal processing state.
ChangeInfoResult
Possible return values for the GrfChangeInfoHandler functions.
@ CIR_INVALID_ID
Attempt to modify an invalid ID.
@ CIR_UNKNOWN
Variable is unknown.
@ CIR_SUCCESS
Variable was parsed and read.
NewGRF internal processing state for vehicles.
Functions related to NewGRF provided sounds.
void AddStringForMapping(GRFStringID source, std::function< void(StringID)> &&func)
Record a static StringID for getting translated later.
NewGRF string mapping definition.
StrongType::Typedef< uint32_t, struct GRFStringIDTag, StrongType::Compare, StrongType::Integer > GRFStringID
Type for GRF-internal string IDs.
static const char32_t NFO_UTF8_IDENTIFIER
This character (thorn) indicates a unicode string to NFO.
Rail specific functions.
const RailTypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition rail.h:300
@ RAILTYPE_MONO
Monorail.
Definition rail_type.h:29
@ RAILTYPE_ELECTRIC
Electric rails.
Definition rail_type.h:28
@ RAILTYPE_RAIL
Standard non-electric rails.
Definition rail_type.h:27
@ RAILTYPE_MAGLEV
Maglev.
Definition rail_type.h:30
Declaration of OTTD revision dependent variables.
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
@ SP_CUSTOM
No profile, special "custom" highscore.
Definition of base types and functions in a cross-platform compatible way.
void StrMakeValidInPlace(char *str, StringValidationSettings settings)
Scans the string for invalid characters and replaces them with a question mark '?
Definition string.cpp:157
static void StrMakeValid(Builder &builder, StringConsumer &consumer, StringValidationSettings settings)
Copies the valid (UTF-8) characters from consumer to the builder.
Definition string.cpp:119
Functions related to low-level strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static const uint MAX_LANG
Maximum number of languages supported by the game, and the NewGRF specs.
uint8_t palette
GRFPalette, bitset.
Dynamic data of a loaded NewGRF.
Definition newgrf.h:117
std::vector< RailTypeLabel > railtype_list
Railtype translation table.
Definition newgrf.h:144
std::vector< RoadTypeLabel > roadtype_list
Roadtype translation table (road).
Definition newgrf.h:147
std::vector< RoadTypeLabel > tramtype_list
Roadtype translation table (tram).
Definition newgrf.h:150
std::vector< CargoLabel > cargo_list
Cargo translation table (local ID -> label).
Definition newgrf.h:138
uint traininfo_vehicle_width
Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details.
Definition newgrf.h:158
int traininfo_vehicle_pitch
Vertical offset for drawing train images in depot GUI and vehicle details.
Definition newgrf.h:157
Mapping between NewGRF and OpenTTD IDs.
uint8_t newgrf_id
NewGRF's internal ID for a case/gender.
uint8_t openttd_id
OpenTTD's internal ID for a case/gender.
Make sure the size is right.
Definition language.h:89
uint8_t GetCaseIndex(std::string_view case_str) const
Get the index for the given case.
Definition language.h:79
uint8_t GetGenderIndex(std::string_view gender_str) const
Get the index for the given gender.
Definition language.h:68
static constexpr uint TILE_HEIGHT
Height of a height level in world coordinate AND in pixels in ZOOM_BASE.
Definition tile_type.h:18
Handling of UTF-8 encoded data.
Base class for all vehicles.