OpenTTD Source 20250613-master-ga1786fa1f4
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 <http://www.gnu.org/licenses/>.
6 */
7
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"
20#include "../newgrf_badge_type.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 '{}'", 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 return LoadTranslationTable<CargoLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<CargoLabel> & { return grf.cargo_list; }, "Cargo");
114
115 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
116 return LoadTranslationTable<RailTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RailTypeLabel> & { return grf.railtype_list; }, "Rail type");
117
118 case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined roadtypes)
119 return LoadTranslationTable<RoadTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RoadTypeLabel> & { return grf.roadtype_list; }, "Road type");
120
121 case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined tramtypes)
122 return LoadTranslationTable<RoadTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RoadTypeLabel> & { return grf.tramtype_list; }, "Tram type");
123
124 case 0x18: // Badge translation table
125 return LoadBadgeTranslationTable(first, last, buf, _cur_gps.grffile->badge_list, "Badge");
126
127 default:
128 break;
129 }
130
131 /* Properties which are handled per item */
133 for (uint id = first; id < last; ++id) {
134 switch (prop) {
135 case 0x08: { // Cost base factor
136 int factor = buf.ReadByte();
137
138 if (id < PR_END) {
139 _cur_gps.grffile->price_base_multipliers[id] = std::min<int>(factor - 8, MAX_PRICE_MODIFIER);
140 } else {
141 GrfMsg(1, "GlobalVarChangeInfo: Price {} out of range, ignoring", id);
142 }
143 break;
144 }
145
146 case 0x0A: { // Currency display names
147 uint curidx = GetNewgrfCurrencyIdConverted(id);
148 if (curidx < CURRENCY_END) {
149 AddStringForMapping(GRFStringID{buf.ReadWord()}, [curidx](StringID str) {
150 _currency_specs[curidx].name = str;
151 _currency_specs[curidx].code.clear();
152 });
153 } else {
154 buf.ReadWord();
155 }
156 break;
157 }
158
159 case 0x0B: { // Currency multipliers
160 uint curidx = GetNewgrfCurrencyIdConverted(id);
161 uint32_t rate = buf.ReadDWord();
162
163 if (curidx < CURRENCY_END) {
164 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
165 * which OTTD does not. For this reason, divide grf value by 1000,
166 * to be compatible */
167 _currency_specs[curidx].rate = rate / 1000;
168 } else {
169 GrfMsg(1, "GlobalVarChangeInfo: Currency multipliers {} out of range, ignoring", curidx);
170 }
171 break;
172 }
173
174 case 0x0C: { // Currency options
175 uint curidx = GetNewgrfCurrencyIdConverted(id);
176 uint16_t options = buf.ReadWord();
177
178 if (curidx < CURRENCY_END) {
179 _currency_specs[curidx].separator.clear();
180 _currency_specs[curidx].separator.push_back(GB(options, 0, 8));
181 /* By specifying only one bit, we prevent errors,
182 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
183 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
184 } else {
185 GrfMsg(1, "GlobalVarChangeInfo: Currency option {} out of range, ignoring", curidx);
186 }
187 break;
188 }
189
190 case 0x0D: { // Currency prefix symbol
191 uint curidx = GetNewgrfCurrencyIdConverted(id);
192 std::string prefix = ReadDWordAsString(buf);
193
194 if (curidx < CURRENCY_END) {
195 _currency_specs[curidx].prefix = std::move(prefix);
196 } else {
197 GrfMsg(1, "GlobalVarChangeInfo: Currency symbol {} out of range, ignoring", curidx);
198 }
199 break;
200 }
201
202 case 0x0E: { // Currency suffix symbol
203 uint curidx = GetNewgrfCurrencyIdConverted(id);
204 std::string suffix = ReadDWordAsString(buf);
205
206 if (curidx < CURRENCY_END) {
207 _currency_specs[curidx].suffix = std::move(suffix);
208 } else {
209 GrfMsg(1, "GlobalVarChangeInfo: Currency symbol {} out of range, ignoring", curidx);
210 }
211 break;
212 }
213
214 case 0x0F: { // Euro introduction dates
215 uint curidx = GetNewgrfCurrencyIdConverted(id);
216 TimerGameCalendar::Year year_euro{buf.ReadWord()};
217
218 if (curidx < CURRENCY_END) {
219 _currency_specs[curidx].to_euro = year_euro;
220 } else {
221 GrfMsg(1, "GlobalVarChangeInfo: Euro intro date {} out of range, ignoring", curidx);
222 }
223 break;
224 }
225
226 case 0x10: // Snow line height table
227 if (last > 1 || IsSnowLineSet()) {
228 GrfMsg(1, "GlobalVarChangeInfo: The snowline can only be set once ({})", last);
229 } else if (buf.Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
230 GrfMsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table ({})", buf.Remaining());
231 } else {
232 auto snow_line = std::make_unique<SnowLine>();
233
234 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
235 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
236 uint8_t &level = snow_line->table[i][j];
237 level = buf.ReadByte();
238 if (_cur_gps.grffile->grf_version >= 8) {
239 if (level != 0xFF) level = level * (1 + _settings_game.construction.map_height_limit) / 256;
240 } else {
241 if (level >= 128) {
242 /* no snow */
243 level = 0xFF;
244 } else {
245 level = level * (1 + _settings_game.construction.map_height_limit) / 128;
246 }
247 }
248
249 snow_line->highest_value = std::max(snow_line->highest_value, level);
250 snow_line->lowest_value = std::min(snow_line->lowest_value, level);
251 }
252 }
253 SetSnowLine(std::move(snow_line));
254 }
255 break;
256
257 case 0x11: // GRF match for engine allocation
258 /* This is loaded during the reservation stage, so just skip it here. */
259 /* Each entry is 8 bytes. */
260 buf.Skip(8);
261 break;
262
263 case 0x13: // Gender translation table
264 case 0x14: // Case translation table
265 case 0x15: { // Plural form translation
266 uint curidx = id; // The current index, i.e. language.
267 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : nullptr;
268 if (lang == nullptr) {
269 GrfMsg(1, "GlobalVarChangeInfo: Language {} is not known, ignoring", curidx);
270 /* Skip over the data. */
271 if (prop == 0x15) {
272 buf.ReadByte();
273 } else {
274 while (buf.ReadByte() != 0) {
275 buf.ReadString();
276 }
277 }
278 break;
279 }
280
281 if (prop == 0x15) {
282 uint plural_form = buf.ReadByte();
283 if (plural_form >= LANGUAGE_MAX_PLURAL) {
284 GrfMsg(1, "GlobalVarChanceInfo: Plural form {} is out of range, ignoring", plural_form);
285 } else {
286 _cur_gps.grffile->language_map[curidx].plural_form = plural_form;
287 }
288 break;
289 }
290
291 uint8_t newgrf_id = buf.ReadByte(); // The NewGRF (custom) identifier.
292 while (newgrf_id != 0) {
293 std::string_view name = buf.ReadString(); // The name for the OpenTTD identifier.
294
295 /* We'll just ignore the UTF8 identifier character. This is (fairly)
296 * safe as OpenTTD's strings gender/cases are usually in ASCII which
297 * is just a subset of UTF8, or they need the bigger UTF8 characters
298 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
299 auto [len, c] = DecodeUtf8(name);
300 if (c == NFO_UTF8_IDENTIFIER) name.remove_prefix(len);
301
303 map.newgrf_id = newgrf_id;
304 if (prop == 0x13) {
305 map.openttd_id = lang->GetGenderIndex(name);
306 if (map.openttd_id >= MAX_NUM_GENDERS) {
307 GrfMsg(1, "GlobalVarChangeInfo: Gender name {} is not known, ignoring", StrMakeValid(name));
308 } else {
309 _cur_gps.grffile->language_map[curidx].gender_map.push_back(map);
310 }
311 } else {
312 map.openttd_id = lang->GetCaseIndex(name);
313 if (map.openttd_id >= MAX_NUM_CASES) {
314 GrfMsg(1, "GlobalVarChangeInfo: Case name {} is not known, ignoring", StrMakeValid(name));
315 } else {
316 _cur_gps.grffile->language_map[curidx].case_map.push_back(map);
317 }
318 }
319 newgrf_id = buf.ReadByte();
320 }
321 break;
322 }
323
324 default:
325 ret = CIR_UNKNOWN;
326 break;
327 }
328 }
329
330 return ret;
331}
332
333static ChangeInfoResult GlobalVarReserveInfo(uint first, uint last, int prop, ByteReader &buf)
334{
335 /* Properties which are handled as a whole */
336 switch (prop) {
337 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
338 return LoadTranslationTable<CargoLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<CargoLabel> & { return grf.cargo_list; }, "Cargo");
339
340 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
341 return LoadTranslationTable<RailTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RailTypeLabel> & { return grf.railtype_list; }, "Rail type");
342
343 case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined roadtypes)
344 return LoadTranslationTable<RoadTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RoadTypeLabel> & { return grf.roadtype_list; }, "Road type");
345
346 case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined tramtypes)
347 return LoadTranslationTable<RoadTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RoadTypeLabel> & { return grf.tramtype_list; }, "Tram type");
348
349 case 0x18: // Badge translation table
350 return LoadBadgeTranslationTable(first, last, buf, _cur_gps.grffile->badge_list, "Badge");
351
352 default:
353 break;
354 }
355
356 /* Properties which are handled per item */
358
359 for (uint id = first; id < last; ++id) {
360 switch (prop) {
361 case 0x08: // Cost base factor
362 case 0x15: // Plural form translation
363 buf.ReadByte();
364 break;
365
366 case 0x0A: // Currency display names
367 case 0x0C: // Currency options
368 case 0x0F: // Euro introduction dates
369 buf.ReadWord();
370 break;
371
372 case 0x0B: // Currency multipliers
373 case 0x0D: // Currency prefix symbol
374 case 0x0E: // Currency suffix symbol
375 buf.ReadDWord();
376 break;
377
378 case 0x10: // Snow line height table
380 break;
381
382 case 0x11: { // GRF match for engine allocation
383 uint32_t s = buf.ReadDWord();
384 uint32_t t = buf.ReadDWord();
385 SetNewGRFOverride(s, t);
386 break;
387 }
388
389 case 0x13: // Gender translation table
390 case 0x14: // Case translation table
391 while (buf.ReadByte() != 0) {
392 buf.ReadString();
393 }
394 break;
395
396 default:
397 ret = CIR_UNKNOWN;
398 break;
399 }
400 }
401
402 return ret;
403}
404
405
417bool GetGlobalVariable(uint8_t param, uint32_t *value, const GRFFile *grffile)
418{
419 switch (param) {
420 case 0x00: // current date
422 return true;
423
424 case 0x01: // current year
426 return true;
427
428 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)
429 TimerGameCalendar::YearMonthDay ymd = TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date);
430 TimerGameCalendar::Date start_of_year = TimerGameCalendar::ConvertYMDToDate(ymd.year, 0, 1);
431 *value = ymd.month | (ymd.day - 1) << 8 | (TimerGameCalendar::IsLeapYear(ymd.year) ? 1 << 15 : 0) | (TimerGameCalendar::date - start_of_year).base() << 16;
432 return true;
433 }
434
435 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
437 return true;
438
439 case 0x06: // road traffic side, bit 4 clear=left, set=right
440 *value = _settings_game.vehicle.road_side << 4;
441 return true;
442
443 case 0x09: // date fraction
444 *value = TimerGameCalendar::date_fract * 885;
445 return true;
446
447 case 0x0A: // animation counter
448 *value = GB(TimerGameTick::counter, 0, 16);
449 return true;
450
451 case 0x0B: { // TTDPatch version
452 uint major = 2;
453 uint minor = 6;
454 uint revision = 1; // special case: 2.0.1 is 2.0.10
455 uint build = 1382;
456 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
457 return true;
458 }
459
460 case 0x0D: // TTD Version, 00=DOS, 01=Windows
461 *value = GetGRFConfig(grffile->grfid)->palette & GRFP_USE_MASK;
462 return true;
463
464 case 0x0E: // Y-offset for train sprites
465 *value = grffile->traininfo_vehicle_pitch;
466 return true;
467
468 case 0x0F: // Rail track type cost factors
469 *value = 0;
470 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
472 /* skip elrail multiplier - disabled */
473 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
474 } else {
475 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
476 /* Skip monorail multiplier - no space in result */
477 }
478 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
479 return true;
480
481 case 0x11: // current rail tool type
482 *value = 0; // constant fake value to avoid desync
483 return true;
484
485 case 0x12: // Game mode
486 *value = _game_mode;
487 return true;
488
489 /* case 0x13: // Tile refresh offset to left not implemented */
490 /* case 0x14: // Tile refresh offset to right not implemented */
491 /* case 0x15: // Tile refresh offset upwards not implemented */
492 /* case 0x16: // Tile refresh offset downwards not implemented */
493 /* case 0x17: // temperate snow line not implemented */
494
495 case 0x1A: // Always -1
496 *value = UINT_MAX;
497 return true;
498
499 case 0x1B: // Display options
500 *value = 0x3F; // constant fake value to avoid desync
501 return true;
502
503 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
504 *value = 1;
505 return true;
506
507 case 0x1E: { // Miscellaneous GRF features
509
510 /* Add the local flags */
512 if (grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) bits.Set(GrfMiscBit::TrainWidth32Pixels);
513
514 *value = bits.base();
515 return true;
516 }
517
518 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
519
520 case 0x20: { // snow line height
521 uint8_t snowline = GetSnowLine();
522 if (_settings_game.game_creation.landscape == LandscapeType::Arctic && snowline <= _settings_game.construction.map_height_limit) {
523 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
524 } else {
525 /* No snow */
526 *value = 0xFF;
527 }
528 return true;
529 }
530
531 case 0x21: // OpenTTD version
532 *value = _openttd_newgrf_version;
533 return true;
534
535 case 0x22: // difficulty level
536 *value = SP_CUSTOM;
537 return true;
538
539 case 0x23: // long format date
540 *value = TimerGameCalendar::date.base();
541 return true;
542
543 case 0x24: // long format year
544 *value = TimerGameCalendar::year.base();
545 return true;
546
547 default: return false;
548 }
549}
550
551template <> ChangeInfoResult GrfChangeInfoHandler<GSF_GLOBALVAR>::Reserve(uint first, uint last, int prop, ByteReader &buf) { return GlobalVarReserveInfo(first, last, prop, buf); }
552template <> 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.
debug_inline 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 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).
Enum-as-bit-set wrapper.
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
The maximum year of the original TTD.
static constexpr TimerGame< struct Calendar >::Year ORIGINAL_BASE_YEAR
The minimum starting year/base year of the original TTD.
static constexpr TimerGame< struct Calendar >::Date DAYS_TILL_ORIGINAL_BASE_YEAR
The date of the first day of the original base year.
static TickCounter counter
Monotonic counter, in ticks, since start of game.
static constexpr bool IsLeapYear(Year year)
Checks whether the given year is a leap year or not.
std::pair< size_t, char32_t > DecodeUtf8(std::string_view buf)
Decode a character from UTF-8.
Definition utf8.cpp:48
uint8_t GetNewgrfCurrencyIdConverted(uint8_t grfcurr_id)
Will return the ottd's index correspondence to the ttdpatch's id.
Definition currency.cpp:118
std::array< CurrencySpec, CURRENCY_END > _currency_specs
Array of currencies used by the system.
Definition currency.cpp:79
@ CURRENCY_END
always the last item
Definition currency.h:72
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.
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
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:2136
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:192
void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
Set the override for a NewGRF.
Definition newgrf.cpp:177
GrfMiscBits _misc_grf_features
Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E.
Definition newgrf.cpp:70
@ TrainWidth32Pixels
Use 32 pixels per train vehicle in depot gui and vehicle details. Never set in the global variable;.
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.
NewGRF buffer reader definition.
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.
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.
void AddStringForMapping(GRFStringID source, std::function< void(StringID)> &&func)
Record a static StringID for getting translated later.
NewGRF string mapping definition.
static const char32_t NFO_UTF8_IDENTIFIER
This character (thorn) indicates a unicode string to NFO.
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
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
@ SP_CUSTOM
No profile, special "custom" highscore.
static void StrMakeValid(Builder &builder, StringConsumer &consumer, StringValidationSettings settings)
Copies the valid (UTF-8) characters from consumer to the builder.
Definition string.cpp:117
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 map_height_limit
the maximum allowed heightlevel
uint8_t palette
GRFPalette, bitset.
Dynamic data of a loaded NewGRF.
Definition newgrf.h:115
std::vector< RailTypeLabel > railtype_list
Railtype translation table.
Definition newgrf.h:142
std::vector< RoadTypeLabel > roadtype_list
Roadtype translation table (road)
Definition newgrf.h:145
std::vector< RoadTypeLabel > tramtype_list
Roadtype translation table (tram)
Definition newgrf.h:148
std::vector< CargoLabel > cargo_list
Cargo translation table (local ID -> label)
Definition newgrf.h:136
uint traininfo_vehicle_width
Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details.
Definition newgrf.h:156
std::vector< BadgeID > badge_list
Badge translation table (local index -> global index)
Definition newgrf.h:139
int traininfo_vehicle_pitch
Vertical offset for drawing train images in depot GUI and vehicle details.
Definition newgrf.h:155
std::unordered_map< uint8_t, LanguageMap > language_map
Mappings related to the languages.
Definition newgrf.h:153
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition newgrf.h:159
LandscapeType landscape
the landscape we're currently in
ConstructionSettings construction
construction of things in-game
GameCreationSettings game_creation
settings used during the creation of a game (map)
VehicleSettings vehicle
options for vehicles
GRF feature handler.
GRFFile * grffile
Currently processed GRF file.
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:93
uint8_t GetCaseIndex(std::string_view case_str) const
Get the index for the given case.
Definition language.h:81
uint8_t GetGenderIndex(std::string_view gender_str) const
Get the index for the given gender.
Definition language.h:68
uint8_t road_side
the side of the road vehicles drive on
bool disable_elrails
when true, the elrails are disabled
static const uint TILE_HEIGHT
Height of a height level in world coordinate AND in pixels in ZOOM_BASE.
Definition tile_type.h:18