OpenTTD Source 20260129-master-g2bb01bd0e4
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
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 /* 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
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
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
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
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();
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 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: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
@ CURRENCY_END
always the last item
Definition currency.h:73
@ 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.
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.
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:2184
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
@ 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.
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: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
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
bool cargo_list_is_fallback
Set if cargo types have been created but a cargo list has not been installed.
Definition newgrf.h:157
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:160
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