OpenTTD Source 20250328-master-gc3457cd4c0
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 "../newgrf.h"
18#include "../newgrf_badge.h"
19#include "../newgrf_badge_type.h"
20#include "../newgrf_cargo.h"
21#include "../newgrf_engine.h"
22#include "../newgrf_sound.h"
23#include "../vehicle_base.h"
24#include "../rail.h"
25#include "newgrf_bytereader.h"
27#include "newgrf_internal.h"
29
30#include "table/strings.h"
31
32#include "../safeguards.h"
33
43template <typename T, typename TGetTableFunc>
44static ChangeInfoResult LoadTranslationTable(uint first, uint last, ByteReader &buf, TGetTableFunc gettable, std::string_view name)
45{
46 if (first != 0) {
47 GrfMsg(1, "LoadTranslationTable: {} translation table must start at zero", name);
48 return CIR_INVALID_ID;
49 }
50
51 std::vector<T> &translation_table = gettable(*_cur.grffile);
52 translation_table.clear();
53 translation_table.reserve(last);
54 for (uint id = first; id < last; ++id) {
55 translation_table.push_back(T(std::byteswap(buf.ReadDWord())));
56 }
57
58 GRFFile *grf_override = GetCurrentGRFOverride();
59 if (grf_override != nullptr) {
60 /* GRF override is present, copy the translation table to the overridden GRF as well. */
61 GrfMsg(1, "LoadTranslationTable: Copying {} translation table to override GRFID '{}'", name, std::byteswap(grf_override->grfid));
62 std::vector<T> &override_table = gettable(*grf_override);
63 override_table = translation_table;
64 }
65
66 return CIR_SUCCESS;
67}
68
69static ChangeInfoResult LoadBadgeTranslationTable(uint first, uint last, ByteReader &buf, std::vector<BadgeID> &translation_table, const char *name)
70{
71 if (first != 0 && first != std::size(translation_table)) {
72 GrfMsg(1, "LoadBadgeTranslationTable: {} translation table must start at zero or {}", name, std::size(translation_table));
73 return CIR_INVALID_ID;
74 }
75
76 if (first == 0) translation_table.clear();
77 translation_table.reserve(last);
78 for (uint id = first; id < last; ++id) {
79 std::string_view label = buf.ReadString();
80 translation_table.push_back(GetOrCreateBadge(label).index);
81 }
82
83 return CIR_SUCCESS;
84}
85
92static std::string ReadDWordAsString(ByteReader &reader)
93{
94 std::string output;
95 for (int i = 0; i < 4; i++) output.push_back(reader.ReadByte());
96 return StrMakeValid(output);
97}
98
107static ChangeInfoResult GlobalVarChangeInfo(uint first, uint last, int prop, ByteReader &buf)
108{
109 /* Properties which are handled as a whole */
110 switch (prop) {
111 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
112 return LoadTranslationTable<CargoLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<CargoLabel> & { return grf.cargo_list; }, "Cargo");
113
114 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
115 return LoadTranslationTable<RailTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RailTypeLabel> & { return grf.railtype_list; }, "Rail type");
116
117 case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined roadtypes)
118 return LoadTranslationTable<RoadTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RoadTypeLabel> & { return grf.roadtype_list; }, "Road type");
119
120 case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined tramtypes)
121 return LoadTranslationTable<RoadTypeLabel>(first, last, buf, [](GRFFile &grf) -> std::vector<RoadTypeLabel> & { return grf.tramtype_list; }, "Tram type");
122
123 case 0x18: // Badge translation table
124 return LoadBadgeTranslationTable(first, last, buf, _cur.grffile->badge_list, "Badge");
125
126 default:
127 break;
128 }
129
130 /* Properties which are handled per item */
132 for (uint id = first; id < last; ++id) {
133 switch (prop) {
134 case 0x08: { // Cost base factor
135 int factor = buf.ReadByte();
136
137 if (id < PR_END) {
138 _cur.grffile->price_base_multipliers[id] = std::min<int>(factor - 8, MAX_PRICE_MODIFIER);
139 } else {
140 GrfMsg(1, "GlobalVarChangeInfo: Price {} out of range, ignoring", id);
141 }
142 break;
143 }
144
145 case 0x0A: { // Currency display names
146 uint curidx = GetNewgrfCurrencyIdConverted(id);
147 if (curidx < CURRENCY_END) {
148 AddStringForMapping(GRFStringID{buf.ReadWord()}, [curidx](StringID str) {
149 _currency_specs[curidx].name = str;
150 _currency_specs[curidx].code.clear();
151 });
152 } else {
153 buf.ReadWord();
154 }
155 break;
156 }
157
158 case 0x0B: { // Currency multipliers
159 uint curidx = GetNewgrfCurrencyIdConverted(id);
160 uint32_t rate = buf.ReadDWord();
161
162 if (curidx < CURRENCY_END) {
163 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
164 * which OTTD does not. For this reason, divide grf value by 1000,
165 * to be compatible */
166 _currency_specs[curidx].rate = rate / 1000;
167 } else {
168 GrfMsg(1, "GlobalVarChangeInfo: Currency multipliers {} out of range, ignoring", curidx);
169 }
170 break;
171 }
172
173 case 0x0C: { // Currency options
174 uint curidx = GetNewgrfCurrencyIdConverted(id);
175 uint16_t options = buf.ReadWord();
176
177 if (curidx < CURRENCY_END) {
178 _currency_specs[curidx].separator.clear();
179 _currency_specs[curidx].separator.push_back(GB(options, 0, 8));
180 /* By specifying only one bit, we prevent errors,
181 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
182 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
183 } else {
184 GrfMsg(1, "GlobalVarChangeInfo: Currency option {} out of range, ignoring", curidx);
185 }
186 break;
187 }
188
189 case 0x0D: { // Currency prefix symbol
190 uint curidx = GetNewgrfCurrencyIdConverted(id);
191 std::string prefix = ReadDWordAsString(buf);
192
193 if (curidx < CURRENCY_END) {
194 _currency_specs[curidx].prefix = std::move(prefix);
195 } else {
196 GrfMsg(1, "GlobalVarChangeInfo: Currency symbol {} out of range, ignoring", curidx);
197 }
198 break;
199 }
200
201 case 0x0E: { // Currency suffix symbol
202 uint curidx = GetNewgrfCurrencyIdConverted(id);
203 std::string suffix = ReadDWordAsString(buf);
204
205 if (curidx < CURRENCY_END) {
206 _currency_specs[curidx].suffix = std::move(suffix);
207 } else {
208 GrfMsg(1, "GlobalVarChangeInfo: Currency symbol {} out of range, ignoring", curidx);
209 }
210 break;
211 }
212
213 case 0x0F: { // Euro introduction dates
214 uint curidx = GetNewgrfCurrencyIdConverted(id);
215 TimerGameCalendar::Year year_euro{buf.ReadWord()};
216
217 if (curidx < CURRENCY_END) {
218 _currency_specs[curidx].to_euro = year_euro;
219 } else {
220 GrfMsg(1, "GlobalVarChangeInfo: Euro intro date {} out of range, ignoring", curidx);
221 }
222 break;
223 }
224
225 case 0x10: // Snow line height table
226 if (last > 1 || IsSnowLineSet()) {
227 GrfMsg(1, "GlobalVarChangeInfo: The snowline can only be set once ({})", last);
228 } else if (buf.Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
229 GrfMsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table ({})", buf.Remaining());
230 } else {
231 auto snow_line = std::make_unique<SnowLine>();
232
233 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
234 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
235 uint8_t &level = snow_line->table[i][j];
236 level = buf.ReadByte();
237 if (_cur.grffile->grf_version >= 8) {
238 if (level != 0xFF) level = level * (1 + _settings_game.construction.map_height_limit) / 256;
239 } else {
240 if (level >= 128) {
241 /* no snow */
242 level = 0xFF;
243 } else {
244 level = level * (1 + _settings_game.construction.map_height_limit) / 128;
245 }
246 }
247
248 snow_line->highest_value = std::max(snow_line->highest_value, level);
249 snow_line->lowest_value = std::min(snow_line->lowest_value, level);
250 }
251 }
252 SetSnowLine(std::move(snow_line));
253 }
254 break;
255
256 case 0x11: // GRF match for engine allocation
257 /* This is loaded during the reservation stage, so just skip it here. */
258 /* Each entry is 8 bytes. */
259 buf.Skip(8);
260 break;
261
262 case 0x13: // Gender translation table
263 case 0x14: // Case translation table
264 case 0x15: { // Plural form translation
265 uint curidx = id; // The current index, i.e. language.
266 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : nullptr;
267 if (lang == nullptr) {
268 GrfMsg(1, "GlobalVarChangeInfo: Language {} is not known, ignoring", curidx);
269 /* Skip over the data. */
270 if (prop == 0x15) {
271 buf.ReadByte();
272 } else {
273 while (buf.ReadByte() != 0) {
274 buf.ReadString();
275 }
276 }
277 break;
278 }
279
280 if (prop == 0x15) {
281 uint plural_form = buf.ReadByte();
282 if (plural_form >= LANGUAGE_MAX_PLURAL) {
283 GrfMsg(1, "GlobalVarChanceInfo: Plural form {} is out of range, ignoring", plural_form);
284 } else {
285 _cur.grffile->language_map[curidx].plural_form = plural_form;
286 }
287 break;
288 }
289
290 uint8_t newgrf_id = buf.ReadByte(); // The NewGRF (custom) identifier.
291 while (newgrf_id != 0) {
292 std::string_view name = buf.ReadString(); // The name for the OpenTTD identifier.
293
294 /* We'll just ignore the UTF8 identifier character. This is (fairly)
295 * safe as OpenTTD's strings gender/cases are usually in ASCII which
296 * is just a subset of UTF8, or they need the bigger UTF8 characters
297 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
298 char32_t c;
299 size_t len = Utf8Decode(&c, name.data());
300 if (len <= name.size() && c == NFO_UTF8_IDENTIFIER) name = name.substr(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.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.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.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
421 *value = std::max(TimerGameCalendar::date - CalendarTime::DAYS_TILL_ORIGINAL_BASE_YEAR, TimerGameCalendar::Date(0)).base();
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 = _cur.grfconfig->palette & GRFP_USE_MASK;
462 return true;
463
464 case 0x0E: // Y-offset for train sprites
465 *value = _cur.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 (_cur.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 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.
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:2138
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:189
void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid)
Set the override for a NewGRF.
Definition newgrf.cpp:174
GrfMiscBits _misc_grf_features
Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E.
Definition newgrf.cpp:69
@ 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.
@ 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:59
@ SP_CUSTOM
No profile, special "custom" highscore.
static void StrMakeValid(T &dst, const char *str, const char *last, StringValidationSettings settings)
Copies the valid (UTF-8) characters from str up to last to the dst.
Definition string.cpp:125
size_t Utf8Decode(char32_t *c, const char *s)
Decode and consume the next UTF-8 encoded character.
Definition string.cpp:451
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:113
std::vector< RailTypeLabel > railtype_list
Railtype translation table.
Definition newgrf.h:140
std::vector< RoadTypeLabel > roadtype_list
Roadtype translation table (road)
Definition newgrf.h:143
std::vector< RoadTypeLabel > tramtype_list
Roadtype translation table (tram)
Definition newgrf.h:146
std::vector< CargoLabel > cargo_list
Cargo translation table (local ID -> label)
Definition newgrf.h:134
uint traininfo_vehicle_width
Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details.
Definition newgrf.h:154
std::vector< BadgeID > badge_list
Badge translation table (local index -> global index)
Definition newgrf.h:137
int traininfo_vehicle_pitch
Vertical offset for drawing train images in depot GUI and vehicle details.
Definition newgrf.h:153
std::unordered_map< uint8_t, LanguageMap > language_map
Mappings related to the languages.
Definition newgrf.h:151
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition newgrf.h:157
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.
GRFConfig * grfconfig
Config of the 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