OpenTTD Source 20251126-master-g67ded4f980
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 {: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 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 StrMakeValidInPlace(_currency_specs[curidx].separator);
182 /* By specifying only one bit, we prevent errors,
183 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
184 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
185 } else {
186 GrfMsg(1, "GlobalVarChangeInfo: Currency option {} out of range, ignoring", curidx);
187 }
188 break;
189 }
190
191 case 0x0D: { // Currency prefix symbol
192 uint curidx = GetNewgrfCurrencyIdConverted(id);
193 std::string prefix = ReadDWordAsString(buf);
194
195 if (curidx < CURRENCY_END) {
196 _currency_specs[curidx].prefix = std::move(prefix);
197 } else {
198 GrfMsg(1, "GlobalVarChangeInfo: Currency symbol {} out of range, ignoring", curidx);
199 }
200 break;
201 }
202
203 case 0x0E: { // Currency suffix symbol
204 uint curidx = GetNewgrfCurrencyIdConverted(id);
205 std::string suffix = ReadDWordAsString(buf);
206
207 if (curidx < CURRENCY_END) {
208 _currency_specs[curidx].suffix = std::move(suffix);
209 } else {
210 GrfMsg(1, "GlobalVarChangeInfo: Currency symbol {} out of range, ignoring", curidx);
211 }
212 break;
213 }
214
215 case 0x0F: { // Euro introduction dates
216 uint curidx = GetNewgrfCurrencyIdConverted(id);
217 TimerGameCalendar::Year year_euro{buf.ReadWord()};
218
219 if (curidx < CURRENCY_END) {
220 _currency_specs[curidx].to_euro = year_euro;
221 } else {
222 GrfMsg(1, "GlobalVarChangeInfo: Euro intro date {} out of range, ignoring", curidx);
223 }
224 break;
225 }
226
227 case 0x10: // Snow line height table
228 if (last > 1 || IsSnowLineSet()) {
229 GrfMsg(1, "GlobalVarChangeInfo: The snowline can only be set once ({})", last);
230 } else if (buf.Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
231 GrfMsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table ({})", buf.Remaining());
232 } else {
233 auto snow_line = std::make_unique<SnowLine>();
234
235 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
236 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
237 uint8_t &level = snow_line->table[i][j];
238 level = buf.ReadByte();
239 if (_cur_gps.grffile->grf_version >= 8) {
240 if (level != 0xFF) level = level * (1 + _settings_game.construction.map_height_limit) / 256;
241 } else {
242 if (level >= 128) {
243 /* no snow */
244 level = 0xFF;
245 } else {
246 level = level * (1 + _settings_game.construction.map_height_limit) / 128;
247 }
248 }
249
250 snow_line->highest_value = std::max(snow_line->highest_value, level);
251 snow_line->lowest_value = std::min(snow_line->lowest_value, level);
252 }
253 }
254 SetSnowLine(std::move(snow_line));
255 }
256 break;
257
258 case 0x11: // GRF match for engine allocation
259 /* This is loaded during the reservation stage, so just skip it here. */
260 /* Each entry is 8 bytes. */
261 buf.Skip(8);
262 break;
263
264 case 0x13: // Gender translation table
265 case 0x14: // Case translation table
266 case 0x15: { // Plural form translation
267 uint curidx = id; // The current index, i.e. language.
268 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : nullptr;
269 if (lang == nullptr) {
270 GrfMsg(1, "GlobalVarChangeInfo: Language {} is not known, ignoring", curidx);
271 /* Skip over the data. */
272 if (prop == 0x15) {
273 buf.ReadByte();
274 } else {
275 while (buf.ReadByte() != 0) {
276 buf.ReadString();
277 }
278 }
279 break;
280 }
281
282 if (prop == 0x15) {
283 uint plural_form = buf.ReadByte();
284 if (plural_form >= LANGUAGE_MAX_PLURAL) {
285 GrfMsg(1, "GlobalVarChanceInfo: Plural form {} is out of range, ignoring", plural_form);
286 } else {
287 _cur_gps.grffile->language_map[curidx].plural_form = plural_form;
288 }
289 break;
290 }
291
292 uint8_t newgrf_id = buf.ReadByte(); // The NewGRF (custom) identifier.
293 while (newgrf_id != 0) {
294 std::string_view name = buf.ReadString(); // The name for the OpenTTD identifier.
295
296 /* We'll just ignore the UTF8 identifier character. This is (fairly)
297 * safe as OpenTTD's strings gender/cases are usually in ASCII which
298 * is just a subset of UTF8, or they need the bigger UTF8 characters
299 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
300 auto [len, c] = DecodeUtf8(name);
301 if (c == NFO_UTF8_IDENTIFIER) name.remove_prefix(len);
302
304 map.newgrf_id = newgrf_id;
305 if (prop == 0x13) {
306 map.openttd_id = lang->GetGenderIndex(name);
307 if (map.openttd_id >= MAX_NUM_GENDERS) {
308 GrfMsg(1, "GlobalVarChangeInfo: Gender name {} is not known, ignoring", StrMakeValid(name));
309 } else {
310 _cur_gps.grffile->language_map[curidx].gender_map.push_back(map);
311 }
312 } else {
313 map.openttd_id = lang->GetCaseIndex(name);
314 if (map.openttd_id >= MAX_NUM_CASES) {
315 GrfMsg(1, "GlobalVarChangeInfo: Case name {} is not known, ignoring", StrMakeValid(name));
316 } else {
317 _cur_gps.grffile->language_map[curidx].case_map.push_back(map);
318 }
319 }
320 newgrf_id = buf.ReadByte();
321 }
322 break;
323 }
324
325 default:
326 ret = CIR_UNKNOWN;
327 break;
328 }
329 }
330
331 return ret;
332}
333
334static ChangeInfoResult GlobalVarReserveInfo(uint first, uint last, int prop, ByteReader &buf)
335{
336 /* Properties which are handled as a whole */
337 switch (prop) {
338 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
339 return LoadTranslationTable<CargoLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<CargoLabel> & { return grf.cargo_list; }, "Cargo");
340
341 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
342 return LoadTranslationTable<RailTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RailTypeLabel> & { return grf.railtype_list; }, "Rail type");
343
344 case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined roadtypes)
345 return LoadTranslationTable<RoadTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RoadTypeLabel> & { return grf.roadtype_list; }, "Road type");
346
347 case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined tramtypes)
348 return LoadTranslationTable<RoadTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RoadTypeLabel> & { return grf.tramtype_list; }, "Tram type");
349
350 case 0x18: // Badge translation table
351 return LoadBadgeTranslationTable(first, last, buf, _cur_gps.grffile->badge_list, "Badge");
352
353 default:
354 break;
355 }
356
357 /* Properties which are handled per item */
359
360 for (uint id = first; id < last; ++id) {
361 switch (prop) {
362 case 0x08: // Cost base factor
363 case 0x15: // Plural form translation
364 buf.ReadByte();
365 break;
366
367 case 0x0A: // Currency display names
368 case 0x0C: // Currency options
369 case 0x0F: // Euro introduction dates
370 buf.ReadWord();
371 break;
372
373 case 0x0B: // Currency multipliers
374 case 0x0D: // Currency prefix symbol
375 case 0x0E: // Currency suffix symbol
376 buf.ReadDWord();
377 break;
378
379 case 0x10: // Snow line height table
381 break;
382
383 case 0x11: { // GRF match for engine allocation
384 uint32_t s = buf.ReadDWord();
385 uint32_t t = buf.ReadDWord();
386 SetNewGRFOverride(s, t);
387 break;
388 }
389
390 case 0x13: // Gender translation table
391 case 0x14: // Case translation table
392 while (buf.ReadByte() != 0) {
393 buf.ReadString();
394 }
395 break;
396
397 default:
398 ret = CIR_UNKNOWN;
399 break;
400 }
401 }
402
403 return ret;
404}
405
406
418bool GetGlobalVariable(uint8_t param, uint32_t *value, const GRFFile *grffile)
419{
420 switch (param) {
421 case 0x00: // current date
423 return true;
424
425 case 0x01: // current year
427 return true;
428
429 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)
430 TimerGameCalendar::YearMonthDay ymd = TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date);
431 TimerGameCalendar::Date start_of_year = TimerGameCalendar::ConvertYMDToDate(ymd.year, 0, 1);
432 *value = ymd.month | (ymd.day - 1) << 8 | (TimerGameCalendar::IsLeapYear(ymd.year) ? 1 << 15 : 0) | (TimerGameCalendar::date - start_of_year).base() << 16;
433 return true;
434 }
435
436 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
438 return true;
439
440 case 0x06: // road traffic side, bit 4 clear=left, set=right
441 *value = _settings_game.vehicle.road_side << 4;
442 return true;
443
444 case 0x09: // date fraction
445 *value = TimerGameCalendar::date_fract * 885;
446 return true;
447
448 case 0x0A: // animation counter
449 *value = GB(TimerGameTick::counter, 0, 16);
450 return true;
451
452 case 0x0B: { // TTDPatch version
453 uint major = 2;
454 uint minor = 6;
455 uint revision = 1; // special case: 2.0.1 is 2.0.10
456 uint build = 1382;
457 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
458 return true;
459 }
460
461 case 0x0D: // TTD Version, 00=DOS, 01=Windows
462 *value = GetGRFConfig(grffile->grfid)->palette & GRFP_USE_MASK;
463 return true;
464
465 case 0x0E: // Y-offset for train sprites
466 *value = grffile->traininfo_vehicle_pitch;
467 return true;
468
469 case 0x0F: // Rail track type cost factors
470 *value = 0;
471 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
473 /* skip elrail multiplier - disabled */
474 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
475 } else {
476 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electrified railway
477 /* Skip monorail multiplier - no space in result */
478 }
479 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
480 return true;
481
482 case 0x11: // current rail tool type
483 *value = 0; // constant fake value to avoid desync
484 return true;
485
486 case 0x12: // Game mode
487 *value = _game_mode;
488 return true;
489
490 /* case 0x13: // Tile refresh offset to left not implemented */
491 /* case 0x14: // Tile refresh offset to right not implemented */
492 /* case 0x15: // Tile refresh offset upwards not implemented */
493 /* case 0x16: // Tile refresh offset downwards not implemented */
494 /* case 0x17: // temperate snow line not implemented */
495
496 case 0x1A: // Always -1
497 *value = UINT_MAX;
498 return true;
499
500 case 0x1B: // Display options
501 *value = 0x3F; // constant fake value to avoid desync
502 return true;
503
504 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
505 *value = 1;
506 return true;
507
508 case 0x1E: { // Miscellaneous GRF features
510
511 /* Add the local flags */
513 if (grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) bits.Set(GrfMiscBit::TrainWidth32Pixels);
514
515 *value = bits.base();
516 return true;
517 }
518
519 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
520
521 case 0x20: { // snow line height
522 uint8_t snowline = GetSnowLine();
523 if (_settings_game.game_creation.landscape == LandscapeType::Arctic && snowline <= _settings_game.construction.map_height_limit) {
524 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
525 } else {
526 /* No snow */
527 *value = 0xFF;
528 }
529 return true;
530 }
531
532 case 0x21: // OpenTTD version
533 *value = _openttd_newgrf_version;
534 return true;
535
536 case 0x22: // difficulty level
537 *value = SP_CUSTOM;
538 return true;
539
540 case 0x23: // long format date
541 *value = TimerGameCalendar::date.base();
542 return true;
543
544 case 0x24: // long format year
545 *value = TimerGameCalendar::year.base();
546 return true;
547
548 default: return false;
549 }
550}
551
552template <> ChangeInfoResult GrfChangeInfoHandler<GSF_GLOBALVAR>::Reserve(uint first, uint last, int prop, ByteReader &buf) { return GlobalVarReserveInfo(first, last, prop, buf); }
553template <> 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:119
std::array< CurrencySpec, CURRENCY_END > _currency_specs
Array of currencies used by the system.
Definition currency.cpp:80
@ CURRENCY_END
always the last item
Definition currency.h:73
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:2157
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:196
void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
Set the override for a NewGRF.
Definition newgrf.cpp:181
GrfMiscBits _misc_grf_features
Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E.
Definition newgrf.cpp:71
@ 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:301
@ 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.
void StrMakeValidInPlace(char *str, StringValidationSettings settings)
Scans the string for invalid characters and replaces them with a question mark '?' (if not ignored).
Definition string.cpp:158
static void StrMakeValid(Builder &builder, StringConsumer &consumer, StringValidationSettings settings)
Copies the valid (UTF-8) characters from consumer to the builder.
Definition string.cpp:120
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: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
uint8_t road_side
the side of the road vehicles drive on
bool disable_elrails
when true, the elrails are disabled
static constexpr uint TILE_HEIGHT
Height of a height level in world coordinate AND in pixels in ZOOM_BASE.
Definition tile_type.h:18