OpenTTD Source: src/newgrf.cpp Source File

OpenTTD Source 1.11.0-RC1

newgrf.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
12 #include <stdarg.h>
13
14 #include "debug.h"
15 #include "fileio_func.h"
16 #include "engine_func.h"
17 #include "engine_base.h"
18 #include "bridge.h"
19 #include "town.h"
20 #include "newgrf_engine.h"
21 #include "newgrf_text.h"
22 #include "fontcache.h"
23 #include "currency.h"
24 #include "landscape.h"
25 #include "newgrf_cargo.h"
26 #include "newgrf_house.h"
27 #include "newgrf_sound.h"
28 #include "newgrf_station.h"
29 #include "industrytype.h"
30 #include "newgrf_canal.h"
31 #include "newgrf_townname.h"
32 #include "newgrf_industries.h"
33 #include "newgrf_airporttiles.h"
34 #include "newgrf_airport.h"
35 #include "newgrf_object.h"
36 #include "rev.h"
37 #include "fios.h"
38 #include "strings_func.h"
39 #include "date_func.h"
40 #include "string_func.h"
41 #include "network/network.h"
42 #include <map>
43 #include "smallmap_gui.h"
44 #include "genworld.h"
45 #include "error.h"
46 #include "vehicle_func.h"
47 #include "language.h"
48 #include "vehicle_base.h"
49 #include "road.h"
50
51 #include "table/strings.h"
52 #include "table/build_industry.h"
53
54 #include "safeguards.h"
55
56 /* TTDPatch extended GRF format codec
57 * (c) Petr Baudis 2004 (GPL'd)
58 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
59 *
60 * Contains portions of documentation by TTDPatch team.
61 * Thanks especially to Josef Drexler for the documentation as well as a lot
62 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
63 * served as subject to the initial testing of this codec. */
64
66 static std::vector<GRFFile *> _grf_files;
67
68 const std::vector<GRFFile *> &GetAllGRFFiles()
69 {
70 return _grf_files;
71 }
72
74 byte _misc_grf_features = 0;
75
77 static uint32 _ttdpatch_flags[8];
78
80 GRFLoadedFeatures _loaded_newgrf_features;
81
82 static const uint MAX_SPRITEGROUP = UINT8_MAX;
83
85 struct GrfProcessingState {
86 private:
88 struct SpriteSet {
89 SpriteID sprite;
90 uint num_sprites;
91 };
92
94 std::map<uint, SpriteSet> spritesets[GSF_END];
95
96 public:
97 /* Global state */
98 GrfLoadingStage stage;
99 SpriteID spriteid;
100
101 /* Local state in the file */
102 uint file_index;
103 GRFFile *grffile;
104 GRFConfig *grfconfig;
105 uint32 nfo_line;
106 byte grf_container_ver;
107
108 /* Kind of return values when processing certain actions */
109 int skip_sprites;
110
111 /* Currently referenceable spritegroups */
112 SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
113
115 void ClearDataForNextFile()
116 {
117 this->nfo_line = 0;
118 this->skip_sprites = 0;
119
120 for (uint i = 0; i < GSF_END; i++) {
121 this->spritesets[i].clear();
122 }
123
124 memset(this->spritegroups, 0, sizeof(this->spritegroups));
125 }
126
135 void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
136 {
137 assert(feature < GSF_END);
138 for (uint i = 0; i < numsets; i++) {
139 SpriteSet &set = this->spritesets[feature][first_set + i];
140 set.sprite = first_sprite + i * numents;
141 set.num_sprites = numents;
142 }
143 }
144
151 bool HasValidSpriteSets(byte feature) const
152 {
153 assert(feature < GSF_END);
154 return !this->spritesets[feature].empty();
155 }
156
164 bool IsValidSpriteSet(byte feature, uint set) const
165 {
166 assert(feature < GSF_END);
167 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
168 }
169
176 SpriteID GetSprite(byte feature, uint set) const
177 {
178 assert(IsValidSpriteSet(feature, set));
179 return this->spritesets[feature].find(set)->second.sprite;
180 }
181
188 uint GetNumEnts(byte feature, uint set) const
189 {
190 assert(IsValidSpriteSet(feature, set));
191 return this->spritesets[feature].find(set)->second.num_sprites;
192 }
193 };
194
195 static GrfProcessingState _cur;
196
197
204 template <VehicleType T>
205 static inline bool IsValidNewGRFImageIndex(uint8 image_index)
206 {
207 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
208 }
209
210 class OTTDByteReaderSignal { };
211
213 class ByteReader {
214 protected:
215 byte *data;
216 byte *end;
217
218 public:
219 ByteReader(byte *data, byte *end) : data(data), end(end) { }
220
221 inline byte ReadByte()
222 {
223 if (data < end) return *(data)++;
224 throw OTTDByteReaderSignal();
225 }
226
227 uint16 ReadWord()
228 {
229 uint16 val = ReadByte();
230 return val | (ReadByte() << 8);
231 }
232
233 uint16 ReadExtendedByte()
234 {
235 uint16 val = ReadByte();
236 return val == 0xFF ? ReadWord() : val;
237 }
238
239 uint32 ReadDWord()
240 {
241 uint32 val = ReadWord();
242 return val | (ReadWord() << 16);
243 }
244
245 uint32 ReadVarSize(byte size)
246 {
247 switch (size) {
248 case 1: return ReadByte();
249 case 2: return ReadWord();
250 case 4: return ReadDWord();
251 default:
252 NOT_REACHED();
253 return 0;
254 }
255 }
256
257 const char *ReadString()
258 {
259 char *string = reinterpret_cast<char *>(data);
260 size_t string_length = ttd_strnlen(string, Remaining());
261
262 if (string_length == Remaining()) {
263 /* String was not NUL terminated, so make sure it is now. */
264 string[string_length - 1] = '\0';
265 grfmsg(7, "String was not terminated with a zero byte.");
266 } else {
267 /* Increase the string length to include the NUL byte. */
268 string_length++;
269 }
270 Skip(string_length);
271
272 return string;
273 }
274
275 inline size_t Remaining() const
276 {
277 return end - data;
278 }
279
280 inline bool HasData(size_t count = 1) const
281 {
282 return data + count <= end;
283 }
284
285 inline byte *Data()
286 {
287 return data;
288 }
289
290 inline void Skip(size_t len)
291 {
292 data += len;
293 /* It is valid to move the buffer to exactly the end of the data,
294 * as there may not be any more data read. */
295 if (data > end) throw OTTDByteReaderSignal();
296 }
297 };
298
299 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
300
301 static const uint NUM_STATIONS_PER_GRF = 255;
302
304 struct GRFTempEngineData {
306 enum Refittability {
307 UNSET = 0,
308 EMPTY,
309 NONEMPTY,
310 };
311
312 uint16 cargo_allowed;
313 uint16 cargo_disallowed;
314 RailTypeLabel railtypelabel;
315 uint8 roadtramtype;
316 const GRFFile *defaultcargo_grf;
317 Refittability refittability;
318 bool prop27_set;
319 uint8 rv_max_speed;
320 CargoTypes ctt_include_mask;
321 CargoTypes ctt_exclude_mask;
322
327 void UpdateRefittability(bool non_empty)
328 {
329 if (non_empty) {
330 this->refittability = NONEMPTY;
331 } else if (this->refittability == UNSET) {
332 this->refittability = EMPTY;
333 }
334 }
335 };
336
337 static GRFTempEngineData *_gted;
338
343 static uint32 _grm_engines[256];
344
346 static uint32 _grm_cargoes[NUM_CARGO * 2];
347
348 struct GRFLocation {
349 uint32 grfid;
350 uint32 nfoline;
351
352 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
353
354 bool operator<(const GRFLocation &other) const
355 {
356 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
357 }
358
359 bool operator == (const GRFLocation &other) const
360 {
361 return this->grfid == other.grfid && this->nfoline == other.nfoline;
362 }
363 };
364
365 static std::map<GRFLocation, SpriteID> _grm_sprites;
366 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
367 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
368
379 void CDECL grfmsg(int severity, const char *str, ...)
380 {
381 char buf[1024];
382 va_list va;
383
384 va_start(va, str);
385 vseprintf(buf, lastof(buf), str, va);
386 va_end(va);
387
388 DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
389 }
390
396 static GRFFile *GetFileByGRFID(uint32 grfid)
397 {
398 for (GRFFile * const file : _grf_files) {
399 if (file->grfid == grfid) return file;
400 }
401 return nullptr;
402 }
403
409 static GRFFile *GetFileByFilename(const char *filename)
410 {
411 for (GRFFile * const file : _grf_files) {
412 if (strcmp(file->filename, filename) == 0) return file;
413 }
414 return nullptr;
415 }
416
418 static void ClearTemporaryNewGRFData(GRFFile *gf)
419 {
420 /* Clear the GOTO labels used for GRF processing */
421 for (GRFLabel *l = gf->label; l != nullptr;) {
422 GRFLabel *l2 = l->next;
423 free(l);
424 l = l2;
425 }
426 gf->label = nullptr;
427 }
428
435 static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = nullptr)
436 {
437 GRFFile *file;
438 if (config != nullptr) {
439 file = GetFileByGRFID(config->ident.grfid);
440 } else {
441 config = _cur.grfconfig;
442 file = _cur.grffile;
443 }
444
445 config->status = GCS_DISABLED;
446 if (file != nullptr) ClearTemporaryNewGRFData(file);
447 if (config == _cur.grfconfig) _cur.skip_sprites = -1;
448
449 if (message != STR_NULL) {
450 delete config->error;
451 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
452 if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
453 }
454
455 return config->error;
456 }
457
461 struct StringIDMapping {
462 uint32 grfid;
463 StringID source;
464 StringID *target;
465 };
466 typedef std::vector<StringIDMapping> StringIDMappingVector;
467 static StringIDMappingVector _string_to_grf_mapping;
468
474 static void AddStringForMapping(StringID source, StringID *target)
475 {
476 *target = STR_UNDEFINED;
477 _string_to_grf_mapping.push_back({_cur.grffile->grfid, source, target});
478 }
479
487 static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
488 {
489 /* StringID table for TextIDs 0x4E->0x6D */
490 static const StringID units_volume[] = {
491 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
492 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
493 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
494 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
495 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
496 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
497 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
498 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
499 };
500
501 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
502 assert(!IsInsideMM(str, 0xD000, 0xD7FF));
503
504 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
505 static_assert(stringend - stringid == end - begin); \
506 if (str >= begin && str <= end) return str + (stringid - begin)
507
508 /* We have some changes in our cargo strings, resulting in some missing. */
509 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
510 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
511 if (str >= 0x004E && str <= 0x006D) return units_volume[str - 0x004E];
512 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
513 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
514 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
515
516 /* Map building names according to our lang file changes. There are several
517 * ranges of house ids, all of which need to be remapped to allow newgrfs
518 * to use original house names. */
519 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
520 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
521 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
522
523 /* Same thing for industries */
524 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
525 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
526 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
527 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
528 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
529
530 switch (str) {
531 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
532 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
533 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
534 }
535 #undef TEXTID_TO_STRINGID
536
537 if (str == STR_NULL) return STR_EMPTY;
538
539 DEBUG(grf, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
540
541 return STR_EMPTY;
542 }
543
551 StringID MapGRFStringID(uint32 grfid, StringID str)
552 {
553 if (IsInsideMM(str, 0xD800, 0xE000)) {
554 /* General text provided by NewGRF.
555 * In the specs this is called the 0xDCxx range (misc persistent texts),
556 * but we meanwhile extended the range to 0xD800-0xDFFF.
557 * Note: We are not involved in the "persistent" business, since we do not store
558 * any NewGRF strings in savegames. */
559 return GetGRFStringID(grfid, str);
560 } else if (IsInsideMM(str, 0xD000, 0xD800)) {
561 /* Callback text provided by NewGRF.
562 * In the specs this is called the 0xD0xx range (misc graphics texts).
563 * These texts can be returned by various callbacks.
564 *
565 * Due to how TTDP implements the GRF-local- to global-textid translation
566 * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
567 * We do not care about that difference and just mask out the 0x400 bit.
568 */
569 str &= ~0x400;
570 return GetGRFStringID(grfid, str);
571 } else {
572 /* The NewGRF wants to include/reference an original TTD string.
573 * Try our best to find an equivalent one. */
574 return TTDPStringIDToOTTDStringIDMapping(str);
575 }
576 }
577
578 static std::map<uint32, uint32> _grf_id_overrides;
579
585 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
586 {
587 _grf_id_overrides[source_grfid] = target_grfid;
588 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
589 }
590
599 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
600 {
601 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
602 * them use the same engine slots. */
603 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
604 if (_settings_game.vehicle.dynamic_engines) {
605 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
606 scope_grfid = file->grfid;
607 uint32 override = _grf_id_overrides[file->grfid];
608 if (override != 0) {
609 scope_grfid = override;
610 const GRFFile *grf_match = GetFileByGRFID(override);
611 if (grf_match == nullptr) {
612 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
613 } else {
614 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
615 }
616 }
617
618 /* Check if the engine is registered in the override manager */
619 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
620 if (engine != INVALID_ENGINE) {
621 Engine *e = Engine::Get(engine);
622 if (e->grf_prop.grffile == nullptr) e->grf_prop.grffile = file;
623 return e;
624 }
625 }
626
627 /* Check if there is an unreserved slot */
628 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
629 if (engine != INVALID_ENGINE) {
630 Engine *e = Engine::Get(engine);
631
632 if (e->grf_prop.grffile == nullptr) {
633 e->grf_prop.grffile = file;
634 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
635 }
636
637 /* Reserve the engine slot */
638 if (!static_access) {
639 EngineIDMapping *eid = _engine_mngr.data() + engine;
640 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
641 }
642
643 return e;
644 }
645
646 if (static_access) return nullptr;
647
648 if (!Engine::CanAllocateItem()) {
649 grfmsg(0, "Can't allocate any more engines");
650 return nullptr;
651 }
652
653 size_t engine_pool_size = Engine::GetPoolSize();
654
655 /* ... it's not, so create a new one based off an existing engine */
656 Engine *e = new Engine(type, internal_id);
657 e->grf_prop.grffile = file;
658
659 /* Reserve the engine slot */
660 assert(_engine_mngr.size() == e->index);
661 _engine_mngr.push_back({
662 scope_grfid, // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
663 internal_id,
664 type,
665 std::min<uint8>(internal_id, _engine_counts[type]) // substitute_id == _engine_counts[subtype] means "no substitute"
666 });
667
668 if (engine_pool_size != Engine::GetPoolSize()) {
669 /* Resize temporary engine data ... */
670 _gted = ReallocT(_gted, Engine::GetPoolSize());
671
672 /* and blank the new block. */
673 size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
674 memset(_gted + engine_pool_size, 0, len);
675 }
676 if (type == VEH_TRAIN) {
677 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
678 }
679
680 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
681
682 return e;
683 }
684
695 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
696 {
697 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
698 if (_settings_game.vehicle.dynamic_engines) {
699 scope_grfid = file->grfid;
700 uint32 override = _grf_id_overrides[file->grfid];
701 if (override != 0) scope_grfid = override;
702 }
703
704 return _engine_mngr.GetID(type, internal_id, scope_grfid);
705 }
706
711 static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
712 {
713 if (HasBit(grf_sprite->pal, 14)) {
714 ClrBit(grf_sprite->pal, 14);
715 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_OPAQUE);
716 }
717
718 if (HasBit(grf_sprite->sprite, 14)) {
719 ClrBit(grf_sprite->sprite, 14);
720 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_TRANSPARENT);
721 }
722
723 if (HasBit(grf_sprite->sprite, 15)) {
724 ClrBit(grf_sprite->sprite, 15);
725 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOUR);
726 }
727 }
728
742 static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags, bool invert_action1_flag, bool use_cur_spritesets, int feature, PalSpriteID *grf_sprite, uint16 *max_sprite_offset = nullptr, uint16 *max_palette_offset = nullptr)
743 {
744 grf_sprite->sprite = buf->ReadWord();
745 grf_sprite->pal = buf->ReadWord();
746 TileLayoutFlags flags = read_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
747
748 MapSpriteMappingRecolour(grf_sprite);
749
750 bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
751 ClrBit(grf_sprite->pal, 15);
752 if (custom_sprite) {
753 /* Use sprite from Action 1 */
754 uint index = GB(grf_sprite->sprite, 0, 14);
755 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
756 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
757 grf_sprite->sprite = SPR_IMG_QUERY;
758 grf_sprite->pal = PAL_NONE;
759 } else {
760 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
761 if (max_sprite_offset != nullptr) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
762 SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
763 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
764 }
765 } else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
766 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
767 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
768 return flags;
769 }
770
771 if (flags & TLF_CUSTOM_PALETTE) {
772 /* Use palette from Action 1 */
773 uint index = GB(grf_sprite->pal, 0, 14);
774 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
775 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
776 grf_sprite->pal = PAL_NONE;
777 } else {
778 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
779 if (max_palette_offset != nullptr) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
780 SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
781 SetBit(grf_sprite->pal, SPRITE_MODIFIER_CUSTOM_SPRITE);
782 }
783 } else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
784 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
785 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
786 return flags;
787 }
788
789 return flags;
790 }
791
800 static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bool is_parent, NewGRFSpriteLayout *dts, uint index)
801 {
802 if (!(flags & TLF_DRAWING_FLAGS)) return;
803
804 if (dts->registers == nullptr) dts->AllocateRegisters();
805 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[index]);
806 regs.flags = flags & TLF_DRAWING_FLAGS;
807
808 if (flags & TLF_DODRAW) regs.dodraw = buf->ReadByte();
809 if (flags & TLF_SPRITE) regs.sprite = buf->ReadByte();
810 if (flags & TLF_PALETTE) regs.palette = buf->ReadByte();
811
812 if (is_parent) {
813 if (flags & TLF_BB_XY_OFFSET) {
814 regs.delta.parent[0] = buf->ReadByte();
815 regs.delta.parent[1] = buf->ReadByte();
816 }
817 if (flags & TLF_BB_Z_OFFSET) regs.delta.parent[2] = buf->ReadByte();
818 } else {
819 if (flags & TLF_CHILD_X_OFFSET) regs.delta.child[0] = buf->ReadByte();
820 if (flags & TLF_CHILD_Y_OFFSET) regs.delta.child[1] = buf->ReadByte();
821 }
822
823 if (flags & TLF_SPRITE_VAR10) {
824 regs.sprite_var10 = buf->ReadByte();
825 if (regs.sprite_var10 > TLR_MAX_VAR10) {
826 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
827 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
828 return;
829 }
830 }
831
832 if (flags & TLF_PALETTE_VAR10) {
833 regs.palette_var10 = buf->ReadByte();
834 if (regs.palette_var10 > TLR_MAX_VAR10) {
835 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
836 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
837 return;
838 }
839 }
840 }
841
853 static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
854 {
855 bool has_flags = HasBit(num_building_sprites, 6);
856 ClrBit(num_building_sprites, 6);
857 TileLayoutFlags valid_flags = TLF_KNOWN_FLAGS;
858 if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
859 dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags
860
861 uint16 *max_sprite_offset = AllocaM(uint16, num_building_sprites + 1);
862 uint16 *max_palette_offset = AllocaM(uint16, num_building_sprites + 1);
863 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
864 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
865
866 /* Groundsprite */
867 TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground, max_sprite_offset, max_palette_offset);
868 if (_cur.skip_sprites < 0) return true;
869
870 if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
871 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
872 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
873 return true;
874 }
875
876 ReadSpriteLayoutRegisters(buf, flags, false, dts, 0);
877 if (_cur.skip_sprites < 0) return true;
878
879 for (uint i = 0; i < num_building_sprites; i++) {
880 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&dts->seq[i]);
881
882 flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
883 if (_cur.skip_sprites < 0) return true;
884
885 if (flags & ~valid_flags) {
886 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
887 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
888 return true;
889 }
890
891 seq->delta_x = buf->ReadByte();
892 seq->delta_y = buf->ReadByte();
893
894 if (!no_z_position) seq->delta_z = buf->ReadByte();
895
896 if (seq->IsParentSprite()) {
897 seq->size_x = buf->ReadByte();
898 seq->size_y = buf->ReadByte();
899 seq->size_z = buf->ReadByte();
900 }
901
902 ReadSpriteLayoutRegisters(buf, flags, seq->IsParentSprite(), dts, i + 1);
903 if (_cur.skip_sprites < 0) return true;
904 }
905
906 /* Check if the number of sprites per spriteset is consistent */
907 bool is_consistent = true;
908 dts->consistent_max_offset = 0;
909 for (uint i = 0; i < num_building_sprites + 1; i++) {
910 if (max_sprite_offset[i] > 0) {
911 if (dts->consistent_max_offset == 0) {
912 dts->consistent_max_offset = max_sprite_offset[i];
913 } else if (dts->consistent_max_offset != max_sprite_offset[i]) {
914 is_consistent = false;
915 break;
916 }
917 }
918 if (max_palette_offset[i] > 0) {
919 if (dts->consistent_max_offset == 0) {
920 dts->consistent_max_offset = max_palette_offset[i];
921 } else if (dts->consistent_max_offset != max_palette_offset[i]) {
922 is_consistent = false;
923 break;
924 }
925 }
926 }
927
928 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
929 assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX)));
930
931 if (!is_consistent || dts->registers != nullptr) {
932 dts->consistent_max_offset = 0;
933 if (dts->registers == nullptr) dts->AllocateRegisters();
934
935 for (uint i = 0; i < num_building_sprites + 1; i++) {
936 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[i]);
937 regs.max_sprite_offset = max_sprite_offset[i];
938 regs.max_palette_offset = max_palette_offset[i];
939 }
940 }
941
942 return false;
943 }
944
948 static CargoTypes TranslateRefitMask(uint32 refit_mask)
949 {
950 CargoTypes result = 0;
951 uint8 bit;
952 FOR_EACH_SET_BIT(bit, refit_mask) {
953 CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true);
954 if (cargo != CT_INVALID) SetBit(result, cargo);
955 }
956 return result;
957 }
958
966 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
967 {
968 /* Special value for 'none' */
969 if (base_pointer == 0) {
970 *index = INVALID_PRICE;
971 return;
972 }
973
974 static const uint32 start = 0x4B34;
975 static const uint32 size = 6;
976
977 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
978 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
979 return;
980 }
981
982 *index = (Price)((base_pointer - start) / size);
983 }
984
986 enum ChangeInfoResult {
987 CIR_SUCCESS,
988 CIR_DISABLED,
989 CIR_UNHANDLED,
990 CIR_UNKNOWN,
991 CIR_INVALID_ID,
992 };
993
994 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
995
1003 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
1004 {
1005 switch (prop) {
1006 case 0x00: // Introduction date
1007 ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
1008 break;
1009
1010 case 0x02: // Decay speed
1011 ei->decay_speed = buf->ReadByte();
1012 break;
1013
1014 case 0x03: // Vehicle life
1015 ei->lifelength = buf->ReadByte();
1016 break;
1017
1018 case 0x04: // Model life
1019 ei->base_life = buf->ReadByte();
1020 break;
1021
1022 case 0x06: // Climates available
1023 ei->climates = buf->ReadByte();
1024 break;
1025
1026 case PROP_VEHICLE_LOAD_AMOUNT: // 0x07 Loading speed
1027 /* Amount of cargo loaded during a vehicle's "loading tick" */
1028 ei->load_amount = buf->ReadByte();
1029 break;
1030
1031 default:
1032 return CIR_UNKNOWN;
1033 }
1034
1035 return CIR_SUCCESS;
1036 }
1037
1046 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1047 {
1048 ChangeInfoResult ret = CIR_SUCCESS;
1049
1050 for (int i = 0; i < numinfo; i++) {
1051 Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i);
1052 if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1053
1054 EngineInfo *ei = &e->info;
1055 RailVehicleInfo *rvi = &e->u.rail;
1056
1057 switch (prop) {
1058 case 0x05: { // Track type
1059 uint8 tracktype = buf->ReadByte();
1060
1061 if (tracktype < _cur.grffile->railtype_list.size()) {
1062 _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype];
1063 break;
1064 }
1065
1066 switch (tracktype) {
1067 case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
1068 case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
1069 case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
1070 default:
1071 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1072 break;
1073 }
1074 break;
1075 }
1076
1077 case 0x08: // AI passenger service
1078 /* Tells the AI that this engine is designed for
1079 * passenger services and shouldn't be used for freight. */
1080 rvi->ai_passenger_only = buf->ReadByte();
1081 break;
1082
1083 case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
1084 uint16 speed = buf->ReadWord();
1085 if (speed == 0xFFFF) speed = 0;
1086
1087 rvi->max_speed = speed;
1088 break;
1089 }
1090
1091 case PROP_TRAIN_POWER: // 0x0B Power
1092 rvi->power = buf->ReadWord();
1093
1094 /* Set engine / wagon state based on power */
1095 if (rvi->power != 0) {
1096 if (rvi->railveh_type == RAILVEH_WAGON) {
1097 rvi->railveh_type = RAILVEH_SINGLEHEAD;
1098 }
1099 } else {
1100 rvi->railveh_type = RAILVEH_WAGON;
1101 }
1102 break;
1103
1104 case PROP_TRAIN_RUNNING_COST_FACTOR: // 0x0D Running cost factor
1105 rvi->running_cost = buf->ReadByte();
1106 break;
1107
1108 case 0x0E: // Running cost base
1109 ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
1110 break;
1111
1112 case 0x12: { // Sprite ID
1113 uint8 spriteid = buf->ReadByte();
1114 uint8 orig_spriteid = spriteid;
1115
1116 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1117 * as an array index, so we need it to be half the original value. */
1118 if (spriteid < 0xFD) spriteid >>= 1;
1119
1120 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1121 rvi->image_index = spriteid;
1122 } else {
1123 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1124 rvi->image_index = 0;
1125 }
1126 break;
1127 }
1128
1129 case 0x13: { // Dual-headed
1130 uint8 dual = buf->ReadByte();
1131
1132 if (dual != 0) {
1133 rvi->railveh_type = RAILVEH_MULTIHEAD;
1134 } else {
1135 rvi->railveh_type = rvi->power == 0 ?
1136 RAILVEH_WAGON : RAILVEH_SINGLEHEAD;
1137 }
1138 break;
1139 }
1140
1141 case PROP_TRAIN_CARGO_CAPACITY: // 0x14 Cargo capacity
1142 rvi->capacity = buf->ReadByte();
1143 break;
1144
1145 case 0x15: { // Cargo type
1146 _gted[e->index].defaultcargo_grf = _cur.grffile;
1147 uint8 ctype = buf->ReadByte();
1148
1149 if (ctype == 0xFF) {
1150 /* 0xFF is specified as 'use first refittable' */
1151 ei->cargo_type = CT_INVALID;
1152 } else if (_cur.grffile->grf_version >= 8) {
1153 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1154 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1155 } else if (ctype < NUM_CARGO) {
1156 /* Use untranslated cargo. */
1157 ei->cargo_type = ctype;
1158 } else {
1159 ei->cargo_type = CT_INVALID;
1160 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1161 }
1162 break;
1163 }
1164
1165 case PROP_TRAIN_WEIGHT: // 0x16 Weight
1166 SB(rvi->weight, 0, 8, buf->ReadByte());
1167 break;
1168
1169 case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
1170 rvi->cost_factor = buf->ReadByte();
1171 break;
1172
1173 case 0x18: // AI rank
1174 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1175 buf->ReadByte();
1176 break;
1177
1178 case 0x19: { // Engine traction type
1179 /* What do the individual numbers mean?
1180 * 0x00 .. 0x07: Steam
1181 * 0x08 .. 0x27: Diesel
1182 * 0x28 .. 0x31: Electric
1183 * 0x32 .. 0x37: Monorail
1184 * 0x38 .. 0x41: Maglev
1185 */
1186 uint8 traction = buf->ReadByte();
1187 EngineClass engclass;
1188
1189 if (traction <= 0x07) {
1190 engclass = EC_STEAM;
1191 } else if (traction <= 0x27) {
1192 engclass = EC_DIESEL;
1193 } else if (traction <= 0x31) {
1194 engclass = EC_ELECTRIC;
1195 } else if (traction <= 0x37) {
1196 engclass = EC_MONORAIL;
1197 } else if (traction <= 0x41) {
1198 engclass = EC_MAGLEV;
1199 } else {
1200 break;
1201 }
1202
1203 if (_cur.grffile->railtype_list.size() == 0) {
1204 /* Use traction type to select between normal and electrified
1205 * rail only when no translation list is in place. */
1206 if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1207 if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
1208 }
1209
1210 rvi->engclass = engclass;
1211 break;
1212 }
1213
1214 case 0x1A: // Alter purchase list sort order
1215 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1216 break;
1217
1218 case 0x1B: // Powered wagons power bonus
1219 rvi->pow_wag_power = buf->ReadWord();
1220 break;
1221
1222 case 0x1C: // Refit cost
1223 ei->refit_cost = buf->ReadByte();
1224 break;
1225
1226 case 0x1D: { // Refit cargo
1227 uint32 mask = buf->ReadDWord();
1228 _gted[e->index].UpdateRefittability(mask != 0);
1229 ei->refit_mask = TranslateRefitMask(mask);
1230 _gted[e->index].defaultcargo_grf = _cur.grffile;
1231 break;
1232 }
1233
1234 case 0x1E: // Callback
1235 ei->callback_mask = buf->ReadByte();
1236 break;
1237
1238 case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
1239 rvi->tractive_effort = buf->ReadByte();
1240 break;
1241
1242 case 0x20: // Air drag
1243 rvi->air_drag = buf->ReadByte();
1244 break;
1245
1246 case PROP_TRAIN_SHORTEN_FACTOR: // 0x21 Shorter vehicle
1247 rvi->shorten_factor = buf->ReadByte();
1248 break;
1249
1250 case 0x22: // Visual effect
1251 rvi->visual_effect = buf->ReadByte();
1252 /* Avoid accidentally setting visual_effect to the default value
1253 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1254 if (rvi->visual_effect == VE_DEFAULT) {
1255 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1256 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1257 }
1258 break;
1259
1260 case 0x23: // Powered wagons weight bonus
1261 rvi->pow_wag_weight = buf->ReadByte();
1262 break;
1263
1264 case 0x24: { // High byte of vehicle weight
1265 byte weight = buf->ReadByte();
1266
1267 if (weight > 4) {
1268 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1269 } else {
1270 SB(rvi->weight, 8, 8, weight);
1271 }
1272 break;
1273 }
1274
1275 case PROP_TRAIN_USER_DATA: // 0x25 User-defined bit mask to set when checking veh. var. 42
1276 rvi->user_def_data = buf->ReadByte();
1277 break;
1278
1279 case 0x26: // Retire vehicle early
1280 ei->retire_early = buf->ReadByte();
1281 break;
1282
1283 case 0x27: // Miscellaneous flags
1284 ei->misc_flags = buf->ReadByte();
1285 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1286 _gted[e->index].prop27_set = true;
1287 break;
1288
1289 case 0x28: // Cargo classes allowed
1290 _gted[e->index].cargo_allowed = buf->ReadWord();
1291 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1292 _gted[e->index].defaultcargo_grf = _cur.grffile;
1293 break;
1294
1295 case 0x29: // Cargo classes disallowed
1296 _gted[e->index].cargo_disallowed = buf->ReadWord();
1297 _gted[e->index].UpdateRefittability(false);
1298 break;
1299
1300 case 0x2A: // Long format introduction date (days since year 0)
1301 ei->base_intro = buf->ReadDWord();
1302 break;
1303
1304 case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
1305 ei->cargo_age_period = buf->ReadWord();
1306 break;
1307
1308 case 0x2C: // CTT refit include list
1309 case 0x2D: { // CTT refit exclude list
1310 uint8 count = buf->ReadByte();
1311 _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
1312 if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile;
1313 CargoTypes &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1314 ctt = 0;
1315 while (count--) {
1316 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1317 if (ctype == CT_INVALID) continue;
1318 SetBit(ctt, ctype);
1319 }
1320 break;
1321 }
1322
1323 default:
1324 ret = CommonVehicleChangeInfo(ei, prop, buf);
1325 break;
1326 }
1327 }
1328
1329 return ret;
1330 }
1331
1340 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1341 {
1342 ChangeInfoResult ret = CIR_SUCCESS;
1343
1344 for (int i = 0; i < numinfo; i++) {
1345 Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i);
1346 if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1347
1348 EngineInfo *ei = &e->info;
1349 RoadVehicleInfo *rvi = &e->u.road;
1350
1351 switch (prop) {
1352 case 0x05: // Road/tram type
1353 /* RoadTypeLabel is looked up later after the engine's road/tram
1354 * flag is set, however 0 means the value has not been set. */
1355 _gted[e->index].roadtramtype = buf->ReadByte() + 1;
1356 break;
1357
1358 case 0x08: // Speed (1 unit is 0.5 kmh)
1359 rvi->max_speed = buf->ReadByte();
1360 break;
1361
1362 case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1363 rvi->running_cost = buf->ReadByte();
1364 break;
1365
1366 case 0x0A: // Running cost base
1367 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1368 break;
1369
1370 case 0x0E: { // Sprite ID
1371 uint8 spriteid = buf->ReadByte();
1372 uint8 orig_spriteid = spriteid;
1373
1374 /* cars have different custom id in the GRF file */
1375 if (spriteid == 0xFF) spriteid = 0xFD;
1376
1377 if (spriteid < 0xFD) spriteid >>= 1;
1378
1379 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1380 rvi->image_index = spriteid;
1381 } else {
1382 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1383 rvi->image_index = 0;
1384 }
1385 break;
1386 }
1387
1388 case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1389 rvi->capacity = buf->ReadByte();
1390 break;
1391
1392 case 0x10: { // Cargo type
1393 _gted[e->index].defaultcargo_grf = _cur.grffile;
1394 uint8 ctype = buf->ReadByte();
1395
1396 if (ctype == 0xFF) {
1397 /* 0xFF is specified as 'use first refittable' */
1398 ei->cargo_type = CT_INVALID;
1399 } else if (_cur.grffile->grf_version >= 8) {
1400 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1401 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1402 } else if (ctype < NUM_CARGO) {
1403 /* Use untranslated cargo. */
1404 ei->cargo_type = ctype;
1405 } else {
1406 ei->cargo_type = CT_INVALID;
1407 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1408 }
1409 break;
1410 }
1411
1412 case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1413 rvi->cost_factor = buf->ReadByte();
1414 break;
1415
1416 case 0x12: // SFX
1417 rvi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1418 break;
1419
1420 case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1421 rvi->power = buf->ReadByte();
1422 break;
1423
1424 case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1425 rvi->weight = buf->ReadByte();
1426 break;
1427
1428 case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1429 _gted[e->index].rv_max_speed = buf->ReadByte();
1430 break;
1431
1432 case 0x16: { // Cargoes available for refitting
1433 uint32 mask = buf->ReadDWord();
1434 _gted[e->index].UpdateRefittability(mask != 0);
1435 ei->refit_mask = TranslateRefitMask(mask);
1436 _gted[e->index].defaultcargo_grf = _cur.grffile;
1437 break;
1438 }
1439
1440 case 0x17: // Callback mask
1441 ei->callback_mask = buf->ReadByte();
1442 break;
1443
1444 case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1445 rvi->tractive_effort = buf->ReadByte();
1446 break;
1447
1448 case 0x19: // Air drag
1449 rvi->air_drag = buf->ReadByte();
1450 break;
1451
1452 case 0x1A: // Refit cost
1453 ei->refit_cost = buf->ReadByte();
1454 break;
1455
1456 case 0x1B: // Retire vehicle early
1457 ei->retire_early = buf->ReadByte();
1458 break;
1459
1460 case 0x1C: // Miscellaneous flags
1461 ei->misc_flags = buf->ReadByte();
1462 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1463 break;
1464
1465 case 0x1D: // Cargo classes allowed
1466 _gted[e->index].cargo_allowed = buf->ReadWord();
1467 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1468 _gted[e->index].defaultcargo_grf = _cur.grffile;
1469 break;
1470
1471 case 0x1E: // Cargo classes disallowed
1472 _gted[e->index].cargo_disallowed = buf->ReadWord();
1473 _gted[e->index].UpdateRefittability(false);
1474 break;
1475
1476 case 0x1F: // Long format introduction date (days since year 0)
1477 ei->base_intro = buf->ReadDWord();
1478 break;
1479
1480 case 0x20: // Alter purchase list sort order
1481 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1482 break;
1483
1484 case 0x21: // Visual effect
1485 rvi->visual_effect = buf->ReadByte();
1486 /* Avoid accidentally setting visual_effect to the default value
1487 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1488 if (rvi->visual_effect == VE_DEFAULT) {
1489 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1490 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1491 }
1492 break;
1493
1494 case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1495 ei->cargo_age_period = buf->ReadWord();
1496 break;
1497
1498 case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
1499 rvi->shorten_factor = buf->ReadByte();
1500 break;
1501
1502 case 0x24: // CTT refit include list
1503 case 0x25: { // CTT refit exclude list
1504 uint8 count = buf->ReadByte();
1505 _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
1506 if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
1507 CargoTypes &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1508 ctt = 0;
1509 while (count--) {
1510 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1511 if (ctype == CT_INVALID) continue;
1512 SetBit(ctt, ctype);
1513 }
1514 break;
1515 }
1516
1517 default:
1518 ret = CommonVehicleChangeInfo(ei, prop, buf);
1519 break;
1520 }
1521 }
1522
1523 return ret;
1524 }
1525
1534 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1535 {
1536 ChangeInfoResult ret = CIR_SUCCESS;
1537
1538 for (int i = 0; i < numinfo; i++) {
1539 Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1540 if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1541
1542 EngineInfo *ei = &e->info;
1543 ShipVehicleInfo *svi = &e->u.ship;
1544
1545 switch (prop) {
1546 case 0x08: { // Sprite ID
1547 uint8 spriteid = buf->ReadByte();
1548 uint8 orig_spriteid = spriteid;
1549
1550 /* ships have different custom id in the GRF file */
1551 if (spriteid == 0xFF) spriteid = 0xFD;
1552
1553 if (spriteid < 0xFD) spriteid >>= 1;
1554
1555 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1556 svi->image_index = spriteid;
1557 } else {
1558 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1559 svi->image_index = 0;
1560 }
1561 break;
1562 }
1563
1564 case 0x09: // Refittable
1565 svi->old_refittable = (buf->ReadByte() != 0);
1566 break;
1567
1568 case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1569 svi->cost_factor = buf->ReadByte();
1570 break;
1571
1572 case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1573 svi->max_speed = buf->ReadByte();
1574 break;
1575
1576 case 0x0C: { // Cargo type
1577 _gted[e->index].defaultcargo_grf = _cur.grffile;
1578 uint8 ctype = buf->ReadByte();
1579
1580 if (ctype == 0xFF) {
1581 /* 0xFF is specified as 'use first refittable' */
1582 ei->cargo_type = CT_INVALID;
1583 } else if (_cur.grffile->grf_version >= 8) {
1584 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1585 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1586 } else if (ctype < NUM_CARGO) {
1587 /* Use untranslated cargo. */
1588 ei->cargo_type = ctype;
1589 } else {
1590 ei->cargo_type = CT_INVALID;
1591 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1592 }
1593 break;
1594 }
1595
1596 case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1597 svi->capacity = buf->ReadWord();
1598 break;
1599
1600 case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1601 svi->running_cost = buf->ReadByte();
1602 break;
1603
1604 case 0x10: // SFX
1605 svi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1606 break;
1607
1608 case 0x11: { // Cargoes available for refitting
1609 uint32 mask = buf->ReadDWord();
1610 _gted[e->index].UpdateRefittability(mask != 0);
1611 ei->refit_mask = TranslateRefitMask(mask);
1612 _gted[e->index].defaultcargo_grf = _cur.grffile;
1613 break;
1614 }
1615
1616 case 0x12: // Callback mask
1617 ei->callback_mask = buf->ReadByte();
1618 break;
1619
1620 case 0x13: // Refit cost
1621 ei->refit_cost = buf->ReadByte();
1622 break;
1623
1624 case 0x14: // Ocean speed fraction
1625 svi->ocean_speed_frac = buf->ReadByte();
1626 break;
1627
1628 case 0x15: // Canal speed fraction
1629 svi->canal_speed_frac = buf->ReadByte();
1630 break;
1631
1632 case 0x16: // Retire vehicle early
1633 ei->retire_early = buf->ReadByte();
1634 break;
1635
1636 case 0x17: // Miscellaneous flags
1637 ei->misc_flags = buf->ReadByte();
1638 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1639 break;
1640
1641 case 0x18: // Cargo classes allowed
1642 _gted[e->index].cargo_allowed = buf->ReadWord();
1643 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1644 _gted[e->index].defaultcargo_grf = _cur.grffile;
1645 break;
1646
1647 case 0x19: // Cargo classes disallowed
1648 _gted[e->index].cargo_disallowed = buf->ReadWord();
1649 _gted[e->index].UpdateRefittability(false);
1650 break;
1651
1652 case 0x1A: // Long format introduction date (days since year 0)
1653 ei->base_intro = buf->ReadDWord();
1654 break;
1655
1656 case 0x1B: // Alter purchase list sort order
1657 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1658 break;
1659
1660 case 0x1C: // Visual effect
1661 svi->visual_effect = buf->ReadByte();
1662 /* Avoid accidentally setting visual_effect to the default value
1663 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1664 if (svi->visual_effect == VE_DEFAULT) {
1665 assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1666 SB(svi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1667 }
1668 break;
1669
1670 case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1671 ei->cargo_age_period = buf->ReadWord();
1672 break;
1673
1674 case 0x1E: // CTT refit include list
1675 case 0x1F: { // CTT refit exclude list
1676 uint8 count = buf->ReadByte();
1677 _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
1678 if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
1679 CargoTypes &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1680 ctt = 0;
1681 while (count--) {
1682 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1683 if (ctype == CT_INVALID) continue;
1684 SetBit(ctt, ctype);
1685 }
1686 break;
1687 }
1688
1689 default:
1690 ret = CommonVehicleChangeInfo(ei, prop, buf);
1691 break;
1692 }
1693 }
1694
1695 return ret;
1696 }
1697
1706 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1707 {
1708 ChangeInfoResult ret = CIR_SUCCESS;
1709
1710 for (int i = 0; i < numinfo; i++) {
1711 Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1712 if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1713
1714 EngineInfo *ei = &e->info;
1715 AircraftVehicleInfo *avi = &e->u.air;
1716
1717 switch (prop) {
1718 case 0x08: { // Sprite ID
1719 uint8 spriteid = buf->ReadByte();
1720 uint8 orig_spriteid = spriteid;
1721
1722 /* aircraft have different custom id in the GRF file */
1723 if (spriteid == 0xFF) spriteid = 0xFD;
1724
1725 if (spriteid < 0xFD) spriteid >>= 1;
1726
1727 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1728 avi->image_index = spriteid;
1729 } else {
1730 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1731 avi->image_index = 0;
1732 }
1733 break;
1734 }
1735
1736 case 0x09: // Helicopter
1737 if (buf->ReadByte() == 0) {
1738 avi->subtype = AIR_HELI;
1739 } else {
1740 SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1741 }
1742 break;
1743
1744 case 0x0A: // Large
1745 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1746 break;
1747
1748 case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1749 avi->cost_factor = buf->ReadByte();
1750 break;
1751
1752 case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1753 avi->max_speed = (buf->ReadByte() * 128) / 10;
1754 break;
1755
1756 case 0x0D: // Acceleration
1757 avi->acceleration = buf->ReadByte();
1758 break;
1759
1760 case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1761 avi->running_cost = buf->ReadByte();
1762 break;
1763
1764 case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1765 avi->passenger_capacity = buf->ReadWord();
1766 break;
1767
1768 case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1769 avi->mail_capacity = buf->ReadByte();
1770 break;
1771
1772 case 0x12: // SFX
1773 avi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1774 break;
1775
1776 case 0x13: { // Cargoes available for refitting
1777 uint32 mask = buf->ReadDWord();
1778 _gted[e->index].UpdateRefittability(mask != 0);
1779 ei->refit_mask = TranslateRefitMask(mask);
1780 _gted[e->index].defaultcargo_grf = _cur.grffile;
1781 break;
1782 }
1783
1784 case 0x14: // Callback mask
1785 ei->callback_mask = buf->ReadByte();
1786 break;
1787
1788 case 0x15: // Refit cost
1789 ei->refit_cost = buf->ReadByte();
1790 break;
1791
1792 case 0x16: // Retire vehicle early
1793 ei->retire_early = buf->ReadByte();
1794 break;
1795
1796 case 0x17: // Miscellaneous flags
1797 ei->misc_flags = buf->ReadByte();
1798 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1799 break;
1800
1801 case 0x18: // Cargo classes allowed
1802 _gted[e->index].cargo_allowed = buf->ReadWord();
1803 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1804 _gted[e->index].defaultcargo_grf = _cur.grffile;
1805 break;
1806
1807 case 0x19: // Cargo classes disallowed
1808 _gted[e->index].cargo_disallowed = buf->ReadWord();
1809 _gted[e->index].UpdateRefittability(false);
1810 break;
1811
1812 case 0x1A: // Long format introduction date (days since year 0)
1813 ei->base_intro = buf->ReadDWord();
1814 break;
1815
1816 case 0x1B: // Alter purchase list sort order
1817 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1818 break;
1819
1820 case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1821 ei->cargo_age_period = buf->ReadWord();
1822 break;
1823
1824 case 0x1D: // CTT refit include list
1825 case 0x1E: { // CTT refit exclude list
1826 uint8 count = buf->ReadByte();
1827 _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
1828 if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
1829 CargoTypes &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1830 ctt = 0;
1831 while (count--) {
1832 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1833 if (ctype == CT_INVALID) continue;
1834 SetBit(ctt, ctype);
1835 }
1836 break;
1837 }
1838
1839 case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
1840 avi->max_range = buf->ReadWord();
1841 break;
1842
1843 default:
1844 ret = CommonVehicleChangeInfo(ei, prop, buf);
1845 break;
1846 }
1847 }
1848
1849 return ret;
1850 }
1851
1860 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
1861 {
1862 ChangeInfoResult ret = CIR_SUCCESS;
1863
1864 if (stid + numinfo > NUM_STATIONS_PER_GRF) {
1865 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
1866 return CIR_INVALID_ID;
1867 }
1868
1869 /* Allocate station specs if necessary */
1870 if (_cur.grffile->stations == nullptr) _cur.grffile->stations = CallocT<StationSpec*>(NUM_STATIONS_PER_GRF);
1871
1872 for (int i = 0; i < numinfo; i++) {
1873 StationSpec *statspec = _cur.grffile->stations[stid + i];
1874
1875 /* Check that the station we are modifying is defined. */
1876 if (statspec == nullptr && prop != 0x08) {
1877 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1878 return CIR_INVALID_ID;
1879 }
1880
1881 switch (prop) {
1882 case 0x08: { // Class ID
1883 StationSpec **spec = &_cur.grffile->stations[stid + i];
1884
1885 /* Property 0x08 is special; it is where the station is allocated */
1886 if (*spec == nullptr) *spec = CallocT<StationSpec>(1);
1887
1888 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1889 uint32 classid = buf->ReadDWord();
1890 (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
1891 break;
1892 }
1893
1894 case 0x09: // Define sprite layout
1895 statspec->tiles = buf->ReadExtendedByte();
1896 delete[] statspec->renderdata; // delete earlier loaded stuff
1897 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1898
1899 for (uint t = 0; t < statspec->tiles; t++) {
1900 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1901 dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
1902
1903 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1904 buf->Skip(4);
1905 extern const DrawTileSprites _station_display_datas_rail[8];
1906 dts->Clone(&_station_display_datas_rail[t % 8]);
1907 continue;
1908 }
1909
1910 ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
1911 /* On error, bail out immediately. Temporary GRF data was already freed */
1912 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1913
1914 static std::vector<DrawTileSeqStruct> tmp_layout;
1915 tmp_layout.clear();
1916 for (;;) {
1917 /* no relative bounding box support */
1918 DrawTileSeqStruct &dtss = tmp_layout.emplace_back();
1919 MemSetT(&dtss, 0);
1920
1921 dtss.delta_x = buf->ReadByte();
1922 if (dtss.IsTerminator()) break;
1923 dtss.delta_y = buf->ReadByte();
1924 dtss.delta_z = buf->ReadByte();
1925 dtss.size_x = buf->ReadByte();
1926 dtss.size_y = buf->ReadByte();
1927 dtss.size_z = buf->ReadByte();
1928
1929 ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss.image);
1930 /* On error, bail out immediately. Temporary GRF data was already freed */
1931 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1932 }
1933 dts->Clone(tmp_layout.data());
1934 }
1935 break;
1936
1937 case 0x0A: { // Copy sprite layout
1938 byte srcid = buf->ReadByte();
1939 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1940
1941 if (srcstatspec == nullptr) {
1942 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1943 continue;
1944 }
1945
1946 delete[] statspec->renderdata; // delete earlier loaded stuff
1947
1948 statspec->tiles = srcstatspec->tiles;
1949 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1950 for (uint t = 0; t < statspec->tiles; t++) {
1951 statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
1952 }
1953 break;
1954 }
1955
1956 case 0x0B: // Callback mask
1957 statspec->callback_mask = buf->ReadByte();
1958 break;
1959
1960 case 0x0C: // Disallowed number of platforms
1961 statspec->disallowed_platforms = buf->ReadByte();
1962 break;
1963
1964 case 0x0D: // Disallowed platform lengths
1965 statspec->disallowed_lengths = buf->ReadByte();
1966 break;
1967
1968 case 0x0E: // Define custom layout
1969 statspec->copied_layouts = false;
1970
1971 while (buf->HasData()) {
1972 byte length = buf->ReadByte();
1973 byte number = buf->ReadByte();
1974 StationLayout layout;
1975 uint l, p;
1976
1977 if (length == 0 || number == 0) break;
1978
1979 if (length > statspec->lengths) {
1980 byte diff_length = length - statspec->lengths;
1981 statspec->platforms = ReallocT(statspec->platforms, length);
1982 memset(statspec->platforms + statspec->lengths, 0, diff_length);
1983
1984 statspec->layouts = ReallocT(statspec->layouts, length);
1985 memset(statspec->layouts + statspec->lengths, 0, diff_length * sizeof(*statspec->layouts));
1986
1987 statspec->lengths = length;
1988 }
1989 l = length - 1; // index is zero-based
1990
1991 if (number > statspec->platforms[l]) {
1992 statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
1993 /* We expect nullptr being 0 here, but C99 guarantees that. */
1994 memset(statspec->layouts[l] + statspec->platforms[l], 0,
1995 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
1996
1997 statspec->platforms[l] = number;
1998 }
1999
2000 p = 0;
2001 layout = MallocT<byte>(length * number);
2002 try {
2003 for (l = 0; l < length; l++) {
2004 for (p = 0; p < number; p++) {
2005 layout[l * number + p] = buf->ReadByte();
2006 }
2007 }
2008 } catch (...) {
2009 free(layout);
2010 throw;
2011 }
2012
2013 l--;
2014 p--;
2015 free(statspec->layouts[l][p]);
2016 statspec->layouts[l][p] = layout;
2017 }
2018 break;
2019
2020 case 0x0F: { // Copy custom layout
2021 byte srcid = buf->ReadByte();
2022 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
2023
2024 if (srcstatspec == nullptr) {
2025 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2026 continue;
2027 }
2028
2029 statspec->lengths = srcstatspec->lengths;
2030 statspec->platforms = srcstatspec->platforms;
2031 statspec->layouts = srcstatspec->layouts;
2032 statspec->copied_layouts = true;
2033 break;
2034 }
2035
2036 case 0x10: // Little/lots cargo threshold
2037 statspec->cargo_threshold = buf->ReadWord();
2038 break;
2039
2040 case 0x11: // Pylon placement
2041 statspec->pylons = buf->ReadByte();
2042 break;
2043
2044 case 0x12: // Cargo types for random triggers
2045 if (_cur.grffile->grf_version >= 7) {
2046 statspec->cargo_triggers = TranslateRefitMask(buf->ReadDWord());
2047 } else {
2048 statspec->cargo_triggers = (CargoTypes)buf->ReadDWord();
2049 }
2050 break;
2051
2052 case 0x13: // General flags
2053 statspec->flags = buf->ReadByte();
2054 break;
2055
2056 case 0x14: // Overhead wire placement
2057 statspec->wires = buf->ReadByte();
2058 break;
2059
2060 case 0x15: // Blocked tiles
2061 statspec->blocked = buf->ReadByte();
2062 break;
2063
2064 case 0x16: // Animation info
2065 statspec->animation.frames = buf->ReadByte();
2066 statspec->animation.status = buf->ReadByte();
2067 break;
2068
2069 case 0x17: // Animation speed
2070 statspec->animation.speed = buf->ReadByte();
2071 break;
2072
2073 case 0x18: // Animation triggers
2074 statspec->animation.triggers = buf->ReadWord();
2075 break;
2076
2077 case 0x1A: // Advanced sprite layout
2078 statspec->tiles = buf->ReadExtendedByte();
2079 delete[] statspec->renderdata; // delete earlier loaded stuff
2080 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
2081
2082 for (uint t = 0; t < statspec->tiles; t++) {
2083 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
2084 uint num_building_sprites = buf->ReadByte();
2085 /* On error, bail out immediately. Temporary GRF data was already freed */
2086 if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED;
2087 }
2088 break;
2089
2090 default:
2091 ret = CIR_UNKNOWN;
2092 break;
2093 }
2094 }
2095
2096 return ret;
2097 }
2098
2107 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
2108 {
2109 ChangeInfoResult ret = CIR_SUCCESS;
2110
2111 if (id + numinfo > CF_END) {
2112 grfmsg(1, "CanalChangeInfo: Canal feature 0x%02X is invalid, max %u, ignoring", id + numinfo, CF_END);
2113 return CIR_INVALID_ID;
2114 }
2115
2116 for (int i = 0; i < numinfo; i++) {
2117 CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
2118
2119 switch (prop) {
2120 case 0x08:
2121 cp->callback_mask = buf->ReadByte();
2122 break;
2123
2124 case 0x09:
2125 cp->flags = buf->ReadByte();
2126 break;
2127
2128 default:
2129 ret = CIR_UNKNOWN;
2130 break;
2131 }
2132 }
2133
2134 return ret;
2135 }
2136
2145 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
2146 {
2147 ChangeInfoResult ret = CIR_SUCCESS;
2148
2149 if (brid + numinfo > MAX_BRIDGES) {
2150 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
2151 return CIR_INVALID_ID;
2152 }
2153
2154 for (int i = 0; i < numinfo; i++) {
2155 BridgeSpec *bridge = &_bridge[brid + i];
2156
2157 switch (prop) {
2158 case 0x08: { // Year of availability
2159 /* We treat '0' as always available */
2160 byte year = buf->ReadByte();
2161 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
2162 break;
2163 }
2164
2165 case 0x09: // Minimum length
2166 bridge->min_length = buf->ReadByte();
2167 break;
2168
2169 case 0x0A: // Maximum length
2170 bridge->max_length = buf->ReadByte();
2171 if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
2172 break;
2173
2174 case 0x0B: // Cost factor
2175 bridge->price = buf->ReadByte();
2176 break;
2177
2178 case 0x0C: // Maximum speed
2179 bridge->speed = buf->ReadWord();
2180 break;
2181
2182 case 0x0D: { // Bridge sprite tables
2183 byte tableid = buf->ReadByte();
2184 byte numtables = buf->ReadByte();
2185
2186 if (bridge->sprite_table == nullptr) {
2187 /* Allocate memory for sprite table pointers and zero out */
2188 bridge->sprite_table = CallocT<PalSpriteID*>(7);
2189 }
2190
2191 for (; numtables-- != 0; tableid++) {
2192 if (tableid >= 7) { // skip invalid data
2193 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2194 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2195 continue;
2196 }
2197
2198 if (bridge->sprite_table[tableid] == nullptr) {
2199 bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
2200 }
2201
2202 for (byte sprite = 0; sprite < 32; sprite++) {
2203 SpriteID image = buf->ReadWord();
2204 PaletteID pal = buf->ReadWord();
2205
2206 bridge->sprite_table[tableid][sprite].sprite = image;
2207 bridge->sprite_table[tableid][sprite].pal = pal;
2208
2209 MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
2210 }
2211 }
2212 break;
2213 }
2214
2215 case 0x0E: // Flags; bit 0 - disable far pillars
2216 bridge->flags = buf->ReadByte();
2217 break;
2218
2219 case 0x0F: // Long format year of availability (year since year 0)
2220 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
2221 break;
2222
2223 case 0x10: { // purchase string
2224 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2225 if (newone != STR_UNDEFINED) bridge->material = newone;
2226 break;
2227 }
2228
2229 case 0x11: // description of bridge with rails or roads
2230 case 0x12: {
2231 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2232 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
2233 break;
2234 }
2235
2236 case 0x13: // 16 bits cost multiplier
2237 bridge->price = buf->ReadWord();
2238 break;
2239
2240 default:
2241 ret = CIR_UNKNOWN;
2242 break;
2243 }
2244 }
2245
2246 return ret;
2247 }
2248
2255 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
2256 {
2257 ChangeInfoResult ret = CIR_SUCCESS;
2258
2259 switch (prop) {
2260 case 0x09:
2261 case 0x0B:
2262 case 0x0C:
2263 case 0x0D:
2264 case 0x0E:
2265 case 0x0F:
2266 case 0x11:
2267 case 0x14:
2268 case 0x15:
2269 case 0x16:
2270 case 0x18:
2271 case 0x19:
2272 case 0x1A:
2273 case 0x1B:
2274 case 0x1C:
2275 case 0x1D:
2276 case 0x1F:
2277 buf->ReadByte();
2278 break;
2279
2280 case 0x0A:
2281 case 0x10:
2282 case 0x12:
2283 case 0x13:
2284 case 0x21:
2285 case 0x22:
2286 buf->ReadWord();
2287 break;
2288
2289 case 0x1E:
2290 buf->ReadDWord();
2291 break;
2292
2293 case 0x17:
2294 for (uint j = 0; j < 4; j++) buf->ReadByte();
2295 break;
2296
2297 case 0x20: {
2298 byte count = buf->ReadByte();
2299 for (byte j = 0; j < count; j++) buf->ReadByte();
2300 break;
2301 }
2302
2303 case 0x23:
2304 buf->Skip(buf->ReadByte() * 2);
2305 break;
2306
2307 default:
2308 ret = CIR_UNKNOWN;
2309 break;
2310 }
2311 return ret;
2312 }
2313
2322 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2323 {
2324 ChangeInfoResult ret = CIR_SUCCESS;
2325
2326 if (hid + numinfo > NUM_HOUSES_PER_GRF) {
2327 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
2328 return CIR_INVALID_ID;
2329 }
2330
2331 /* Allocate house specs if they haven't been allocated already. */
2332 if (_cur.grffile->housespec == nullptr) {
2333 _cur.grffile->housespec = CallocT<HouseSpec*>(NUM_HOUSES_PER_GRF);
2334 }
2335
2336 for (int i = 0; i < numinfo; i++) {
2337 HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2338
2339 if (prop != 0x08 && housespec == nullptr) {
2340 /* If the house property 08 is not yet set, ignore this property */
2341 ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2342 if (cir > ret) ret = cir;
2343 continue;
2344 }
2345
2346 switch (prop) {
2347 case 0x08: { // Substitute building type, and definition of a new house
2348 HouseSpec **house = &_cur.grffile->housespec[hid + i];
2349 byte subs_id = buf->ReadByte();
2350
2351 if (subs_id == 0xFF) {
2352 /* Instead of defining a new house, a substitute house id
2353 * of 0xFF disables the old house with the current id. */
2354 HouseSpec::Get(hid + i)->enabled = false;
2355 continue;
2356 } else if (subs_id >= NEW_HOUSE_OFFSET) {
2357 /* The substitute id must be one of the original houses. */
2358 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2359 continue;
2360 }
2361
2362 /* Allocate space for this house. */
2363 if (*house == nullptr) *house = CallocT<HouseSpec>(1);
2364
2365 housespec = *house;
2366
2367 MemCpyT(housespec, HouseSpec::Get(subs_id));
2368
2369 housespec->enabled = true;
2370 housespec->grf_prop.local_id = hid + i;
2371 housespec->grf_prop.subst_id = subs_id;
2372 housespec->grf_prop.grffile = _cur.grffile;
2373 housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2374 housespec->random_colour[1] = 0x08; // for all new houses
2375 housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2376 housespec->random_colour[3] = 0x06;
2377
2378 /* Make sure that the third cargo type is valid in this
2379 * climate. This can cause problems when copying the properties
2380 * of a house that accepts food, where the new house is valid
2381 * in the temperate climate. */
2382 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2383 housespec->cargo_acceptance[2] = 0;
2384 }
2385 break;
2386 }
2387
2388 case 0x09: // Building flags
2389 housespec->building_flags = (BuildingFlags)buf->ReadByte();
2390 break;
2391
2392 case 0x0A: { // Availability years
2393 uint16 years = buf->ReadWord();
2394 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2395 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2396 break;
2397 }
2398
2399 case 0x0B: // Population
2400 housespec->population = buf->ReadByte();
2401 break;
2402
2403 case 0x0C: // Mail generation multiplier
2404 housespec->mail_generation = buf->ReadByte();
2405 break;
2406
2407 case 0x0D: // Passenger acceptance
2408 case 0x0E: // Mail acceptance
2409 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2410 break;
2411
2412 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2413 int8 goods = buf->ReadByte();
2414
2415 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2416 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2417 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2418 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2419
2420 /* Make sure the cargo type is valid in this climate. */
2421 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2422
2423 housespec->accepts_cargo[2] = cid;
2424 housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2425 break;
2426 }
2427
2428 case 0x10: // Local authority rating decrease on removal
2429 housespec->remove_rating_decrease = buf->ReadWord();
2430 break;
2431
2432 case 0x11: // Removal cost multiplier
2433 housespec->removal_cost = buf->ReadByte();
2434 break;
2435
2436 case 0x12: // Building name ID
2437 AddStringForMapping(buf->ReadWord(), &housespec->building_name);
2438 break;
2439
2440 case 0x13: // Building availability mask
2441 housespec->building_availability = (HouseZones)buf->ReadWord();
2442 break;
2443
2444 case 0x14: // House callback mask
2445 housespec->callback_mask |= buf->ReadByte();
2446 break;
2447
2448 case 0x15: { // House override byte
2449 byte override = buf->ReadByte();
2450
2451 /* The house being overridden must be an original house. */
2452 if (override >= NEW_HOUSE_OFFSET) {
2453 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2454 continue;
2455 }
2456
2457 _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2458 break;
2459 }
2460
2461 case 0x16: // Periodic refresh multiplier
2462 housespec->processing_time = std::min<byte>(buf->ReadByte(), 63u);
2463 break;
2464
2465 case 0x17: // Four random colours to use
2466 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2467 break;
2468
2469 case 0x18: // Relative probability of appearing
2470 housespec->probability = buf->ReadByte();
2471 break;
2472
2473 case 0x19: // Extra flags
2474 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2475 break;
2476
2477 case 0x1A: // Animation frames
2478 housespec->animation.frames = buf->ReadByte();
2479 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2480 SB(housespec->animation.frames, 7, 1, 0);
2481 break;
2482
2483 case 0x1B: // Animation speed
2484 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2485 break;
2486
2487 case 0x1C: // Class of the building type
2488 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2489 break;
2490
2491 case 0x1D: // Callback mask part 2
2492 housespec->callback_mask |= (buf->ReadByte() << 8);
2493 break;
2494
2495 case 0x1E: { // Accepted cargo types
2496 uint32 cargotypes = buf->ReadDWord();
2497
2498 /* Check if the cargo types should not be changed */
2499 if (cargotypes == 0xFFFFFFFF) break;
2500
2501 for (uint j = 0; j < 3; j++) {
2502 /* Get the cargo number from the 'list' */
2503 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2504 CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2505
2506 if (cargo == CT_INVALID) {
2507 /* Disable acceptance of invalid cargo type */
2508 housespec->cargo_acceptance[j] = 0;
2509 } else {
2510 housespec->accepts_cargo[j] = cargo;
2511 }
2512 }
2513 break;
2514 }
2515
2516 case 0x1F: // Minimum life span
2517 housespec->minimum_life = buf->ReadByte();
2518 break;
2519
2520 case 0x20: { // Cargo acceptance watch list
2521 byte count = buf->ReadByte();
2522 for (byte j = 0; j < count; j++) {
2523 CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2524 if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
2525 }
2526 break;
2527 }
2528
2529 case 0x21: // long introduction year
2530 housespec->min_year = buf->ReadWord();
2531 break;
2532
2533 case 0x22: // long maximum year
2534 housespec->max_year = buf->ReadWord();
2535 break;
2536
2537 case 0x23: { // variable length cargo types accepted
2538 uint count = buf->ReadByte();
2539 if (count > lengthof(housespec->accepts_cargo)) {
2540 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
2541 error->param_value[1] = prop;
2542 return CIR_DISABLED;
2543 }
2544 /* Always write the full accepts_cargo array, and check each index for being inside the
2545 * provided data. This ensures all values are properly initialized, and also avoids
2546 * any risks of array overrun. */
2547 for (uint i = 0; i < lengthof(housespec->accepts_cargo); i++) {
2548 if (i < count) {
2549 housespec->accepts_cargo[i] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2550 housespec->cargo_acceptance[i] = buf->ReadByte();
2551 } else {
2552 housespec->accepts_cargo[i] = CT_INVALID;
2553 housespec->cargo_acceptance[i] = 0;
2554 }
2555 }
2556 break;
2557 }
2558
2559 default:
2560 ret = CIR_UNKNOWN;
2561 break;
2562 }
2563 }
2564
2565 return ret;
2566 }
2567
2574 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2575 {
2576 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2577 const GRFFile *grffile = GetFileByGRFID(grfid);
2578 return (grffile != nullptr && grffile->language_map != nullptr && language_id < MAX_LANG) ? &grffile->language_map[language_id] : nullptr;
2579 }
2580
2590 template <typename T>
2591 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
2592 {
2593 if (gvid != 0) {
2594 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
2595 return CIR_INVALID_ID;
2596 }
2597
2598 translation_table.clear();
2599 for (int i = 0; i < numinfo; i++) {
2600 uint32 item = buf->ReadDWord();
2601 translation_table.push_back(BSWAP32(item));
2602 }
2603
2604 return CIR_SUCCESS;
2605 }
2606
2615 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2616 {
2617 /* Properties which are handled as a whole */
2618 switch (prop) {
2619 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2620 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2621
2622 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2623 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2624
2625 case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2626 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->roadtype_list, "Road type");
2627
2628 case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2629 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->tramtype_list, "Tram type");
2630
2631 default:
2632 break;
2633 }
2634
2635 /* Properties which are handled per item */
2636 ChangeInfoResult ret = CIR_SUCCESS;
2637 for (int i = 0; i < numinfo; i++) {
2638 switch (prop) {
2639 case 0x08: { // Cost base factor
2640 int factor = buf->ReadByte();
2641 uint price = gvid + i;
2642
2643 if (price < PR_END) {
2644 _cur.grffile->price_base_multipliers[price] = std::min<int>(factor - 8, MAX_PRICE_MODIFIER);
2645 } else {
2646 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2647 }
2648 break;
2649 }
2650
2651 case 0x0A: { // Currency display names
2652 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2653 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2654
2655 if ((newone != STR_UNDEFINED) && (curidx < CURRENCY_END)) {
2656 _currency_specs[curidx].name = newone;
2657 }
2658 break;
2659 }
2660
2661 case 0x0B: { // Currency multipliers
2662 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2663 uint32 rate = buf->ReadDWord();
2664
2665 if (curidx < CURRENCY_END) {
2666 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2667 * which OTTD does not. For this reason, divide grf value by 1000,
2668 * to be compatible */
2669 _currency_specs[curidx].rate = rate / 1000;
2670 } else {
2671 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2672 }
2673 break;
2674 }
2675
2676 case 0x0C: { // Currency options
2677 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2678 uint16 options = buf->ReadWord();
2679
2680 if (curidx < CURRENCY_END) {
2681 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
2682 _currency_specs[curidx].separator[1] = '\0';
2683 /* By specifying only one bit, we prevent errors,
2684 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2685 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
2686 } else {
2687 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2688 }
2689 break;
2690 }
2691
2692 case 0x0D: { // Currency prefix symbol
2693 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2694 uint32 tempfix = buf->ReadDWord();
2695
2696 if (curidx < CURRENCY_END) {
2697 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
2698 _currency_specs[curidx].prefix[4] = 0;
2699 } else {
2700 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2701 }
2702 break;
2703 }
2704
2705 case 0x0E: { // Currency suffix symbol
2706 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2707 uint32 tempfix = buf->ReadDWord();
2708
2709 if (curidx < CURRENCY_END) {
2710 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
2711 _currency_specs[curidx].suffix[4] = 0;
2712 } else {
2713 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2714 }
2715 break;
2716 }
2717
2718 case 0x0F: { // Euro introduction dates
2719 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2720 Year year_euro = buf->ReadWord();
2721
2722 if (curidx < CURRENCY_END) {
2723 _currency_specs[curidx].to_euro = year_euro;
2724 } else {
2725 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2726 }
2727 break;
2728 }
2729
2730 case 0x10: // Snow line height table
2731 if (numinfo > 1 || IsSnowLineSet()) {
2732 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2733 } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
2734 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2735 } else {
2736 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2737
2738 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2739 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2740 table[i][j] = buf->ReadByte();
2741 if (_cur.grffile->grf_version >= 8) {
2742 if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 256;
2743 } else {
2744 if (table[i][j] >= 128) {
2745 /* no snow */
2746 table[i][j] = 0xFF;
2747 } else {
2748 table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 128;
2749 }
2750 }
2751 }
2752 }
2753 SetSnowLine(table);
2754 }
2755 break;
2756
2757 case 0x11: // GRF match for engine allocation
2758 /* This is loaded during the reservation stage, so just skip it here. */
2759 /* Each entry is 8 bytes. */
2760 buf->Skip(8);
2761 break;
2762
2763 case 0x13: // Gender translation table
2764 case 0x14: // Case translation table
2765 case 0x15: { // Plural form translation
2766 uint curidx = gvid + i; // The current index, i.e. language.
2767 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : nullptr;
2768 if (lang == nullptr) {
2769 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2770 /* Skip over the data. */
2771 if (prop == 0x15) {
2772 buf->ReadByte();
2773 } else {
2774 while (buf->ReadByte() != 0) {
2775 buf->ReadString();
2776 }
2777 }
2778 break;
2779 }
2780
2781 if (_cur.grffile->language_map == nullptr) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2782
2783 if (prop == 0x15) {
2784 uint plural_form = buf->ReadByte();
2785 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2786 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2787 } else {
2788 _cur.grffile->language_map[curidx].plural_form = plural_form;
2789 }
2790 break;
2791 }
2792
2793 byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2794 while (newgrf_id != 0) {
2795 const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2796
2797 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2798 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2799 * is just a subset of UTF8, or they need the bigger UTF8 characters
2800 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2801 WChar c;
2802 size_t len = Utf8Decode(&c, name);
2803 if (c == NFO_UTF8_IDENTIFIER) name += len;
2804
2805 LanguageMap::Mapping map;
2806 map.newgrf_id = newgrf_id;
2807 if (prop == 0x13) {
2808 map.openttd_id = lang->GetGenderIndex(name);
2809 if (map.openttd_id >= MAX_NUM_GENDERS) {
2810 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2811 } else {
2812 _cur.grffile->language_map[curidx].gender_map.push_back(map);
2813 }
2814 } else {
2815 map.openttd_id = lang->GetCaseIndex(name);
2816 if (map.openttd_id >= MAX_NUM_CASES) {
2817 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2818 } else {
2819 _cur.grffile->language_map[curidx].case_map.push_back(map);
2820 }
2821 }
2822 newgrf_id = buf->ReadByte();
2823 }
2824 break;
2825 }
2826
2827 default:
2828 ret = CIR_UNKNOWN;
2829 break;
2830 }
2831 }
2832
2833 return ret;
2834 }
2835
2836 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2837 {
2838 /* Properties which are handled as a whole */
2839 switch (prop) {
2840 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2841 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2842
2843 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2844 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2845
2846 case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined roadtypes)
2847 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->roadtype_list, "Road type");
2848
2849 case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined tramtypes)
2850 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->tramtype_list, "Tram type");
2851
2852 default:
2853 break;
2854 }
2855
2856 /* Properties which are handled per item */
2857 ChangeInfoResult ret = CIR_SUCCESS;
2858 for (int i = 0; i < numinfo; i++) {
2859 switch (prop) {
2860 case 0x08: // Cost base factor
2861 case 0x15: // Plural form translation
2862 buf->ReadByte();
2863 break;
2864
2865 case 0x0A: // Currency display names
2866 case 0x0C: // Currency options
2867 case 0x0F: // Euro introduction dates
2868 buf->ReadWord();
2869 break;
2870
2871 case 0x0B: // Currency multipliers
2872 case 0x0D: // Currency prefix symbol
2873 case 0x0E: // Currency suffix symbol
2874 buf->ReadDWord();
2875 break;
2876
2877 case 0x10: // Snow line height table
2878 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
2879 break;
2880
2881 case 0x11: { // GRF match for engine allocation
2882 uint32 s = buf->ReadDWord();
2883 uint32 t = buf->ReadDWord();
2884 SetNewGRFOverride(s, t);
2885 break;
2886 }
2887
2888 case 0x13: // Gender translation table
2889 case 0x14: // Case translation table
2890 while (buf->ReadByte() != 0) {
2891 buf->ReadString();
2892 }
2893 break;
2894
2895 default:
2896 ret = CIR_UNKNOWN;
2897 break;
2898 }
2899 }
2900
2901 return ret;
2902 }
2903
2904
2913 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
2914 {
2915 ChangeInfoResult ret = CIR_SUCCESS;
2916
2917 if (cid + numinfo > NUM_CARGO) {
2918 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
2919 return CIR_INVALID_ID;
2920 }
2921
2922 for (int i = 0; i < numinfo; i++) {
2923 CargoSpec *cs = CargoSpec::Get(cid + i);
2924
2925 switch (prop) {
2926 case 0x08: // Bit number of cargo
2927 cs->bitnum = buf->ReadByte();
2928 if (cs->IsValid()) {
2929 cs->grffile = _cur.grffile;
2930 SetBit(_cargo_mask, cid + i);
2931 } else {
2932 ClrBit(_cargo_mask, cid + i);
2933 }
2934 break;
2935
2936 case 0x09: // String ID for cargo type name
2937 AddStringForMapping(buf->ReadWord(), &cs->name);
2938 break;
2939
2940 case 0x0A: // String for 1 unit of cargo
2941 AddStringForMapping(buf->ReadWord(), &cs->name_single);
2942 break;
2943
2944 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2945 case 0x1B: // String for cargo units
2946 /* String for units of cargo. This is different in OpenTTD
2947 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2948 * Property 1B is used to set OpenTTD's behaviour. */
2949 AddStringForMapping(buf->ReadWord(), &cs->units_volume);
2950 break;
2951
2952 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2953 case 0x1C: // String for any amount of cargo
2954 /* Strings for an amount of cargo. This is different in OpenTTD
2955 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2956 * Property 1C is used to set OpenTTD's behaviour. */
2957 AddStringForMapping(buf->ReadWord(), &cs->quantifier);
2958 break;
2959
2960 case 0x0D: // String for two letter cargo abbreviation
2961 AddStringForMapping(buf->ReadWord(), &cs->abbrev);
2962 break;
2963
2964 case 0x0E: // Sprite ID for cargo icon
2965 cs->sprite = buf->ReadWord();
2966 break;
2967
2968 case 0x0F: // Weight of one unit of cargo
2969 cs->weight = buf->ReadByte();
2970 break;
2971
2972 case 0x10: // Used for payment calculation
2973 cs->transit_days[0] = buf->ReadByte();
2974 break;
2975
2976 case 0x11: // Used for payment calculation
2977 cs->transit_days[1] = buf->ReadByte();
2978 break;
2979
2980 case 0x12: // Base cargo price
2981 cs->initial_payment = buf->ReadDWord();
2982 break;
2983
2984 case 0x13: // Colour for station rating bars
2985 cs->rating_colour = buf->ReadByte();
2986 break;
2987
2988 case 0x14: // Colour for cargo graph
2989 cs->legend_colour = buf->ReadByte();
2990 break;
2991
2992 case 0x15: // Freight status
2993 cs->is_freight = (buf->ReadByte() != 0);
2994 break;
2995
2996 case 0x16: // Cargo classes
2997 cs->classes = buf->ReadWord();
2998 break;
2999
3000 case 0x17: // Cargo label
3001 cs->label = buf->ReadDWord();
3002 cs->label = BSWAP32(cs->label);
3003 break;
3004
3005 case 0x18: { // Town growth substitute type
3006 uint8 substitute_type = buf->ReadByte();
3007
3008 switch (substitute_type) {
3009 case 0x00: cs->town_effect = TE_PASSENGERS; break;
3010 case 0x02: cs->town_effect = TE_MAIL; break;
3011 case 0x05: cs->town_effect = TE_GOODS; break;
3012 case 0x09: cs->town_effect = TE_WATER; break;
3013 case 0x0B: cs->town_effect = TE_FOOD; break;
3014 default:
3015 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
3016 FALLTHROUGH;
3017 case 0xFF: cs->town_effect = TE_NONE; break;
3018 }
3019 break;
3020 }
3021
3022 case 0x19: // Town growth coefficient
3023 cs->multipliertowngrowth = buf->ReadWord();
3024 break;
3025
3026 case 0x1A: // Bitmask of callbacks to use
3027 cs->callback_mask = buf->ReadByte();
3028 break;
3029
3030 case 0x1D: // Vehicle capacity muliplier
3031 cs->multiplier = std::max<uint16>(1u, buf->ReadWord());
3032 break;
3033
3034 default:
3035 ret = CIR_UNKNOWN;
3036 break;
3037 }
3038 }
3039
3040 return ret;
3041 }
3042
3043
3052 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
3053 {
3054 ChangeInfoResult ret = CIR_SUCCESS;
3055
3056 if (_cur.grffile->sound_offset == 0) {
3057 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3058 return CIR_INVALID_ID;
3059 }
3060
3061 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
3062 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
3063 return CIR_INVALID_ID;
3064 }
3065
3066 for (int i = 0; i < numinfo; i++) {
3067 SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
3068
3069 switch (prop) {
3070 case 0x08: // Relative volume
3071 sound->volume = buf->ReadByte();
3072 break;
3073
3074 case 0x09: // Priority
3075 sound->priority = buf->ReadByte();
3076 break;
3077
3078 case 0x0A: { // Override old sound
3079 SoundID orig_sound = buf->ReadByte();
3080
3081 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
3082 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
3083 } else {
3084 SoundEntry *old_sound = GetSound(orig_sound);
3085
3086 /* Literally copy the data of the new sound over the original */
3087 *old_sound = *sound;
3088 }
3089 break;
3090 }
3091
3092 default:
3093 ret = CIR_UNKNOWN;
3094 break;
3095 }
3096 }
3097
3098 return ret;
3099 }
3100
3107 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
3108 {
3109 ChangeInfoResult ret = CIR_SUCCESS;
3110
3111 switch (prop) {
3112 case 0x09:
3113 case 0x0D:
3114 case 0x0E:
3115 case 0x10:
3116 case 0x11:
3117 case 0x12:
3118 buf->ReadByte();
3119 break;
3120
3121 case 0x0A:
3122 case 0x0B:
3123 case 0x0C:
3124 case 0x0F:
3125 buf->ReadWord();
3126 break;
3127
3128 case 0x13:
3129 buf->Skip(buf->ReadByte() * 2);
3130 break;
3131
3132 default:
3133 ret = CIR_UNKNOWN;
3134 break;
3135 }
3136 return ret;
3137 }
3138
3147 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
3148 {
3149 ChangeInfoResult ret = CIR_SUCCESS;
3150
3151 if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
3152 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
3153 return CIR_INVALID_ID;
3154 }
3155
3156 /* Allocate industry tile specs if they haven't been allocated already. */
3157 if (_cur.grffile->indtspec == nullptr) {
3158 _cur.grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES_PER_GRF);
3159 }
3160
3161 for (int i = 0; i < numinfo; i++) {
3162 IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
3163
3164 if (prop != 0x08 && tsp == nullptr) {
3165 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
3166 if (cir > ret) ret = cir;
3167 continue;
3168 }
3169
3170 switch (prop) {
3171 case 0x08: { // Substitute industry tile type
3172 IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i];
3173 byte subs_id = buf->ReadByte();
3174
3175 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
3176 /* The substitute id must be one of the original industry tile. */
3177 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3178 continue;
3179 }
3180
3181 /* Allocate space for this industry. */
3182 if (*tilespec == nullptr) {
3183 *tilespec = CallocT<IndustryTileSpec>(1);
3184 tsp = *tilespec;
3185
3186 memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
3187 tsp->enabled = true;
3188
3189 /* A copied tile should not have the animation infos copied too.
3190 * The anim_state should be left untouched, though
3191 * It is up to the author to animate them himself */
3192 tsp->anim_production = INDUSTRYTILE_NOANIM;
3193 tsp->anim_next = INDUSTRYTILE_NOANIM;
3194
3195 tsp->grf_prop.local_id = indtid + i;
3196 tsp->grf_prop.subst_id = subs_id;
3197 tsp->grf_prop.grffile = _cur.grffile;
3198 _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3199 }
3200 break;
3201 }
3202
3203 case 0x09: { // Industry tile override
3204 byte ovrid = buf->ReadByte();
3205
3206 /* The industry being overridden must be an original industry. */
3207 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
3208 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3209 continue;
3210 }
3211
3212 _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
3213 break;
3214 }
3215
3216 case 0x0A: // Tile acceptance
3217 case 0x0B:
3218 case 0x0C: {
3219 uint16 acctp = buf->ReadWord();
3220 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
3221 tsp->acceptance[prop - 0x0A] = Clamp(GB(acctp, 8, 8), 0, 16);
3222 break;
3223 }
3224
3225 case 0x0D: // Land shape flags
3226 tsp->slopes_refused = (Slope)buf->ReadByte();
3227 break;
3228
3229 case 0x0E: // Callback mask
3230 tsp->callback_mask = buf->ReadByte();
3231 break;
3232
3233 case 0x0F: // Animation information
3234 tsp->animation.frames = buf->ReadByte();
3235 tsp->animation.status = buf->ReadByte();
3236 break;
3237
3238 case 0x10: // Animation speed
3239 tsp->animation.speed = buf->ReadByte();
3240 break;
3241
3242 case 0x11: // Triggers for callback 25
3243 tsp->animation.triggers = buf->ReadByte();
3244 break;
3245
3246 case 0x12: // Special flags
3247 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
3248 break;
3249
3250 case 0x13: { // variable length cargo acceptance
3251 byte num_cargoes = buf->ReadByte();
3252 if (num_cargoes > lengthof(tsp->acceptance)) {
3253 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3254 error->param_value[1] = prop;
3255 return CIR_DISABLED;
3256 }
3257 for (uint i = 0; i < lengthof(tsp->acceptance); i++) {
3258 if (i < num_cargoes) {
3259 tsp->accepts_cargo[i] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3260 /* Tile acceptance can be negative to counteract the INDTILE_SPECIAL_ACCEPTS_ALL_CARGO flag */
3261 tsp->acceptance[i] = (int8)buf->ReadByte();
3262 } else {
3263 tsp->accepts_cargo[i] = CT_INVALID;
3264 tsp->acceptance[i] = 0;
3265 }
3266 }
3267 break;
3268 }
3269
3270 default:
3271 ret = CIR_UNKNOWN;
3272 break;
3273 }
3274 }
3275
3276 return ret;
3277 }
3278
3285 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
3286 {
3287 ChangeInfoResult ret = CIR_SUCCESS;
3288
3289 switch (prop) {
3290 case 0x09:
3291 case 0x0B:
3292 case 0x0F:
3293 case 0x12:
3294 case 0x13:
3295 case 0x14:
3296 case 0x17:
3297 case 0x18:
3298 case 0x19:
3299 case 0x21:
3300 case 0x22:
3301 buf->ReadByte();
3302 break;
3303
3304 case 0x0C:
3305 case 0x0D:
3306 case 0x0E:
3307 case 0x10:
3308 case 0x1B:
3309 case 0x1F:
3310 case 0x24:
3311 buf->ReadWord();
3312 break;
3313
3314 case 0x11:
3315 case 0x1A:
3316 case 0x1C:
3317 case 0x1D:
3318 case 0x1E:
3319 case 0x20:
3320 case 0x23:
3321 buf->ReadDWord();
3322 break;
3323
3324 case 0x0A: {
3325 byte num_table = buf->ReadByte();
3326 for (byte j = 0; j < num_table; j++) {
3327 for (uint k = 0;; k++) {
3328 byte x = buf->ReadByte();
3329 if (x == 0xFE && k == 0) {
3330 buf->ReadByte();
3331 buf->ReadByte();
3332 break;
3333 }
3334
3335 byte y = buf->ReadByte();
3336 if (x == 0 && y == 0x80) break;
3337
3338 byte gfx = buf->ReadByte();
3339 if (gfx == 0xFE) buf->ReadWord();
3340 }
3341 }
3342 break;
3343 }
3344
3345 case 0x16:
3346 for (byte j = 0; j < 3; j++) buf->ReadByte();
3347 break;
3348
3349 case 0x15:
3350 case 0x25:
3351 case 0x26:
3352 case 0x27:
3353 buf->Skip(buf->ReadByte());
3354 break;
3355
3356 case 0x28: {
3357 int num_inputs = buf->ReadByte();
3358 int num_outputs = buf->ReadByte();
3359 buf->Skip(num_inputs * num_outputs * 2);
3360 break;
3361 }
3362
3363 default:
3364 ret = CIR_UNKNOWN;
3365 break;
3366 }
3367 return ret;
3368 }
3369
3375 static bool ValidateIndustryLayout(const IndustryTileLayout &layout)
3376 {
3377 const size_t size = layout.size();
3378 for (size_t i = 0; i < size - 1; i++) {
3379 for (size_t j = i + 1; j < size; j++) {
3380 if (layout[i].ti.x == layout[j].ti.x &&
3381 layout[i].ti.y == layout[j].ti.y) {
3382 return false;
3383 }
3384 }
3385 }
3386 return true;
3387 }
3388
3397 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3398 {
3399 ChangeInfoResult ret = CIR_SUCCESS;
3400
3401 if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
3402 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
3403 return CIR_INVALID_ID;
3404 }
3405
3406 /* Allocate industry specs if they haven't been allocated already. */
3407 if (_cur.grffile->industryspec == nullptr) {
3408 _cur.grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES_PER_GRF);
3409 }
3410
3411 for (int i = 0; i < numinfo; i++) {
3412 IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3413
3414 if (prop != 0x08 && indsp == nullptr) {
3415 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3416 if (cir > ret) ret = cir;
3417 continue;
3418 }
3419
3420 switch (prop) {
3421 case 0x08: { // Substitute industry type
3422 IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i];
3423 byte subs_id = buf->ReadByte();
3424
3425 if (subs_id == 0xFF) {
3426 /* Instead of defining a new industry, a substitute industry id
3427 * of 0xFF disables the old industry with the current id. */
3428 _industry_specs[indid + i].enabled = false;
3429 continue;
3430 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3431 /* The substitute id must be one of the original industry. */
3432 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3433 continue;
3434 }
3435
3436 /* Allocate space for this industry.
3437 * Only need to do it once. If ever it is called again, it should not
3438 * do anything */
3439 if (*indspec == nullptr) {
3440 *indspec = new IndustrySpec;
3441 indsp = *indspec;
3442
3443 *indsp = _origin_industry_specs[subs_id];
3444 indsp->enabled = true;
3445 indsp->grf_prop.local_id = indid + i;
3446 indsp->grf_prop.subst_id = subs_id;
3447 indsp->grf_prop.grffile = _cur.grffile;
3448 /* If the grf industry needs to check its surrounding upon creation, it should
3449 * rely on callbacks, not on the original placement functions */
3450 indsp->check_proc = CHECK_NOTHING;
3451 }
3452 break;
3453 }
3454
3455 case 0x09: { // Industry type override
3456 byte ovrid = buf->ReadByte();
3457
3458 /* The industry being overridden must be an original industry. */
3459 if (ovrid >= NEW_INDUSTRYOFFSET) {
3460 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3461 continue;
3462 }
3463 indsp->grf_prop.override = ovrid;
3464 _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3465 break;
3466 }
3467
3468 case 0x0A: { // Set industry layout(s)
3469 byte new_num_layouts = buf->ReadByte();
3470 uint32 definition_size = buf->ReadDWord();
3471 uint32 bytes_read = 0;
3472 std::vector<IndustryTileLayout> new_layouts;
3473 IndustryTileLayout layout;
3474
3475 for (byte j = 0; j < new_num_layouts; j++) {
3476 layout.clear();
3477
3478 for (uint k = 0;; k++) {
3479 if (bytes_read >= definition_size) {
3480 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3481 /* Avoid warning twice */
3482 definition_size = UINT32_MAX;
3483 }
3484
3485 layout.push_back(IndustryTileLayoutTile{});
3486 IndustryTileLayoutTile &it = layout.back();
3487
3488 it.ti.x = buf->ReadByte(); // Offsets from northermost tile
3489 ++bytes_read;
3490
3491 if (it.ti.x == 0xFE && k == 0) {
3492 /* This means we have to borrow the layout from an old industry */
3493 IndustryType type = buf->ReadByte();
3494 byte laynbr = buf->ReadByte();
3495 bytes_read += 2;
3496
3497 if (type >= lengthof(_origin_industry_specs)) {
3498 grfmsg(1, "IndustriesChangeInfo: Invalid original industry number for layout import, industry %u", indid);
3499 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
3500 return CIR_DISABLED;
3501 }
3502 if (laynbr >= _origin_industry_specs[type].layouts.size()) {
3503 grfmsg(1, "IndustriesChangeInfo: Invalid original industry layout index for layout import, industry %u", indid);
3504 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
3505 return CIR_DISABLED;
3506 }
3507 layout = _origin_industry_specs[type].layouts[laynbr];
3508 break;
3509 }
3510
3511 it.ti.y = buf->ReadByte(); // Or table definition finalisation
3512 ++bytes_read;
3513
3514 if (it.ti.x == 0 && it.ti.y == 0x80) {
3515 /* Terminator, remove and finish up */
3516 layout.pop_back();
3517 break;
3518 }
3519
3520 it.gfx = buf->ReadByte();
3521 ++bytes_read;
3522
3523 if (it.gfx == 0xFE) {
3524 /* Use a new tile from this GRF */
3525 int local_tile_id = buf->ReadWord();
3526 bytes_read += 2;
3527
3528 /* Read the ID from the _industile_mngr. */
3529 int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3530
3531 if (tempid == INVALID_INDUSTRYTILE) {
3532 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3533 } else {
3534 /* Declared as been valid, can be used */
3535 it.gfx = tempid;
3536 }
3537 } else if (it.gfx == 0xFF) {
3538 it.ti.x = (int8)GB(it.ti.x, 0, 8);
3539 it.ti.y = (int8)GB(it.ti.y, 0, 8);
3540
3541 /* When there were only 256x256 maps, TileIndex was a uint16 and
3542 * it.ti was just a TileIndexDiff that was added to it.
3543 * As such negative "x" values were shifted into the "y" position.
3544 * x = -1, y = 1 -> x = 255, y = 0
3545 * Since GRF version 8 the position is interpreted as pair of independent int8.
3546 * For GRF version < 8 we need to emulate the old shifting behaviour.
3547 */
3548 if (_cur.grffile->grf_version < 8 && it.ti.x < 0) it.ti.y += 1;
3549 }
3550 }
3551
3552 if (!ValidateIndustryLayout(layout)) {
3553 /* The industry layout was not valid, so skip this one. */
3554 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3555 new_num_layouts--;
3556 j--;
3557 } else {
3558 new_layouts.push_back(layout);
3559 }
3560 }
3561
3562 /* Install final layout construction in the industry spec */
3563 indsp->layouts = new_layouts;
3564 break;
3565 }
3566
3567 case 0x0B: // Industry production flags
3568 indsp->life_type = (IndustryLifeType)buf->ReadByte();
3569 break;
3570
3571 case 0x0C: // Industry closure message
3572 AddStringForMapping(buf->ReadWord(), &indsp->closure_text);
3573 break;
3574
3575 case 0x0D: // Production increase message
3576 AddStringForMapping(buf->ReadWord(), &indsp->production_up_text);
3577 break;
3578
3579 case 0x0E: // Production decrease message
3580 AddStringForMapping(buf->ReadWord(), &indsp->production_down_text);
3581 break;
3582
3583 case 0x0F: // Fund cost multiplier
3584 indsp->cost_multiplier = buf->ReadByte();
3585 break;
3586
3587 case 0x10: // Production cargo types
3588 for (byte j = 0; j < 2; j++) {
3589 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3590 }
3591 break;
3592
3593 case 0x11: // Acceptance cargo types
3594 for (byte j = 0; j < 3; j++) {
3595 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3596 }
3597 buf->ReadByte(); // Unnused, eat it up
3598 break;
3599
3600 case 0x12: // Production multipliers
3601 case 0x13:
3602 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3603 break;
3604
3605 case 0x14: // Minimal amount of cargo distributed
3606 indsp->minimal_cargo = buf->ReadByte();
3607 break;
3608
3609 case 0x15: { // Random sound effects
3610 indsp->number_of_sounds = buf->ReadByte();
3611 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
3612
3613 try {
3614 for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
3615 sounds[j] = buf->ReadByte();
3616 }
3617 } catch (...) {
3618 free(sounds);
3619 throw;
3620 }
3621
3622 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3623 free(indsp->random_sounds);
3624 }
3625 indsp->random_sounds = sounds;
3626 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
3627 break;
3628 }
3629
3630 case 0x16: // Conflicting industry types
3631 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3632 break;
3633
3634 case 0x17: // Probability in random game
3635 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3636 break;
3637
3638 case 0x18: // Probability during gameplay
3639 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3640 break;
3641
3642 case 0x19: // Map colour
3643 indsp->map_colour = buf->ReadByte();
3644 break;
3645
3646 case 0x1A: // Special industry flags to define special behavior
3647 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3648 break;
3649
3650 case 0x1B: // New industry text ID
3651 AddStringForMapping(buf->ReadWord(), &indsp->new_industry_text);
3652 break;
3653
3654 case 0x1C: // Input cargo multipliers for the three input cargo types
3655 case 0x1D:
3656 case 0x1E: {
3657 uint32 multiples = buf->ReadDWord();
3658 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3659 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3660 break;
3661 }
3662
3663 case 0x1F: // Industry name
3664 AddStringForMapping(buf->ReadWord(), &indsp->name);
3665 break;
3666
3667 case 0x20: // Prospecting success chance
3668 indsp->prospecting_chance = buf->ReadDWord();
3669 break;
3670
3671 case 0x21: // Callback mask
3672 case 0x22: { // Callback additional mask
3673 byte aflag = buf->ReadByte();
3674 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3675 break;
3676 }
3677
3678 case 0x23: // removal cost multiplier
3679 indsp->removal_cost_multiplier = buf->ReadDWord();
3680 break;
3681
3682 case 0x24: { // name for nearby station
3683 uint16 str = buf->ReadWord();
3684 if (str == 0) {
3685 indsp->station_name = STR_NULL;
3686 } else {
3687 AddStringForMapping(str, &indsp->station_name);
3688 }
3689 break;
3690 }
3691
3692 case 0x25: { // variable length produced cargoes
3693 byte num_cargoes = buf->ReadByte();
3694 if (num_cargoes > lengthof(indsp->produced_cargo)) {
3695 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3696 error->param_value[1] = prop;
3697 return CIR_DISABLED;
3698 }
3699 for (uint i = 0; i < lengthof(indsp->produced_cargo); i++) {
3700 if (i < num_cargoes) {
3701 CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3702 indsp->produced_cargo[i] = cargo;
3703 } else {
3704 indsp->produced_cargo[i] = CT_INVALID;
3705 }
3706 }
3707 break;
3708 }
3709
3710 case 0x26: { // variable length accepted cargoes
3711 byte num_cargoes = buf->ReadByte();
3712 if (num_cargoes > lengthof(indsp->accepts_cargo)) {
3713 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3714 error->param_value[1] = prop;
3715 return CIR_DISABLED;
3716 }
3717 for (uint i = 0; i < lengthof(indsp->accepts_cargo); i++) {
3718 if (i < num_cargoes) {
3719 CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3720 indsp->accepts_cargo[i] = cargo;
3721 } else {
3722 indsp->accepts_cargo[i] = CT_INVALID;
3723 }
3724 }
3725 break;
3726 }
3727
3728 case 0x27: { // variable length production rates
3729 byte num_cargoes = buf->ReadByte();
3730 if (num_cargoes > lengthof(indsp->production_rate)) {
3731 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3732 error->param_value[1] = prop;
3733 return CIR_DISABLED;
3734 }
3735 for (uint i = 0; i < lengthof(indsp->production_rate); i++) {
3736 if (i < num_cargoes) {
3737 indsp->production_rate[i] = buf->ReadByte();
3738 } else {
3739 indsp->production_rate[i] = 0;
3740 }
3741 }
3742 break;
3743 }
3744
3745 case 0x28: { // variable size input/output production multiplier table
3746 byte num_inputs = buf->ReadByte();
3747 byte num_outputs = buf->ReadByte();
3748 if (num_inputs > lengthof(indsp->accepts_cargo) || num_outputs > lengthof(indsp->produced_cargo)) {
3749 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG);
3750 error->param_value[1] = prop;
3751 return CIR_DISABLED;
3752 }
3753 for (uint i = 0; i < lengthof(indsp->accepts_cargo); i++) {
3754 for (uint j = 0; j < lengthof(indsp->produced_cargo); j++) {
3755 uint16 mult = 0;
3756 if (i < num_inputs && j < num_outputs) mult = buf->ReadWord();
3757 indsp->input_cargo_multiplier[i][j] = mult;
3758 }
3759 }
3760 break;
3761 }
3762
3763 default:
3764 ret = CIR_UNKNOWN;
3765 break;
3766 }
3767 }
3768
3769 return ret;
3770 }
3771
3777 static void DuplicateTileTable(AirportSpec *as)
3778 {
3779 AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
3780 for (int i = 0; i < as->num_table; i++) {
3781 uint num_tiles = 1;
3782 const AirportTileTable *it = as->table[0];
3783 do {
3784 num_tiles++;
3785 } while ((++it)->ti.x != -0x80);
3786 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3787 MemCpyT(table_list[i], as->table[i], num_tiles);
3788 }
3789 as->table = table_list;
3790 HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
3791 MemCpyT(depot_table, as->depot_table, as->nof_depots);
3792 as->depot_table = depot_table;
3793 Direction *rotation = MallocT<Direction>(as->num_table);
3794 MemCpyT(rotation, as->rotation, as->num_table);
3795 as->rotation = rotation;
3796 }
3797
3806 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3807 {
3808 ChangeInfoResult ret = CIR_SUCCESS;
3809
3810 if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
3811 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
3812 return CIR_INVALID_ID;
3813 }
3814
3815 /* Allocate industry specs if they haven't been allocated already. */
3816 if (_cur.grffile->airportspec == nullptr) {
3817 _cur.grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS_PER_GRF);
3818 }
3819
3820 for (int i = 0; i < numinfo; i++) {
3821 AirportSpec *as = _cur.grffile->airportspec[airport + i];
3822
3823 if (as == nullptr && prop != 0x08 && prop != 0x09) {
3824 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3825 return CIR_INVALID_ID;
3826 }
3827
3828 switch (prop) {
3829 case 0x08: { // Modify original airport
3830 byte subs_id = buf->ReadByte();
3831
3832 if (subs_id == 0xFF) {
3833 /* Instead of defining a new airport, an airport id
3834 * of 0xFF disables the old airport with the current id. */
3835 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3836 continue;
3837 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3838 /* The substitute id must be one of the original airports. */
3839 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3840 continue;
3841 }
3842
3843 AirportSpec **spec = &_cur.grffile->airportspec[airport + i];
3844 /* Allocate space for this airport.
3845 * Only need to do it once. If ever it is called again, it should not
3846 * do anything */
3847 if (*spec == nullptr) {
3848 *spec = MallocT<AirportSpec>(1);
3849 as = *spec;
3850
3851 memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
3852 as->enabled = true;
3853 as->grf_prop.local_id = airport + i;
3854 as->grf_prop.subst_id = subs_id;
3855 as->grf_prop.grffile = _cur.grffile;
3856 /* override the default airport */
3857 _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3858 /* Create a copy of the original tiletable so it can be freed later. */
3859 DuplicateTileTable(as);
3860 }
3861 break;
3862 }
3863
3864 case 0x0A: { // Set airport layout
3865 free(as->rotation);
3866 as->num_table = buf->ReadByte(); // Number of layaouts
3867 as->rotation = MallocT<Direction>(as->num_table);
3868 uint32 defsize = buf->ReadDWord(); // Total size of the definition
3869 AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3870 AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
3871 int size;
3872 const AirportTileTable *copy_from;
3873 try {
3874 for (byte j = 0; j < as->num_table; j++) {
3875 const_cast<Direction&>(as->rotation[j]) = (Direction)buf->ReadByte();
3876 for (int k = 0;; k++) {
3877 att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3878 att[k].ti.y = buf->ReadByte();
3879
3880 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3881 /* Not the same terminator. The one we are using is rather
3882 * x = -80, y = 0 . So, adjust it. */
3883 att[k].ti.x = -0x80;
3884 att[k].ti.y = 0;
3885 att[k].gfx = 0;
3886
3887 size = k + 1;
3888 copy_from = att;
3889 break;
3890 }
3891
3892 att[k].gfx = buf->ReadByte();
3893
3894 if (att[k].gfx == 0xFE) {
3895 /* Use a new tile from this GRF */
3896 int local_tile_id = buf->ReadWord();
3897
3898 /* Read the ID from the _airporttile_mngr. */
3899 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3900
3901 if (tempid == INVALID_AIRPORTTILE) {
3902 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3903 } else {
3904 /* Declared as been valid, can be used */
3905 att[k].gfx = tempid;
3906 }
3907 } else if (att[k].gfx == 0xFF) {
3908 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3909 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3910 }
3911
3912 if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
3913 as->size_x = std::max<byte>(as->size_x, att[k].ti.y + 1);
3914 as->size_y = std::max<byte>(as->size_y, att[k].ti.x + 1);
3915 } else {
3916 as->size_x = std::max<byte>(as->size_x, att[k].ti.x + 1);
3917 as->size_y = std::max<byte>(as->size_y, att[k].ti.y + 1);
3918 }
3919 }
3920 tile_table[j] = CallocT<AirportTileTable>(size);
3921 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3922 }
3923 /* Install final layout construction in the airport spec */
3924 as->table = tile_table;
3925 free(att);
3926 } catch (...) {
3927 for (int i = 0; i < as->num_table; i++) {
3928 free(tile_table[i]);
3929 }
3930 free(tile_table);
3931 free(att);
3932 throw;
3933 }
3934 break;
3935 }
3936
3937 case 0x0C:
3938 as->min_year = buf->ReadWord();
3939 as->max_year = buf->ReadWord();
3940 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3941 break;
3942
3943 case 0x0D:
3944 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3945 break;
3946
3947 case 0x0E:
3948 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3949 break;
3950
3951 case 0x0F:
3952 as->noise_level = buf->ReadByte();
3953 break;
3954
3955 case 0x10:
3956 AddStringForMapping(buf->ReadWord(), &as->name);
3957 break;
3958
3959 case 0x11: // Maintenance cost factor
3960 as->maintenance_cost = buf->ReadWord();
3961 break;
3962
3963 default:
3964 ret = CIR_UNKNOWN;
3965 break;
3966 }
3967 }
3968
3969 return ret;
3970 }
3971
3978 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
3979 {
3980 ChangeInfoResult ret = CIR_SUCCESS;
3981
3982 switch (prop) {
3983 case 0x0B:
3984 case 0x0C:
3985 case 0x0D:
3986 case 0x12:
3987 case 0x14:
3988 case 0x16:
3989 case 0x17:
3990 buf->ReadByte();
3991 break;
3992
3993 case 0x09:
3994 case 0x0A:
3995 case 0x10:
3996 case 0x11:
3997 case 0x13:
3998 case 0x15:
3999 buf->ReadWord();
4000 break;
4001
4002 case 0x08:
4003 case 0x0E:
4004 case 0x0F:
4005 buf->ReadDWord();
4006 break;
4007
4008 default:
4009 ret = CIR_UNKNOWN;
4010 break;
4011 }
4012
4013 return ret;
4014 }
4015
4024 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4025 {
4026 ChangeInfoResult ret = CIR_SUCCESS;
4027
4028 if (id + numinfo > NUM_OBJECTS_PER_GRF) {
4029 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
4030 return CIR_INVALID_ID;
4031 }
4032
4033 /* Allocate object specs if they haven't been allocated already. */
4034 if (_cur.grffile->objectspec == nullptr) {
4035 _cur.grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS_PER_GRF);
4036 }
4037
4038 for (int i = 0; i < numinfo; i++) {
4039 ObjectSpec *spec = _cur.grffile->objectspec[id + i];
4040
4041 if (prop != 0x08 && spec == nullptr) {
4042 /* If the object property 08 is not yet set, ignore this property */
4043 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
4044 if (cir > ret) ret = cir;
4045 continue;
4046 }
4047
4048 switch (prop) {
4049 case 0x08: { // Class ID
4050 ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
4051
4052 /* Allocate space for this object. */
4053 if (*ospec == nullptr) {
4054 *ospec = CallocT<ObjectSpec>(1);
4055 (*ospec)->views = 1; // Default for NewGRFs that don't set it.
4056 (*ospec)->size = 0x11; // Default for NewGRFs that manage to not set it (1x1)
4057 }
4058
4059 /* Swap classid because we read it in BE. */
4060 uint32 classid = buf->ReadDWord();
4061 (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
4062 (*ospec)->enabled = true;
4063 break;
4064 }
4065
4066 case 0x09: { // Class name
4067 ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
4068 AddStringForMapping(buf->ReadWord(), &objclass->name);
4069 break;
4070 }
4071
4072 case 0x0A: // Object name
4073 AddStringForMapping(buf->ReadWord(), &spec->name);
4074 break;
4075
4076 case 0x0B: // Climate mask
4077 spec->climate = buf->ReadByte();
4078 break;
4079
4080 case 0x0C: // Size
4081 spec->size = buf->ReadByte();
4082 if ((spec->size & 0xF0) == 0 || (spec->size & 0x0F) == 0) {
4083 grfmsg(1, "ObjectChangeInfo: Invalid object size requested (%u) for object id %u. Ignoring.", spec->size, id + i);
4084 spec->size = 0x11; // 1x1
4085 }
4086 break;
4087
4088 case 0x0D: // Build cost multipler
4089 spec->build_cost_multiplier = buf->ReadByte();
4090 spec->clear_cost_multiplier = spec->build_cost_multiplier;
4091 break;
4092
4093 case 0x0E: // Introduction date
4094 spec->introduction_date = buf->ReadDWord();
4095 break;
4096
4097 case 0x0F: // End of life
4098 spec->end_of_life_date = buf->ReadDWord();
4099 break;
4100
4101 case 0x10: // Flags
4102 spec->flags = (ObjectFlags)buf->ReadWord();
4103 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
4104 break;
4105
4106 case 0x11: // Animation info
4107 spec->animation.frames = buf->ReadByte();
4108 spec->animation.status = buf->ReadByte();
4109 break;
4110
4111 case 0x12: // Animation speed
4112 spec->animation.speed = buf->ReadByte();
4113 break;
4114
4115 case 0x13: // Animation triggers
4116 spec->animation.triggers = buf->ReadWord();
4117 break;
4118
4119 case 0x14: // Removal cost multiplier
4120 spec->clear_cost_multiplier = buf->ReadByte();
4121 break;
4122
4123 case 0x15: // Callback mask
4124 spec->callback_mask = buf->ReadWord();
4125 break;
4126
4127 case 0x16: // Building height
4128 spec->height = buf->ReadByte();
4129 break;
4130
4131 case 0x17: // Views
4132 spec->views = buf->ReadByte();
4133 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
4134 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
4135 spec->views = 1;
4136 }
4137 break;
4138
4139 case 0x18: // Amount placed on 256^2 map on map creation
4140 spec->generate_amount = buf->ReadByte();
4141 break;
4142
4143 default:
4144 ret = CIR_UNKNOWN;
4145 break;
4146 }
4147 }
4148
4149 return ret;
4150 }
4151
4160 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4161 {
4162 ChangeInfoResult ret = CIR_SUCCESS;
4163
4164 extern RailtypeInfo _railtypes[RAILTYPE_END];
4165
4166 if (id + numinfo > RAILTYPE_END) {
4167 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4168 return CIR_INVALID_ID;
4169 }
4170
4171 for (int i = 0; i < numinfo; i++) {
4172 RailType rt = _cur.grffile->railtype_map[id + i];
4173 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
4174
4175 RailtypeInfo *rti = &_railtypes[rt];
4176
4177 switch (prop) {
4178 case 0x08: // Label of rail type
4179 /* Skipped here as this is loaded during reservation stage. */
4180 buf->ReadDWord();
4181 break;
4182
4183 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4184 uint16 str = buf->ReadWord();
4185 AddStringForMapping(str, &rti->strings.toolbar_caption);
4186 if (_cur.grffile->grf_version < 8) {
4187 AddStringForMapping(str, &rti->strings.name);
4188 }
4189 break;
4190 }
4191
4192 case 0x0A: // Menu text of railtype
4193 AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4194 break;
4195
4196 case 0x0B: // Build window caption
4197 AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4198 break;
4199
4200 case 0x0C: // Autoreplace text
4201 AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4202 break;
4203
4204 case 0x0D: // New locomotive text
4205 AddStringForMapping(buf->ReadWord(), &rti->strings.new_loco);
4206 break;
4207
4208 case 0x0E: // Compatible railtype list
4209 case 0x0F: // Powered railtype list
4210 case 0x18: // Railtype list required for date introduction
4211 case 0x19: // Introduced railtype list
4212 {
4213 /* Rail type compatibility bits are added to the existing bits
4214 * to allow multiple GRFs to modify compatibility with the
4215 * default rail types. */
4216 int n = buf->ReadByte();
4217 for (int j = 0; j != n; j++) {
4218 RailTypeLabel label = buf->ReadDWord();
4219 RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
4220 if (rt != INVALID_RAILTYPE) {
4221 switch (prop) {
4222 case 0x0F: SetBit(rti->powered_railtypes, rt); FALLTHROUGH; // Powered implies compatible.
4223 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
4224 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
4225 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
4226 }
4227 }
4228 }
4229 break;
4230 }
4231
4232 case 0x10: // Rail Type flags
4233 rti->flags = (RailTypeFlags)buf->ReadByte();
4234 break;
4235
4236 case 0x11: // Curve speed advantage
4237 rti->curve_speed = buf->ReadByte();
4238 break;
4239
4240 case 0x12: // Station graphic
4241 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
4242 break;
4243
4244 case 0x13: // Construction cost factor
4245 rti->cost_multiplier = buf->ReadWord();
4246 break;
4247
4248 case 0x14: // Speed limit
4249 rti->max_speed = buf->ReadWord();
4250 break;
4251
4252 case 0x15: // Acceleration model
4253 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
4254 break;
4255
4256 case 0x16: // Map colour
4257 rti->map_colour = buf->ReadByte();
4258 break;
4259
4260 case 0x17: // Introduction date
4261 rti->introduction_date = buf->ReadDWord();
4262 break;
4263
4264 case 0x1A: // Sort order
4265 rti->sorting_order = buf->ReadByte();
4266 break;
4267
4268 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4269 AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4270 break;
4271
4272 case 0x1C: // Maintenance cost factor
4273 rti->maintenance_multiplier = buf->ReadWord();
4274 break;
4275
4276 case 0x1D: // Alternate rail type label list
4277 /* Skipped here as this is loaded during reservation stage. */
4278 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4279 break;
4280
4281 default:
4282 ret = CIR_UNKNOWN;
4283 break;
4284 }
4285 }
4286
4287 return ret;
4288 }
4289
4290 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4291 {
4292 ChangeInfoResult ret = CIR_SUCCESS;
4293
4294 extern RailtypeInfo _railtypes[RAILTYPE_END];
4295
4296 if (id + numinfo > RAILTYPE_END) {
4297 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4298 return CIR_INVALID_ID;
4299 }
4300
4301 for (int i = 0; i < numinfo; i++) {
4302 switch (prop) {
4303 case 0x08: // Label of rail type
4304 {
4305 RailTypeLabel rtl = buf->ReadDWord();
4306 rtl = BSWAP32(rtl);
4307
4308 RailType rt = GetRailTypeByLabel(rtl, false);
4309 if (rt == INVALID_RAILTYPE) {
4310 /* Set up new rail type */
4311 rt = AllocateRailType(rtl);
4312 }
4313
4314 _cur.grffile->railtype_map[id + i] = rt;
4315 break;
4316 }
4317
4318 case 0x09: // Toolbar caption of railtype
4319 case 0x0A: // Menu text
4320 case 0x0B: // Build window caption
4321 case 0x0C: // Autoreplace text
4322 case 0x0D: // New loco
4323 case 0x13: // Construction cost
4324 case 0x14: // Speed limit
4325 case 0x1B: // Name of railtype
4326 case 0x1C: // Maintenance cost factor
4327 buf->ReadWord();
4328 break;
4329
4330 case 0x1D: // Alternate rail type label list
4331 if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
4332 int n = buf->ReadByte();
4333 for (int j = 0; j != n; j++) {
4334 _railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.push_back(BSWAP32(buf->ReadDWord()));
4335 }
4336 break;
4337 }
4338 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
4339 FALLTHROUGH;
4340
4341 case 0x0E: // Compatible railtype list
4342 case 0x0F: // Powered railtype list
4343 case 0x18: // Railtype list required for date introduction
4344 case 0x19: // Introduced railtype list
4345 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4346 break;
4347
4348 case 0x10: // Rail Type flags
4349 case 0x11: // Curve speed advantage
4350 case 0x12: // Station graphic
4351 case 0x15: // Acceleration model
4352 case 0x16: // Map colour
4353 case 0x1A: // Sort order
4354 buf->ReadByte();
4355 break;
4356
4357 case 0x17: // Introduction date
4358 buf->ReadDWord();
4359 break;
4360
4361 default:
4362 ret = CIR_UNKNOWN;
4363 break;
4364 }
4365 }
4366
4367 return ret;
4368 }
4369
4378 static ChangeInfoResult RoadTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf, RoadTramType rtt)
4379 {
4380 ChangeInfoResult ret = CIR_SUCCESS;
4381
4382 extern RoadTypeInfo _roadtypes[ROADTYPE_END];
4383 RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map;
4384
4385 if (id + numinfo > ROADTYPE_END) {
4386 grfmsg(1, "RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring", id + numinfo, ROADTYPE_END);
4387 return CIR_INVALID_ID;
4388 }
4389
4390 for (int i = 0; i < numinfo; i++) {
4391 RoadType rt = type_map[id + i];
4392 if (rt == INVALID_ROADTYPE) return CIR_INVALID_ID;
4393
4394 RoadTypeInfo *rti = &_roadtypes[rt];
4395
4396 switch (prop) {
4397 case 0x08: // Label of road type
4398 /* Skipped here as this is loaded during reservation stage. */
4399 buf->ReadDWord();
4400 break;
4401
4402 case 0x09: { // Toolbar caption of roadtype (sets name as well for backwards compatibility for grf ver < 8)
4403 uint16 str = buf->ReadWord();
4404 AddStringForMapping(str, &rti->strings.toolbar_caption);
4405 break;
4406 }
4407
4408 case 0x0A: // Menu text of roadtype
4409 AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4410 break;
4411
4412 case 0x0B: // Build window caption
4413 AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4414 break;
4415
4416 case 0x0C: // Autoreplace text
4417 AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4418 break;
4419
4420 case 0x0D: // New engine text
4421 AddStringForMapping(buf->ReadWord(), &rti->strings.new_engine);
4422 break;
4423
4424 case 0x0F: // Powered roadtype list
4425 case 0x18: // Roadtype list required for date introduction
4426 case 0x19: { // Introduced roadtype list
4427 /* Road type compatibility bits are added to the existing bits
4428 * to allow multiple GRFs to modify compatibility with the
4429 * default road types. */
4430 int n = buf->ReadByte();
4431 for (int j = 0; j != n; j++) {
4432 RoadTypeLabel label = buf->ReadDWord();
4433 RoadType rt = GetRoadTypeByLabel(BSWAP32(label), false);
4434 if (rt != INVALID_ROADTYPE) {
4435 switch (prop) {
4436 case 0x0F: SetBit(rti->powered_roadtypes, rt); break;
4437 case 0x18: SetBit(rti->introduction_required_roadtypes, rt); break;
4438 case 0x19: SetBit(rti->introduces_roadtypes, rt); break;
4439 }
4440 }
4441 }
4442 break;
4443 }
4444
4445 case 0x10: // Road Type flags
4446 rti->flags = (RoadTypeFlags)buf->ReadByte();
4447 break;
4448
4449 case 0x13: // Construction cost factor
4450 rti->cost_multiplier = buf->ReadWord();
4451 break;
4452
4453 case 0x14: // Speed limit
4454 rti->max_speed = buf->ReadWord();
4455 break;
4456
4457 case 0x16: // Map colour
4458 rti->map_colour = buf->ReadByte();
4459 break;
4460
4461 case 0x17: // Introduction date
4462 rti->introduction_date = buf->ReadDWord();
4463 break;
4464
4465 case 0x1A: // Sort order
4466 rti->sorting_order = buf->ReadByte();
4467 break;
4468
4469 case 0x1B: // Name of roadtype
4470 AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4471 break;
4472
4473 case 0x1C: // Maintenance cost factor
4474 rti->maintenance_multiplier = buf->ReadWord();
4475 break;
4476
4477 case 0x1D: // Alternate road type label list
4478 /* Skipped here as this is loaded during reservation stage. */
4479 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4480 break;
4481
4482 default:
4483 ret = CIR_UNKNOWN;
4484 break;
4485 }
4486 }
4487
4488 return ret;
4489 }
4490
4491 static ChangeInfoResult RoadTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4492 {
4493 return RoadTypeChangeInfo(id, numinfo, prop, buf, RTT_ROAD);
4494 }
4495
4496 static ChangeInfoResult TramTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4497 {
4498 return RoadTypeChangeInfo(id, numinfo, prop, buf, RTT_TRAM);
4499 }
4500
4501
4502 static ChangeInfoResult RoadTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf, RoadTramType rtt)
4503 {
4504 ChangeInfoResult ret = CIR_SUCCESS;
4505
4506 extern RoadTypeInfo _roadtypes[ROADTYPE_END];
4507 RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map;
4508
4509 if (id + numinfo > ROADTYPE_END) {
4510 grfmsg(1, "RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring", id + numinfo, ROADTYPE_END);
4511 return CIR_INVALID_ID;
4512 }
4513
4514 for (int i = 0; i < numinfo; i++) {
4515 switch (prop) {
4516 case 0x08: { // Label of road type
4517 RoadTypeLabel rtl = buf->ReadDWord();
4518 rtl = BSWAP32(rtl);
4519
4520 RoadType rt = GetRoadTypeByLabel(rtl, false);
4521 if (rt == INVALID_ROADTYPE) {
4522 /* Set up new road type */
4523 rt = AllocateRoadType(rtl, rtt);
4524 } else if (GetRoadTramType(rt) != rtt) {
4525 grfmsg(1, "RoadTypeReserveInfo: Road type %u is invalid type (road/tram), ignoring", id + numinfo);
4526 return CIR_INVALID_ID;
4527 }
4528
4529 type_map[id + i] = rt;
4530 break;
4531 }
4532 case 0x09: // Toolbar caption of roadtype
4533 case 0x0A: // Menu text
4534 case 0x0B: // Build window caption
4535 case 0x0C: // Autoreplace text
4536 case 0x0D: // New loco
4537 case 0x13: // Construction cost
4538 case 0x14: // Speed limit
4539 case 0x1B: // Name of roadtype
4540 case 0x1C: // Maintenance cost factor
4541 buf->ReadWord();
4542 break;
4543
4544 case 0x1D: // Alternate road type label list
4545 if (type_map[id + i] != INVALID_ROADTYPE) {
4546 int n = buf->ReadByte();
4547 for (int j = 0; j != n; j++) {
4548 _roadtypes[type_map[id + i]].alternate_labels.push_back(BSWAP32(buf->ReadDWord()));
4549 }
4550 break;
4551 }
4552 grfmsg(1, "RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set", id + i);
4553 /* FALL THROUGH */
4554
4555 case 0x0F: // Powered roadtype list
4556 case 0x18: // Roadtype list required for date introduction
4557 case 0x19: // Introduced roadtype list
4558 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4559 break;
4560
4561 case 0x10: // Road Type flags
4562 case 0x16: // Map colour
4563 case 0x1A: // Sort order
4564 buf->ReadByte();
4565 break;
4566
4567 case 0x17: // Introduction date
4568 buf->ReadDWord();
4569 break;
4570
4571 default:
4572 ret = CIR_UNKNOWN;
4573 break;
4574 }
4575 }
4576
4577 return ret;
4578 }
4579
4580 static ChangeInfoResult RoadTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4581 {
4582 return RoadTypeReserveInfo(id, numinfo, prop, buf, RTT_ROAD);
4583 }
4584
4585 static ChangeInfoResult TramTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4586 {
4587 return RoadTypeReserveInfo(id, numinfo, prop, buf, RTT_TRAM);
4588 }
4589
4590 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
4591 {
4592 ChangeInfoResult ret = CIR_SUCCESS;
4593
4594 if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
4595 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
4596 return CIR_INVALID_ID;
4597 }
4598
4599 /* Allocate airport tile specs if they haven't been allocated already. */
4600 if (_cur.grffile->airtspec == nullptr) {
4601 _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES_PER_GRF);
4602 }
4603
4604 for (int i = 0; i < numinfo; i++) {
4605 AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
4606
4607 if (prop != 0x08 && tsp == nullptr) {
4608 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4609 return CIR_INVALID_ID;
4610 }
4611
4612 switch (prop) {
4613 case 0x08: { // Substitute airport tile type
4614 AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
4615 byte subs_id = buf->ReadByte();
4616
4617 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
4618 /* The substitute id must be one of the original airport tiles. */
4619 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4620 continue;
4621 }
4622
4623 /* Allocate space for this airport tile. */
4624 if (*tilespec == nullptr) {
4625 *tilespec = CallocT<AirportTileSpec>(1);
4626 tsp = *tilespec;
4627
4628 memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
4629 tsp->enabled = true;
4630
4631 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
4632
4633 tsp->grf_prop.local_id = airtid + i;
4634 tsp->grf_prop.subst_id = subs_id;
4635 tsp->grf_prop.grffile = _cur.grffile;
4636 _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
4637 }
4638 break;
4639 }
4640
4641 case 0x09: { // Airport tile override
4642 byte override = buf->ReadByte();
4643
4644 /* The airport tile being overridden must be an original airport tile. */
4645 if (override >= NEW_AIRPORTTILE_OFFSET) {
4646 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
4647 continue;
4648 }
4649
4650 _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
4651 break;
4652 }
4653
4654 case 0x0E: // Callback mask
4655 tsp->callback_mask = buf->ReadByte();
4656 break;
4657
4658 case 0x0F: // Animation information
4659 tsp->animation.frames = buf->ReadByte();
4660 tsp->animation.status = buf->ReadByte();
4661 break;
4662
4663 case 0x10: // Animation speed
4664 tsp->animation.speed = buf->ReadByte();
4665 break;
4666
4667 case 0x11: // Animation triggers
4668 tsp->animation.triggers = buf->ReadByte();
4669 break;
4670
4671 default:
4672 ret = CIR_UNKNOWN;
4673 break;
4674 }
4675 }
4676
4677 return ret;
4678 }
4679
4680 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4681 {
4682 switch (cir) {
4683 default: NOT_REACHED();
4684
4685 case CIR_DISABLED:
4686 /* Error has already been printed; just stop parsing */
4687 return true;
4688
4689 case CIR_SUCCESS:
4690 return false;
4691
4692 case CIR_UNHANDLED:
4693 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4694 return false;
4695
4696 case CIR_UNKNOWN:
4697 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4698 FALLTHROUGH;
4699
4700 case CIR_INVALID_ID: {
4701 /* No debug message for an invalid ID, as it has already been output */
4702 GRFError *error = DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4703 if (cir != CIR_INVALID_ID) error->param_value[1] = property;
4704 return true;
4705 }
4706 }
4707 }
4708
4709 /* Action 0x00 */
4710 static void FeatureChangeInfo(ByteReader *buf)
4711 {
4712 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4713 *
4714 * B feature
4715 * B num-props how many properties to change per vehicle/station
4716 * B num-info how many vehicles/stations to change
4717 * E id ID of first vehicle/station to change, if num-info is
4718 * greater than one, this one and the following
4719 * vehicles/stations will be changed
4720 * B property what property to change, depends on the feature
4721 * V new-info new bytes of info (variable size; depends on properties) */
4722
4723 static const VCI_Handler handler[] = {
4724 /* GSF_TRAINS */ RailVehicleChangeInfo,
4725 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4726 /* GSF_SHIPS */ ShipVehicleChangeInfo,
4727 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4728 /* GSF_STATIONS */ StationChangeInfo,
4729 /* GSF_CANALS */ CanalChangeInfo,
4730 /* GSF_BRIDGES */ BridgeChangeInfo,
4731 /* GSF_HOUSES */ TownHouseChangeInfo,
4732 /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4733 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4734 /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4735 /* GSF_CARGOES */ nullptr, // Cargo is handled during reservation
4736 /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4737 /* GSF_AIRPORTS */ AirportChangeInfo,
4738 /* GSF_SIGNALS */ nullptr,
4739 /* GSF_OBJECTS */ ObjectChangeInfo,
4740 /* GSF_RAILTYPES */ RailTypeChangeInfo,
4741 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4742 /* GSF_ROADTYPES */ RoadTypeChangeInfo,
4743 /* GSF_TRAMTYPES */ TramTypeChangeInfo,
4744 };
4745
4746 uint8 feature = buf->ReadByte();
4747 uint8 numprops = buf->ReadByte();
4748 uint numinfo = buf->ReadByte();
4749 uint engine = buf->ReadExtendedByte();
4750
4751 if (feature >= GSF_END) {
4752 grfmsg(1, "FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4753 return;
4754 }
4755
4756 grfmsg(6, "FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d",
4757 feature, numprops, engine, numinfo);
4758
4759 if (feature >= lengthof(handler) || handler[feature] == nullptr) {
4760 if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature);
4761 return;
4762 }
4763
4764 /* Mark the feature as used by the grf */
4765 SetBit(_cur.grffile->grf_features, feature);
4766
4767 while (numprops-- && buf->HasData()) {
4768 uint8 prop = buf->ReadByte();
4769
4770 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4771 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
4772 }
4773 }
4774
4775 /* Action 0x00 (GLS_SAFETYSCAN) */
4776 static void SafeChangeInfo(ByteReader *buf)
4777 {
4778 uint8 feature = buf->ReadByte();
4779 uint8 numprops = buf->ReadByte();
4780 uint numinfo = buf->ReadByte();
4781 buf->ReadExtendedByte(); // id
4782
4783 if (feature == GSF_BRIDGES && numprops == 1) {
4784 uint8 prop = buf->ReadByte();
4785 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4786 * is considered safe. */
4787 if (prop == 0x0D) return;
4788 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4789 uint8 prop = buf->ReadByte();
4790 /* Engine ID Mappings are safe, if the source is static */
4791 if (prop == 0x11) {
4792 bool is_safe = true;
4793 for (uint i = 0; i < numinfo; i++) {
4794 uint32 s = buf->ReadDWord();
4795 buf->ReadDWord(); // dest
4796 const GRFConfig *grfconfig = GetGRFConfig(s);
4797 if (grfconfig != nullptr && !HasBit(grfconfig->flags, GCF_STATIC)) {
4798 is_safe = false;
4799 break;
4800 }
4801 }
4802 if (is_safe) return;
4803 }
4804 }
4805
4806 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4807
4808 /* Skip remainder of GRF */
4809 _cur.skip_sprites = -1;
4810 }
4811
4812 /* Action 0x00 (GLS_RESERVE) */
4813 static void ReserveChangeInfo(ByteReader *buf)
4814 {
4815 uint8 feature = buf->ReadByte();
4816
4817 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES && feature != GSF_ROADTYPES && feature != GSF_TRAMTYPES) return;
4818
4819 uint8 numprops = buf->ReadByte();
4820 uint8 numinfo = buf->ReadByte();
4821 uint8 index = buf->ReadExtendedByte();
4822
4823 while (numprops-- && buf->HasData()) {
4824 uint8 prop = buf->ReadByte();
4825 ChangeInfoResult cir = CIR_SUCCESS;
4826
4827 switch (feature) {
4828 default: NOT_REACHED();
4829 case GSF_CARGOES:
4830 cir = CargoChangeInfo(index, numinfo, prop, buf);
4831 break;
4832
4833 case GSF_GLOBALVAR:
4834 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4835 break;
4836
4837 case GSF_RAILTYPES:
4838 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4839 break;
4840
4841 case GSF_ROADTYPES:
4842 cir = RoadTypeReserveInfo(index, numinfo, prop, buf);
4843 break;
4844
4845 case GSF_TRAMTYPES:
4846 cir = TramTypeReserveInfo(index, numinfo, prop, buf);
4847 break;
4848 }
4849
4850 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
4851 }
4852 }
4853
4854 /* Action 0x01 */
4855 static void NewSpriteSet(ByteReader *buf)
4856 {
4857 /* Basic format: <01> <feature> <num-sets> <num-ent>
4858 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4859 *
4860 * B feature feature to define sprites for
4861 * 0, 1, 2, 3: veh-type, 4: train stations
4862 * E first-set first sprite set to define
4863 * B num-sets number of sprite sets (extended byte in extended format)
4864 * E num-ent how many entries per sprite set
4865 * For vehicles, this is the number of different
4866 * vehicle directions in each sprite set
4867 * Set num-dirs=8, unless your sprites are symmetric.
4868 * In that case, use num-dirs=4.
4869 */
4870
4871 uint8 feature = buf->ReadByte();
4872 uint16 num_sets = buf->ReadByte();
4873 uint16 first_set = 0;
4874
4875 if (num_sets == 0 && buf->HasData(3)) {
4876 /* Extended Action1 format.
4877 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4878 first_set = buf->ReadExtendedByte();
4879 num_sets = buf->ReadExtendedByte();
4880 }
4881 uint16 num_ents = buf->ReadExtendedByte();
4882
4883 if (feature >= GSF_END) {
4884 _cur.skip_sprites = num_sets * num_ents;
4885 grfmsg(1, "NewSpriteSet: Unsupported feature 0x%02X, skipping %d sprites", feature, _cur.skip_sprites);
4886 return;
4887 }
4888
4889 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4890
4891 grfmsg(7, "New sprite set at %d of feature 0x%02X, consisting of %d sets with %d views each (total %d)",
4892 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4893 );
4894
4895 for (int i = 0; i < num_sets * num_ents; i++) {
4896 _cur.nfo_line++;
4897 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
4898 }
4899 }
4900
4901 /* Action 0x01 (SKIP) */
4902 static void SkipAct1(ByteReader *buf)
4903 {
4904 buf->ReadByte();
4905 uint16 num_sets = buf->ReadByte();
4906
4907 if (num_sets == 0 && buf->HasData(3)) {
4908 /* Extended Action1 format.
4909 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4910 buf->ReadExtendedByte(); // first_set
4911 num_sets = buf->ReadExtendedByte();
4912 }
4913 uint16 num_ents = buf->ReadExtendedByte();
4914
4915 _cur.skip_sprites = num_sets * num_ents;
4916
4917 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
4918 }
4919
4920 /* Helper function to either create a callback or link to a previously
4921 * defined spritegroup. */
4922 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4923 {
4924 if (HasBit(groupid, 15)) {
4925 assert(CallbackResultSpriteGroup::CanAllocateItem());
4926 return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
4927 }
4928
4929 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == nullptr) {
4930 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4931 return nullptr;
4932 }
4933
4934 return _cur.spritegroups[groupid];
4935 }
4936
4945 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4946 {
4947 if (HasBit(spriteid, 15)) {
4948 assert(CallbackResultSpriteGroup::CanAllocateItem());
4949 return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
4950 }
4951
4952 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4953 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4954 return nullptr;
4955 }
4956
4957 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4958 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4959
4960 /* Ensure that the sprites are loeded */
4961 assert(spriteset_start + num_sprites <= _cur.spriteid);
4962
4963 assert(ResultSpriteGroup::CanAllocateItem());
4964 return new ResultSpriteGroup(spriteset_start, num_sprites);
4965 }
4966
4967 /* Action 0x02 */
4968 static void NewSpriteGroup(ByteReader *buf)
4969 {
4970 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4971 *
4972 * B feature see action 1
4973 * B set-id ID of this particular definition
4974 * B type/num-entries
4975 * if 80 or greater, this is a randomized or variational
4976 * list definition, see below
4977 * otherwise it specifies a number of entries, the exact
4978 * meaning depends on the feature
4979 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4980 SpriteGroup *act_group = nullptr;
4981
4982 uint8 feature = buf->ReadByte();
4983 if (feature >= GSF_END) {
4984 grfmsg(1, "NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
4985 return;
4986 }
4987
4988 uint8 setid = buf->ReadByte();
4989 uint8 type = buf->ReadByte();
4990
4991 /* Sprite Groups are created here but they are allocated from a pool, so
4992 * we do not need to delete anything if there is an exception from the
4993 * ByteReader. */
4994
4995 switch (type) {
4996 /* Deterministic Sprite Group */
4997 case 0x81: // Self scope, byte
4998 case 0x82: // Parent scope, byte
4999 case 0x85: // Self scope, word
5000 case 0x86: // Parent scope, word
5001 case 0x89: // Self scope, dword
5002 case 0x8A: // Parent scope, dword
5003 {
5004 byte varadjust;
5005 byte varsize;
5006
5007 assert(DeterministicSpriteGroup::CanAllocateItem());
5008 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
5009 group->nfo_line = _cur.nfo_line;
5010 act_group = group;
5011 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
5012
5013 switch (GB(type, 2, 2)) {
5014 default: NOT_REACHED();
5015 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
5016 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
5017 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
5018 }
5019
5020 static std::vector<DeterministicSpriteGroupAdjust> adjusts;
5021 adjusts.clear();
5022
5023 /* Loop through the var adjusts. Unfortunately we don't know how many we have
5024 * from the outset, so we shall have to keep reallocing. */
5025 do {
5026 DeterministicSpriteGroupAdjust &adjust = adjusts.emplace_back();
5027
5028 /* The first var adjust doesn't have an operation specified, so we set it to add. */
5029 adjust.operation = adjusts.size() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
5030 adjust.variable = buf->ReadByte();
5031 if (adjust.variable == 0x7E) {
5032 /* Link subroutine group */
5033 adjust.subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
5034 } else {
5035 adjust.parameter = IsInsideMM(adjust.variable, 0x60, 0x80) ? buf->ReadByte() : 0;
5036 }
5037
5038 varadjust = buf->ReadByte();
5039 adjust.shift_num = GB(varadjust, 0, 5);
5040 adjust.type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
5041 adjust.and_mask = buf->ReadVarSize(varsize);
5042
5043 if (adjust.type != DSGA_TYPE_NONE) {
5044 adjust.add_val = buf->ReadVarSize(varsize);
5045 adjust.divmod_val = buf->ReadVarSize(varsize);
5046 } else {
5047 adjust.add_val = 0;
5048 adjust.divmod_val = 0;
5049 }
5050
5051 /* Continue reading var adjusts while bit 5 is set. */
5052 } while (HasBit(varadjust, 5));
5053
5054 group->num_adjusts = (uint)adjusts.size();
5055 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
5056 MemCpyT(group->adjusts, adjusts.data(), group->num_adjusts);
5057
5058 std::vector<DeterministicSpriteGroupRange> ranges;
5059 ranges.resize(buf->ReadByte());
5060 for (uint i = 0; i < ranges.size(); i++) {
5061 ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5062 ranges[i].low = buf->ReadVarSize(varsize);
5063 ranges[i].high = buf->ReadVarSize(varsize);
5064 }
5065
5066 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
5067 group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
5068 /* nvar == 0 is a special case -- we turn our value into a callback result */
5069 group->calculated_result = ranges.size() == 0;
5070
5071 /* Sort ranges ascending. When ranges overlap, this may required clamping or splitting them */
5072 std::vector<uint32> bounds;
5073 for (uint i = 0; i < ranges.size(); i++) {
5074 bounds.push_back(ranges[i].low);
5075 if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
5076 }
5077 std::sort(bounds.begin(), bounds.end());
5078 bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
5079
5080 std::vector<const SpriteGroup *> target;
5081 for (uint j = 0; j < bounds.size(); ++j) {
5082 uint32 v = bounds[j];
5083 const SpriteGroup *t = group->default_group;
5084 for (uint i = 0; i < ranges.size(); i++) {
5085 if (ranges[i].low <= v && v <= ranges[i].high) {
5086 t = ranges[i].group;
5087 break;
5088 }
5089 }
5090 target.push_back(t);
5091 }
5092 assert(target.size() == bounds.size());
5093
5094 std::vector<DeterministicSpriteGroupRange> optimised;
5095 for (uint j = 0; j < bounds.size(); ) {
5096 if (target[j] != group->default_group) {
5097 DeterministicSpriteGroupRange r;
5098 r.group = target[j];
5099 r.low = bounds[j];
5100 while (j < bounds.size() && target[j] == r.group) {
5101 j++;
5102 }
5103 r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
5104 optimised.push_back(r);
5105 } else {
5106 j++;
5107 }
5108 }
5109
5110 group->num_ranges = (uint)optimised.size(); // cast is safe, there should never be 2**31 elements here
5111 if (group->num_ranges > 0) {
5112 group->ranges = MallocT<DeterministicSpriteGroupRange>(group->num_ranges);
5113 MemCpyT(group->ranges, &optimised.front(), group->num_ranges);
5114 }
5115 break;
5116 }
5117
5118 /* Randomized Sprite Group */
5119 case 0x80: // Self scope
5120 case 0x83: // Parent scope
5121 case 0x84: // Relative scope
5122 {
5123 assert(RandomizedSpriteGroup::CanAllocateItem());
5124 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
5125 group->nfo_line = _cur.nfo_line;
5126 act_group = group;
5127 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
5128
5129 if (HasBit(type, 2)) {
5130 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
5131 group->count = buf->ReadByte();
5132 }
5133
5134 uint8 triggers = buf->ReadByte();
5135 group->triggers = GB(triggers, 0, 7);
5136 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
5137 group->lowest_randbit = buf->ReadByte();
5138 group->num_groups = buf->ReadByte();
5139 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
5140
5141 for (uint i = 0; i < group->num_groups; i++) {
5142 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
5143 }
5144
5145 break;
5146 }
5147
5148 /* Neither a variable or randomized sprite group... must be a real group */
5149 default:
5150 {
5151 switch (feature) {
5152 case GSF_TRAINS:
5153 case GSF_ROADVEHICLES:
5154 case GSF_SHIPS:
5155 case GSF_AIRCRAFT:
5156 case GSF_STATIONS:
5157 case GSF_CANALS:
5158 case GSF_CARGOES:
5159 case GSF_AIRPORTS:
5160 case GSF_RAILTYPES:
5161 case GSF_ROADTYPES:
5162 case GSF_TRAMTYPES:
5163 {
5164 byte num_loaded = type;
5165 byte num_loading = buf->ReadByte();
5166
5167 if (!_cur.HasValidSpriteSets(feature)) {
5168 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
5169 return;
5170 }
5171
5172 assert(RealSpriteGroup::CanAllocateItem());
5173 RealSpriteGroup *group = new RealSpriteGroup();
5174 group->nfo_line = _cur.nfo_line;
5175 act_group = group;
5176
5177 group->num_loaded = num_loaded;
5178 group->num_loading = num_loading;
5179 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
5180 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
5181
5182 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
5183 setid, num_loaded, num_loading);
5184
5185 for (uint i = 0; i < num_loaded; i++) {
5186 uint16 spriteid = buf->ReadWord();
5187 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
5188 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
5189 }
5190
5191 for (uint i = 0; i < num_loading; i++) {
5192 uint16 spriteid = buf->ReadWord();
5193 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
5194 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
5195 }
5196
5197 break;
5198 }
5199
5200 case GSF_HOUSES:
5201 case GSF_AIRPORTTILES:
5202 case GSF_OBJECTS:
5203 case GSF_INDUSTRYTILES: {
5204 byte num_building_sprites = std::max((uint8)1, type);
5205
5206 assert(TileLayoutSpriteGroup::CanAllocateItem());
5207 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
5208 group->nfo_line = _cur.nfo_line;
5209 act_group = group;
5210
5211 /* On error, bail out immediately. Temporary GRF data was already freed */
5212 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
5213 break;
5214 }
5215
5216 case GSF_INDUSTRIES: {
5217 if (type > 2) {
5218 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
5219 break;
5220 }
5221
5222 assert(IndustryProductionSpriteGroup::CanAllocateItem());
5223 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
5224 group->nfo_line = _cur.nfo_line;
5225 act_group = group;
5226 group->version = type;
5227 if (type == 0) {
5228 group->num_input = 3;
5229 for (uint i = 0; i < 3; i++) {
5230 group->subtract_input[i] = (int16)buf->ReadWord(); // signed
5231 }
5232 group->num_output = 2;
5233 for (uint i = 0; i < 2; i++) {
5234 group->add_output[i] = buf->ReadWord(); // unsigned
5235 }
5236 group->again = buf->ReadByte();
5237 } else if (type == 1) {
5238 group->num_input = 3;
5239 for (uint i = 0; i < 3; i++) {
5240 group->subtract_input[i] = buf->ReadByte();
5241 }
5242 group->num_output = 2;
5243 for (uint i = 0; i < 2; i++) {
5244 group->add_output[i] = buf->ReadByte();
5245 }
5246 group->again = buf->ReadByte();
5247 } else if (type == 2) {
5248 group->num_input = buf->ReadByte();
5249 if (group->num_input > lengthof(group->subtract_input)) {
5250 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
5251 error->data = "too many inputs (max 16)";
5252 return;
5253 }
5254 for (uint i = 0; i < group->num_input; i++) {
5255 byte rawcargo = buf->ReadByte();
5256 CargoID cargo = GetCargoTranslation(rawcargo, _cur.grffile);
5257 if (cargo == CT_INVALID) {
5258 /* The mapped cargo is invalid. This is permitted at this point,
5259 * as long as the result is not used. Mark it invalid so this
5260 * can be tested later. */
5261 group->version = 0xFF;
5262 } else if (std::find(group->cargo_input, group->cargo_input + i, cargo) != group->cargo_input + i) {
5263 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
5264 error->data = "duplicate input cargo";
5265 return;
5266 }
5267 group->cargo_input[i] = cargo;
5268 group->subtract_input[i] = buf->ReadByte();
5269 }
5270 group->num_output = buf->ReadByte();
5271 if (group->num_output > lengthof(group->add_output)) {
5272 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
5273 error->data = "too many outputs (max 16)";
5274 return;
5275 }
5276 for (uint i = 0; i < group->num_output; i++) {
5277 byte rawcargo = buf->ReadByte();
5278 CargoID cargo = GetCargoTranslation(rawcargo, _cur.grffile);
5279 if (cargo == CT_INVALID) {
5280 /* Mark this result as invalid to use */
5281 group->version = 0xFF;
5282 } else if (std::find(group->cargo_output, group->cargo_output + i, cargo) != group->cargo_output + i) {
5283 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK);
5284 error->data = "duplicate output cargo";
5285 return;
5286 }
5287 group->cargo_output[i] = cargo;
5288 group->add_output[i] = buf->ReadByte();
5289 }
5290 group->again = buf->ReadByte();
5291 } else {
5292 NOT_REACHED();
5293 }
5294 break;
5295 }
5296
5297 /* Loading of Tile Layout and Production Callback groups would happen here */
5298 default: grfmsg(1, "NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5299 }
5300 }
5301 }
5302
5303 _cur.spritegroups[setid] = act_group;
5304 }
5305
5306 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
5307 {
5308 if (feature == GSF_OBJECTS) {
5309 switch (ctype) {
5310 case 0: return 0;
5311 case 0xFF: return CT_PURCHASE_OBJECT;
5312 default:
5313 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
5314 return CT_INVALID;
5315 }
5316 }
5317 /* Special cargo types for purchase list and stations */
5318 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
5319 if (ctype == 0xFF) return CT_PURCHASE;
5320
5321 if (_cur.grffile->cargo_list.size() == 0) {
5322 /* No cargo table, so use bitnum values */
5323 if (ctype >= 32) {
5324 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
5325 return CT_INVALID;
5326 }
5327
5328 const CargoSpec *cs;
5329 FOR_ALL_CARGOSPECS(cs) {
5330 if (cs->bitnum == ctype) {
5331 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
5332 return cs->Index();
5333 }
5334 }
5335
5336 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
5337 return CT_INVALID;
5338 }
5339
5340 /* Check if the cargo type is out of bounds of the cargo translation table */
5341 if (ctype >= _cur.grffile->cargo_list.size()) {
5342 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, (unsigned int)_cur.grffile->cargo_list.size() - 1);
5343 return CT_INVALID;
5344 }
5345
5346 /* Look up the cargo label from the translation table */
5347 CargoLabel cl = _cur.grffile->cargo_list[ctype];
5348 if (cl == 0) {
5349 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
5350 return CT_INVALID;
5351 }
5352
5353 ctype = GetCargoIDByLabel(cl);
5354 if (ctype == CT_INVALID) {
5355 grfmsg(5, "TranslateCargo: Cargo '%c%c%c%c' unsupported, skipping.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8));
5356 return CT_INVALID;
5357 }
5358
5359 grfmsg(6, "TranslateCargo: Cargo '%c%c%c%c' mapped to cargo type %d.", GB(cl, 24, 8), GB(cl, 16, 8), GB(cl, 8, 8), GB(cl, 0, 8), ctype);
5360 return ctype;
5361 }
5362
5363
5364 static bool IsValidGroupID(uint16 groupid, const char *function)
5365 {
5366 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == nullptr) {
5367 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
5368 return false;
5369 }
5370
5371 return true;
5372 }
5373
5374 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
5375 {
5376 static EngineID *last_engines;
5377 static uint last_engines_count;
5378 bool wagover = false;
5379
5380 /* Test for 'wagon override' flag */
5381 if (HasBit(idcount, 7)) {
5382 wagover = true;
5383 /* Strip off the flag */
5384 idcount = GB(idcount, 0, 7);
5385
5386 if (last_engines_count == 0) {
5387 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5388 return;
5389 }
5390
5391 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5392 last_engines_count, idcount);
5393 } else {
5394 if (last_engines_count != idcount) {
5395 last_engines = ReallocT(last_engines, idcount);
5396 last_engines_count = idcount;
5397 }
5398 }
5399
5400 EngineID *engines = AllocaM(EngineID, idcount);
5401 for (uint i = 0; i < idcount; i++) {
5402 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
5403 if (e == nullptr) {
5404 /* No engine could be allocated?!? Deal with it. Okay,
5405 * this might look bad. Also make sure this NewGRF
5406 * gets disabled, as a half loaded one is bad. */
5407 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
5408 return;
5409 }
5410
5411 engines[i] = e->index;
5412 if (!wagover) last_engines[i] = engines[i];
5413 }
5414
5415 uint8 cidcount = buf->ReadByte();
5416 for (uint c = 0; c < cidcount; c++) {
5417 uint8 ctype = buf->ReadByte();
5418 uint16 groupid = buf->ReadWord();
5419 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
5420
5421 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5422
5423 ctype = TranslateCargo(feature, ctype);
5424 if (ctype == CT_INVALID) continue;
5425
5426 for (uint i = 0; i < idcount; i++) {
5427 EngineID engine = engines[i];
5428
5429 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5430
5431 if (wagover) {
5432 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5433 } else {
5434 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5435 }
5436 }
5437 }
5438
5439 uint16 groupid = buf->ReadWord();
5440 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
5441
5442 grfmsg(8, "-- Default group id 0x%04X", groupid);
5443
5444 for (uint i = 0; i < idcount; i++) {
5445 EngineID engine = engines[i];
5446
5447 if (wagover) {
5448 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5449 } else {
5450 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5451 SetEngineGRF(engine, _cur.grffile);
5452 }
5453 }
5454 }
5455
5456
5457 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
5458 {
5459 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
5460 for (uint i = 0; i < idcount; i++) {
5461 cfs[i] = (CanalFeature)buf->ReadByte();
5462 }
5463
5464 uint8 cidcount = buf->ReadByte();
5465 buf->Skip(cidcount * 3);
5466
5467 uint16 groupid = buf->ReadWord();
5468 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
5469
5470 for (uint i = 0; i < idcount; i++) {
5471 CanalFeature cf = cfs[i];
5472
5473 if (cf >= CF_END) {
5474 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5475 continue;
5476 }
5477
5478 _water_feature[cf].grffile = _cur.grffile;
5479 _water_feature[cf].group = _cur.spritegroups[groupid];
5480 }
5481 }
5482
5483
5484 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
5485 {
5486 uint8 *stations = AllocaM(uint8, idcount);
5487 for (uint i = 0; i < idcount; i++) {
5488 stations[i] = buf->ReadByte();
5489 }
5490
5491 uint8 cidcount = buf->ReadByte();
5492 for (uint c = 0; c < cidcount; c++) {
5493 uint8 ctype = buf->ReadByte();
5494 uint16 groupid = buf->ReadWord();
5495 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
5496
5497 ctype = TranslateCargo(GSF_STATIONS, ctype);
5498 if (ctype == CT_INVALID) continue;
5499
5500 for (uint i = 0; i < idcount; i++) {
5501 StationSpec *statspec = _cur.grffile->stations == nullptr ? nullptr : _cur.grffile->stations[stations[i]];
5502
5503 if (statspec == nullptr) {
5504 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5505 continue;
5506 }
5507
5508 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5509 }
5510 }
5511
5512 uint16 groupid = buf->ReadWord();
5513 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
5514
5515 for (uint i = 0; i < idcount; i++) {
5516 StationSpec *statspec = _cur.grffile->stations == nullptr ? nullptr : _cur.grffile->stations[stations[i]];
5517
5518 if (statspec == nullptr) {
5519 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5520 continue;
5521 }
5522
5523 if (statspec->grf_prop.grffile != nullptr) {
5524 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5525 continue;
5526 }
5527
5528 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
5529 statspec->grf_prop.grffile = _cur.grffile;
5530 statspec->grf_prop.local_id = stations[i];
5531 StationClass::Assign(statspec);
5532 }
5533 }
5534
5535
5536 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
5537 {
5538 uint8 *houses = AllocaM(uint8, idcount);
5539 for (uint i = 0; i < idcount; i++) {
5540 houses[i] = buf->ReadByte();
5541 }
5542
5543 /* Skip the cargo type section, we only care about the default group */
5544 uint8 cidcount = buf->ReadByte();
5545 buf->Skip(cidcount * 3);
5546
5547 uint16 groupid = buf->ReadWord();
5548 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
5549
5550 if (_cur.grffile->housespec == nullptr) {
5551 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5552 return;
5553 }
5554
5555 for (uint i = 0; i < idcount; i++) {
5556 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
5557
5558 if (hs == nullptr) {
5559 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5560 continue;
5561 }
5562
5563 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5564 }
5565 }
5566
5567 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5568 {
5569 uint8 *industries = AllocaM(uint8, idcount);
5570 for (uint i = 0; i < idcount; i++) {
5571 industries[i] = buf->ReadByte();
5572 }
5573
5574 /* Skip the cargo type section, we only care about the default group */
5575 uint8 cidcount = buf->ReadByte();
5576 buf->Skip(cidcount * 3);
5577
5578 uint16 groupid = buf->ReadWord();
5579 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5580
5581 if (_cur.grffile->industryspec == nullptr) {
5582 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5583 return;
5584 }
5585
5586 for (uint i = 0; i < idcount; i++) {
5587 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5588
5589 if (indsp == nullptr) {
5590 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5591 continue;
5592 }
5593
5594 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5595 }
5596 }
5597
5598 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5599 {
5600 uint8 *indtiles = AllocaM(uint8, idcount);
5601 for (uint i = 0; i < idcount; i++) {
5602 indtiles[i] = buf->ReadByte();
5603 }
5604
5605 /* Skip the cargo type section, we only care about the default group */
5606 uint8 cidcount = buf->ReadByte();
5607 buf->Skip(cidcount * 3);
5608
5609 uint16 groupid = buf->ReadWord();
5610 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5611
5612 if (_cur.grffile->indtspec == nullptr) {
5613 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5614 return;
5615 }
5616
5617 for (uint i = 0; i < idcount; i++) {
5618 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5619
5620 if (indtsp == nullptr) {
5621 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5622 continue;
5623 }
5624
5625 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5626 }
5627 }
5628
5629 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5630 {
5631 CargoID *cargoes = AllocaM(CargoID, idcount);
5632 for (uint i = 0; i < idcount; i++) {
5633 cargoes[i] = buf->ReadByte();
5634 }
5635
5636 /* Skip the cargo type section, we only care about the default group */
5637 uint8 cidcount = buf->ReadByte();
5638 buf->Skip(cidcount * 3);
5639
5640 uint16 groupid = buf->ReadWord();
5641 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5642
5643 for (uint i = 0; i < idcount; i++) {
5644 CargoID cid = cargoes[i];
5645
5646 if (cid >= NUM_CARGO) {
5647 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5648 continue;
5649 }
5650
5651 CargoSpec *cs = CargoSpec::Get(cid);
5652 cs->grffile = _cur.grffile;
5653 cs->group = _cur.spritegroups[groupid];
5654 }
5655 }
5656
5657 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5658 {
5659 if (_cur.grffile->objectspec == nullptr) {
5660 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5661 return;
5662 }
5663
5664 uint8 *objects = AllocaM(uint8, idcount);
5665 for (uint i = 0; i < idcount; i++) {
5666 objects[i] = buf->ReadByte();
5667 }
5668
5669 uint8 cidcount = buf->ReadByte();
5670 for (uint c = 0; c < cidcount; c++) {
5671 uint8 ctype = buf->ReadByte();
5672 uint16 groupid = buf->ReadWord();
5673 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5674
5675 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5676 if (ctype == CT_INVALID) continue;
5677
5678 for (uint i = 0; i < idcount; i++) {
5679 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5680
5681 if (spec == nullptr) {
5682 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5683 continue;
5684 }
5685
5686 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5687 }
5688 }
5689
5690 uint16 groupid = buf->ReadWord();
5691 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5692
5693 for (uint i = 0; i < idcount; i++) {
5694 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5695
5696 if (spec == nullptr) {
5697 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5698 continue;
5699 }
5700
5701 if (spec->grf_prop.grffile != nullptr) {
5702 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5703 continue;
5704 }
5705
5706 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5707 spec->grf_prop.grffile = _cur.grffile;
5708 spec->grf_prop.local_id = objects[i];
5709 }
5710 }
5711
5712 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5713 {
5714 uint8 *railtypes = AllocaM(uint8, idcount);
5715 for (uint i = 0; i < idcount; i++) {
5716 uint8 id = buf->ReadByte();
5717 railtypes[i] = id < RAILTYPE_END ? _cur.grffile->railtype_map[id] : INVALID_RAILTYPE;
5718 }
5719
5720 uint8 cidcount = buf->ReadByte();
5721 for (uint c = 0; c < cidcount; c++) {
5722 uint8 ctype = buf->ReadByte();
5723 uint16 groupid = buf->ReadWord();
5724 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5725
5726 if (ctype >= RTSG_END) continue;
5727
5728 extern RailtypeInfo _railtypes[RAILTYPE_END];
5729 for (uint i = 0; i < idcount; i++) {
5730 if (railtypes[i] != INVALID_RAILTYPE) {
5731 RailtypeInfo *rti = &_railtypes[railtypes[i]];
5732
5733 rti->grffile[ctype] = _cur.grffile;
5734 rti->group[ctype] = _cur.spritegroups[groupid];
5735 }
5736 }
5737 }
5738
5739 /* Railtypes do not use the default group. */
5740 buf->ReadWord();
5741 }
5742
5743 static void RoadTypeMapSpriteGroup(ByteReader *buf, uint8 idcount, RoadTramType rtt)
5744 {
5745 RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map;
5746
5747 uint8 *roadtypes = AllocaM(uint8, idcount);
5748 for (uint i = 0; i < idcount; i++) {
5749 uint8 id = buf->ReadByte();
5750 roadtypes[i] = id < ROADTYPE_END ? type_map[id] : INVALID_ROADTYPE;
5751 }
5752
5753 uint8 cidcount = buf->ReadByte();
5754 for (uint c = 0; c < cidcount; c++) {
5755 uint8 ctype = buf->ReadByte();
5756 uint16 groupid = buf->ReadWord();
5757 if (!IsValidGroupID(groupid, "RoadTypeMapSpriteGroup")) continue;
5758
5759 if (ctype >= ROTSG_END) continue;
5760
5761 extern RoadTypeInfo _roadtypes[ROADTYPE_END];
5762 for (uint i = 0; i < idcount; i++) {
5763 if (roadtypes[i] != INVALID_ROADTYPE) {
5764 RoadTypeInfo *rti = &_roadtypes[roadtypes[i]];
5765
5766 rti->grffile[ctype] = _cur.grffile;
5767 rti->group[ctype] = _cur.spritegroups[groupid];
5768 }
5769 }
5770 }
5771
5772 /* Roadtypes do not use the default group. */
5773 buf->ReadWord();
5774 }
5775
5776 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5777 {
5778 uint8 *airports = AllocaM(uint8, idcount);
5779 for (uint i = 0; i < idcount; i++) {
5780 airports[i] = buf->ReadByte();
5781 }
5782
5783 /* Skip the cargo type section, we only care about the default group */
5784 uint8 cidcount = buf->ReadByte();
5785 buf->Skip(cidcount * 3);
5786
5787 uint16 groupid = buf->ReadWord();
5788 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5789
5790 if (_cur.grffile->airportspec == nullptr) {
5791 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5792 return;
5793 }
5794
5795 for (uint i = 0; i < idcount; i++) {
5796 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5797
5798 if (as == nullptr) {
5799 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5800 continue;
5801 }
5802
5803 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5804 }
5805 }
5806
5807 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5808 {
5809 uint8 *airptiles = AllocaM(uint8, idcount);
5810 for (uint i = 0; i < idcount; i++) {
5811 airptiles[i] = buf->ReadByte();
5812 }
5813
5814 /* Skip the cargo type section, we only care about the default group */
5815 uint8 cidcount = buf->ReadByte();
5816 buf->Skip(cidcount * 3);
5817
5818 uint16 groupid = buf->ReadWord();
5819 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5820
5821 if (_cur.grffile->airtspec == nullptr) {
5822 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5823 return;
5824 }
5825
5826 for (uint i = 0; i < idcount; i++) {
5827 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5828
5829 if (airtsp == nullptr) {
5830 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5831 continue;
5832 }
5833
5834 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5835 }
5836 }
5837
5838
5839 /* Action 0x03 */
5840 static void FeatureMapSpriteGroup(ByteReader *buf)
5841 {
5842 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5843 * id-list := [<id>] [id-list]
5844 * cargo-list := <cargo-type> <cid> [cargo-list]
5845 *
5846 * B feature see action 0
5847 * B n-id bits 0-6: how many IDs this definition applies to
5848 * bit 7: if set, this is a wagon override definition (see below)
5849 * B ids the IDs for which this definition applies
5850 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5851 * can be zero, in that case the def-cid is used always
5852 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5853 * W cid cargo ID (sprite group ID) for this type of cargo
5854 * W def-cid default cargo ID (sprite group ID) */
5855
5856 uint8 feature = buf->ReadByte();
5857 uint8 idcount = buf->ReadByte();
5858
5859 if (feature >= GSF_END) {
5860 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5861 return;
5862 }
5863
5864 /* If idcount is zero, this is a feature callback */
5865 if (idcount == 0) {
5866 /* Skip number of cargo ids? */
5867 buf->ReadByte();
5868 uint16 groupid = buf->ReadWord();
5869 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
5870
5871 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature 0x%02X", feature);
5872
5873 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5874 return;
5875 }
5876
5877 /* Mark the feature as used by the grf (generic callbacks do not count) */
5878 SetBit(_cur.grffile->grf_features, feature);
5879
5880 grfmsg(6, "FeatureMapSpriteGroup: Feature 0x%02X, %d ids", feature, idcount);
5881
5882 switch (feature) {
5883 case GSF_TRAINS:
5884 case GSF_ROADVEHICLES:
5885 case GSF_SHIPS:
5886 case GSF_AIRCRAFT:
5887 VehicleMapSpriteGroup(buf, feature, idcount);
5888 return;
5889
5890 case GSF_CANALS:
5891 CanalMapSpriteGroup(buf, idcount);
5892 return;
5893
5894 case GSF_STATIONS:
5895 StationMapSpriteGroup(buf, idcount);
5896 return;
5897
5898 case GSF_HOUSES:
5899 TownHouseMapSpriteGroup(buf, idcount);
5900 return;
5901
5902 case GSF_INDUSTRIES:
5903 IndustryMapSpriteGroup(buf, idcount);
5904 return;
5905
5906 case GSF_INDUSTRYTILES:
5907 IndustrytileMapSpriteGroup(buf, idcount);
5908 return;
5909
5910 case GSF_CARGOES:
5911 CargoMapSpriteGroup(buf, idcount);
5912 return;
5913
5914 case GSF_AIRPORTS:
5915 AirportMapSpriteGroup(buf, idcount);
5916 return;
5917
5918 case GSF_OBJECTS:
5919 ObjectMapSpriteGroup(buf, idcount);
5920 break;
5921
5922 case GSF_RAILTYPES:
5923 RailTypeMapSpriteGroup(buf, idcount);
5924 break;
5925
5926 case GSF_ROADTYPES:
5927 RoadTypeMapSpriteGroup(buf, idcount, RTT_ROAD);
5928 break;
5929
5930 case GSF_TRAMTYPES:
5931 RoadTypeMapSpriteGroup(buf, idcount, RTT_TRAM);
5932 break;
5933
5934 case GSF_AIRPORTTILES:
5935 AirportTileMapSpriteGroup(buf, idcount);
5936 return;
5937
5938 default:
5939 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature);
5940 return;
5941 }
5942 }
5943
5944 /* Action 0x04 */
5945 static void FeatureNewName(ByteReader *buf)
5946 {
5947 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5948 *
5949 * B veh-type see action 0 (as 00..07, + 0A
5950 * But IF veh-type = 48, then generic text
5951 * B language-id If bit 6 is set, This is the extended language scheme,
5952 * with up to 64 language.
5953 * Otherwise, it is a mapping where set bits have meaning
5954 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5955 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5956 * B num-veh number of vehicles which are getting a new name
5957 * B/W offset number of the first vehicle that gets a new name
5958 * Byte : ID of vehicle to change
5959 * Word : ID of string to change/add
5960 * S data new texts, each of them zero-terminated, after
5961 * which the next name begins. */
5962
5963 bool new_scheme = _cur.grffile->grf_version >= 7;
5964
5965 uint8 feature = buf->ReadByte();
5966 if (feature >= GSF_END && feature != 0x48) {
5967 grfmsg(1, "FeatureNewName: Unsupported feature 0x%02X, skipping", feature);
5968 return;
5969 }
5970
5971 uint8 lang = buf->ReadByte();
5972 uint8 num = buf->ReadByte();
5973 bool generic = HasBit(lang, 7);
5974 uint16 id;
5975 if (generic) {
5976 id = buf->ReadWord();
5977 } else if (feature <= GSF_AIRCRAFT) {
5978 id = buf->ReadExtendedByte();
5979 } else {
5980 id = buf->ReadByte();
5981 }
5982
5983 ClrBit(lang, 7);
5984
5985 uint16 endid = id + num;
5986
5987 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature 0x%02X) in language 0x%02X",
5988 id, endid, feature, lang);
5989
5990 for (; id < endid && buf->HasData(); id++) {
5991 const char *name = buf->ReadString();
5992 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5993
5994 switch (feature) {
5995 case GSF_TRAINS:
5996 case GSF_ROADVEHICLES:
5997 case GSF_SHIPS:
5998 case GSF_AIRCRAFT:
5999 if (!generic) {
6000 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
6001 if (e == nullptr) break;
6002 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
6003 e->info.string_id = string;
6004 } else {
6005 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
6006 }
6007 break;
6008
6009 default:
6010 if (IsInsideMM(id, 0xD000, 0xD400) || IsInsideMM(id, 0xD800, 0xE000)) {
6011 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
6012 break;
6013 }
6014
6015 switch (GB(id, 8, 8)) {
6016 case 0xC4: // Station class name
6017 if (_cur.grffile->stations == nullptr || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) {
6018 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
6019 } else {
6020 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
6021 StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6022 }
6023 break;
6024
6025 case 0xC5: // Station name
6026 if (_cur.grffile->stations == nullptr || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) {
6027 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
6028 } else {
6029 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6030 }
6031 break;
6032
6033 case 0xC7: // Airporttile name
6034 if (_cur.grffile->airtspec == nullptr || _cur.grffile->airtspec[GB(id, 0, 8)] == nullptr) {
6035 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
6036 } else {
6037 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6038 }
6039 break;
6040
6041 case 0xC9: // House name
6042 if (_cur.grffile->housespec == nullptr || _cur.grffile->housespec[GB(id, 0, 8)] == nullptr) {
6043 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
6044 } else {
6045 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6046 }
6047 break;
6048
6049 default:
6050 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
6051 break;
6052 }
6053 break;
6054 }
6055 }
6056 }
6057
6066 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
6067 {
6068
6069 if (offset >= max_sprites) {
6070 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
6071 uint orig_num = num;
6072 num = 0;
6073 return orig_num;
6074 }
6075
6076 if (offset + num > max_sprites) {
6077 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
6078 uint orig_num = num;
6079 num = std::max(max_sprites - offset, 0);
6080 return orig_num - num;
6081 }
6082
6083 return 0;
6084 }
6085
6086
6088 enum Action5BlockType {
6089 A5BLOCK_FIXED,
6090 A5BLOCK_ALLOW_OFFSET,
6091 A5BLOCK_INVALID,
6092 };
6094 struct Action5Type {
6095 Action5BlockType block_type;
6096 SpriteID sprite_base;
6097 uint16 min_sprites;
6098 uint16 max_sprites;
6099 const char *name;
6100 };
6101
6103 static const Action5Type _action5_types[] = {
6104 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
6105 /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
6106 /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
6107 /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
6108 /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
6109 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
6110 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Rail catenary graphics" },
6111 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
6112 /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
6113 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
6114 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
6115 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
6116 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
6117 /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
6118 /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
6119 /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
6120 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
6121 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
6122 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
6123 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
6124 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
6125 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
6126 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
6127 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
6128 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
6129 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET, SPR_PALETTE_BASE, 1, PALETTE_SPRITE_COUNT, "Palette" },
6130 };
6131
6132 /* Action 0x05 */
6133 static void GraphicsNew(ByteReader *buf)
6134 {
6135 /* <05> <graphics-type> <num-sprites> <other data...>
6136 *
6137 * B graphics-type What set of graphics the sprites define.
6138 * E num-sprites How many sprites are in this set?
6139 * V other data Graphics type specific data. Currently unused. */
6140
6141 uint8 type = buf->ReadByte();
6142 uint16 num = buf->ReadExtendedByte();
6143 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
6144 ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
6145
6146 if ((type == 0x0D) && (num == 10) && HasBit(_cur.grfconfig->flags, GCF_SYSTEM)) {
6147 /* Special not-TTDP-compatible case used in openttd.grf
6148 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
6149 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
6150 LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_S
6151 LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_W
6152 LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_WSE
6153 LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_N
6154 LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NWS
6155 LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_ENW
6156 LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_SEN
6157 LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_E
6158 LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_EW
6159 LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NS
6160 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
6161 return;
6162 }
6163
6164 /* Supported type? */
6165 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
6166 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
6167 _cur.skip_sprites = num;
6168 return;
6169 }
6170
6171 const Action5Type *action5_type = &_action5_types[type];
6172
6173 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
6174 * except for the long version of the shore type:
6175 * Ignore offset if not allowed */
6176 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
6177 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
6178 offset = 0;
6179 }
6180
6181 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
6182 * This does not make sense, if <offset> is allowed */
6183 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
6184 grfmsg(1, "GraphicsNew: %s (type 0x%02X) count must be at least %d. Only %d were specified. Skipping.", action5_type->name, type, action5_type->min_sprites, num);
6185 _cur.skip_sprites = num;
6186 return;
6187 }
6188
6189 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extensions) */
6190 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
6191 SpriteID replace = action5_type->sprite_base + offset;
6192
6193 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
6194 grfmsg(2, "GraphicsNew: Replacing sprites %d to %d of %s (type 0x%02X) at SpriteID 0x%04X", offset, offset + num - 1, action5_type->name, type, replace);
6195
6196 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
6197
6198 if (type == 0x0B) {
6199 static const SpriteID depot_with_track_offset = SPR_TRAMWAY_DEPOT_WITH_TRACK - SPR_TRAMWAY_BASE;
6200 static const SpriteID depot_no_track_offset = SPR_TRAMWAY_DEPOT_NO_TRACK - SPR_TRAMWAY_BASE;
6201 if (offset <= depot_with_track_offset && offset + num > depot_with_track_offset) _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_WITH_TRACK;
6202 if (offset <= depot_no_track_offset && offset + num > depot_no_track_offset) _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_NO_TRACK;
6203 }
6204
6205 for (; num > 0; num--) {
6206 _cur.nfo_line++;
6207 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
6208 }
6209
6210 _cur.skip_sprites = skip_num;
6211 }
6212
6213 /* Action 0x05 (SKIP) */
6214 static void SkipAct5(ByteReader *buf)
6215 {
6216 /* Ignore type byte */
6217 buf->ReadByte();
6218
6219 /* Skip the sprites of this action */
6220 _cur.skip_sprites = buf->ReadExtendedByte();
6221
6222 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
6223 }
6224
6236 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
6237 {
6238 switch (param) {
6239 case 0x00: // current date
6240 *value = std::max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
6241 return true;
6242
6243 case 0x01: // current year
6244 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
6245 return true;
6246
6247 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)
6248 YearMonthDay ymd;
6249 ConvertDateToYMD(_date, &ymd);
6250 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
6251 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
6252 return true;
6253 }
6254
6255 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
6256 *value = _settings_game.game_creation.landscape;
6257 return true;
6258
6259 case 0x06: // road traffic side, bit 4 clear=left, set=right
6260 *value = _settings_game.vehicle.road_side << 4;
6261 return true;
6262
6263 case 0x09: // date fraction
6264 *value = _date_fract * 885;
6265 return true;
6266
6267 case 0x0A: // animation counter
6268 *value = _tick_counter;
6269 return true;
6270
6271 case 0x0B: { // TTDPatch version
6272 uint major = 2;
6273 uint minor = 6;
6274 uint revision = 1; // special case: 2.0.1 is 2.0.10
6275 uint build = 1382;
6276 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
6277 return true;
6278 }
6279
6280 case 0x0D: // TTD Version, 00=DOS, 01=Windows
6281 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
6282 return true;
6283
6284 case 0x0E: // Y-offset for train sprites
6285 *value = _cur.grffile->traininfo_vehicle_pitch;
6286 return true;
6287
6288 case 0x0F: // Rail track type cost factors
6289 *value = 0;
6290 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
6291 if (_settings_game.vehicle.disable_elrails) {
6292 /* skip elrail multiplier - disabled */
6293 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
6294 } else {
6295 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
6296 /* Skip monorail multiplier - no space in result */
6297 }
6298 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
6299 return true;
6300
6301 case 0x11: // current rail tool type
6302 *value = 0; // constant fake value to avoid desync
6303 return true;
6304
6305 case 0x12: // Game mode
6306 *value = _game_mode;
6307 return true;
6308
6309 /* case 0x13: // Tile refresh offset to left not implemented */
6310 /* case 0x14: // Tile refresh offset to right not implemented */
6311 /* case 0x15: // Tile refresh offset upwards not implemented */
6312 /* case 0x16: // Tile refresh offset downwards not implemented */
6313 /* case 0x17: // temperate snow line not implemented */
6314
6315 case 0x1A: // Always -1
6316 *value = UINT_MAX;
6317 return true;
6318
6319 case 0x1B: // Display options
6320 *value = 0x3F; // constant fake value to avoid desync
6321 return true;
6322
6323 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
6324 *value = 1;
6325 return true;
6326
6327 case 0x1E: // Miscellaneous GRF features
6328 *value = _misc_grf_features;
6329
6330 /* Add the local flags */
6331 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
6332 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
6333 return true;
6334
6335 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
6336
6337 case 0x20: { // snow line height
6338 byte snowline = GetSnowLine();
6339 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= _settings_game.construction.max_heightlevel) {
6340 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
6341 } else {
6342 /* No snow */
6343 *value = 0xFF;
6344 }
6345 return true;
6346 }
6347
6348 case 0x21: // OpenTTD version
6349 *value = _openttd_newgrf_version;
6350 return true;
6351
6352 case 0x22: // difficulty level
6353 *value = SP_CUSTOM;
6354 return true;
6355
6356 case 0x23: // long format date
6357 *value = _date;
6358 return true;
6359
6360 case 0x24: // long format year
6361 *value = _cur_year;
6362 return true;
6363
6364 default: return false;
6365 }
6366 }
6367
6368 static uint32 GetParamVal(byte param, uint32 *cond_val)
6369 {
6370 /* First handle variable common with VarAction2 */
6371 uint32 value;
6372 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
6373
6374 /* Non-common variable */
6375 switch (param) {
6376 case 0x84: { // GRF loading stage
6377 uint32 res = 0;
6378
6379 if (_cur.stage > GLS_INIT) SetBit(res, 0);
6380 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
6381 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
6382 return res;
6383 }
6384
6385 case 0x85: // TTDPatch flags, only for bit tests
6386 if (cond_val == nullptr) {
6387 /* Supported in Action 0x07 and 0x09, not 0x0D */
6388 return 0;
6389 } else {
6390 uint32 index = *cond_val / 0x20;
6391 uint32 param_val = index < lengthof(_ttdpatch_flags) ? _ttdpatch_flags[index] : 0;
6392 *cond_val %= 0x20;
6393 return param_val;
6394 }
6395
6396 case 0x88: // GRF ID check
6397 return 0;
6398
6399 /* case 0x99: Global ID offset not implemented */
6400
6401 default:
6402 /* GRF Parameter */
6403 if (param < 0x80) return _cur.grffile->GetParam(param);
6404
6405 /* In-game variable. */
6406 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
6407 return UINT_MAX;
6408 }
6409 }
6410
6411 /* Action 0x06 */
6412 static void CfgApply(ByteReader *buf)
6413 {
6414 /* <06> <param-num> <param-size> <offset> ... <FF>
6415 *
6416 * B param-num Number of parameter to substitute (First = "zero")
6417 * Ignored if that parameter was not specified in newgrf.cfg
6418 * B param-size How many bytes to replace. If larger than 4, the
6419 * bytes of the following parameter are used. In that
6420 * case, nothing is applied unless *all* parameters
6421 * were specified.
6422 * B offset Offset into data from beginning of next sprite
6423 * to place where parameter is to be stored. */
6424
6425 /* Preload the next sprite */
6426 size_t pos = FioGetPos();
6427 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
6428 uint8 type = FioReadByte();
6429 byte *preload_sprite = nullptr;
6430
6431 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
6432 if (type == 0xFF) {
6433 preload_sprite = MallocT<byte>(num);
6434 FioReadBlock(preload_sprite, num);
6435 }
6436
6437 /* Reset the file position to the start of the next sprite */
6438 FioSeekTo(pos, SEEK_SET);
6439
6440 if (type != 0xFF) {
6441 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
6442 free(preload_sprite);
6443 return;
6444 }
6445
6446 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
6447 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
6448 if (it != _grf_line_to_action6_sprite_override.end()) {
6449 free(preload_sprite);
6450 preload_sprite = _grf_line_to_action6_sprite_override[location];
6451 } else {
6452 _grf_line_to_action6_sprite_override[location] = preload_sprite;
6453 }
6454
6455 /* Now perform the Action 0x06 on our data. */
6456
6457 for (;;) {
6458 uint i;
6459 uint param_num;
6460 uint param_size;
6461 uint offset;
6462 bool add_value;
6463
6464 /* Read the parameter to apply. 0xFF indicates no more data to change. */
6465 param_num = buf->ReadByte();
6466 if (param_num == 0xFF) break;
6467
6468 /* Get the size of the parameter to use. If the size covers multiple
6469 * double words, sequential parameter values are used. */
6470 param_size = buf->ReadByte();
6471
6472 /* Bit 7 of param_size indicates we should add to the original value
6473 * instead of replacing it. */
6474 add_value = HasBit(param_size, 7);
6475 param_size = GB(param_size, 0, 7);
6476
6477 /* Where to apply the data to within the pseudo sprite data. */
6478 offset = buf->ReadExtendedByte();
6479
6480 /* If the parameter is a GRF parameter (not an internal variable) check
6481 * if it (and all further sequential parameters) has been defined. */
6482 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
6483 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6484 break;
6485 }
6486
6487 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6488
6489 bool carry = false;
6490 for (i = 0; i < param_size && offset + i < num; i++) {
6491 uint32 value = GetParamVal(param_num + i / 4, nullptr);
6492 /* Reset carry flag for each iteration of the variable (only really
6493 * matters if param_size is greater than 4) */
6494 if (i % 4 == 0) carry = false;
6495
6496 if (add_value) {
6497 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6498 preload_sprite[offset + i] = GB(new_value, 0, 8);
6499 /* Check if the addition overflowed */
6500 carry = new_value >= 256;
6501 } else {
6502 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
6503 }
6504 }
6505 }
6506 }
6507
6517 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
6518 {
6519 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
6520 error->data = _cur.grfconfig->GetName();
6521 }
6522
6523 /* Action 0x07
6524 * Action 0x09 */
6525 static void SkipIf(ByteReader *buf)
6526 {
6527 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6528 *
6529 * B param-num
6530 * B param-size
6531 * B condition-type
6532 * V value
6533 * B num-sprites */
6534 uint32 cond_val = 0;
6535 uint32 mask = 0;
6536 bool result;
6537
6538 uint8 param = buf->ReadByte();
6539 uint8 paramsize = buf->ReadByte();
6540 uint8 condtype = buf->ReadByte();
6541
6542 if (condtype < 2) {
6543 /* Always 1 for bit tests, the given value should be ignored. */
6544 paramsize = 1;
6545 }
6546
6547 switch (paramsize) {
6548 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6549 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6550 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6551 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6552 default: break;
6553 }
6554
6555 if (param < 0x80 && _cur.grffile->param_end <= param) {
6556 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6557 return;
6558 }
6559
6560 grfmsg(7, "SkipIf: Test condtype %d, param 0x%02X, condval 0x%08X", condtype, param, cond_val);
6561
6562 /* condtypes that do not use 'param' are always valid.
6563 * condtypes that use 'param' are either not valid for param 0x88, or they are only valid for param 0x88.
6564 */
6565 if (condtype >= 0x0B) {
6566 /* Tests that ignore 'param' */
6567 switch (condtype) {
6568 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6569 break;
6570 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6571 break;
6572 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6573 break;
6574 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6575 break;
6576 case 0x0F: {
6577 RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val));
6578 result = rt == INVALID_ROADTYPE || !RoadTypeIsRoad(rt);
6579 break;
6580 }
6581 case 0x10: {
6582 RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val));
6583 result = rt != INVALID_ROADTYPE && RoadTypeIsRoad(rt);
6584 break;
6585 }
6586 case 0x11: {
6587 RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val));
6588 result = rt == INVALID_ROADTYPE || !RoadTypeIsTram(rt);
6589 break;
6590 }
6591 case 0x12: {
6592 RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val));
6593 result = rt != INVALID_ROADTYPE && RoadTypeIsTram(rt);
6594 break;
6595 }
6596 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
6597 }
6598 } else if (param == 0x88) {
6599 /* GRF ID checks */
6600
6601 GRFConfig *c = GetGRFConfig(cond_val, mask);
6602
6603 if (c != nullptr && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6604 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6605 c = nullptr;
6606 }
6607
6608 if (condtype != 10 && c == nullptr) {
6609 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6610 return;
6611 }
6612
6613 switch (condtype) {
6614 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6615 case 0x06: // Is GRFID active?
6616 result = c->status == GCS_ACTIVATED;
6617 break;
6618
6619 case 0x07: // Is GRFID non-active?
6620 result = c->status != GCS_ACTIVATED;
6621 break;
6622
6623 case 0x08: // GRFID is not but will be active?
6624 result = c->status == GCS_INITIALISED;
6625 break;
6626
6627 case 0x09: // GRFID is or will be active?
6628 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6629 break;
6630
6631 case 0x0A: // GRFID is not nor will be active
6632 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6633 result = c == nullptr || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6634 break;
6635
6636 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
6637 }
6638 } else {
6639 /* Tests that use 'param' and are not GRF ID checks. */
6640 uint32 param_val = GetParamVal(param, &cond_val); // cond_val is modified for param == 0x85
6641 switch (condtype) {
6642 case 0x00: result = !!(param_val & (1 << cond_val));
6643 break;
6644 case 0x01: result = !(param_val & (1 << cond_val));
6645 break;
6646 case 0x02: result = (param_val & mask) == cond_val;
6647 break;
6648 case 0x03: result = (param_val & mask) != cond_val;
6649 break;
6650 case 0x04: result = (param_val & mask) < cond_val;
6651 break;
6652 case 0x05: result = (param_val & mask) > cond_val;
6653 break;
6654 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
6655 }
6656 }
6657
6658 if (!result) {
6659 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6660 return;
6661 }
6662
6663 uint8 numsprites = buf->ReadByte();
6664
6665 /* numsprites can be a GOTO label if it has been defined in the GRF
6666 * file. The jump will always be the first matching label that follows
6667 * the current nfo_line. If no matching label is found, the first matching
6668 * label in the file is used. */
6669 GRFLabel *choice = nullptr;
6670 for (GRFLabel *label = _cur.grffile->label; label != nullptr; label = label->next) {
6671 if (label->label != numsprites) continue;
6672
6673 /* Remember a goto before the current line */
6674 if (choice == nullptr) choice = label;
6675 /* If we find a label here, this is definitely good */
6676 if (label->nfo_line > _cur.nfo_line) {
6677 choice = label;
6678 break;
6679 }
6680 }
6681
6682 if (choice != nullptr) {
6683 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6684 FioSeekTo(choice->pos, SEEK_SET);
6685 _cur.nfo_line = choice->nfo_line;
6686 return;
6687 }
6688
6689 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6690 _cur.skip_sprites = numsprites;
6691 if (_cur.skip_sprites == 0) {
6692 /* Zero means there are no sprites to skip, so
6693 * we use -1 to indicate that all further
6694 * sprites should be skipped. */
6695 _cur.skip_sprites = -1;
6696
6697 /* If an action 8 hasn't been encountered yet, disable the grf. */
6698 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6699 DisableGrf();
6700 }
6701 }
6702 }
6703
6704
6705 /* Action 0x08 (GLS_FILESCAN) */
6706 static void ScanInfo(ByteReader *buf)
6707 {
6708 uint8 grf_version = buf->ReadByte();
6709 uint32 grfid = buf->ReadDWord();
6710 const char *name = buf->ReadString();
6711
6712 _cur.grfconfig->ident.grfid = grfid;
6713
6714 if (grf_version < 2 || grf_version > 8) {
6715 SetBit(_cur.grfconfig->flags, GCF_INVALID);
6716 DEBUG(grf, 0, "%s: NewGRF \"%s\" (GRFID %08X) uses GRF version %d, which is incompatible with this version of OpenTTD.", _cur.grfconfig->filename, name, BSWAP32(grfid), grf_version);
6717 }
6718
6719 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6720 if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6721
6722 AddGRFTextToList(_cur.grfconfig->name, 0x7F, grfid, false, name);
6723
6724 if (buf->HasData()) {
6725 const char *info = buf->ReadString();
6726 AddGRFTextToList(_cur.grfconfig->info, 0x7F, grfid, true, info);
6727 }
6728
6729 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6730 _cur.skip_sprites = -1;
6731 }
6732
6733 /* Action 0x08 */
6734 static void GRFInfo(ByteReader *buf)
6735 {
6736 /* <08> <version> <grf-id> <name> <info>
6737 *
6738 * B version newgrf version, currently 06
6739 * 4*B grf-id globally unique ID of this .grf file
6740 * S name name of this .grf set
6741 * S info string describing the set, and e.g. author and copyright */
6742
6743 uint8 version = buf->ReadByte();
6744 uint32 grfid = buf->ReadDWord();
6745 const char *name = buf->ReadString();
6746
6747 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6748 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6749 return;
6750 }
6751
6752 if (_cur.grffile->grfid != grfid) {
6753 DEBUG(grf, 0, "GRFInfo: GRFID %08X in FILESCAN stage does not match GRFID %08X in INIT/RESERVE/ACTIVATION stage", BSWAP32(_cur.grffile->grfid), BSWAP32(grfid));
6754 _cur.grffile->grfid = grfid;
6755 }
6756
6757 _cur.grffile->grf_version = version;
6758 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6759
6760 /* Do swap the GRFID for displaying purposes since people expect that */
6761 DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s, version: %i)", version, BSWAP32(grfid), name, (_cur.grfconfig->palette & GRFP_USE_MASK) ? "Windows" : "DOS", _cur.grfconfig->version);
6762 }
6763
6764 /* Action 0x0A */
6765 static void SpriteReplace(ByteReader *buf)
6766 {
6767 /* <0A> <num-sets> <set1> [<set2> ...]
6768 * <set>: <num-sprites> <first-sprite>
6769 *
6770 * B num-sets How many sets of sprites to replace.
6771 * Each set:
6772 * B num-sprites How many sprites are in this set
6773 * W first-sprite First sprite number to replace */
6774
6775 uint8 num_sets = buf->ReadByte();
6776
6777 for (uint i = 0; i < num_sets; i++) {
6778 uint8 num_sprites = buf->ReadByte();
6779 uint16 first_sprite = buf->ReadWord();
6780
6781 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6782 i, num_sprites, first_sprite
6783 );
6784
6785 for (uint j = 0; j < num_sprites; j++) {
6786 int load_index = first_sprite + j;
6787 _cur.nfo_line++;
6788 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6789
6790 /* Shore sprites now located at different addresses.
6791 * So detect when the old ones get replaced. */
6792 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6793 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
6794 }
6795 }
6796 }
6797 }
6798
6799 /* Action 0x0A (SKIP) */
6800 static void SkipActA(ByteReader *buf)
6801 {
6802 uint8 num_sets = buf->ReadByte();
6803
6804 for (uint i = 0; i < num_sets; i++) {
6805 /* Skip the sprites this replaces */
6806 _cur.skip_sprites += buf->ReadByte();
6807 /* But ignore where they go */
6808 buf->ReadWord();
6809 }
6810
6811 grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
6812 }
6813
6814 /* Action 0x0B */
6815 static void GRFLoadError(ByteReader *buf)
6816 {
6817 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6818 *
6819 * B severity 00: notice, continue loading grf file
6820 * 01: warning, continue loading grf file
6821 * 02: error, but continue loading grf file, and attempt
6822 * loading grf again when loading or starting next game
6823 * 03: error, abort loading and prevent loading again in
6824 * the future (only when restarting the patch)
6825 * B language-id see action 4, use 1F for built-in error messages
6826 * B message-id message to show, see below
6827 * S message for custom messages (message-id FF), text of the message
6828 * not present for built-in messages.
6829 * V data additional data for built-in (or custom) messages
6830 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6831
6832 static const StringID msgstr[] = {
6833 STR_NEWGRF_ERROR_VERSION_NUMBER,
6834 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6835 STR_NEWGRF_ERROR_UNSET_SWITCH,
6836 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6837 STR_NEWGRF_ERROR_LOAD_BEFORE,
6838 STR_NEWGRF_ERROR_LOAD_AFTER,
6839 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6840 };
6841
6842 static const StringID sevstr[] = {
6843 STR_NEWGRF_ERROR_MSG_INFO,
6844 STR_NEWGRF_ERROR_MSG_WARNING,
6845 STR_NEWGRF_ERROR_MSG_ERROR,
6846 STR_NEWGRF_ERROR_MSG_FATAL
6847 };
6848
6849 byte severity = buf->ReadByte();
6850 byte lang = buf->ReadByte();
6851 byte message_id = buf->ReadByte();
6852
6853 /* Skip the error if it isn't valid for the current language. */
6854 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
6855
6856 /* Skip the error until the activation stage unless bit 7 of the severity
6857 * is set. */
6858 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6859 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6860 return;
6861 }
6862 ClrBit(severity, 7);
6863
6864 if (severity >= lengthof(sevstr)) {
6865 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6866 severity = 2;
6867 } else if (severity == 3) {
6868 /* This is a fatal error, so make sure the GRF is deactivated and no
6869 * more of it gets loaded. */
6870 DisableGrf();
6871
6872 /* Make sure we show fatal errors, instead of silly infos from before */
6873 delete _cur.grfconfig->error;
6874 _cur.grfconfig->error = nullptr;
6875 }
6876
6877 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6878 grfmsg(7, "GRFLoadError: Invalid message id.");
6879 return;
6880 }
6881
6882 if (buf->Remaining() <= 1) {
6883 grfmsg(7, "GRFLoadError: No message data supplied.");
6884 return;
6885 }
6886
6887 /* For now we can only show one message per newgrf file. */
6888 if (_cur.grfconfig->error != nullptr) return;
6889
6890 GRFError *error = new GRFError(sevstr[severity]);
6891
6892 if (message_id == 0xFF) {
6893 /* This is a custom error message. */
6894 if (buf->HasData()) {
6895 const char *message = buf->ReadString();
6896
6897 error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, SCC_RAW_STRING_POINTER);
6898 } else {
6899 grfmsg(7, "GRFLoadError: No custom message supplied.");
6900 error->custom_message.clear();
6901 }
6902 } else {
6903 error->message = msgstr[message_id];
6904 }
6905
6906 if (buf->HasData()) {
6907 const char *data = buf->ReadString();
6908
6909 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6910 } else {
6911 grfmsg(7, "GRFLoadError: No message data supplied.");
6912 error->data.clear();
6913 }
6914
6915 /* Only two parameter numbers can be used in the string. */
6916 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6917 uint param_number = buf->ReadByte();
6918 error->param_value[i] = _cur.grffile->GetParam(param_number);
6919 }
6920
6921 _cur.grfconfig->error = error;
6922 }
6923
6924 /* Action 0x0C */
6925 static void GRFComment(ByteReader *buf)
6926 {
6927 /* <0C> [<ignored...>]
6928 *
6929 * V ignored Anything following the 0C is ignored */
6930
6931 if (!buf->HasData()) return;
6932
6933 const char *text = buf->ReadString();
6934 grfmsg(2, "GRFComment: %s", text);
6935 }
6936
6937 /* Action 0x0D (GLS_SAFETYSCAN) */
6938 static void SafeParamSet(ByteReader *buf)
6939 {
6940 uint8 target = buf->ReadByte();
6941
6942 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6943 if (target < 0x80 || target == 0x9E) return;
6944
6945 /* GRM could be unsafe, but as here it can only happen after other GRFs
6946 * are loaded, it should be okay. If the GRF tried to use the slots it
6947 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6948 * sprites is considered safe. */
6949
6950 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6951
6952 /* Skip remainder of GRF */
6953 _cur.skip_sprites = -1;
6954 }
6955
6956
6957 static uint32 GetPatchVariable(uint8 param)
6958 {
6959 switch (param) {
6960 /* start year - 1920 */
6961 case 0x0B: return std::max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
6962
6963 /* freight trains weight factor */
6964 case 0x0E: return _settings_game.vehicle.freight_trains;
6965
6966 /* empty wagon speed increase */
6967 case 0x0F: return 0;
6968
6969 /* plane speed factor; our patch option is reversed from TTDPatch's,
6970 * the following is good for 1x, 2x and 4x (most common?) and...
6971 * well not really for 3x. */
6972 case 0x10:
6973 switch (_settings_game.vehicle.plane_speed) {
6974 default:
6975 case 4: return 1;
6976 case 3: return 2;
6977 case 2: return 2;
6978 case 1: return 4;
6979 }
6980
6981
6982 /* 2CC colourmap base sprite */
6983 case 0x11: return SPR_2CCMAP_BASE;
6984
6985 /* map size: format = -MABXYSS
6986 * M : the type of map
6987 * bit 0 : set : squared map. Bit 1 is now not relevant
6988 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6989 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6990 * clear : X is the bigger edge.
6991 * A : minimum edge(log2) of the map
6992 * B : maximum edge(log2) of the map
6993 * XY : edges(log2) of each side of the map.
6994 * SS : combination of both X and Y, thus giving the size(log2) of the map
6995 */
6996 case 0x13: {
6997 byte map_bits = 0;
6998 byte log_X = MapLogX() - 6; // subtraction is required to make the minimal size (64) zero based
6999 byte log_Y = MapLogY() - 6;
7000 byte max_edge = std::max(log_X, log_Y);
7001
7002 if (log_X == log_Y) { // we have a squared map, since both edges are identical
7003 SetBit(map_bits, 0);
7004 } else {
7005 if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
7006 }
7007
7008 return (map_bits << 24) | (std::min(log_X, log_Y) << 20) | (max_edge << 16) |
7009 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
7010 }
7011
7012 /* The maximum height of the map. */
7013 case 0x14:
7014 return _settings_game.construction.max_heightlevel;
7015
7016 /* Extra foundations base sprite */
7017 case 0x15:
7018 return SPR_SLOPES_BASE;
7019
7020 /* Shore base sprite */
7021 case 0x16:
7022 return SPR_SHORE_BASE;
7023
7024 default:
7025 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
7026 return 0;
7027 }
7028 }
7029
7030
7031 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
7032 {
7033 uint start = 0;
7034 uint size = 0;
7035
7036 if (op == 6) {
7037 /* Return GRFID of set that reserved ID */
7038 return grm[_cur.grffile->GetParam(target)];
7039 }
7040
7041 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
7042 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
7043
7044 for (uint i = start; i < num_ids; i++) {
7045 if (grm[i] == 0) {
7046 size++;
7047 } else {
7048 if (op == 2 || op == 3) break;
7049 start = i + 1;
7050 size = 0;
7051 }
7052
7053 if (size == count) break;
7054 }
7055
7056 if (size == count) {
7057 /* Got the slot... */
7058 if (op == 0 || op == 3) {
7059 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
7060 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
7061 }
7062 return start;
7063 }
7064
7065 /* Unable to allocate */
7066 if (op != 4 && op != 5) {
7067 /* Deactivate GRF */
7068 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
7069 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
7070 return UINT_MAX;
7071 }
7072
7073 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
7074 return UINT_MAX;
7075 }
7076
7077
7079 static void ParamSet(ByteReader *buf)
7080 {
7081 /* <0D> <target> <operation> <source1> <source2> [<data>]
7082 *
7083 * B target parameter number where result is stored
7084 * B operation operation to perform, see below
7085 * B source1 first source operand
7086 * B source2 second source operand
7087 * D data data to use in the calculation, not necessary
7088 * if both source1 and source2 refer to actual parameters
7089 *
7090 * Operations
7091 * 00 Set parameter equal to source1
7092 * 01 Addition, source1 + source2
7093 * 02 Subtraction, source1 - source2
7094 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
7095 * 04 Signed multiplication, source1 * source2 (both signed)
7096 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
7097 * signed quantity; left shift if positive and right shift if
7098 * negative, source1 is unsigned)
7099 * 06 Signed bit shift, source1 by source2
7100 * (source2 like in 05, and source1 as well)
7101 */
7102
7103 uint8 target = buf->ReadByte();
7104 uint8 oper = buf->ReadByte();
7105 uint32 src1 = buf->ReadByte();
7106 uint32 src2 = buf->ReadByte();
7107
7108 uint32 data = 0;
7109 if (buf->Remaining() >= 4) data = buf->ReadDWord();
7110
7111 /* You can add 80 to the operation to make it apply only if the target
7112 * is not defined yet. In this respect, a parameter is taken to be
7113 * defined if any of the following applies:
7114 * - it has been set to any value in the newgrf(w).cfg parameter list
7115 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
7116 * an earlier action D */
7117 if (HasBit(oper, 7)) {
7118 if (target < 0x80 && target < _cur.grffile->param_end) {
7119 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
7120 return;
7121 }
7122
7123 oper = GB(oper, 0, 7);
7124 }
7125
7126 if (src2 == 0xFE) {
7127 if (GB(data, 0, 8) == 0xFF) {
7128 if (data == 0x0000FFFF) {
7129 /* Patch variables */
7130 src1 = GetPatchVariable(src1);
7131 } else {
7132 /* GRF Resource Management */
7133 uint8 op = src1;
7134 uint8 feature = GB(data, 8, 8);
7135 uint16 count = GB(data, 16, 16);
7136
7137 if (_cur.stage == GLS_RESERVE) {
7138 if (feature == 0x08) {
7139 /* General sprites */
7140 if (op == 0) {
7141 /* Check if the allocated sprites will fit below the original sprite limit */
7142 if (_cur.spriteid + count >= 16384) {
7143 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
7144 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
7145 return;
7146 }
7147
7148 /* Reserve space at the current sprite ID */
7149 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
7150 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
7151 _cur.spriteid += count;
7152 }
7153 }
7154 /* Ignore GRM result during reservation */
7155 src1 = 0;
7156 } else if (_cur.stage == GLS_ACTIVATION) {
7157 switch (feature) {
7158 case 0x00: // Trains
7159 case 0x01: // Road Vehicles
7160 case 0x02: // Ships
7161 case 0x03: // Aircraft
7162 if (!_settings_game.vehicle.dynamic_engines) {
7163 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
7164 if (_cur.skip_sprites == -1) return;
7165 } else {
7166 /* GRM does not apply for dynamic engine allocation. */
7167 switch (op) {
7168 case 2:
7169 case 3:
7170 src1 = _cur.grffile->GetParam(target);
7171 break;
7172
7173 default:
7174 src1 = 0;
7175 break;
7176 }
7177 }
7178 break;
7179
7180 case 0x08: // General sprites
7181 switch (op) {
7182 case 0:
7183 /* Return space reserved during reservation stage */
7184 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
7185 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
7186 break;
7187
7188 case 1:
7189 src1 = _cur.spriteid;
7190 break;
7191
7192 default:
7193 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
7194 return;
7195 }
7196 break;
7197
7198 case 0x0B: // Cargo
7199 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
7200 src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
7201 if (_cur.skip_sprites == -1) return;
7202 break;
7203
7204 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
7205 }
7206 } else {
7207 /* Ignore GRM during initialization */
7208 src1 = 0;
7209 }
7210 }
7211 } else {
7212 /* Read another GRF File's parameter */
7213 const GRFFile *file = GetFileByGRFID(data);
7214 GRFConfig *c = GetGRFConfig(data);
7215 if (c != nullptr && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
7216 /* Disable the read GRF if it is a static NewGRF. */
7217 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
7218 src1 = 0;
7219 } else if (file == nullptr || c == nullptr || c->status == GCS_DISABLED) {
7220 src1 = 0;
7221 } else if (src1 == 0xFE) {
7222 src1 = c->version;
7223 } else {
7224 src1 = file->GetParam(src1);
7225 }
7226 }
7227 } else {
7228 /* The source1 and source2 operands refer to the grf parameter number
7229 * like in action 6 and 7. In addition, they can refer to the special
7230 * variables available in action 7, or they can be FF to use the value
7231 * of <data>. If referring to parameters that are undefined, a value
7232 * of 0 is used instead. */
7233 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, nullptr);
7234 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, nullptr);
7235 }
7236
7237 uint32 res;
7238 switch (oper) {
7239 case 0x00:
7240 res = src1;
7241 break;
7242
7243 case 0x01:
7244 res = src1 + src2;
7245 break;
7246
7247 case 0x02:
7248 res = src1 - src2;
7249 break;
7250
7251 case 0x03:
7252 res = src1 * src2;
7253 break;
7254
7255 case 0x04:
7256 res = (int32)src1 * (int32)src2;
7257 break;
7258
7259 case 0x05:
7260 if ((int32)src2 < 0) {
7261 res = src1 >> -(int32)src2;
7262 } else {
7263 res = src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
7264 }
7265 break;
7266
7267 case 0x06:
7268 if ((int32)src2 < 0) {
7269 res = (int32)src1 >> -(int32)src2;
7270 } else {
7271 res = (int32)src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
7272 }
7273 break;
7274
7275 case 0x07: // Bitwise AND
7276 res = src1 & src2;
7277 break;
7278
7279 case 0x08: // Bitwise OR
7280 res = src1 | src2;
7281 break;
7282
7283 case 0x09: // Unsigned division
7284 if (src2 == 0) {
7285 res = src1;
7286 } else {
7287 res = src1 / src2;
7288 }
7289 break;
7290
7291 case 0x0A: // Signed division
7292 if (src2 == 0) {
7293 res = src1;
7294 } else {
7295 res = (int32)src1 / (int32)src2;
7296 }
7297 break;
7298
7299 case 0x0B: // Unsigned modulo
7300 if (src2 == 0) {
7301 res = src1;
7302 } else {
7303 res = src1 % src2;
7304 }
7305 break;
7306
7307 case 0x0C: // Signed modulo
7308 if (src2 == 0) {
7309 res = src1;
7310 } else {
7311 res = (int32)src1 % (int32)src2;
7312 }
7313 break;
7314
7315 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
7316 }
7317
7318 switch (target) {
7319 case 0x8E: // Y-Offset for train sprites
7320 _cur.grffile->traininfo_vehicle_pitch = res;
7321 break;
7322
7323 case 0x8F: { // Rail track type cost factors
7324 extern RailtypeInfo _railtypes[RAILTYPE_END];
7325 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
7326 if (_settings_game.vehicle.disable_elrails) {
7327 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
7328 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
7329 } else {
7330 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
7331 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
7332 }
7333 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
7334 break;
7335 }
7336
7337 /* not implemented */
7338 case 0x93: // Tile refresh offset to left -- Intended to allow support for larger sprites, not necessary for OTTD
7339 case 0x94: // Tile refresh offset to right
7340 case 0x95: // Tile refresh offset upwards
7341 case 0x96: // Tile refresh offset downwards
7342 case 0x97: // Snow line height -- Better supported by feature 8 property 10h (snow line table) TODO: implement by filling the entire snow line table with the given value
7343 case 0x99: // Global ID offset -- Not necessary since IDs are remapped automatically
7344 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
7345 break;
7346
7347 case 0x9E: // Miscellaneous GRF features
7348 /* Set train list engine width */
7349 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
7350 /* Remove the local flags from the global flags */
7351 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
7352
7353 /* Only copy safe bits for static grfs */
7354 if (HasBit(_cur.grfconfig->flags, GCF_STATIC)) {
7355 uint32 safe_bits = 0;
7356 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
7357
7358 _misc_grf_features = (_misc_grf_features & ~safe_bits) | (res & safe_bits);
7359 } else {
7360 _misc_grf_features = res;
7361 }
7362 break;
7363
7364 case 0x9F: // locale-dependent settings
7365 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
7366 break;
7367
7368 default:
7369 if (target < 0x80) {
7370 _cur.grffile->param[target] = res;
7371 /* param is zeroed by default */
7372 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
7373 } else {
7374 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
7375 }
7376 break;
7377 }
7378 }
7379
7380 /* Action 0x0E (GLS_SAFETYSCAN) */
7381 static void SafeGRFInhibit(ByteReader *buf)
7382 {
7383 /* <0E> <num> <grfids...>
7384 *
7385 * B num Number of GRFIDs that follow
7386 * D grfids GRFIDs of the files to deactivate */
7387
7388 uint8 num = buf->ReadByte();
7389
7390 for (uint i = 0; i < num; i++) {
7391 uint32 grfid = buf->ReadDWord();
7392
7393 /* GRF is unsafe it if tries to deactivate other GRFs */
7394 if (grfid != _cur.grfconfig->ident.grfid) {
7395 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7396
7397 /* Skip remainder of GRF */
7398 _cur.skip_sprites = -1;
7399
7400 return;
7401 }
7402 }
7403 }
7404
7405 /* Action 0x0E */
7406 static void GRFInhibit(ByteReader *buf)
7407 {
7408 /* <0E> <num> <grfids...>
7409 *
7410 * B num Number of GRFIDs that follow
7411 * D grfids GRFIDs of the files to deactivate */
7412
7413 uint8 num = buf->ReadByte();
7414
7415 for (uint i = 0; i < num; i++) {
7416 uint32 grfid = buf->ReadDWord();
7417 GRFConfig *file = GetGRFConfig(grfid);
7418
7419 /* Unset activation flag */
7420 if (file != nullptr && file != _cur.grfconfig) {
7421 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
7422 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
7423 error->data = stredup(_cur.grfconfig->GetName());
7424 }
7425 }
7426 }
7427
7429 static void FeatureTownName(ByteReader *buf)
7430 {
7431 /* <0F> <id> <style-name> <num-parts> <parts>
7432 *
7433 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
7434 * V style-name Name of the style (only for final definition)
7435 * B num-parts Number of parts in this definition
7436 * V parts The parts */
7437
7438 uint32 grfid = _cur.grffile->grfid;
7439
7440 GRFTownName *townname = AddGRFTownName(grfid);
7441
7442 byte id = buf->ReadByte();
7443 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
7444
7445 if (HasBit(id, 7)) {
7446 /* Final definition */
7447 ClrBit(id, 7);
7448 bool new_scheme = _cur.grffile->grf_version >= 7;
7449
7450 byte lang = buf->ReadByte();
7451
7452 byte nb_gen = townname->nb_gen;
7453 do {
7454 ClrBit(lang, 7);
7455
7456 const char *name = buf->ReadString();
7457
7458 std::string lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
7459 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name.c_str());
7460
7461 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
7462
7463 lang = buf->ReadByte();
7464 } while (lang != 0);
7465 townname->id[nb_gen] = id;
7466 townname->nb_gen++;
7467 }
7468
7469 byte nb = buf->ReadByte();
7470 grfmsg(6, "FeatureTownName: %u parts", nb);
7471
7472 townname->nbparts[id] = nb;
7473 townname->partlist[id] = CallocT<NamePartList>(nb);
7474
7475 for (int i = 0; i < nb; i++) {
7476 byte nbtext = buf->ReadByte();
7477 townname->partlist[id][i].bitstart = buf->ReadByte();
7478 townname->partlist[id][i].bitcount = buf->ReadByte();
7479 townname->partlist[id][i].maxprob = 0;
7480 townname->partlist[id][i].partcount = nbtext;
7481 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
7482 grfmsg(6, "FeatureTownName: part %d contains %d texts and will use GB(seed, %d, %d)", i, nbtext, townname->partlist[id][i].bitstart, townname->partlist[id][i].bitcount);
7483
7484 for (int j = 0; j < nbtext; j++) {
7485 byte prob = buf->ReadByte();
7486
7487 if (HasBit(prob, 7)) {
7488 byte ref_id = buf->ReadByte();
7489
7490 if (townname->nbparts[ref_id] == 0) {
7491 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7492 DelGRFTownName(grfid);
7493 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
7494 return;
7495 }
7496
7497 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7498 townname->partlist[id][i].parts[j].data.id = ref_id;
7499 } else {
7500 const char *text = buf->ReadString();
7501 townname->partlist[id][i].parts[j].data.text = stredup(TranslateTTDPatchCodes(grfid, 0, false, text).c_str());
7502 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
7503 }
7504 townname->partlist[id][i].parts[j].prob = prob;
7505 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
7506 }
7507 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
7508 }
7509 }
7510
7512 static void DefineGotoLabel(ByteReader *buf)
7513 {
7514 /* <10> <label> [<comment>]
7515 *
7516 * B label The label to define
7517 * V comment Optional comment - ignored */
7518
7519 byte nfo_label = buf->ReadByte();
7520
7521 GRFLabel *label = MallocT<GRFLabel>(1);
7522 label->label = nfo_label;
7523 label->nfo_line = _cur.nfo_line;
7524 label->pos = FioGetPos();
7525 label->next = nullptr;
7526
7527 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7528 if (_cur.grffile->label == nullptr) {
7529 _cur.grffile->label = label;
7530 } else {
7531 /* Attach the label to the end of the list */
7532 GRFLabel *l;
7533 for (l = _cur.grffile->label; l->next != nullptr; l = l->next) {}
7534 l->next = label;
7535 }
7536
7537 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7538 }
7539
7544 static void ImportGRFSound(SoundEntry *sound)
7545 {
7546 const GRFFile *file;
7547 uint32 grfid = FioReadDword();
7548 SoundID sound_id = FioReadWord();
7549
7550 file = GetFileByGRFID(grfid);
7551 if (file == nullptr || file->sound_offset == 0) {
7552 grfmsg(1, "ImportGRFSound: Source file not available");
7553 return;
7554 }
7555
7556 if (sound_id >= file->num_sounds) {
7557 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
7558 return;
7559 }
7560
7561 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7562
7563 *sound = *GetSound(file->sound_offset + sound_id);
7564
7565 /* Reset volume and priority, which TTDPatch doesn't copy */
7566 sound->volume = 128;
7567 sound->priority = 0;
7568 }
7569
7575 static void LoadGRFSound(size_t offs, SoundEntry *sound)
7576 {
7577 /* Set default volume and priority */
7578 sound->volume = 0x80;
7579 sound->priority = 0;
7580
7581 if (offs != SIZE_MAX) {
7582 /* Sound is present in the NewGRF. */
7583 sound->file_slot = _cur.file_index;
7584 sound->file_offset = offs;
7585 sound->grf_container_ver = _cur.grf_container_ver;
7586 }
7587 }
7588
7589 /* Action 0x11 */
7590 static void GRFSound(ByteReader *buf)
7591 {
7592 /* <11> <num>
7593 *
7594 * W num Number of sound files that follow */
7595
7596 uint16 num = buf->ReadWord();
7597 if (num == 0) return;
7598
7599 SoundEntry *sound;
7600 if (_cur.grffile->sound_offset == 0) {
7601 _cur.grffile->sound_offset = GetNumSounds();
7602 _cur.grffile->num_sounds = num;
7603 sound = AllocateSound(num);
7604 } else {
7605 sound = GetSound(_cur.grffile->sound_offset);
7606 }
7607
7608 for (int i = 0; i < num; i++) {
7609 _cur.nfo_line++;
7610
7611 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7612 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7613 bool invalid = i >= _cur.grffile->num_sounds;
7614
7615 size_t offs = FioGetPos();
7616
7617 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7618 byte type = FioReadByte();
7619
7620 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7621 /* Reference to sprite section. */
7622 if (invalid) {
7623 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7624 FioSkipBytes(len);
7625 } else if (len != 4) {
7626 grfmsg(1, "GRFSound: Invalid sprite section import");
7627 FioSkipBytes(len);
7628 } else {
7629 uint32 id = FioReadDword();
7630 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7631 }
7632 continue;
7633 }
7634
7635 if (type != 0xFF) {
7636 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7637 FioSkipBytes(7);
7638 SkipSpriteData(type, len - 8);
7639 continue;
7640 }
7641
7642 if (invalid) {
7643 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7644 FioSkipBytes(len);
7645 }
7646
7647 byte action = FioReadByte();
7648 switch (action) {
7649 case 0xFF:
7650 /* Allocate sound only in init stage. */
7651 if (_cur.stage == GLS_INIT) {
7652 if (_cur.grf_container_ver >= 2) {
7653 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7654 } else {
7655 LoadGRFSound(offs, sound + i);
7656 }
7657 }
7658 FioSkipBytes(len - 1); // already read <action>
7659 break;
7660
7661 case 0xFE:
7662 if (_cur.stage == GLS_ACTIVATION) {
7663 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7664 * importing sounds, so this is probably all wrong... */
7665 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7666 ImportGRFSound(sound + i);
7667 } else {
7668 FioSkipBytes(len - 1); // already read <action>
7669 }
7670 break;
7671
7672 default:
7673 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7674 FioSkipBytes(len - 1); // already read <action>
7675 break;
7676 }
7677 }
7678 }
7679
7680 /* Action 0x11 (SKIP) */
7681 static void SkipAct11(ByteReader *buf)
7682 {
7683 /* <11> <num>
7684 *
7685 * W num Number of sound files that follow */
7686
7687 _cur.skip_sprites = buf->ReadWord();
7688
7689 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
7690 }
7691
7693 static void LoadFontGlyph(ByteReader *buf)
7694 {
7695 /* <12> <num_def> <font_size> <num_char> <base_char>
7696 *
7697 * B num_def Number of definitions
7698 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7699 * B num_char Number of consecutive glyphs
7700 * W base_char First character index */
7701
7702 uint8 num_def = buf->ReadByte();
7703
7704 for (uint i = 0; i < num_def; i++) {
7705 FontSize size = (FontSize)buf->ReadByte();
7706 uint8 num_char = buf->ReadByte();
7707 uint16 base_char = buf->ReadWord();
7708
7709 if (size >= FS_END) {
7710 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7711 }
7712
7713 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7714
7715 for (uint c = 0; c < num_char; c++) {
7716 if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
7717 _cur.nfo_line++;
7718 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7719 }
7720 }
7721 }
7722
7724 static void SkipAct12(ByteReader *buf)
7725 {
7726 /* <12> <num_def> <font_size> <num_char> <base_char>
7727 *
7728 * B num_def Number of definitions
7729 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7730 * B num_char Number of consecutive glyphs
7731 * W base_char First character index */
7732
7733 uint8 num_def = buf->ReadByte();
7734
7735 for (uint i = 0; i < num_def; i++) {
7736 /* Ignore 'size' byte */
7737 buf->ReadByte();
7738
7739 /* Sum up number of characters */
7740 _cur.skip_sprites += buf->ReadByte();
7741
7742 /* Ignore 'base_char' word */
7743 buf->ReadWord();
7744 }
7745
7746 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
7747 }
7748
7750 static void TranslateGRFStrings(ByteReader *buf)
7751 {
7752 /* <13> <grfid> <num-ent> <offset> <text...>
7753 *
7754 * 4*B grfid The GRFID of the file whose texts are to be translated
7755 * B num-ent Number of strings
7756 * W offset First text ID
7757 * S text... Zero-terminated strings */
7758
7759 uint32 grfid = buf->ReadDWord();
7760 const GRFConfig *c = GetGRFConfig(grfid);
7761 if (c == nullptr || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7762 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7763 return;
7764 }
7765
7766 if (c->status == GCS_INITIALISED) {
7767 /* If the file is not active but will be activated later, give an error
7768 * and disable this file. */
7769 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
7770
7771 char tmp[256];
7772 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
7773 error->data = tmp;
7774
7775 return;
7776 }
7777
7778 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7779 * to be added as a generic string, thus the language id of 0x7F. For this to work
7780 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7781 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7782 * not change anything if a string has been provided specifically for this language. */
7783 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7784 byte num_strings = buf->ReadByte();
7785 uint16 first_id = buf->ReadWord();
7786
7787 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7788 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7789 return;
7790 }
7791
7792 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7793 const char *string = buf->ReadString();
7794
7795 if (StrEmpty(string)) {
7796 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7797 continue;
7798 }
7799
7800 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7801 }
7802 }
7803
7805 static bool ChangeGRFName(byte langid, const char *str)
7806 {
7807 AddGRFTextToList(_cur.grfconfig->name, langid, _cur.grfconfig->ident.grfid, false, str);
7808 return true;
7809 }
7810
7812 static bool ChangeGRFDescription(byte langid, const char *str)
7813 {
7814 AddGRFTextToList(_cur.grfconfig->info, langid, _cur.grfconfig->ident.grfid, true, str);
7815 return true;
7816 }
7817
7819 static bool ChangeGRFURL(byte langid, const char *str)
7820 {
7821 AddGRFTextToList(_cur.grfconfig->url, langid, _cur.grfconfig->ident.grfid, false, str);
7822 return true;
7823 }
7824
7826 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7827 {
7828 if (len != 1) {
7829 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7830 buf->Skip(len);
7831 } else {
7832 _cur.grfconfig->num_valid_params = std::min<byte>(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7833 }
7834 return true;
7835 }
7836
7838 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7839 {
7840 if (len != 1) {
7841 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7842 buf->Skip(len);
7843 } else {
7844 char data = buf->ReadByte();
7845 GRFPalette pal = GRFP_GRF_UNSET;
7846 switch (data) {
7847 case '*':
7848 case 'A': pal = GRFP_GRF_ANY; break;
7849 case 'W': pal = GRFP_GRF_WINDOWS; break;
7850 case 'D': pal = GRFP_GRF_DOS; break;
7851 default:
7852 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7853 break;
7854 }
7855 if (pal != GRFP_GRF_UNSET) {
7856 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7857 _cur.grfconfig->palette |= pal;
7858 }
7859 }
7860 return true;
7861 }
7862
7864 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7865 {
7866 if (len != 1) {
7867 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7868 buf->Skip(len);
7869 } else {
7870 char data = buf->ReadByte();
7871 GRFPalette pal = GRFP_BLT_UNSET;
7872 switch (data) {
7873 case '8': pal = GRFP_BLT_UNSET; break;
7874 case '3': pal = GRFP_BLT_32BPP; break;
7875 default:
7876 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7877 return true;
7878 }
7879 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7880 _cur.grfconfig->palette |= pal;
7881 }
7882 return true;
7883 }
7884
7886 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7887 {
7888 if (len != 4) {
7889 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7890 buf->Skip(len);
7891 } else {
7892 /* Set min_loadable_version as well (default to minimal compatibility) */
7893 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7894 }
7895 return true;
7896 }
7897
7899 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7900 {
7901 if (len != 4) {
7902 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7903 buf->Skip(len);
7904 } else {
7905 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7906 if (_cur.grfconfig->version == 0) {
7907 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7908 _cur.grfconfig->min_loadable_version = 0;
7909 }
7910 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7911 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7912 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
7913 }
7914 }
7915 return true;
7916 }
7917
7918 static GRFParameterInfo *_cur_parameter;
7919
7921 static bool ChangeGRFParamName(byte langid, const char *str)
7922 {
7923 AddGRFTextToList(_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
7924 return true;
7925 }
7926
7928 static bool ChangeGRFParamDescription(byte langid, const char *str)
7929 {
7930 AddGRFTextToList(_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
7931 return true;
7932 }
7933
7935 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7936 {
7937 if (len != 1) {
7938 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7939 buf->Skip(len);
7940 } else {
7941 GRFParameterType type = (GRFParameterType)buf->ReadByte();
7942 if (type < PTYPE_END) {
7943 _cur_parameter->type = type;
7944 } else {
7945 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7946 }
7947 }
7948 return true;
7949 }
7950
7952 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7953 {
7954 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7955 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7956 buf->Skip(len);
7957 } else if (len != 8) {
7958 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7959 buf->Skip(len);
7960 } else {
7961 uint32 min_value = buf->ReadDWord();
7962 uint32 max_value = buf->ReadDWord();
7963 if (min_value <= max_value) {
7964 _cur_parameter->min_value = min_value;
7965 _cur_parameter->max_value = max_value;
7966 } else {
7967 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field");
7968 }
7969 }
7970 return true;
7971 }
7972
7974 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7975 {
7976 if (len < 1 || len > 3) {
7977 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7978 buf->Skip(len);
7979 } else {
7980 byte param_nr = buf->ReadByte();
7981 if (param_nr >= lengthof(_cur.grfconfig->param)) {
7982 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7983 buf->Skip(len - 1);
7984 } else {
7985 _cur_parameter->param_nr = param_nr;
7986 if (len >= 2) _cur_parameter->first_bit = std::min<byte>(buf->ReadByte(), 31);
7987 if (len >= 3) _cur_parameter->num_bit = std::min<byte>(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7988 }
7989 }
7990
7991 return true;
7992 }
7993
7995 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7996 {
7997 if (len != 4) {
7998 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7999 buf->Skip(len);
8000 } else {
8001 _cur_parameter->def_value = buf->ReadDWord();
8002 }
8003 _cur.grfconfig->has_param_defaults = true;
8004 return true;
8005 }
8006
8007 typedef bool (*DataHandler)(size_t, ByteReader *);
8008 typedef bool (*TextHandler)(byte, const char *str);
8009 typedef bool (*BranchHandler)(ByteReader *);
8010
8018 struct AllowedSubtags {
8020 AllowedSubtags() :
8021 id(0),
8022 type(0)
8023 {}
8024
8030 AllowedSubtags(uint32 id, DataHandler handler) :
8031 id(id),
8032 type('B')
8033 {
8034 this->handler.data = handler;
8035 }
8036
8042 AllowedSubtags(uint32 id, TextHandler handler) :
8043 id(id),
8044 type('T')
8045 {
8046 this->handler.text = handler;
8047 }
8048
8054 AllowedSubtags(uint32 id, BranchHandler handler) :
8055 id(id),
8056 type('C')
8057 {
8058 this->handler.call_handler = true;
8059 this->handler.u.branch = handler;
8060 }
8061
8067 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
8068 id(id),
8069 type('C')
8070 {
8071 this->handler.call_handler = false;
8072 this->handler.u.subtags = subtags;
8073 }
8074
8075 uint32 id;
8076 byte type;
8077 union {
8078 DataHandler data;
8079 TextHandler text;
8080 struct {
8081 union {
8082 BranchHandler branch;
8083 AllowedSubtags *subtags;
8084 } u;
8085 bool call_handler;
8086 };
8087 } handler;
8088 };
8089
8090 static bool SkipUnknownInfo(ByteReader *buf, byte type);
8091 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
8092
8099 static bool ChangeGRFParamValueNames(ByteReader *buf)
8100 {
8101 byte type = buf->ReadByte();
8102 while (type != 0) {
8103 uint32 id = buf->ReadDWord();
8104 if (type != 'T' || id > _cur_parameter->max_value) {
8105 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
8106 if (!SkipUnknownInfo(buf, type)) return false;
8107 type = buf->ReadByte();
8108 continue;
8109 }
8110
8111 byte langid = buf->ReadByte();
8112 const char *name_string = buf->ReadString();
8113
8114 std::pair<uint32, GRFTextList> *val_name = _cur_parameter->value_names.Find(id);
8115 if (val_name != _cur_parameter->value_names.End()) {
8116 AddGRFTextToList(val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
8117 } else {
8118 GRFTextList list;
8119 AddGRFTextToList(list, langid, _cur.grfconfig->ident.grfid, false, name_string);
8120 _cur_parameter->value_names.Insert(id, list);
8121 }
8122
8123 type = buf->ReadByte();
8124 }
8125 return true;
8126 }
8127
8129 AllowedSubtags _tags_parameters[] = {
8130 AllowedSubtags('NAME', ChangeGRFParamName),
8131 AllowedSubtags('DESC', ChangeGRFParamDescription),
8132 AllowedSubtags('TYPE', ChangeGRFParamType),
8133 AllowedSubtags('LIMI', ChangeGRFParamLimits),
8134 AllowedSubtags('MASK', ChangeGRFParamMask),
8135 AllowedSubtags('VALU', ChangeGRFParamValueNames),
8136 AllowedSubtags('DFLT', ChangeGRFParamDefault),
8137 AllowedSubtags()
8138 };
8139
8146 static bool HandleParameterInfo(ByteReader *buf)
8147 {
8148 byte type = buf->ReadByte();
8149 while (type != 0) {
8150 uint32 id = buf->ReadDWord();
8151 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
8152 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
8153 if (!SkipUnknownInfo(buf, type)) return false;
8154 type = buf->ReadByte();
8155 continue;
8156 }
8157
8158 if (id >= _cur.grfconfig->param_info.size()) {
8159 _cur.grfconfig->param_info.resize(id + 1);
8160 }
8161 if (_cur.grfconfig->param_info[id] == nullptr) {
8162 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
8163 }
8164 _cur_parameter = _cur.grfconfig->param_info[id];
8165 /* Read all parameter-data and process each node. */
8166 if (!HandleNodes(buf, _tags_parameters)) return false;
8167 type = buf->ReadByte();
8168 }
8169 return true;
8170 }
8171
8173 AllowedSubtags _tags_info[] = {
8174 AllowedSubtags('NAME', ChangeGRFName),
8175 AllowedSubtags('DESC', ChangeGRFDescription),
8176 AllowedSubtags('URL_', ChangeGRFURL),
8177 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
8178 AllowedSubtags('PALS', ChangeGRFPalette),
8179 AllowedSubtags('BLTR', ChangeGRFBlitter),
8180 AllowedSubtags('VRSN', ChangeGRFVersion),
8181 AllowedSubtags('MINV', ChangeGRFMinVersion),
8182 AllowedSubtags('PARA', HandleParameterInfo),
8183 AllowedSubtags()
8184 };
8185
8187 AllowedSubtags _tags_root[] = {
8188 AllowedSubtags('INFO', _tags_info),
8189 AllowedSubtags()
8190 };
8191
8192
8199 static bool SkipUnknownInfo(ByteReader *buf, byte type)
8200 {
8201 /* type and id are already read */
8202 switch (type) {
8203 case 'C': {
8204 byte new_type = buf->ReadByte();
8205 while (new_type != 0) {
8206 buf->ReadDWord(); // skip the id
8207 if (!SkipUnknownInfo(buf, new_type)) return false;
8208 new_type = buf->ReadByte();
8209 }
8210 break;
8211 }
8212
8213 case 'T':
8214 buf->ReadByte(); // lang
8215 buf->ReadString(); // actual text
8216 break;
8217
8218 case 'B': {
8219 uint16 size = buf->ReadWord();
8220 buf->Skip(size);
8221 break;
8222 }
8223
8224 default:
8225 return false;
8226 }
8227
8228 return true;
8229 }
8230
8239 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
8240 {
8241 uint i = 0;
8242 AllowedSubtags *tag;
8243 while ((tag = &subtags[i++])->type != 0) {
8244 if (tag->id != BSWAP32(id) || tag->type != type) continue;
8245 switch (type) {
8246 default: NOT_REACHED();
8247
8248 case 'T': {
8249 byte langid = buf->ReadByte();
8250 return tag->handler.text(langid, buf->ReadString());
8251 }
8252
8253 case 'B': {
8254 size_t len = buf->ReadWord();
8255 if (buf->Remaining() < len) return false;
8256 return tag->handler.data(len, buf);
8257 }
8258
8259 case 'C': {
8260 if (tag->handler.call_handler) {
8261 return tag->handler.u.branch(buf);
8262 }
8263 return HandleNodes(buf, tag->handler.u.subtags);
8264 }
8265 }
8266 }
8267 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
8268 return SkipUnknownInfo(buf, type);
8269 }
8270
8277 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
8278 {
8279 byte type = buf->ReadByte();
8280 while (type != 0) {
8281 uint32 id = buf->ReadDWord();
8282 if (!HandleNode(type, id, buf, subtags)) return false;
8283 type = buf->ReadByte();
8284 }
8285 return true;
8286 }
8287
8292 static void StaticGRFInfo(ByteReader *buf)
8293 {
8294 /* <14> <type> <id> <text/data...> */
8295 HandleNodes(buf, _tags_root);
8296 }
8297
8303 static void GRFUnsafe(ByteReader *buf)
8304 {
8305 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
8306
8307 /* Skip remainder of GRF */
8308 _cur.skip_sprites = -1;
8309 }
8310
8311
8313 static void InitializeGRFSpecial()
8314 {
8315 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
8316 | (1 << 0x0D) // newairports
8317 | (1 << 0x0E) // largestations
8318 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
8319 | (0 << 0x10) // loadtime
8320 | (1 << 0x12) // presignals
8321 | (1 << 0x13) // extpresignals
8322 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
8323 | (1 << 0x1B) // multihead
8324 | (1 << 0x1D) // lowmemory
8325 | (1 << 0x1E); // generalfixes
8326
8327 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
8328 | (1 << 0x08) // mammothtrains
8329 | (1 << 0x09) // trainrefit
8330 | (0 << 0x0B) // subsidiaries
8331 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
8332 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
8333 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
8334 | (1 << 0x14) // bridgespeedlimits
8335 | (1 << 0x16) // eternalgame
8336 | (1 << 0x17) // newtrains
8337 | (1 << 0x18) // newrvs
8338 | (1 << 0x19) // newships
8339 | (1 << 0x1A) // newplanes
8340 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
8341 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
8342
8343 _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
8344 | (1 << 0x03) // semaphores
8345 | (1 << 0x0A) // newobjects
8346 | (0 << 0x0B) // enhancedgui
8347 | (0 << 0x0C) // newagerating
8348 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
8349 | (1 << 0x0E) // fullloadany
8350 | (1 << 0x0F) // planespeed
8351 | (0 << 0x10) // moreindustriesperclimate - obsolete
8352 | (0 << 0x11) // moretoylandfeatures
8353 | (1 << 0x12) // newstations
8354 | (1 << 0x13) // tracktypecostdiff
8355 | (1 << 0x14) // manualconvert
8356 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
8357 | (1 << 0x16) // canals
8358 | (1 << 0x17) // newstartyear
8359 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
8360 | (1 << 0x19) // newhouses
8361 | (1 << 0x1A) // newbridges
8362 | (1 << 0x1B) // newtownnames
8363 | (1 << 0x1C) // moreanimation
8364 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
8365 | (1 << 0x1E) // newshistory
8366 | (0 << 0x1F); // custombridgeheads
8367
8368 _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
8369 | (1 << 0x01) // windowsnap
8370 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
8371 | (1 << 0x03) // pathbasedsignalling
8372 | (0 << 0x04) // aichoosechance
8373 | (1 << 0x05) // resolutionwidth
8374 | (1 << 0x06) // resolutionheight
8375 | (1 << 0x07) // newindustries
8376 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
8377 | (0 << 0x09) // townroadbranchprob
8378 | (0 << 0x0A) // tempsnowline
8379 | (1 << 0x0B) // newcargo
8380 | (1 << 0x0C) // enhancemultiplayer
8381 | (1 << 0x0D) // onewayroads
8382 | (1 << 0x0E) // irregularstations
8383 | (1 << 0x0F) // statistics
8384 | (1 << 0x10) // newsounds
8385 | (1 << 0x11) // autoreplace
8386 | (1 << 0x12) // autoslope
8387 | (0 << 0x13) // followvehicle
8388 | (1 << 0x14) // trams
8389 | (0 << 0x15) // enhancetunnels
8390 | (1 << 0x16) // shortrvs
8391 | (1 << 0x17) // articulatedrvs
8392 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
8393 | (1 << 0x1E) // variablerunningcosts
8394 | (1 << 0x1F); // any switch is on
8395
8396 _ttdpatch_flags[4] = (1 << 0x00) // larger persistent storage
8397 | ((_settings_game.economy.inflation ? 1 : 0) << 0x01); // inflation is on
8398 }
8399
8401 static void ResetCustomStations()
8402 {
8403 for (GRFFile * const file : _grf_files) {
8404 StationSpec **&stations = file->stations;
8405 if (stations == nullptr) continue;
8406 for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
8407 if (stations[i] == nullptr) continue;
8408 StationSpec *statspec = stations[i];
8409
8410 delete[] statspec->renderdata;
8411
8412 /* Release platforms and layouts */
8413 if (!statspec->copied_layouts) {
8414 for (uint l = 0; l < statspec->lengths; l++) {
8415 for (uint p = 0; p < statspec->platforms[l]; p++) {
8416 free(statspec->layouts[l][p]);
8417 }
8418 free(statspec->layouts[l]);
8419 }
8420 free(statspec->layouts);
8421 free(statspec->platforms);
8422 }
8423
8424 /* Release this station */
8425 free(statspec);
8426 }
8427
8428 /* Free and reset the station data */
8429 free(stations);
8430 stations = nullptr;
8431 }
8432 }
8433
8435 static void ResetCustomHouses()
8436 {
8437 for (GRFFile * const file : _grf_files) {
8438 HouseSpec **&housespec = file->housespec;
8439 if (housespec == nullptr) continue;
8440 for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8441 free(housespec[i]);
8442 }
8443
8444 free(housespec);
8445 housespec = nullptr;
8446 }
8447 }
8448
8450 static void ResetCustomAirports()
8451 {
8452 for (GRFFile * const file : _grf_files) {
8453 AirportSpec **aslist = file->airportspec;
8454 if (aslist != nullptr) {
8455 for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8456 AirportSpec *as = aslist[i];
8457
8458 if (as != nullptr) {
8459 /* We need to remove the tiles layouts */
8460 for (int j = 0; j < as->num_table; j++) {
8461 /* remove the individual layouts */
8462 free(as->table[j]);
8463 }
8464 free(as->table);
8465 free(as->depot_table);
8466 free(as->rotation);
8467
8468 free(as);
8469 }
8470 }
8471 free(aslist);
8472 file->airportspec = nullptr;
8473 }
8474
8475 AirportTileSpec **&airporttilespec = file->airtspec;
8476 if (airporttilespec != nullptr) {
8477 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8478 free(airporttilespec[i]);
8479 }
8480 free(airporttilespec);
8481 airporttilespec = nullptr;
8482 }
8483 }
8484 }
8485
8487 static void ResetCustomIndustries()
8488 {
8489 for (GRFFile * const file : _grf_files) {
8490 IndustrySpec **&industryspec = file->industryspec;
8491 IndustryTileSpec **&indtspec = file->indtspec;
8492
8493 /* We are verifiying both tiles and industries specs loaded from the grf file
8494 * First, let's deal with industryspec */
8495 if (industryspec != nullptr) {
8496 for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8497 IndustrySpec *ind = industryspec[i];
8498 delete ind;
8499 }
8500
8501 free(industryspec);
8502 industryspec = nullptr;
8503 }
8504
8505 if (indtspec == nullptr) continue;
8506 for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8507 free(indtspec[i]);
8508 }
8509
8510 free(indtspec);
8511 indtspec = nullptr;
8512 }
8513 }
8514
8516 static void ResetCustomObjects()
8517 {
8518 for (GRFFile * const file : _grf_files) {
8519 ObjectSpec **&objectspec = file->objectspec;
8520 if (objectspec == nullptr) continue;
8521 for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8522 free(objectspec[i]);
8523 }
8524
8525 free(objectspec);
8526 objectspec = nullptr;
8527 }
8528 }
8529
8531 static void ResetNewGRF()
8532 {
8533 for (GRFFile * const file : _grf_files) {
8534 delete file;
8535 }
8536
8537 _grf_files.clear();
8538 _cur.grffile = nullptr;
8539 }
8540
8542 static void ResetNewGRFErrors()
8543 {
8544 for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
8545 if (!HasBit(c->flags, GCF_COPY) && c->error != nullptr) {
8546 delete c->error;
8547 c->error = nullptr;
8548 }
8549 }
8550 }
8551
8555 void ResetNewGRFData()
8556 {
8557 CleanUpStrings();
8558 CleanUpGRFTownNames();
8559
8560 /* Copy/reset original engine info data */
8561 SetupEngines();
8562
8563 /* Copy/reset original bridge info data */
8564 ResetBridges();
8565
8566 /* Reset rail type information */
8567 ResetRailTypes();
8568
8569 /* Copy/reset original road type info data */
8570 ResetRoadTypes();
8571
8572 /* Allocate temporary refit/cargo class data */
8573 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
8574
8575 /* Fill rail type label temporary data for default trains */
8576 for (const Engine *e : Engine::IterateType(VEH_TRAIN)) {
8577 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
8578 }
8579
8580 /* Reset GRM reservations */
8581 memset(&_grm_engines, 0, sizeof(_grm_engines));
8582 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
8583
8584 /* Reset generic feature callback lists */
8585 ResetGenericCallbacks();
8586
8587 /* Reset price base data */
8588 ResetPriceBaseMultipliers();
8589
8590 /* Reset the curencies array */
8591 ResetCurrencies();
8592
8593 /* Reset the house array */
8594 ResetCustomHouses();
8595 ResetHouses();
8596
8597 /* Reset the industries structures*/
8598 ResetCustomIndustries();
8599 ResetIndustries();
8600
8601 /* Reset the objects. */
8602 ObjectClass::Reset();
8603 ResetCustomObjects();
8604 ResetObjects();
8605
8606 /* Reset station classes */
8607 StationClass::Reset();
8608 ResetCustomStations();
8609
8610 /* Reset airport-related structures */
8611 AirportClass::Reset();
8612 ResetCustomAirports();
8613 AirportSpec::ResetAirports();
8614 AirportTileSpec::ResetAirportTiles();
8615
8616 /* Reset canal sprite groups and flags */
8617 memset(_water_feature, 0, sizeof(_water_feature));
8618
8619 /* Reset the snowline table. */
8620 ClearSnowLine();
8621
8622 /* Reset NewGRF files */
8623 ResetNewGRF();
8624
8625 /* Reset NewGRF errors. */
8626 ResetNewGRFErrors();
8627
8628 /* Set up the default cargo types */
8629 SetupCargoForClimate(_settings_game.game_creation.landscape);
8630
8631 /* Reset misc GRF features and train list display variables */
8632 _misc_grf_features = 0;
8633
8634 _loaded_newgrf_features.has_2CC = false;
8635 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8636 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
8637 _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_NONE;
8638
8639 /* Clear all GRF overrides */
8640 _grf_id_overrides.clear();
8641
8642 InitializeSoundPool();
8643 _spritegroup_pool.CleanPool();
8644 }
8645
8649 void ResetPersistentNewGRFData()
8650 {
8651 /* Reset override managers */
8652 _engine_mngr.ResetToDefaultMapping();
8653 _house_mngr.ResetMapping();
8654 _industry_mngr.ResetMapping();
8655 _industile_mngr.ResetMapping();
8656 _airport_mngr.ResetMapping();
8657 _airporttile_mngr.ResetMapping();
8658 }
8659
8664 static void BuildCargoTranslationMap()
8665 {
8666 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8667
8668 for (CargoID c = 0; c < NUM_CARGO; c++) {
8669 const CargoSpec *cs = CargoSpec::Get(c);
8670 if (!cs->IsValid()) continue;
8671
8672 if (_cur.grffile->cargo_list.size() == 0) {
8673 /* Default translation table, so just a straight mapping to bitnum */
8674 _cur.grffile->cargo_map[c] = cs->bitnum;
8675 } else {
8676 /* Check the translation table for this cargo's label */
8677 int idx = find_index(_cur.grffile->cargo_list, {cs->label});
8678 if (idx >= 0) _cur.grffile->cargo_map[c] = idx;
8679 }
8680 }
8681 }
8682
8687 static void InitNewGRFFile(const GRFConfig *config)
8688 {
8689 GRFFile *newfile = GetFileByFilename(config->filename);
8690 if (newfile != nullptr) {
8691 /* We already loaded it once. */
8692 _cur.grffile = newfile;
8693 return;
8694 }
8695
8696 newfile = new GRFFile(config);
8697 _grf_files.push_back(_cur.grffile = newfile);
8698 }
8699
8704 GRFFile::GRFFile(const GRFConfig *config)
8705 {
8706 this->filename = stredup(config->filename);
8707 this->grfid = config->ident.grfid;
8708
8709 /* Initialise local settings to defaults */
8710 this->traininfo_vehicle_pitch = 0;
8711 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8712
8713 /* Mark price_base_multipliers as 'not set' */
8714 for (Price i = PR_BEGIN; i < PR_END; i++) {
8715 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8716 }
8717
8718 /* Initialise rail type map with default rail types */
8719 std::fill(std::begin(this->railtype_map), std::end(this->railtype_map), INVALID_RAILTYPE);
8720 this->railtype_map[0] = RAILTYPE_RAIL;
8721 this->railtype_map[1] = RAILTYPE_ELECTRIC;
8722 this->railtype_map[2] = RAILTYPE_MONO;
8723 this->railtype_map[3] = RAILTYPE_MAGLEV;
8724
8725 /* Initialise road type map with default road types */
8726 std::fill(std::begin(this->roadtype_map), std::end(this->roadtype_map), INVALID_ROADTYPE);
8727 this->roadtype_map[0] = ROADTYPE_ROAD;
8728
8729 /* Initialise tram type map with default tram types */
8730 std::fill(std::begin(this->tramtype_map), std::end(this->tramtype_map), INVALID_ROADTYPE);
8731 this->tramtype_map[0] = ROADTYPE_TRAM;
8732
8733 /* Copy the initial parameter list
8734 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8735 static_assert(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8736
8737 assert(config->num_params <= lengthof(config->param));
8738 this->param_end = config->num_params;
8739 if (this->param_end > 0) {
8740 MemCpyT(this->param, config->param, this->param_end);
8741 }
8742 }
8743
8744 GRFFile::~GRFFile()
8745 {
8746 free(this->filename);
8747 delete[] this->language_map;
8748 }
8749
8750
8755 static const CargoLabel _default_refitmasks_rail[] = {
8756 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8757 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8758 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8759 'PLST', 'FZDR',
8760 0 };
8761
8762 static const CargoLabel _default_refitmasks_road[] = {
8763 0 };
8764
8765 static const CargoLabel _default_refitmasks_ships[] = {
8766 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8767 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8768 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8769 'PLST', 'FZDR',
8770 0 };
8771
8772 static const CargoLabel _default_refitmasks_aircraft[] = {
8773 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8774 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8775 0 };
8776
8777 static const CargoLabel * const _default_refitmasks[] = {
8778 _default_refitmasks_rail,
8779 _default_refitmasks_road,
8780 _default_refitmasks_ships,
8781 _default_refitmasks_aircraft,
8782 };
8783
8784
8788 static void CalculateRefitMasks()
8789 {
8790 for (Engine *e : Engine::Iterate()) {
8791 EngineID engine = e->index;
8792 EngineInfo *ei = &e->info;
8793 bool only_defaultcargo;
8794
8795 /* Did the newgrf specify any refitting? If not, use defaults. */
8796 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8797 CargoTypes mask = 0;
8798 CargoTypes not_mask = 0;
8799 CargoTypes xor_mask = ei->refit_mask;
8800
8801 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8802 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8803 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8804
8805 if (_gted[engine].cargo_allowed != 0) {
8806 /* Build up the list of cargo types from the set cargo classes. */
8807 const CargoSpec *cs;
8808 FOR_ALL_CARGOSPECS(cs) {
8809 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8810 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8811 }
8812 }
8813
8814 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8815
8816 /* Apply explicit refit includes/excludes. */
8817 ei->refit_mask |= _gted[engine].ctt_include_mask;
8818 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8819 } else {
8820 CargoTypes xor_mask = 0;
8821
8822 /* Don't apply default refit mask to wagons nor engines with no capacity */
8823 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8824 const CargoLabel *cl = _default_refitmasks[e->type];
8825 for (uint i = 0;; i++) {
8826 if (cl[i] == 0) break;
8827
8828 CargoID cargo = GetCargoIDByLabel(cl[i]);
8829 if (cargo == CT_INVALID) continue;
8830
8831 SetBit(xor_mask, cargo);
8832 }
8833 }
8834
8835 ei->refit_mask = xor_mask & _cargo_mask;
8836
8837 /* If the mask is zero, the vehicle shall only carry the default cargo */
8838 only_defaultcargo = (ei->refit_mask == 0);
8839 }
8840
8841 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8842 if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8843
8844 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8845 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8846 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8847 ei->cargo_type = CT_INVALID;
8848 }
8849
8850 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8851 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8852 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8853 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8854 const uint8 *cargo_map_for_first_refittable = nullptr;
8855 {
8856 const GRFFile *file = _gted[engine].defaultcargo_grf;
8857 if (file == nullptr) file = e->GetGRF();
8858 if (file != nullptr && file->grf_version >= 8 && file->cargo_list.size() != 0) {
8859 cargo_map_for_first_refittable = file->cargo_map;
8860 }
8861 }
8862
8863 if (cargo_map_for_first_refittable != nullptr) {
8864 /* Use first refittable cargo from cargo translation table */
8865 byte best_local_slot = 0xFF;
8866 CargoID cargo_type;
8867 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8868 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8869 if (local_slot < best_local_slot) {
8870 best_local_slot = local_slot;
8871 ei->cargo_type = cargo_type;
8872 }
8873 }
8874 }
8875
8876 if (ei->cargo_type == CT_INVALID) {
8877 /* Use first refittable cargo slot */
8878 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8879 }
8880 }
8881 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8882
8883 /* Clear refit_mask for not refittable ships */
8884 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8885 ei->refit_mask = 0;
8886 }
8887 }
8888 }
8889
8891 static void FinaliseCanals()
8892 {
8893 for (uint i = 0; i < CF_END; i++) {
8894 if (_water_feature[i].grffile != nullptr) {
8895 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
8896 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
8897 }
8898 }
8899 }
8900
8902 static void FinaliseEngineArray()
8903 {
8904 for (Engine *e : Engine::Iterate()) {
8905 if (e->GetGRF() == nullptr) {
8906 const EngineIDMapping &eid = _engine_mngr[e->index];
8907 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8908 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8909 }
8910 }
8911
8912 if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue;
8913
8914 /* When the train does not set property 27 (misc flags), but it
8915 * is overridden by a NewGRF graphically we want to disable the
8916 * flipping possibility. */
8917 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != nullptr && is_custom_sprite(e->u.rail.image_index)) {
8918 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8919 }
8920
8921 /* Skip wagons, there livery is defined via the engine */
8922 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8923 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, nullptr);
8924 SetBit(_loaded_newgrf_features.used_liveries, ls);
8925 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8926
8927 if (e->type == VEH_TRAIN) {
8928 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8929 switch (ls) {
8930 case LS_STEAM:
8931 case LS_DIESEL:
8932 case LS_ELECTRIC:
8933 case LS_MONORAIL:
8934 case LS_MAGLEV:
8935 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8936 break;
8937
8938 case LS_DMU:
8939 case LS_EMU:
8940 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8941 break;
8942
8943 default: NOT_REACHED();
8944 }
8945 }
8946 }
8947 }
8948 }
8949
8951 static void FinaliseCargoArray()
8952 {
8953 for (CargoID c = 0; c < NUM_CARGO; c++) {
8954 CargoSpec *cs = CargoSpec::Get(c);
8955 if (!cs->IsValid()) {
8956 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8957 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8958 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8959 }
8960 }
8961 }
8962
8974 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8975 {
8976 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8977 (next1 == nullptr || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8978 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8979 (next2 == nullptr || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8980 next3 == nullptr || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8981 hs->enabled = false;
8982 if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", filename, hs->grf_prop.local_id);
8983 return false;
8984 }
8985
8986 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8987 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8988 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8989 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8990 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8991 hs->enabled = false;
8992 if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", filename, hs->grf_prop.local_id);
8993 return false;
8994 }
8995
8996 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8997 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8998 if (filename != nullptr && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8999 hs->enabled = false;
9000 DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d with different house size then it's substitute type. Disabling house.", filename, hs->grf_prop.local_id);
9001 return false;
9002 }
9003
9004 /* Make sure that additional parts of multitile houses are not available. */
9005 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
9006 hs->enabled = false;
9007 if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d without a size but marked it as available. Disabling house.", filename, hs->grf_prop.local_id);
9008 return false;
9009 }
9010
9011 return true;
9012 }
9013
9020 static void EnsureEarlyHouse(HouseZones bitmask)
9021 {
9022 Year min_year = MAX_YEAR;
9023
9024 for (int i = 0; i < NUM_HOUSES; i++) {
9025 HouseSpec *hs = HouseSpec::Get(i);
9026 if (hs == nullptr || !hs->enabled) continue;
9027 if ((hs->building_availability & bitmask) != bitmask) continue;
9028 if (hs->min_year < min_year) min_year = hs->min_year;
9029 }
9030
9031 if (min_year == 0) return;
9032
9033 for (int i = 0; i < NUM_HOUSES; i++) {
9034 HouseSpec *hs = HouseSpec::Get(i);
9035 if (hs == nullptr || !hs->enabled) continue;
9036 if ((hs->building_availability & bitmask) != bitmask) continue;
9037 if (hs->min_year == min_year) hs->min_year = 0;
9038 }
9039 }
9040
9047 static void FinaliseHouseArray()
9048 {
9049 /* If there are no houses with start dates before 1930, then all houses
9050 * with start dates of 1930 have them reset to 0. This is in order to be
9051 * compatible with TTDPatch, where if no houses have start dates before
9052 * 1930 and the date is before 1930, the game pretends that this is 1930.
9053 * If there have been any houses defined with start dates before 1930 then
9054 * the dates are left alone.
9055 * On the other hand, why 1930? Just 'fix' the houses with the lowest
9056 * minimum introduction date to 0.
9057 */
9058 for (GRFFile * const file : _grf_files) {
9059 HouseSpec **&housespec = file->housespec;
9060 if (housespec == nullptr) continue;
9061
9062 for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
9063 HouseSpec *hs = housespec[i];
9064
9065 if (hs == nullptr) continue;
9066
9067 const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : nullptr);
9068 const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : nullptr);
9069 const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : nullptr);
9070
9071 if (!IsHouseSpecValid(hs, next1, next2, next3, file->filename)) continue;
9072
9073 _house_mngr.SetEntitySpec(hs);
9074 }
9075 }
9076
9077 for (int i = 0; i < NUM_HOUSES; i++) {
9078 HouseSpec *hs = HouseSpec::Get(i);
9079 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr);
9080 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr);
9081 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : nullptr);
9082
9083 /* We need to check all houses again to we are sure that multitile houses
9084 * did get consecutive IDs and none of the parts are missing. */
9085 if (!IsHouseSpecValid(hs, next1, next2, next3, nullptr)) {
9086 /* GetHouseNorthPart checks 3 houses that are directly before
9087 * it in the house pool. If any of those houses have multi-tile
9088 * flags set it assumes it's part of a multitile house. Since
9089 * we can have invalid houses in the pool marked as disabled, we
9090 * don't want to have them influencing valid tiles. As such set
9091 * building_flags to zero here to make sure any house following
9092 * this one in the pool is properly handled as 1x1 house. */
9093 hs->building_flags = TILE_NO_FLAG;
9094 }
9095 }
9096
9097 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
9098 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
9099 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
9100 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
9101 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
9102 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
9103
9104 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
9105 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
9106 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
9107 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
9108 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
9109 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
9110 }
9111 }
9112
9118 static void FinaliseIndustriesArray()
9119 {
9120 for (GRFFile * const file : _grf_files) {
9121 IndustrySpec **&industryspec = file->industryspec;
9122 IndustryTileSpec **&indtspec = file->indtspec;
9123 if (industryspec != nullptr) {
9124 for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
9125 IndustrySpec *indsp = industryspec[i];
9126
9127 if (indsp != nullptr && indsp->enabled) {
9128 StringID strid;
9129 /* process the conversion of text at the end, so to be sure everything will be fine
9130 * and available. Check if it does not return undefind marker, which is a very good sign of a
9131 * substitute industry who has not changed the string been examined, thus using it as such */
9132 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
9133 if (strid != STR_UNDEFINED) indsp->name = strid;
9134
9135 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
9136 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
9137
9138 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
9139 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
9140
9141 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
9142 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
9143
9144 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
9145 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
9146
9147 if (indsp->station_name != STR_NULL) {
9148 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
9149 * station's name. Don't want to lose the value, therefore, do not process. */
9150 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
9151 if (strid != STR_UNDEFINED) indsp->station_name = strid;
9152 }
9153
9154 _industry_mngr.SetEntitySpec(indsp);
9155 }
9156 }
9157 }
9158
9159 if (indtspec != nullptr) {
9160 for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
9161 IndustryTileSpec *indtsp = indtspec[i];
9162 if (indtsp != nullptr) {
9163 _industile_mngr.SetEntitySpec(indtsp);
9164 }
9165 }
9166 }
9167 }
9168
9169 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
9170 IndustrySpec *indsp = &_industry_specs[j];
9171 if (indsp->enabled && indsp->grf_prop.grffile != nullptr) {
9172 for (uint i = 0; i < 3; i++) {
9173 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
9174 }
9175 }
9176 if (!indsp->enabled) {
9177 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
9178 }
9179 }
9180 }
9181
9187 static void FinaliseObjectsArray()
9188 {
9189 for (GRFFile * const file : _grf_files) {
9190 ObjectSpec **&objectspec = file->objectspec;
9191 if (objectspec != nullptr) {
9192 for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
9193 if (objectspec[i] != nullptr && objectspec[i]->grf_prop.grffile != nullptr && objectspec[i]->enabled) {
9194 _object_mngr.SetEntitySpec(objectspec[i]);
9195 }
9196 }
9197 }
9198 }
9199 }
9200
9206 static void FinaliseAirportsArray()
9207 {
9208 for (GRFFile * const file : _grf_files) {
9209 AirportSpec **&airportspec = file->airportspec;
9210 if (airportspec != nullptr) {
9211 for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
9212 if (airportspec[i] != nullptr && airportspec[i]->enabled) {
9213 _airport_mngr.SetEntitySpec(airportspec[i]);
9214 }
9215 }
9216 }
9217
9218 AirportTileSpec **&airporttilespec = file->airtspec;
9219 if (airporttilespec != nullptr) {
9220 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
9221 if (airporttilespec[i] != nullptr && airporttilespec[i]->enabled) {
9222 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
9223 }
9224 }
9225 }
9226 }
9227 }
9228
9229 /* Here we perform initial decoding of some special sprites (as are they
9230 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
9231 * partial implementation yet).
9232 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
9233 * a crafted invalid GRF file. We should tell that to the user somehow, or
9234 * better make this more robust in the future. */
9235 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
9236 {
9237 /* XXX: There is a difference between staged loading in TTDPatch and
9238 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
9239 * during stage 1, whilst action 3 is carried out during stage 2 (to
9240 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
9241 * IDs are valid only within a given set (action 1) block, and may be
9242 * overwritten after action 3 associates them. But overwriting happens
9243 * in an earlier stage than associating, so... We just process actions
9244 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
9245 * --pasky
9246 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
9247 * is not in memory and scanning the file every time would be too expensive.
9248 * In other stages we skip action 0x10 since it's already dealt with. */
9249 static const SpecialSpriteHandler handlers[][GLS_END] = {
9250 /* 0x00 */ { nullptr, SafeChangeInfo, nullptr, nullptr, ReserveChangeInfo, FeatureChangeInfo, },
9251 /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
9252 /* 0x02 */ { nullptr, nullptr, nullptr, nullptr, nullptr, NewSpriteGroup, },
9253 /* 0x03 */ { nullptr, GRFUnsafe, nullptr, nullptr, nullptr, FeatureMapSpriteGroup, },
9254 /* 0x04 */ { nullptr, nullptr, nullptr, nullptr, nullptr, FeatureNewName, },
9255 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
9256 /* 0x06 */ { nullptr, nullptr, nullptr, CfgApply, CfgApply, CfgApply, },
9257 /* 0x07 */ { nullptr, nullptr, nullptr, nullptr, SkipIf, SkipIf, },
9258 /* 0x08 */ { ScanInfo, nullptr, nullptr, GRFInfo, GRFInfo, GRFInfo, },
9259 /* 0x09 */ { nullptr, nullptr, nullptr, SkipIf, SkipIf, SkipIf, },
9260 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
9261 /* 0x0B */ { nullptr, nullptr, nullptr, GRFLoadError, GRFLoadError, GRFLoadError, },
9262 /* 0x0C */ { nullptr, nullptr, nullptr, GRFComment, nullptr, GRFComment, },
9263 /* 0x0D */ { nullptr, SafeParamSet, nullptr, ParamSet, ParamSet, ParamSet, },
9264 /* 0x0E */ { nullptr, SafeGRFInhibit, nullptr, GRFInhibit, GRFInhibit, GRFInhibit, },
9265 /* 0x0F */ { nullptr, GRFUnsafe, nullptr, FeatureTownName, nullptr, nullptr, },
9266 /* 0x10 */ { nullptr, nullptr, DefineGotoLabel, nullptr, nullptr, nullptr, },
9267 /* 0x11 */ { SkipAct11, GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
9268 /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
9269 /* 0x13 */ { nullptr, nullptr, nullptr, nullptr, nullptr, TranslateGRFStrings, },
9270 /* 0x14 */ { StaticGRFInfo, nullptr, nullptr, nullptr, nullptr, nullptr, },
9271 };
9272
9273 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
9274
9275 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
9276 if (it == _grf_line_to_action6_sprite_override.end()) {
9277 /* No preloaded sprite to work with; read the
9278 * pseudo sprite content. */
9279 FioReadBlock(buf, num);
9280 } else {
9281 /* Use the preloaded sprite data. */
9282 buf = _grf_line_to_action6_sprite_override[location];
9283 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
9284
9285 /* Skip the real (original) content of this action. */
9286 FioSeekTo(num, SEEK_CUR);
9287 }
9288
9289 ByteReader br(buf, buf + num);
9290 ByteReader *bufp = &br;
9291
9292 try {
9293 byte action = bufp->ReadByte();
9294
9295 if (action == 0xFF) {
9296 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
9297 } else if (action == 0xFE) {
9298 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
9299 } else if (action >= lengthof(handlers)) {
9300 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
9301 } else if (handlers[action][stage] == nullptr) {
9302 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
9303 } else {
9304 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
9305 handlers[action][stage](bufp);
9306 }
9307 } catch (...) {
9308 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
9309 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
9310 }
9311 }
9312
9313
9315 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
9316
9321 byte GetGRFContainerVersion()
9322 {
9323 size_t pos = FioGetPos();
9324
9325 if (FioReadWord() == 0) {
9326 /* Check for GRF container version 2, which is identified by the bytes
9327 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
9328 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
9329 if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
9330 }
9331
9332 return 2;
9333 }
9334
9335 /* Container version 1 has no header, rewind to start. */
9336 FioSeekTo(pos, SEEK_SET);
9337 return 1;
9338 }
9339
9347 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
9348 {
9349 const char *filename = config->filename;
9350
9351 /* A .grf file is activated only if it was active when the game was
9352 * started. If a game is loaded, only its active .grfs will be
9353 * reactivated, unless "loadallgraphics on" is used. A .grf file is
9354 * considered active if its action 8 has been processed, i.e. its
9355 * action 8 hasn't been skipped using an action 7.
9356 *
9357 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
9358 * carried out. All others are ignored, because they only need to be
9359 * processed once at initialization. */
9360 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
9361 _cur.grffile = GetFileByFilename(filename);
9362 if (_cur.grffile == nullptr) usererror("File '%s' lost in cache.\n", filename);
9363 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
9364 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
9365 }
9366
9367 if (file_index >= MAX_FILE_SLOTS) {
9368 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of file slots has been reached", filename);
9369 config->status = GCS_DISABLED;
9370 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9371 return;
9372 }
9373
9374 FioOpenFile(file_index, filename, subdir);
9375 _cur.file_index = file_index; // XXX
9376 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
9377
9378 _cur.grfconfig = config;
9379
9380 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
9381
9382 _cur.grf_container_ver = GetGRFContainerVersion();
9383 if (_cur.grf_container_ver == 0) {
9384 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
9385 return;
9386 }
9387
9388 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
9389 /* We need the sprite offsets in the init stage for NewGRF sounds
9390 * and in the activation stage for real sprites. */
9391 ReadGRFSpriteOffsets(_cur.grf_container_ver);
9392 } else {
9393 /* Skip sprite section offset if present. */
9394 if (_cur.grf_container_ver >= 2) FioReadDword();
9395 }
9396
9397 if (_cur.grf_container_ver >= 2) {
9398 /* Read compression value. */
9399 byte compression = FioReadByte();
9400 if (compression != 0) {
9401 DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
9402 return;
9403 }
9404 }
9405
9406 /* Skip the first sprite; we don't care about how many sprites this
9407 * does contain; newest TTDPatches and George's longvehicles don't
9408 * neither, apparently. */
9409 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
9410 if (num == 4 && FioReadByte() == 0xFF) {
9411 FioReadDword();
9412 } else {
9413 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
9414 return;
9415 }
9416
9417 _cur.ClearDataForNextFile();
9418
9419 ReusableBuffer<byte> buf;
9420
9421 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
9422 byte type = FioReadByte();
9423 _cur.nfo_line++;
9424
9425 if (type == 0xFF) {
9426 if (_cur.skip_sprites == 0) {
9427 DecodeSpecialSprite(buf.Allocate(num), num, stage);
9428
9429 /* Stop all processing if we are to skip the remaining sprites */
9430 if (_cur.skip_sprites == -1) break;
9431
9432 continue;
9433 } else {
9434 FioSkipBytes(num);
9435 }
9436 } else {
9437 if (_cur.skip_sprites == 0) {
9438 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
9439 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
9440 break;
9441 }
9442
9443 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
9444 /* Reference to data section. Container version >= 2 only. */
9445 FioSkipBytes(num);
9446 } else {
9447 FioSkipBytes(7);
9448 SkipSpriteData(type, num - 8);
9449 }
9450 }
9451
9452 if (_cur.skip_sprites > 0) _cur.skip_sprites--;
9453 }
9454 }
9455
9463 static void ActivateOldShore()
9464 {
9465 /* Use default graphics, if no shore sprites were loaded.
9466 * Should not happen, as the base set's extra grf should include some. */
9467 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
9468
9469 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
9470 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
9471 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
9472 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
9473 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
9474 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
9475 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
9476 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
9477 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
9478 }
9479
9480 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
9481 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
9482 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
9483 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
9484 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
9485 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
9486 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
9487 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
9488 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
9489
9490 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
9491 * If they would be used somewhen, then these grass tiles will most like not look as needed */
9492 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
9493 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
9494 }
9495 }
9496
9500 static void ActivateOldTramDepot()
9501 {
9502 if (_loaded_newgrf_features.tram == TRAMWAY_REPLACE_DEPOT_WITH_TRACK) {
9503 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0); // use road depot graphics for "no tracks"
9504 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
9505 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2); // use road depot graphics for "no tracks"
9506 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
9507 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
9508 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
9509 }
9510 }
9511
9515 static void FinalisePriceBaseMultipliers()
9516 {
9517 extern const PriceBaseSpec _price_base_specs[];
9519 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9520
9521 /* Evaluate grf overrides */
9522 int num_grfs = (uint)_grf_files.size();
9523 int *grf_overrides = AllocaM(int, num_grfs);
9524 for (int i = 0; i < num_grfs; i++) {
9525 grf_overrides[i] = -1;
9526
9527 GRFFile *source = _grf_files[i];
9528 uint32 override = _grf_id_overrides[source->grfid];
9529 if (override == 0) continue;
9530
9531 GRFFile *dest = GetFileByGRFID(override);
9532 if (dest == nullptr) continue;
9533
9534 grf_overrides[i] = find_index(_grf_files, dest);
9535 assert(grf_overrides[i] >= 0);
9536 }
9537
9538 /* Override features and price base multipliers of earlier loaded grfs */
9539 for (int i = 0; i < num_grfs; i++) {
9540 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
9541 GRFFile *source = _grf_files[i];
9542 GRFFile *dest = _grf_files[grf_overrides[i]];
9543
9544 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9545 source->grf_features |= features;
9546 dest->grf_features |= features;
9547
9548 for (Price p = PR_BEGIN; p < PR_END; p++) {
9549 /* No price defined -> nothing to do */
9550 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
9551 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9552 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9553 }
9554 }
9555
9556 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9557 for (int i = num_grfs - 1; i >= 0; i--) {
9558 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
9559 GRFFile *source = _grf_files[i];
9560 GRFFile *dest = _grf_files[grf_overrides[i]];
9561
9562 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9563 source->grf_features |= features;
9564 dest->grf_features |= features;
9565
9566 for (Price p = PR_BEGIN; p < PR_END; p++) {
9567 /* Already a price defined -> nothing to do */
9568 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
9569 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9570 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9571 }
9572 }
9573
9574 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9575 for (int i = 0; i < num_grfs; i++) {
9576 if (grf_overrides[i] < 0) continue;
9577 GRFFile *source = _grf_files[i];
9578 GRFFile *dest = _grf_files[grf_overrides[i]];
9579
9580 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9581 source->grf_features |= features;
9582 dest->grf_features |= features;
9583
9584 for (Price p = PR_BEGIN; p < PR_END; p++) {
9585 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
9586 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
9587 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9588 }
9589 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
9590 }
9591 }
9592
9593 /* Apply fallback prices for grf version < 8 */
9594 for (GRFFile * const file : _grf_files) {
9595 if (file->grf_version >= 8) continue;
9596 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9597 for (Price p = PR_BEGIN; p < PR_END; p++) {
9598 Price fallback_price = _price_base_specs[p].fallback_price;
9599 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9600 /* No price multiplier has been set.
9601 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9602 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9603 }
9604 }
9605 }
9606
9607 /* Decide local/global scope of price base multipliers */
9608 for (GRFFile * const file : _grf_files) {
9609 PriceMultipliers &price_base_multipliers = file->price_base_multipliers;
9610 for (Price p = PR_BEGIN; p < PR_END; p++) {
9611 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9612 /* No multiplier was set; set it to a neutral value */
9613 price_base_multipliers[p] = 0;
9614 } else {
9615 if (!HasBit(file->grf_features, _price_base_specs[p].grf_feature)) {
9616 /* The grf does not define any objects of the feature,
9617 * so it must be a difficulty setting. Apply it globally */
9618 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", file->filename, p);
9619 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9620 price_base_multipliers[p] = 0;
9621 } else {
9622 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", file->filename, p);
9623 }
9624 }
9625 }
9626 }
9627 }
9628
9629 extern void InitGRFTownGeneratorNames();
9630
9632 static void AfterLoadGRFs()
9633 {
9634 for (StringIDMapping &it : _string_to_grf_mapping) {
9635 *it.target = MapGRFStringID(it.grfid, it.source);
9636 }
9637 _string_to_grf_mapping.clear();
9638
9639 /* Free the action 6 override sprites. */
9640 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9641 free((*it).second);
9642 }
9643 _grf_line_to_action6_sprite_override.clear();
9644
9645 /* Polish cargoes */
9646 FinaliseCargoArray();
9647
9648 /* Pre-calculate all refit masks after loading GRF files. */
9649 CalculateRefitMasks();
9650
9651 /* Polish engines */
9652 FinaliseEngineArray();
9653
9654 /* Set the actually used Canal properties */
9655 FinaliseCanals();
9656
9657 /* Add all new houses to the house array. */
9658 FinaliseHouseArray();
9659
9660 /* Add all new industries to the industry array. */
9661 FinaliseIndustriesArray();
9662
9663 /* Add all new objects to the object array. */
9664 FinaliseObjectsArray();
9665
9666 InitializeSortedCargoSpecs();
9667
9668 /* Sort the list of industry types. */
9669 SortIndustryTypes();
9670
9671 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9672 BuildIndustriesLegend();
9673
9674 /* Build the routemap legend, based on the available cargos */
9675 BuildLinkStatsLegend();
9676
9677 /* Add all new airports to the airports array. */
9678 FinaliseAirportsArray();
9679 BindAirportSpecs();
9680
9681 /* Update the townname generators list */
9682 InitGRFTownGeneratorNames();
9683
9684 /* Run all queued vehicle list order changes */
9685 CommitVehicleListOrderChanges();
9686
9687 /* Load old shore sprites in new position, if they were replaced by ActionA */
9688 ActivateOldShore();
9689
9690 /* Load old tram depot sprites in new position, if no new ones are present */
9691 ActivateOldTramDepot();
9692
9693 /* Set up custom rail types */
9694 InitRailTypes();
9695 InitRoadTypes();
9696
9697 for (Engine *e : Engine::IterateType(VEH_ROAD)) {
9698 if (_gted[e->index].rv_max_speed != 0) {
9699 /* Set RV maximum speed from the mph/0.8 unit value */
9700 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9701 }
9702
9703 RoadTramType rtt = HasBit(e->info.misc_flags, EF_ROAD_TRAM) ? RTT_TRAM : RTT_ROAD;
9704
9705 const GRFFile *file = e->GetGRF();
9706 if (file == nullptr || _gted[e->index].roadtramtype == 0) {
9707 e->u.road.roadtype = (rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
9708 continue;
9709 }
9710
9711 /* Remove +1 offset. */
9712 _gted[e->index].roadtramtype--;
9713
9714 const std::vector<RoadTypeLabel> *list = (rtt == RTT_TRAM) ? &file->tramtype_list : &file->roadtype_list;
9715 if (_gted[e->index].roadtramtype < list->size())
9716 {
9717 RoadTypeLabel rtl = (*list)[_gted[e->index].roadtramtype];
9718 RoadType rt = GetRoadTypeByLabel(rtl);
9719 if (rt != INVALID_ROADTYPE && GetRoadTramType(rt) == rtt) {
9720 e->u.road.roadtype = rt;
9721 continue;
9722 }
9723 }
9724
9725 /* Road type is not available, so disable this engine */
9726 e->info.climates = 0;
9727 }
9728
9729 for (Engine *e : Engine::IterateType(VEH_TRAIN)) {
9730 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9731 if (railtype == INVALID_RAILTYPE) {
9732 /* Rail type is not available, so disable this engine */
9733 e->info.climates = 0;
9734 } else {
9735 e->u.rail.railtype = railtype;
9736 }
9737 }
9738
9739 SetYearEngineAgingStops();
9740
9741 FinalisePriceBaseMultipliers();
9742
9743 /* Deallocate temporary loading data */
9744 free(_gted);
9745 _grm_sprites.clear();
9746 }
9747
9754 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9755 {
9756 /* In case of networking we need to "sync" the start values
9757 * so all NewGRFs are loaded equally. For this we use the
9758 * start date of the game and we set the counters, etc. to
9759 * 0 so they're the same too. */
9760 Date date = _date;
9761 Year year = _cur_year;
9762 DateFract date_fract = _date_fract;
9763 uint16 tick_counter = _tick_counter;
9764 byte display_opt = _display_opt;
9765
9766 if (_networking) {
9767 _cur_year = _settings_game.game_creation.starting_year;
9768 _date = ConvertYMDToDate(_cur_year, 0, 1);
9769 _date_fract = 0;
9770 _tick_counter = 0;
9771 _display_opt = 0;
9772 }
9773
9774 InitializeGRFSpecial();
9775
9776 ResetNewGRFData();
9777
9778 /*
9779 * Reset the status of all files, so we can 'retry' to load them.
9780 * This is needed when one for example rearranges the NewGRFs in-game
9781 * and a previously disabled NewGRF becomes usable. If it would not
9782 * be reset, the NewGRF would remain disabled even though it should
9783 * have been enabled.
9784 */
9785 for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
9786 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9787 }
9788
9789 _cur.spriteid = load_index;
9790
9791 /* Load newgrf sprites
9792 * in each loading stage, (try to) open each file specified in the config
9793 * and load information from it. */
9794 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9795 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9796 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9797 for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
9798 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9799 }
9800
9801 if (stage == GLS_RESERVE) {
9802 static const uint32 overrides[][2] = {
9803 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9804 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9805 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9806 };
9807 for (size_t i = 0; i < lengthof(overrides); i++) {
9808 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9809 }
9810 }
9811
9812 uint slot = file_index;
9813 uint num_non_static = 0;
9814
9815 _cur.stage = stage;
9816 for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
9817 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9818 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9819
9820 Subdirectory subdir = slot < file_index + num_baseset ? BASESET_DIR : NEWGRF_DIR;
9821 if (!FioCheckFileExists(c->filename, subdir)) {
9822 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9823 c->status = GCS_NOT_FOUND;
9824 continue;
9825 }
9826
9827 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
9828
9829 if (!HasBit(c->flags, GCF_STATIC) && !HasBit(c->flags, GCF_SYSTEM)) {
9830 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
9831 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
9832 c->status = GCS_DISABLED;
9833 c->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9834 continue;
9835 }
9836 num_non_static++;
9837 }
9838 LoadNewGRFFile(c, slot++, stage, subdir);
9839 if (stage == GLS_RESERVE) {
9840 SetBit(c->flags, GCF_RESERVED);
9841 } else if (stage == GLS_ACTIVATION) {
9842 ClrBit(c->flags, GCF_RESERVED);
9843 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9844 ClearTemporaryNewGRFData(_cur.grffile);
9845 BuildCargoTranslationMap();
9846 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9847 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9848 /* We're not going to activate this, so free whatever data we allocated */
9849 ClearTemporaryNewGRFData(_cur.grffile);
9850 }
9851 }
9852 }
9853
9854 /* Pseudo sprite processing is finished; free temporary stuff */
9855 _cur.ClearDataForNextFile();
9856
9857 /* Call any functions that should be run after GRFs have been loaded. */
9858 AfterLoadGRFs();
9859
9860 /* Now revert back to the original situation */
9861 _cur_year = year;
9862 _date = date;
9863 _date_fract = date_fract;
9864 _tick_counter = tick_counter;
9865 _display_opt = display_opt;
9866 }
VEH_AIRCRAFT
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition: vehicle_type.h:27
MapLogX
static uint MapLogX()
Logarithm of the map size along the X side.
Definition: map_func.h:51
GRFConfig::version
uint32 version
NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown.
Definition: newgrf_config.h:165
ResetCustomHouses
static void ResetCustomHouses()
Reset and clear all NewGRF houses.
Definition: newgrf.cpp:8435
AirportSpec::min_year
Year min_year
first year the airport is available
Definition: newgrf_airport.h:109
RoadTypeInfo::flags
RoadTypeFlags flags
Bit mask of road type flags.
Definition: road.h:124
ChangeGRFName
static bool ChangeGRFName(byte langid, const char *str)
Callback function for 'INFO'->'NAME' to add a translation to the newgrf name.
Definition: newgrf.cpp:7805
AllowedSubtags::call_handler
bool call_handler
True if there is a callback function for this node, false if there is a list of subnodes.
Definition: newgrf.cpp:8085
RoadTypeInfo::new_engine
StringID new_engine
Name of an engine for this type of road in the engine preview GUI.
Definition: road.h:105
StationChangeInfo
static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
Define properties for stations.
Definition: newgrf.cpp:1860
ParamSet
static void ParamSet(ByteReader *buf)
Action 0x0D: Set parameter.
Definition: newgrf.cpp:7079
GRFLocation
Definition: newgrf.cpp:348
TE_WATER
@ TE_WATER
Cargo behaves water-like.
Definition: cargotype.h:30
CalculateRefitMasks
static void CalculateRefitMasks()
Precalculate refit masks from cargo classes for all vehicles.
Definition: newgrf.cpp:8788
GRFP_USE_MASK
@ GRFP_USE_MASK
Bitmask to get only the use palette use states.
Definition: newgrf_config.h:68
RoadTypeInfo::toolbar_caption
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition: road.h:101
HouseSpec::removal_cost
byte removal_cost
cost multiplier for removing it
Definition: house.h:103
AllocateSound
SoundEntry * AllocateSound(uint num)
Allocate sound slots.
Definition: newgrf_sound.cpp:31
GRFTempEngineData::UpdateRefittability
void UpdateRefittability(bool non_empty)
Update the summary refittability on setting a refittability property.
Definition: newgrf.cpp:327
INVALID_ENGINE
static const EngineID INVALID_ENGINE
Constant denoting an invalid engine.
Definition: engine_type.h:174
EngineInfo::base_life
Year base_life
Basic duration of engine availability (without random parts). 0xFF means infinite life.
Definition: engine_type.h:135
YearMonthDay::day
Day day
Day (1..31)
Definition: date_type.h:106
Action5Type::sprite_base
SpriteID sprite_base
Load the sprites starting from this sprite.
Definition: newgrf.cpp:6096
OrderSettings::improved_load
bool improved_load
improved loading algorithm
Definition: settings_type.h:451
MAX_NUM_GENDERS
static const uint8 MAX_NUM_GENDERS
Maximum number of supported genders.
Definition: language.h:20
INVALID_AIRPORTTILE
static const uint INVALID_AIRPORTTILE
id for an invalid airport tile
Definition: airport.h:25
RoadTypeInfo
Definition: road.h:75
GRFConfig::num_valid_params
uint8 num_valid_params
NOSAVE: Number of valid parameters (action 0x14)
Definition: newgrf_config.h:172
DuplicateTileTable
static void DuplicateTileTable(AirportSpec *as)
Create a copy of the tile table so it can be freed later without problems.
Definition: newgrf.cpp:3777
NUM_STATIONS_PER_GRF
static const uint NUM_STATIONS_PER_GRF
Number of StationSpecs per NewGRF; limited to 255 to allow extending Action3 with an extended byte la...
Definition: newgrf.cpp:301
PROP_TRAIN_SPEED
@ PROP_TRAIN_SPEED
Max. speed: 1 unit = 1/1.6 mph = 1 km-ish/h.
Definition: newgrf_properties.h:21
GRFConfig::info
GRFTextWrapper info
NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
Definition: newgrf_config.h:161
CargoSpec::callback_mask
uint8 callback_mask
Bitmask of cargo callbacks that have to be called.
Definition: cargotype.h:68
AllowedSubtags::AllowedSubtags
AllowedSubtags()
Create empty subtags object used to identify the end of a list.
Definition: newgrf.cpp:8020
RealSpriteGroup::loaded
const SpriteGroup ** loaded
List of loaded groups (can be SpriteIDs or Callback results)
Definition: newgrf_spritegroup.h:92
GRFFileProps::override
uint16 override
id of the entity been replaced by
Definition: newgrf_commons.h:333
NUM_INDUSTRYTYPES
static const IndustryType NUM_INDUSTRYTYPES
total number of industry types, new and old; limited to 240 because we need some special ids like INV...
Definition: industry_type.h:26
RAILTYPE_MAGLEV
@ RAILTYPE_MAGLEV
Maglev.
Definition: rail_type.h:32
ResetCustomObjects
static void ResetCustomObjects()
Reset and clear all NewObjects.
Definition: newgrf.cpp:8516
RailVehicleInfo::pow_wag_weight
byte pow_wag_weight
Extra weight applied to consist if wagon should be powered.
Definition: engine_type.h:56
Engine::IterateType
static Pool::IterateWrapperFiltered< Engine, EngineTypeFilter > IterateType(VehicleType vt, size_t from=0)
Returns an iterable ensemble of all valid engines of the given type.
Definition: engine_base.h:157
IndustrySpec::map_colour
byte map_colour
colour used for the small map
Definition: industrytype.h:126
LanguageMetadata
Make sure the size is right.
Definition: language.h:92
VE_DISABLE_EFFECT
@ VE_DISABLE_EFFECT
Flag to disable visual effect.
Definition: vehicle_base.h:88
RailtypeInfo::max_speed
uint16 max_speed
Maximum speed for vehicles travelling on this rail type.
Definition: rail.h:228
newgrf_station.h
newgrf_house.h
GRFFile::language_map
struct LanguageMap * language_map
Mappings related to the languages.
Definition: newgrf.h:140
GRFFile::roadtype_list
std::vector< RoadTypeLabel > roadtype_list
Roadtype translation table (road)
Definition: newgrf.h:132
Pool::PoolItem<&_engine_pool >::Get
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:329
EngineOverrideManager::ResetToDefaultMapping
void ResetToDefaultMapping()
Initializes the EngineOverrideManager with the default engines.
Definition: engine.cpp:484
CargoSpec::label
CargoLabel label
Unique label of the cargo type.
Definition: cargotype.h:57
StationSpec::flags
byte flags
Bitmask of flags, bit 0: use different sprite set; bit 1: divide cargo about by station size.
Definition: newgrf_station.h:160
LanguageMap::case_map
std::vector< Mapping > case_map
Mapping of NewGRF and OpenTTD IDs for cases.
Definition: newgrf_text.h:72
PROP_TRAIN_CARGO_CAPACITY
@ PROP_TRAIN_CARGO_CAPACITY
Capacity (if dualheaded: for each single vehicle)
Definition: newgrf_properties.h:24
Direction
Direction
Defines the 8 directions on the map.
Definition: direction_type.h:24
AllowedSubtags::AllowedSubtags
AllowedSubtags(uint32 id, AllowedSubtags *subtags)
Create a branch node with a list of sub-nodes.
Definition: newgrf.cpp:8067
GRFConfig::error
GRFError * error
NOSAVE: Error/Warning during GRF loading (Action 0x0B)
Definition: newgrf_config.h:163
GameSettings::station
StationSettings station
settings related to station management
Definition: settings_type.h:571
WChar
char32_t WChar
Type for wide characters, i.e.
Definition: string_type.h:35
ResetCustomAirports
static void ResetCustomAirports()
Reset and clear all NewGRF airports.
Definition: newgrf.cpp:8450
GRFTextList
std::vector< GRFText > GRFTextList
A GRF text with a list of translations.
Definition: newgrf_text.h:31
PROP_ROADVEH_TRACTIVE_EFFORT
@ PROP_ROADVEH_TRACTIVE_EFFORT
Tractive effort coefficient in 1/256.
Definition: newgrf_properties.h:38
SNOW_LINE_DAYS
static const uint SNOW_LINE_DAYS
Number of days in each month in the snow line table.
Definition: landscape.h:17
ObjectChangeInfo
static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
Define properties for objects.
Definition: newgrf.cpp:4024
FioReadBlock
void FioReadBlock(void *ptr, size_t size)
Read a block.
Definition: fileio.cpp:161
EngineIDMapping::grfid
uint32 grfid
The GRF ID of the file the entity belongs to.
Definition: engine_base.h:164
RoadTypeInfo::menu_text
StringID menu_text
Name of this rail type in the main toolbar dropdown.
Definition: road.h:102
IndustryProductionSpriteGroup::subtract_input
int16 subtract_input[INDUSTRY_NUM_INPUTS]
Take this much of the input cargo (can be negative, is indirect in cb version 1+)
Definition: newgrf_spritegroup.h:281
usererror
void CDECL usererror(const char *s,...)
Error handling for fatal user errors.
Definition: openttd.cpp:102
DeterministicSpriteGroupRange
Definition: newgrf_spritegroup.h:163
NUM_INDUSTRYTYPES_PER_GRF
static const IndustryType NUM_INDUSTRYTYPES_PER_GRF
maximum number of industry types per NewGRF; limited to 128 because bit 7 has a special meaning in so...
Definition: industry_type.h:23
GB
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
Definition: bitmath_func.hpp:32
SPR_SHORE_BASE
static const SpriteID SPR_SHORE_BASE
shore tiles - action 05-0D
Definition: sprites.h:218
TLF_DODRAW
@ TLF_DODRAW
Only draw sprite if value of register TileLayoutRegisters::dodraw is non-zero.
Definition: newgrf_commons.h:36
ReusableBuffer
A reusable buffer that can be used for places that temporary allocate a bit of memory and do that ver...
Definition: alloc_type.hpp:24
AircraftVehicleInfo::subtype
byte subtype
Type of aircraft.
Definition: engine_type.h:101
OBJECT_FLAG_2CC_COLOUR
@ OBJECT_FLAG_2CC_COLOUR
Object wants 2CC colour mapping.
Definition: newgrf_object.h:34
ShipVehicleChangeInfo
static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for ships.
Definition: newgrf.cpp:1534
FioReadWord
uint16 FioReadWord()
Read a word (16 bits) from the file (in low endian format).
Definition: fileio.cpp:140
GetRoadTypeByLabel
RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels)
Get the road type for a given label.
Definition: road.cpp:243
HouseSpec::random_colour
byte random_colour[4]
4 "random" colours
Definition: house.h:116
PROP_ROADVEH_COST_FACTOR
@ PROP_ROADVEH_COST_FACTOR
Purchase cost.
Definition: newgrf_properties.h:34
GCS_ACTIVATED
@ GCS_ACTIVATED
GRF file has been activated.
Definition: newgrf_config.h:39
ObjectSpec
Allow incrementing of ObjectClassID variables.
Definition: newgrf_object.h:58
CanalProperties::callback_mask
uint8 callback_mask
Bitmask of canal callbacks that have to be called.
Definition: newgrf.h:40
RailtypeInfo::menu_text
StringID menu_text
Name of this rail type in the main toolbar dropdown.
Definition: rail.h:175
ObjectSpec::grf_prop
GRFFilePropsBase< 2 > grf_prop
Properties related the the grf file.
Definition: newgrf_object.h:60
GrfProcessingState::grffile
GRFFile * grffile
Currently processed GRF file.
Definition: newgrf.cpp:103
RoadTypeInfo::strings
struct RoadTypeInfo::@44 strings
Strings associated with the rail type.
ObjectFlags
ObjectFlags
Various object behaviours.
Definition: newgrf_object.h:24
DrawTileSeqStruct::IsParentSprite
bool IsParentSprite() const
Check whether this is a parent sprite with a boundingbox.
Definition: sprite.h:47
ConstructionSettings::max_heightlevel
uint8 max_heightlevel
maximum allowed heightlevel
Definition: settings_type.h:317
BridgeSpec::flags
byte flags
bit 0 set: disable drawing of far pillars.
Definition: bridge.h:52
ObjectSpec::build_cost_multiplier
uint8 build_cost_multiplier
Build cost multiplier per tile.
Definition: newgrf_object.h:66
BridgeSpec::avail_year
Year avail_year
the year where it becomes available
Definition: bridge.h:42
ResetCustomIndustries
static void ResetCustomIndustries()
Reset and clear all NewGRF industries.
Definition: newgrf.cpp:8487
PROP_TRAIN_RUNNING_COST_FACTOR
@ PROP_TRAIN_RUNNING_COST_FACTOR
Yearly runningcost (if dualheaded: sum of both vehicles)
Definition: newgrf_properties.h:23
smallmap_gui.h
_grf_files
static std::vector< GRFFile * > _grf_files
List of all loaded GRF files.
Definition: newgrf.cpp:66
SPRITE_WIDTH
@ SPRITE_WIDTH
number of bits for the sprite number
Definition: sprites.h:1519
GameCreationSettings::landscape
byte landscape
the landscape we're currently in
Definition: settings_type.h:305
StringIDMapping::grfid
uint32 grfid
Source NewGRF.
Definition: newgrf.cpp:462
ShipVehicleInfo::canal_speed_frac
byte canal_speed_frac
Fraction of maximum speed for canal/river tiles.
Definition: engine_type.h:75
TLF_CHILD_X_OFFSET
@ TLF_CHILD_X_OFFSET
Add signed offset to child sprite X positions from register TileLayoutRegisters::delta....
Definition: newgrf_commons.h:44
RoadTypeInfo::introduces_roadtypes
RoadTypes introduces_roadtypes
Bitmask of which other roadtypes are introduced when this roadtype is introduced.
Definition: road.h:174
_engine_counts
const uint8 _engine_counts[4]
Number of engines of each vehicle type in original engine data.
Definition: engine.cpp:50
AllowedSubtags::AllowedSubtags
AllowedSubtags(uint32 id, DataHandler handler)
Create a binary leaf node.
Definition: newgrf.cpp:8030
GRFFile::price_base_multipliers
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition: newgrf.h:146
FeatureTownName
static void FeatureTownName(ByteReader *buf)
Action 0x0F - Define Town names.
Definition: newgrf.cpp:7429
grfmsg
void CDECL grfmsg(int severity, const char *str,...)
DEBUG() function dedicated to newGRF debugging messages Function is essentially the same as DEBUG(grf...
Definition: newgrf.cpp:379
_cur_year
Year _cur_year
Current year, starting at 0.
Definition: date.cpp:26
IndustriesChangeInfo
static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
Define properties for industries.
Definition: newgrf.cpp:3397
DeterministicSpriteGroup
Definition: newgrf_spritegroup.h:170
TileLayoutRegisters::sprite
uint8 sprite
Register specifying a signed offset for the sprite.
Definition: newgrf_commons.h:94
PROP_TRAIN_TRACTIVE_EFFORT
@ PROP_TRAIN_TRACTIVE_EFFORT
Tractive effort coefficient in 1/256.
Definition: newgrf_properties.h:27
AllowedSubtags::branch
BranchHandler branch
Callback function for a branch node, only valid if type == 'C' && call_handler.
Definition: newgrf.cpp:8082
FioOpenFile
void FioOpenFile(int slot, const std::string &filename, Subdirectory subdir)
Open a slotted file.
Definition: fileio.cpp:196
HandleNodes
static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
Handle the contents of a 'C' choice of an Action14.
Definition: newgrf.cpp:8277
HouseSpec::accepts_cargo
CargoID accepts_cargo[HOUSE_NUM_ACCEPTS]
input cargo slots
Definition: house.h:108
RoadTypeInfo::sorting_order
byte sorting_order
The sorting order of this roadtype for the toolbar dropdown.
Definition: road.h:179
AirportSpec::size_y
byte size_y
size of airport in y direction
Definition: newgrf_airport.h:106
CargoSpec::town_effect
TownEffect town_effect
The effect that delivering this cargo type has on towns. Also affects destination of subsidies.
Definition: cargotype.h:66
NewGRFSpriteLayout::AllocateRegisters
void AllocateRegisters()
Allocate memory for register modifiers.
Definition: newgrf_commons.cpp:636
RealSpriteGroup::num_loaded
byte num_loaded
Number of loaded groups.
Definition: newgrf_spritegroup.h:90
Pool::CleanPool
virtual void CleanPool()
Virtual method that deletes all items in the pool.
PALETTE_MODIFIER_COLOUR
@ PALETTE_MODIFIER_COLOUR
this bit is set when a recolouring process is in action
Definition: sprites.h:1534
BASESET_DIR
@ BASESET_DIR
Subdirectory for all base data (base sets, intro game)
Definition: fileio_type.h:116
currency.h
GRFConfig::num_params
uint8 num_params
Number of used parameters.
Definition: newgrf_config.h:171
GetNewEngine
static Engine * GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access=false)
Returns the engine associated to a certain internal_id, resp.
Definition: newgrf.cpp:599
_date_fract
DateFract _date_fract
Fractional part of the day.
Definition: date.cpp:29
TileLayoutRegisters::parent
uint8 parent[3]
Registers for signed offsets for the bounding box position of parent sprites.
Definition: newgrf_commons.h:99
NamePart::prob
byte prob
The relative probability of the following name to appear in the bottom 7 bits.
Definition: newgrf_townname.h:20
Price
Price
Enumeration of all base prices for use with Prices.
Definition: economy_type.h:74
PROP_AIRCRAFT_MAIL_CAPACITY
@ PROP_AIRCRAFT_MAIL_CAPACITY
Mail Capacity.
Definition: newgrf_properties.h:52
AirportSpec::name
StringID name
name of this airport
Definition: newgrf_airport.h:111
INVALID_ROADTYPE
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition: road_type.h:27
FinaliseCanals
static void FinaliseCanals()
Set to use the correct action0 properties for each canal feature.
Definition: newgrf.cpp:8891
RailtypeInfo::replace_text
StringID replace_text
Text used in the autoreplace GUI.
Definition: rail.h:177
TE_FOOD
@ TE_FOOD
Cargo behaves food/fizzy-drinks-like.
Definition: cargotype.h:31
GRFFile::grf_features
uint32 grf_features
Bitset of GrfSpecFeature the grf uses.
Definition: newgrf.h:145
LanguageMap::plural_form
int plural_form
The plural form used for this language.
Definition: newgrf_text.h:73
CurrencySpec::symbol_pos
byte symbol_pos
The currency symbol is represented by two possible values, prefix and suffix Usage of one or the othe...
Definition: currency.h:87
EC_STEAM
@ EC_STEAM
Steam rail engine.
Definition: engine_type.h:34
PriceBaseSpec::grf_feature
uint grf_feature
GRF Feature that decides whether price multipliers apply locally or globally, #GSF_END if none.
Definition: economy_type.h:193
AircraftVehicleInfo::passenger_capacity
uint16 passenger_capacity
Passenger capacity (persons).
Definition: engine_type.h:106
IndustrySpec::removal_cost_multiplier
uint32 removal_cost_multiplier
Base removal cost multiplier.
Definition: industrytype.h:110
RandomizedSpriteGroup::cmp_mode
RandomizedSpriteGroupCompareMode cmp_mode
Check for these triggers:
Definition: newgrf_spritegroup.h:202
DeterministicSpriteGroupAdjust::parameter
byte parameter
Used for variables between 0x60 and 0x7F inclusive.
Definition: newgrf_spritegroup.h:154
VE_DEFAULT
@ VE_DEFAULT
Default value to indicate that visual effect should be based on engine class.
Definition: vehicle_base.h:92
A5BLOCK_INVALID
@ A5BLOCK_INVALID
unknown/not-implemented type
Definition: newgrf.cpp:6091
Action5BlockType
Action5BlockType
The type of action 5 type.
Definition: newgrf.cpp:6088
ChangeGRFParamLimits
static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter.
Definition: newgrf.cpp:7952
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition: pool_type.hpp:227
PROP_ROADVEH_SHORTEN_FACTOR
@ PROP_ROADVEH_SHORTEN_FACTOR
Shorter vehicles.
Definition: newgrf_properties.h:40
BridgeSpec::sprite_table
PalSpriteID ** sprite_table
table of sprites for drawing the bridge
Definition: bridge.h:51
IsValidNewGRFImageIndex
static bool IsValidNewGRFImageIndex(uint8 image_index)
Helper to check whether an image index is valid for a particular NewGRF vehicle.
Definition: newgrf.cpp:205
AirportSpec::max_year
Year max_year
last year the airport is available
Definition: newgrf_airport.h:110
CargoSpec::Get
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
Definition: cargotype.h:117
IndustryProductionSpriteGroup::num_input
uint8 num_input
How many subtract_input values are valid.
Definition: newgrf_spritegroup.h:280
ResetPersistentNewGRFData
void ResetPersistentNewGRFData()
Reset NewGRF data which is stored persistently in savegames.
Definition: newgrf.cpp:8649
PROP_SHIP_CARGO_CAPACITY
@ PROP_SHIP_CARGO_CAPACITY
Capacity.
Definition: newgrf_properties.h:44
TileLayoutRegisters::palette_var10
uint8 palette_var10
Value for variable 10 when resolving the palette.
Definition: newgrf_commons.h:103
HouseExtraFlags
HouseExtraFlags
Definition: house.h:88
_grf_cont_v2_sig
const byte _grf_cont_v2_sig[8]
Signature of a container version 2 GRF.
_bridge
BridgeSpec _bridge[MAX_BRIDGES]
The specification of all bridges.
Definition: tunnelbridge_cmd.cpp:49
PalSpriteID::sprite
SpriteID sprite
The 'real' sprite.
Definition: gfx_type.h:23
GrfProcessingState::ClearDataForNextFile
void ClearDataForNextFile()
Clear temporary data before processing the next file in the current loading stage.
Definition: newgrf.cpp:115
GrfProcessingState::grf_container_ver
byte grf_container_ver
Container format of the current GRF file.
Definition: newgrf.cpp:106
PROP_AIRCRAFT_RUNNING_COST_FACTOR
@ PROP_AIRCRAFT_RUNNING_COST_FACTOR
Yearly runningcost.
Definition: newgrf_properties.h:50
RAILTYPE_MONO
@ RAILTYPE_MONO
Monorail.
Definition: rail_type.h:31
HouseSpec::enabled
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition: house.h:111
AirportSpec::noise_level
byte noise_level
noise that this airport generates
Definition: newgrf_airport.h:107
ChangeGRFVersion
static bool ChangeGRFVersion(size_t len, ByteReader *buf)
Callback function for 'INFO'->'VRSN' to the version of the NewGRF.
Definition: newgrf.cpp:7886
SortIndustryTypes
void SortIndustryTypes()
Initialize the list of sorted industry types.
Definition: industry_gui.cpp:207
HasBit
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Definition: bitmath_func.hpp:103
ResetPriceBaseMultipliers
void ResetPriceBaseMultipliers()
Reset changes to the price base multipliers.
Definition: economy.cpp:871
ChangeGRFParamName
static bool ChangeGRFParamName(byte langid, const char *str)
Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter.
Definition: newgrf.cpp:7921
ResetRailTypes
void ResetRailTypes()
Reset all rail type information to its default values.
Definition: rail_cmd.cpp:63
GrfProcessingState::spritesets
std::map< uint, SpriteSet > spritesets[GSF_END]
Currently referenceable spritesets.
Definition: newgrf.cpp:94
GrfProcessingState::spriteid
SpriteID spriteid
First available SpriteID for loading realsprites.
Definition: newgrf.cpp:99
RailtypeInfo
This struct contains all the info that is needed to draw and construct tracks.
Definition: rail.h:124
WaterFeature::callback_mask
uint8 callback_mask
Bitmask of canal callbacks that have to be called.
Definition: newgrf_canal.h:25
ClrBit
static T ClrBit(T &x, const uint8 y)
Clears a bit in a variable.
Definition: bitmath_func.hpp:151
VehicleSettings::wagon_speed_limits
bool wagon_speed_limits
enable wagon speed limits
Definition: settings_type.h:466
CIR_INVALID_ID
@ CIR_INVALID_ID
Attempt to modify an invalid ID.
Definition: newgrf.cpp:991
GRFParameterInfo::param_nr
byte param_nr
GRF parameter to store content in.
Definition: newgrf_config.h:140
TLF_CUSTOM_PALETTE
@ TLF_CUSTOM_PALETTE
Palette is from Action 1 (moved to SPRITE_MODIFIER_CUSTOM_SPRITE in palette during loading).
Definition: newgrf_commons.h:39
RailtypeInfo::grffile
const GRFFile * grffile[RTSG_END]
NewGRF providing the Action3 for the railtype.
Definition: rail.h:273
SetNewGRFOverride
static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
Set the override for a NewGRF.
Definition: newgrf.cpp:585
_tags_info
AllowedSubtags _tags_info[]
Action14 tags for the INFO node.
Definition: newgrf.cpp:8173
Year
int32 Year
Type for the year, note: 0 based, i.e. starts at the year 0.
Definition: date_type.h:18
ReadGRFSpriteOffsets
void ReadGRFSpriteOffsets(byte container_version)
Parse the sprite section of GRFs.
Definition: spritecache.cpp:517
vehicle_base.h
GRFUnsafe
static void GRFUnsafe(ByteReader *buf)
Set the current NewGRF as unsafe for static use.
Definition: newgrf.cpp:8303
GRFParameterInfo::def_value
uint32 def_value
Default value of this parameter.
Definition: newgrf_config.h:139
ROADTYPE_END
@ ROADTYPE_END
Used for iterations.
Definition: road_type.h:26
fileio_func.h
GCS_NOT_FOUND
@ GCS_NOT_FOUND
GRF file was not found in the local cache.
Definition: newgrf_config.h:37
ConvertTTDBasePrice
static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
Converts TTD(P) Base Price pointers into the enum used by OTTD See http://wiki.ttdpatch....
Definition: newgrf.cpp:966
newgrf_airport.h
SetupCargoForClimate
void SetupCargoForClimate(LandscapeID l)
Set up the default cargo types for the given landscape type.
Definition: cargotype.cpp:39
build_industry.h
GRFTempEngineData::ctt_include_mask
CargoTypes ctt_include_mask
Cargo types always included in the refit mask.
Definition: newgrf.cpp:320
HouseSpec::building_name
StringID building_name
building name
Definition: house.h:104
ObjectSpec::end_of_life_date
Date end_of_life_date
When can't this object be built anymore.
Definition: newgrf_object.h:69
SetupEngines
void SetupEngines()
Initialise the engine pool with the data from the original vehicles.
Definition: engine.cpp:540
GetGRFContainerVersion
byte GetGRFContainerVersion()
Get the container version of the currently opened GRF file.
Definition: newgrf.cpp:9321
OverrideManagerBase::GetID
virtual uint16 GetID(uint8 grf_local_id, uint32 grfid) const
Return the ID (if ever available) of a previously inserted entity.
Definition: newgrf_commons.cpp:102
GRFConfig::ident
GRFIdentifier ident
grfid and md5sum to uniquely identify newgrfs
Definition: newgrf_config.h:157
newgrf_townname.h
TE_NONE
@ TE_NONE
Cargo has no effect.
Definition: cargotype.h:26
AircraftVehicleInfo::max_speed
uint16 max_speed
Maximum speed (1 unit = 8 mph = 12.8 km-ish/h)
Definition: engine_type.h:104
AirportSpec::ResetAirports
static void ResetAirports()
This function initializes the airportspec array.
Definition: newgrf_airport.cpp:155
GCF_COPY
@ GCF_COPY
The data is copied from a grf in _all_grfs.
Definition: newgrf_config.h:27
CargoSpec
Specification of a cargo type.
Definition: cargotype.h:55
AllowedSubtags::AllowedSubtags
AllowedSubtags(uint32 id, TextHandler handler)
Create a text leaf node.
Definition: newgrf.cpp:8042
ReusableBuffer::Allocate
T * Allocate(size_t count)
Get buffer of at least count times T.
Definition: alloc_type.hpp:42
GRFConfig::status
GRFStatus status
NOSAVE: GRFStatus, enum.
Definition: newgrf_config.h:168
GetNewGRFSoundID
SoundID GetNewGRFSoundID(const GRFFile *file, SoundID sound_id)
Resolve NewGRF sound ID.
Definition: newgrf_sound.cpp:168
VE_TYPE_COUNT
@ VE_TYPE_COUNT
Number of bits used for the effect type.
Definition: vehicle_base.h:82
town.h
ORIGINAL_BASE_YEAR
static const Year ORIGINAL_BASE_YEAR
The minimum starting year/base year of the original TTD.
Definition: date_type.h:49
NUM_OBJECTS_PER_GRF
static const ObjectType NUM_OBJECTS_PER_GRF
Number of supported objects per NewGRF; limited to 255 to allow extending Action3 with an extended by...
Definition: object_type.h:22
RailVehicleInfo::power
uint16 power
Power of engine (hp); For multiheaded engines the sum of both engine powers.
Definition: engine_type.h:48
GRFP_GRF_UNSET
@ GRFP_GRF_UNSET
The NewGRF provided no information.
Definition: newgrf_config.h:70
EngineInfo
Information about a vehicle.
Definition: engine_type.h:132
ChangeGRFParamType
static bool ChangeGRFParamType(size_t len, ByteReader *buf)
Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter.
Definition: newgrf.cpp:7935
DSGA_OP_ADD
@ DSGA_OP_ADD
a + b
Definition: newgrf_spritegroup.h:124
GMB_TRAIN_WIDTH_32_PIXELS
@ GMB_TRAIN_WIDTH_32_PIXELS
Use 32 pixels per train vehicle in depot gui and vehicle details. Never set in the global variable;.
Definition: newgrf.h:60
IndustrySpec::station_name
StringID station_name
Default name for nearby station.
Definition: industrytype.h:132
CreateGroupFromGroupID
static const SpriteGroup * CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
Helper function to either create a callback or a result sprite group.
Definition: newgrf.cpp:4945
DIR_W
@ DIR_W
West.
Definition: direction_type.h:32
_display_opt
byte _display_opt
What do we want to draw/do?
Definition: transparency_gui.cpp:26
OverrideManagerBase::Add
void Add(uint8 local_id, uint32 grfid, uint entity_type)
Since the entity IDs defined by the GRF file does not necessarily correlate to those used by the game...
Definition: newgrf_commons.cpp:72
EngineInfo::base_intro
Date base_intro
Basic date of engine introduction (without random parts).
Definition: engine_type.h:133
CIR_SUCCESS
@ CIR_SUCCESS
Variable was parsed and read.
Definition: newgrf.cpp:987
MAX_SPRITEGROUP
static const uint MAX_SPRITEGROUP
Maximum GRF-local ID for a spritegroup.
Definition: newgrf.cpp:82
GRFLoadedFeatures::used_liveries
uint64 used_liveries
Bitmask of LiveryScheme used by the defined engines.
Definition: newgrf.h:176
HouseSpec::max_year
Year max_year
last year it can be built
Definition: house.h:101
VehicleSettings::road_side
byte road_side
the side of the road vehicles drive on
Definition: settings_type.h:477
RoadTypeInfo::replace_text
StringID replace_text
Text used in the autoreplace GUI.
Definition: road.h:104
AllowedSubtags::text
TextHandler text
Callback function for a text node, only valid if type == 'T'.
Definition: newgrf.cpp:8079
VSG_SCOPE_PARENT
@ VSG_SCOPE_PARENT
Related object of the resolved one.
Definition: newgrf_spritegroup.h:104
RailtypeInfo::fallback_railtype
byte fallback_railtype
Original railtype number to use when drawing non-newgrf railtypes, or when drawing stations.
Definition: rail.h:198
Engine
Definition: engine_base.h:21
VEH_ROAD
@ VEH_ROAD
Road vehicle type.
Definition: vehicle_type.h:25
EngineIDMapping::internal_id
uint16 internal_id
The internal ID within the GRF file.
Definition: engine_base.h:165
GRFParameterInfo::type
GRFParameterType type
The type of this parameter.
Definition: newgrf_config.h:136
SoundEffectChangeInfo
static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
Define properties for sound effects.
Definition: newgrf.cpp:3052
_tags_parameters
AllowedSubtags _tags_parameters[]
Action14 parameter tags.
Definition: newgrf.cpp:8129
RoadVehicleInfo::roadtype
RoadType roadtype
Road type.
Definition: engine_type.h:125
RoadTypeInfo::introduction_date
Date introduction_date
Introduction date.
Definition: road.h:163
ROADTYPE_ROAD
@ ROADTYPE_ROAD
Basic road type.
Definition: road_type.h:24
SoundEntry::grf_container_ver
byte grf_container_ver
NewGRF container version if the sound is from a NewGRF.
Definition: sound_type.h:22
fios.h
TranslateGRFStrings
static void TranslateGRFStrings(ByteReader *buf)
Action 0x13.
Definition: newgrf.cpp:7750
SmallMap::Insert
bool Insert(const T &key, const U &data)
Adds new item to this map.
Definition: smallmap_type.hpp:127
BridgeSpec::speed
uint16 speed
maximum travel speed (1 unit = 1/1.6 mph = 1 km-ish/h)
Definition: bridge.h:46
FinalisePriceBaseMultipliers
static void FinalisePriceBaseMultipliers()
Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them...
Definition: newgrf.cpp:9515
TranslateTTDPatchCodes
std::string TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newlines, const std::string &str, StringControlCode byte80)
Translate TTDPatch string codes into something OpenTTD can handle (better).
Definition: newgrf_text.cpp:241
MemCpyT
static void MemCpyT(T *destination, const T *source, size_t num=1)
Type-safe version of memcpy().
Definition: mem_func.hpp:23
TLF_BB_Z_OFFSET
@ TLF_BB_Z_OFFSET
Add signed offset to bounding box Z positions from register TileLayoutRegisters::delta....
Definition: newgrf_commons.h:42
GRFTempEngineData::rv_max_speed
uint8 rv_max_speed
Temporary storage of RV prop 15, maximum speed in mph/0.8.
Definition: newgrf.cpp:319
ObjectSpec::size
uint8 size
The size of this objects; low nibble for X, high nibble for Y.
Definition: newgrf_object.h:65
GRFFile::GetParam
uint32 GetParam(uint number) const
Get GRF Parameter with range checking.
Definition: newgrf.h:152
AirportSpec
Defines the data structure for an airport.
Definition: newgrf_airport.h:98
EngineOverrideManager::GetID
EngineID GetID(VehicleType type, uint16 grf_local_id, uint32 grfid)
Looks up an EngineID in the EngineOverrideManager.
Definition: engine.cpp:507
ObjectSpec::callback_mask
uint16 callback_mask
Bitmask of requested/allowed callbacks.
Definition: newgrf_object.h:72
NUM_HOUSES_PER_GRF
static const HouseID NUM_HOUSES_PER_GRF
Number of supported houses per NewGRF; limited to 255 to allow extending Action3 with an extended byt...
Definition: house.h:25
genworld.h
RailtypeInfo::sorting_order
byte sorting_order
The sorting order of this railtype for the toolbar dropdown.
Definition: rail.h:268
TileLayoutRegisters
Additional modifiers for items in sprite layouts.
Definition: newgrf_commons.h:91
AnimationInfo::speed
uint8 speed
The speed, i.e. the amount of time between frames.
Definition: newgrf_animation_type.h:21
TileLayoutRegisters::dodraw
uint8 dodraw
Register deciding whether the sprite shall be drawn at all. Non-zero means drawing.
Definition: newgrf_commons.h:93
GRFIdentifier::grfid
uint32 grfid
GRF ID (defined by Action 0x08)
Definition: newgrf_config.h:84
GRFP_BLT_UNSET
@ GRFP_BLT_UNSET
The NewGRF provided no information or doesn't care about a 32 bpp blitter.
Definition: newgrf_config.h:76
CargoLabel
uint32 CargoLabel
Globally unique label of a cargo type.
Definition: cargotype.h:21
ObjectSpec::animation
AnimationInfo animation
Information about the animation.
Definition: newgrf_object.h:71
CIR_UNHANDLED
@ CIR_UNHANDLED
Variable was parsed but unread.
Definition: newgrf.cpp:989
RoadVehicleInfo::air_drag
uint8 air_drag
Coefficient of air drag.
Definition: engine_type.h:122
AirportSpec::maintenance_cost
uint16 maintenance_cost
maintenance cost multiplier
Definition: newgrf_airport.h:115
VSG_SCOPE_SELF
@ VSG_SCOPE_SELF
Resolved object itself.
Definition: newgrf_spritegroup.h:103
CargoSpec::bitnum
uint8 bitnum
Cargo bit number, is INVALID_CARGO for a non-used spec.
Definition: cargotype.h:56
SPR_AQUEDUCT_BASE
static const SpriteID SPR_AQUEDUCT_BASE
Sprites for the Aqueduct.
Definition: sprites.h:180
RailVehicleInfo::cost_factor
byte cost_factor
Purchase cost factor; For multiheaded engines the sum of both engine prices.
Definition: engine_type.h:45
StationSpec::renderdata
NewGRFSpriteLayout * renderdata
Array of tile layouts.
Definition: newgrf_station.h:148
DeterministicSpriteGroupAdjustOperation
DeterministicSpriteGroupAdjustOperation
Definition: newgrf_spritegroup.h:123
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition: settings_type.h:560
GRFParameterInfo::num_bit
byte num_bit
Number of bits to use for this parameter.
Definition: newgrf_config.h:142
RAILTYPE_ELECTRIC
@ RAILTYPE_ELECTRIC
Electric rails.
Definition: rail_type.h:30
RandomizedSpriteGroup::var_scope
VarSpriteGroupScope var_scope
Take this object:
Definition: newgrf_spritegroup.h:200
GCF_INVALID
@ GCF_INVALID
GRF is unusable with this version of OpenTTD.
Definition: newgrf_config.h:30
AllocateRoadType
RoadType AllocateRoadType(RoadTypeLabel label, RoadTramType rtt)
Allocate a new road type label.
Definition: road_cmd.cpp:138
FioReadDword
uint32 FioReadDword()
Read a double word (32 bits) from the file (in low endian format).
Definition: fileio.cpp:150
AirportChangeInfo
static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
Define properties for airports.
Definition: newgrf.cpp:3806
IndustryTileLayout
std::vector< IndustryTileLayoutTile > IndustryTileLayout
A complete tile layout for an industry is a list of tiles.
Definition: industrytype.h:102
GCF_INIT_ONLY
@ GCF_INIT_ONLY
GRF file is processed up to GLS_INIT.
Definition: newgrf_config.h:28
EC_ELECTRIC
@ EC_ELECTRIC
Electric rail engine.
Definition: engine_type.h:36
AddGRFString
StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid_to_add, bool new_scheme, bool allow_newlines, const char *text_to_add, StringID def_string)
Add the new read string into our structure.
Definition: newgrf_text.cpp:552
IsInsideMM
static bool IsInsideMM(const T x, const size_t min, const size_t max)
Checks if a value is in an interval.
Definition: math_func.hpp:204
GetFileByGRFID
static GRFFile * GetFileByGRFID(uint32 grfid)
Obtain a NewGRF file by its grfID.
Definition: newgrf.cpp:396
SpriteID
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:17
ObjectSpec::introduction_date
Date introduction_date
From when can this object be built.
Definition: newgrf_object.h:68
TE_MAIL
@ TE_MAIL
Cargo behaves mail-like.
Definition: cargotype.h:28
StringIDMapping::target
StringID * target
Destination for mapping result.
Definition: newgrf.cpp:464
StationSpec::tiles
uint tiles
Number of tile layouts.
Definition: newgrf_station.h:147
RailtypeInfo::introduction_required_railtypes
RailTypes introduction_required_railtypes
Bitmask of railtypes that are required for this railtype to be introduced at a given introduction_dat...
Definition: rail.h:258
BridgeSpec
Struct containing information about a single bridge type.
Definition: bridge.h:41
RailtypeInfo::name
StringID name
Name of this rail type.
Definition: rail.h:173
IndustrySpec::closure_text
StringID closure_text
Message appearing when the industry closes.
Definition: industrytype.h:129
EngineInfo::lifelength
Year lifelength
Lifetime of a single vehicle.
Definition: engine_type.h:134
Engine::GetGRF
const GRFFile * GetGRF() const
Retrieve the NewGRF the engine is tied to.
Definition: engine_base.h:138
GrfProcessingState::SpriteSet::sprite
SpriteID sprite
SpriteID of the first sprite of the set.
Definition: newgrf.cpp:89
RandomizedSpriteGroup::num_groups
byte num_groups
must be power of 2
Definition: newgrf_spritegroup.h:207
GRFFile::traininfo_vehicle_pitch
int traininfo_vehicle_pitch
Vertical offset for drawing train images in depot GUI and vehicle details.
Definition: newgrf.h:142
AirportTileSpec::ResetAirportTiles
static void ResetAirportTiles()
This function initializes the tile array of AirportTileSpec.
Definition: newgrf_airporttiles.cpp:57
TLF_KNOWN_FLAGS
@ TLF_KNOWN_FLAGS
Known flags. Any unknown set flag will disable the GRF.
Definition: newgrf_commons.h:50
TE_PASSENGERS
@ TE_PASSENGERS
Cargo behaves passenger-like.
Definition: cargotype.h:27
ShipVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:73
RoadVehicleInfo::max_speed
uint16 max_speed
Maximum speed (1 unit = 1/3.2 mph = 0.5 km-ish/h)
Definition: engine_type.h:117
DrawTileSprites::ground
PalSpriteID ground
Palette and sprite for the ground.
Definition: sprite.h:59
HouseSpec::extra_flags
HouseExtraFlags extra_flags
some more flags
Definition: house.h:118
GetRailTypeInfo
static const RailtypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition: rail.h:304
AirportTileSpec
Defines the data structure of each individual tile of an airport.
Definition: newgrf_airporttiles.h:66
HouseSpec::probability
byte probability
Relative probability of appearing (16 is the standard value)
Definition: house.h:117
NETWORK_MAX_GRF_COUNT
static const uint NETWORK_MAX_GRF_COUNT
Maximum number of GRFs that can be sent.
Definition: config.h:58
IndustryTileSpec::special_flags
IndustryTileSpecialFlags special_flags
Bitmask of extra flags used by the tile.
Definition: industrytype.h:170
StationSpec::cls_id
StationClassID cls_id
The class to which this spec belongs.
Definition: newgrf_station.h:125
EC_MAGLEV
@ EC_MAGLEV
Maglev engine.
Definition: engine_type.h:38
GRFTempEngineData::Refittability
Refittability
Summary state of refittability properties.
Definition: newgrf.cpp:306
RealSpriteGroup::loading
const SpriteGroup ** loading
List of loading groups (can be SpriteIDs or Callback results)
Definition: newgrf_spritegroup.h:93
NFO_UTF8_IDENTIFIER
static const WChar NFO_UTF8_IDENTIFIER
This character, the thorn ('þ'), indicates a unicode string to NFO.
Definition: newgrf_text.h:22
IndustryProductionSpriteGroup::num_output
uint8 num_output
How many add_output values are valid.
Definition: newgrf_spritegroup.h:283
newgrf_airporttiles.h
GameSettings::order
OrderSettings order
settings related to orders
Definition: settings_type.h:567
Pool::PoolItem<&_engine_pool >::GetPoolSize
static size_t GetPoolSize()
Returns first unused index.
Definition: pool_type.hpp:350
InitGRFTownGeneratorNames
void InitGRFTownGeneratorNames()
Allocate memory for the NewGRF town names.
Definition: newgrf_townname.cpp:109
GRFP_GRF_DOS
@ GRFP_GRF_DOS
The NewGRF says the DOS palette can be used.
Definition: newgrf_config.h:71
_grm_engines
static uint32 _grm_engines[256]
Contains the GRF ID of the owner of a vehicle if it has been reserved.
Definition: newgrf.cpp:343
FioSkipBytes
void FioSkipBytes(int n)
Skip n bytes ahead in the file.
Definition: fileio.cpp:124
MAX_CATCHMENT
@ MAX_CATCHMENT
Maximum catchment for airports with "modified catchment" enabled.
Definition: station_type.h:84
AnimationInfo::frames
uint8 frames
The number of frames.
Definition: newgrf_animation_type.h:19
DrawTileSeqStruct::delta_x
int8 delta_x
0x80 is sequence terminator
Definition: sprite.h:26
GRFLoadedFeatures::has_2CC
bool has_2CC
Set if any vehicle is loaded which uses 2cc (two company colours).
Definition: newgrf.h:175
PROP_ROADVEH_SPEED
@ PROP_ROADVEH_SPEED
Max. speed: 1 unit = 1/0.8 mph = 2 km-ish/h.
Definition: newgrf_properties.h:37
RailVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:57
TileIndexDiffC::y
int16 y
The y value of the coordinate.
Definition: map_type.h:59
GrfProcessingState::HasValidSpriteSets
bool HasValidSpriteSets(byte feature) const
Check whether there are any valid spritesets for a feature.
Definition: newgrf.cpp:151
DisableStaticNewGRFInfluencingNonStaticNewGRFs
static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
Disable a static NewGRF when it is influencing another (non-static) NewGRF as this could cause desync...
Definition: newgrf.cpp:6517
CargoSpec::Index
CargoID Index() const
Determines index of this cargospec.
Definition: cargotype.h:88
AirportSpec::rotation
const Direction * rotation
the rotation of each tiletable
Definition: newgrf_airport.h:101
EngineID
uint16 EngineID
Unique identification number of an engine.
Definition: engine_type.h:21
SHORE_REPLACE_NONE
@ SHORE_REPLACE_NONE
No shore sprites were replaced.
Definition: newgrf.h:162
RailVehicleInfo::ai_passenger_only
byte ai_passenger_only
Bit value to tell AI that this engine is for passenger use only.
Definition: engine_type.h:54
EconomySettings::station_noise_level
bool station_noise_level
build new airports when the town noise level is still within accepted limits
Definition: settings_type.h:503
RailVehicleInfo
Information about a rail vehicle.
Definition: engine_type.h:42
GRFLoadedFeatures::shore
ShoreReplacement shore
In which way shore sprites were replaced.
Definition: newgrf.h:177
_gted
static GRFTempEngineData * _gted
Temporary engine data used during NewGRF loading.
Definition: newgrf.cpp:337
RoadTypeInfo::powered_roadtypes
RoadTypes powered_roadtypes
bitmask to the OTHER roadtypes on which a vehicle of THIS roadtype generates power
Definition: road.h:119
NUM_AIRPORTTILES_PER_GRF
static const uint NUM_AIRPORTTILES_PER_GRF
Number of airport tiles per NewGRF; limited to 255 to allow extending Action3 with an extended byte l...
Definition: airport.h:21
RailVehicleInfo::engclass
EngineClass engclass
Class of engine for this vehicle.
Definition: engine_type.h:52
IndustryTileSpec::acceptance
int8 acceptance[INDUSTRY_NUM_INPUTS]
Level of acceptance per cargo type (signed, may be negative!)
Definition: industrytype.h:158
BindAirportSpecs
void BindAirportSpecs()
Tie all airportspecs to their class.
Definition: newgrf_airport.cpp:167
VE_TYPE_START
@ VE_TYPE_START
First bit used for the type of effect.
Definition: vehicle_base.h:81
RailType
RailType
Enumeration for all possible railtypes.
Definition: rail_type.h:27
GRFFile::tramtype_list
std::vector< RoadTypeLabel > tramtype_list
Roadtype translation table (tram)
Definition: newgrf.h:135
GetSnowLine
byte GetSnowLine()
Get the current snow line, either variable or static.
Definition: landscape.cpp:644
_date
Date _date
Current date in days (day counter)
Definition: date.cpp:28
PROP_AIRCRAFT_CARGO_AGE_PERIOD
@ PROP_AIRCRAFT_CARGO_AGE_PERIOD
Number of ticks before carried cargo is aged.
Definition: newgrf_properties.h:53
NEW_INDUSTRYOFFSET
static const IndustryType NEW_INDUSTRYOFFSET
original number of industry types
Definition: industry_type.h:25
RailVehicleInfo::air_drag
byte air_drag
Coefficient of air drag.
Definition: engine_type.h:60
LanguageMap::GetLanguageMap
static const LanguageMap * GetLanguageMap(uint32 grfid, uint8 language_id)
Get the language map associated with a given NewGRF and language.
Definition: newgrf.cpp:2574
GCF_UNSAFE
@ GCF_UNSAFE
GRF file is unsafe for static usage.
Definition: newgrf_config.h:24
GCS_INITIALISED
@ GCS_INITIALISED
GRF file has been initialised.
Definition: newgrf_config.h:38
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition: newgrf_config.h:152
NUM_HOUSES
static const HouseID NUM_HOUSES
Total number of houses.
Definition: house.h:29
newgrf_engine.h
PROP_ROADVEH_CARGO_AGE_PERIOD
@ PROP_ROADVEH_CARGO_AGE_PERIOD
Number of ticks before carried cargo is aged.
Definition: newgrf_properties.h:39
MAX_BRIDGES
static const uint MAX_BRIDGES
Maximal number of available bridge specs.
Definition: bridge.h:34
DrawTileSeqStruct::delta_z
int8 delta_z
0x80 identifies child sprites
Definition: sprite.h:28
StringIDMapping::source
StringID source
Source StringID (GRF local).
Definition: newgrf.cpp:463
AirportSpec::num_table
byte num_table
number of elements in the table
Definition: newgrf_airport.h:102
SetPriceBaseMultiplier
void SetPriceBaseMultiplier(Price price, int factor)
Change a price base by the given factor.
Definition: economy.cpp:883
IndustrySpec::conflicting
IndustryType conflicting[3]
Industries this industry cannot be close to.
Definition: industrytype.h:112
EngineInfo::callback_mask
byte callback_mask
Bitmask of vehicle callbacks that have to be called.
Definition: engine_type.h:143
TLF_BB_XY_OFFSET
@ TLF_BB_XY_OFFSET
Add signed offset to bounding box X and Y positions from register TileLayoutRegisters::delta....
Definition: newgrf_commons.h:41
DIR_E
@ DIR_E
East.
Definition: direction_type.h:28
MIN_YEAR
static const Year MIN_YEAR
The absolute minimum & maximum years in OTTD.
Definition: date_type.h:83
OverrideManagerBase::ResetMapping
void ResetMapping()
Resets the mapping, which is used while initializing game.
Definition: newgrf_commons.cpp:82
FinaliseIndustriesArray
static void FinaliseIndustriesArray()
Add all new industries to the industry array.
Definition: newgrf.cpp:9118
TLF_CHILD_Y_OFFSET
@ TLF_CHILD_Y_OFFSET
Add signed offset to child sprite Y positions from register TileLayoutRegisters::delta....
Definition: newgrf_commons.h:45
GRFP_GRF_ANY
@ GRFP_GRF_ANY
The NewGRF says any palette can be used.
Definition: newgrf_config.h:73
GCF_SYSTEM
@ GCF_SYSTEM
GRF file is an openttd-internal system grf.
Definition: newgrf_config.h:23
YearMonthDay::month
Month month
Month (0..11)
Definition: date_type.h:105
NEW_HOUSE_OFFSET
static const HouseID NEW_HOUSE_OFFSET
Offset for new houses.
Definition: house.h:28
HandleParameterInfo
static bool HandleParameterInfo(ByteReader *buf)
Callback function for 'INFO'->'PARA' to set extra information about the parameters.
Definition: newgrf.cpp:8146
StationSpec::pylons
byte pylons
Bitmask of base tiles (0 - 7) which should contain elrail pylons.
Definition: newgrf_station.h:162
DEBUG
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:35
AirportTileTable::gfx
StationGfx gfx
AirportTile to use for this tile.
Definition: newgrf_airport.h:25
CallbackResultSpriteGroup
Definition: newgrf_spritegroup.h:218
CargoSpec::units_volume
StringID units_volume
Name of a single unit of cargo of this type.
Definition: cargotype.h:72
CargoSpec::IsValid
bool IsValid() const
Tests for validity of this cargospec.
Definition: cargotype.h:98
RailtypeInfo::alternate_labels
RailTypeLabelList alternate_labels
Rail type labels this type provides in addition to the main label.
Definition: rail.h:238
HouseSpec::building_flags
BuildingFlags building_flags
some flags that describe the house (size, stadium etc...)
Definition: house.h:109
SkipSpriteData
bool SkipSpriteData(byte type, uint16 num)
Skip the given amount of sprite graphics data.
Definition: spritecache.cpp:95
RoadVehicleInfo
Information about a road vehicle.
Definition: engine_type.h:111
GRFConfig::flags
uint8 flags
NOSAVE: GCF_Flags, bitset.
Definition: newgrf_config.h:167
BranchHandler
bool(* BranchHandler)(ByteReader *)
Type of callback function for branch nodes.
Definition: newgrf.cpp:8009
LanguageMap::Mapping::openttd_id
byte openttd_id
OpenTTD's internal ID for a case/gender.
Definition: newgrf_text.h:62
SB
static T SB(T &x, const uint8 s, const uint8 n, const U d)
Set n bits in x starting at bit s to d.
Definition: bitmath_func.hpp:58
RoadVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:123
IndustryProductionSpriteGroup
Definition: newgrf_spritegroup.h:276
ConvertYMDToDate
Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
Definition: date.cpp:149
IndustrySpec::layouts
std::vector< IndustryTileLayout > layouts
List of possible tile layouts for the industry.
Definition: industrytype.h:108
SPRITE_MODIFIER_OPAQUE
@ SPRITE_MODIFIER_OPAQUE
Set when a sprite must not ever be displayed transparently.
Definition: sprites.h:1532
IndustrySpec::accepts_cargo
CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]
16 accepted cargoes.
Definition: industrytype.h:121
INDUSTRYTILE_NOANIM
static const IndustryGfx INDUSTRYTILE_NOANIM
flag to mark industry tiles as having no animation
Definition: industry_type.h:31
INVALID_INDUSTRYTILE
static const IndustryGfx INVALID_INDUSTRYTILE
one above amount is considered invalid
Definition: industry_type.h:34
GetGRFSpriteOffset
size_t GetGRFSpriteOffset(uint32 id)
Get the file offset for a specific sprite in the sprite section of a GRF.
Definition: spritecache.cpp:508
EF_USES_2CC
@ EF_USES_2CC
Vehicle uses two company colours.
Definition: engine_type.h:155
ROADTYPE_TRAM
@ ROADTYPE_TRAM
Trams.
Definition: road_type.h:25
SHORE_REPLACE_ONLY_NEW
@ SHORE_REPLACE_ONLY_NEW
Only corner-shores were loaded by Action5 (openttd(w/d).grf only).
Definition: newgrf.h:165
IndustrySpec::number_of_sounds
uint8 number_of_sounds
Number of sounds available in the sounds array.
Definition: industrytype.h:135
find_index
int find_index(std::vector< T > const &vec, T const &item)
Helper function to get the index of an item Consider using std::set, std::unordered_set or std::flat_...
Definition: smallvec_type.hpp:44
BridgeSpec::transport_name
StringID transport_name[2]
description of the bridge, when built for road or rail
Definition: bridge.h:50
_cargo_mask
CargoTypes _cargo_mask
Bitmask of cargo types available.
Definition: cargotype.cpp:28
AircraftVehicleInfo::max_range
uint16 max_range
Maximum range of this aircraft.
Definition: engine_type.h:107
AddGenericCallback
void AddGenericCallback(uint8 feature, const GRFFile *file, const SpriteGroup *group)
Add a generic feature callback sprite group to the appropriate feature list.
Definition: newgrf_generic.cpp:111
SP_CUSTOM
@ SP_CUSTOM
No profile, special "custom" highscore.
Definition: settings_type.h:43
NUM_AIRPORTS_PER_GRF
@ NUM_AIRPORTS_PER_GRF
Maximal number of airports per NewGRF.
Definition: airport.h:40
IndustrySpec::production_up_text
StringID production_up_text
Message appearing when the industry's production is increasing.
Definition: industrytype.h:130
CleanUpStrings
void CleanUpStrings()
House cleaning.
Definition: newgrf_text.cpp:696
Date
int32 Date
The type to store our dates in.
Definition: date_type.h:14
EnsureEarlyHouse
static void EnsureEarlyHouse(HouseZones bitmask)
Make sure there is at least one house available in the year 0 for the given climate / housezone combi...
Definition: newgrf.cpp:9020
GrfProcessingState::SpriteSet
Definition of a single Action1 spriteset.
Definition: newgrf.cpp:88
CargoSpec::multipliertowngrowth
uint16 multipliertowngrowth
Size of the effect.
Definition: cargotype.h:67
IndustrySpec::input_cargo_multiplier
uint16 input_cargo_multiplier[INDUSTRY_NUM_INPUTS][INDUSTRY_NUM_OUTPUTS]
Input cargo multipliers (multiply amount of incoming cargo for the produced cargoes)
Definition: industrytype.h:122
CargoSpec::grffile
const struct GRFFile * grffile
NewGRF where #group belongs to.
Definition: cargotype.h:79
StaticGRFInfo
static void StaticGRFInfo(ByteReader *buf)
Handle Action 0x14.
Definition: newgrf.cpp:8292
EC_DIESEL
@ EC_DIESEL
Diesel rail engine.
Definition: engine_type.h:35
HZ_ZONALL
@ HZ_ZONALL
1F This is just to englobe all above types at once
Definition: house.h:78
NewGRFClass
Struct containing information relating to NewGRF classes for stations and airports.
Definition: newgrf_class.h:19
StationSettings::never_expire_airports
bool never_expire_airports
never expire airports
Definition: settings_type.h:535
AfterLoadGRFs
static void AfterLoadGRFs()
Finish loading NewGRFs and execute needed post-processing.
Definition: newgrf.cpp:9632
_cur_parameter
static GRFParameterInfo * _cur_parameter
The parameter which info is currently changed by the newgrf.
Definition: newgrf.cpp:7918
IndustrySpec::minimal_cargo
byte minimal_cargo
minimum amount of cargo transported to the stations.
Definition: industrytype.h:120
RoadTypeInfo::group
const SpriteGroup * group[ROTSG_END]
Sprite groups for resolving sprites.
Definition: road.h:189
LanguageMap::gender_map
std::vector< Mapping > gender_map
Mapping of NewGRF and OpenTTD IDs for genders.
Definition: newgrf_text.h:71
SHORE_REPLACE_ACTION_5
@ SHORE_REPLACE_ACTION_5
Shore sprites were replaced by Action5.
Definition: newgrf.h:163
StringIDMapping
Information for mapping static StringIDs.
Definition: newgrf.cpp:461
RailtypeInfo::introduction_date
Date introduction_date
Introduction date.
Definition: rail.h:252
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:80
HouseSpec::animation
AnimationInfo animation
information about the animation.
Definition: house.h:120
NUM_INDUSTRYTILES_PER_GRF
static const IndustryGfx NUM_INDUSTRYTILES_PER_GRF
Maximum number of industry tiles per NewGRF; limited to 255 to allow extending Action3 with an extend...
Definition: industry_type.h:29
ANIM_STATUS_NO_ANIMATION
static const uint8 ANIM_STATUS_NO_ANIMATION
There is no animation.
Definition: newgrf_animation_type.h:15
ValidateIndustryLayout
static bool ValidateIndustryLayout(const IndustryTileLayout &layout)
Validate the industry layout; e.g.
Definition: newgrf.cpp:3375
MAX_FILE_SLOTS
@ MAX_FILE_SLOTS
Maximum number of slots.
Definition: fios.h:99
RoadTypeInfo::alternate_labels
RoadTypeLabelList alternate_labels
Road type labels this type provides in addition to the main label.
Definition: road.h:149
MapNewGRFIndustryType
IndustryType MapNewGRFIndustryType(IndustryType grf_type, uint32 grf_id)
Map the GRF local type to an industry type.
Definition: newgrf_industries.cpp:39
ChangeGRFURL
static bool ChangeGRFURL(byte langid, const char *str)
Callback function for 'INFO'->'URL_' to set the newgrf url.
Definition: newgrf.cpp:7819
_water_feature
WaterFeature _water_feature[CF_END]
Table of canal 'feature' sprite groups.
Definition: newgrf_canal.cpp:21
PriceBaseSpec::fallback_price
Price fallback_price
Fallback price multiplier for new prices but old grfs.
Definition: economy_type.h:194
GRFParameterInfo
Information about one grf parameter.
Definition: newgrf_config.h:131
CargoSpec::sprite
SpriteID sprite
Icon to display this cargo type, may be 0xFFF (which means to resolve an action123 chain).
Definition: cargotype.h:76
ConvertDateToYMD
void ConvertDateToYMD(Date date, YearMonthDay *ymd)
Converts a Date to a Year, Month & Day.
Definition: date.cpp:94
GameSettings::economy
EconomySettings economy
settings to change the economy
Definition: settings_type.h:569
DrawTileSeqStruct::IsTerminator
bool IsTerminator() const
Check whether this is a sequence terminator.
Definition: sprite.h:41
AirportSpec::ttd_airport_type
TTDPAirportType ttd_airport_type
ttdpatch airport type (Small/Large/Helipad/Oilrig)
Definition: newgrf_airport.h:112
PROP_SHIP_CARGO_AGE_PERIOD
@ PROP_SHIP_CARGO_AGE_PERIOD
Number of ticks before carried cargo is aged.
Definition: newgrf_properties.h:46
HandleNode
static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
Handle the nodes of an Action14.
Definition: newgrf.cpp:8239
_tick_counter
uint16 _tick_counter
Ever incrementing (and sometimes wrapping) tick counter for setting off various events.
Definition: date.cpp:30
TileLayoutRegisters::child
uint8 child[2]
Registers for signed offsets for the position of child sprites.
Definition: newgrf_commons.h:100
_action5_types
static const Action5Type _action5_types[]
The information about action 5 types.
Definition: newgrf.cpp:6103
NewGRFSpriteLayout
NewGRF supplied spritelayout.
Definition: newgrf_commons.h:113
MAX_LANG
static const uint MAX_LANG
Maximum number of languages supported by the game, and the NewGRF specs.
Definition: strings_type.h:19
safeguards.h
GRFFile::label
GRFLabel * label
Pointer to the first label. This is a linked list, not an array.
Definition: newgrf.h:124
ChangeGRFParamMask
static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use.
Definition: newgrf.cpp:7974
StationSpec::name
StringID name
Name of this station.
Definition: newgrf_station.h:126
ObjectOverrideManager::SetEntitySpec
void SetEntitySpec(ObjectSpec *spec)
Method to install the new object data in its proper slot The slot assignment is internal of this meth...
Definition: newgrf_commons.cpp:315
GRFP_BLT_32BPP
@ GRFP_BLT_32BPP
The NewGRF prefers a 32 bpp blitter.
Definition: newgrf_config.h:77
HouseSpec::callback_mask
uint16 callback_mask
Bitmask of house callbacks that have to be called.
Definition: house.h:115
IndustryTileSpec::slopes_refused
Slope slopes_refused
slope pattern on which this tile cannot be built
Definition: industrytype.h:159
ChangeGRFParamValueNames
static bool ChangeGRFParamValueNames(ByteReader *buf)
Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names of some parameter values (ty...
Definition: newgrf.cpp:8099
ImportGRFSound
static void ImportGRFSound(SoundEntry *sound)
Process a sound import from another GRF file.
Definition: newgrf.cpp:7544
GRFConfig::has_param_defaults
bool has_param_defaults
NOSAVE: did this newgrf specify any defaults for it's parameters.
Definition: newgrf_config.h:175
GRFFile::param_end
uint param_end
one more than the highest set parameter
Definition: newgrf.h:122
TLR_MAX_VAR10
static const uint TLR_MAX_VAR10
Maximum value for var 10.
Definition: newgrf_commons.h:106
GetGRFStringID
StringID GetGRFStringID(uint32 grfid, StringID stringid)
Returns the index for this stringid associated with its grfID.
Definition: newgrf_text.cpp:602
ttd_strnlen
static size_t ttd_strnlen(const char *str, size_t maxlen)
Get the length of a string, within a limited buffer.
Definition: string_func.h:72
GrfProcessingState
Temporary data during loading of GRFs.
Definition: newgrf.cpp:85
SPRITE_MODIFIER_CUSTOM_SPRITE
@ SPRITE_MODIFIER_CUSTOM_SPRITE
Set when a sprite originates from an Action 1.
Definition: sprites.h:1531
IndustryTileSpec::enabled
bool enabled
entity still available (by default true).newgrf can disable it, though
Definition: industrytype.h:171
StrEmpty
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:60
_tags_root
AllowedSubtags _tags_root[]
Action14 root tags.
Definition: newgrf.cpp:8187
CargoSpec::weight
uint8 weight
Weight of a single unit of this cargo type in 1/16 ton (62.5 kg).
Definition: cargotype.h:60
FinaliseObjectsArray
static void FinaliseObjectsArray()
Add all new objects to the object array.
Definition: newgrf.cpp:9187
GRFTempEngineData::EMPTY
@ EMPTY
GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
Definition: newgrf.cpp:308
TranslateRefitMask
static CargoTypes TranslateRefitMask(uint32 refit_mask)
Translate the refit mask.
Definition: newgrf.cpp:948
ObjectSpec::height
uint8 height
The height of this structure, in heightlevels; max MAX_TILE_HEIGHT.
Definition: newgrf_object.h:73
WaterFeature::flags
uint8 flags
Flags controlling display.
Definition: newgrf_canal.h:26
NamePart::text
char * text
If probability bit 7 is clear.
Definition: newgrf_townname.h:22
DrawTileSprites
Ground palette sprite of a tile, together with its sprite layout.
Definition: sprite.h:58
HouseSpec::minimum_life
byte minimum_life
The minimum number of years this house will survive before the town rebuilds it.
Definition: house.h:122
_networking
bool _networking
are we in networking mode?
Definition: network.cpp:52
TTDPAirportType
TTDPAirportType
Allow incrementing of AirportClassID variables.
Definition: newgrf_airport.h:81
CanalChangeInfo
static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
Define properties for water features.
Definition: newgrf.cpp:2107
LoadTranslationTable
static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
Load a cargo- or railtype-translation table.
Definition: newgrf.cpp:2591
GlobalVarChangeInfo
static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
Define properties for global variables.
Definition: newgrf.cpp:2615
newgrf_text.h
road.h
vseprintf
int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap)
Safer implementation of vsnprintf; same as vsnprintf except:
Definition: string.cpp:61
LoadNewGRFFile
void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
Load a particular NewGRF.
Definition: newgrf.cpp:9347
RoadTypeInfo::name
StringID name
Name of this rail type.
Definition: road.h:100
error.h
GrfProcessingState::GetSprite
SpriteID GetSprite(byte feature, uint set) const
Returns the first sprite of a spriteset.
Definition: newgrf.cpp:176
RailVehicleChangeInfo
static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for rail vehicles.
Definition: newgrf.cpp:1046
CargoSpec::is_freight
bool is_freight
Cargo type is considered to be freight (affects train freight multiplier).
Definition: cargotype.h:65
RandomizedSpriteGroup::groups
const SpriteGroup ** groups
Take the group with appropriate index:
Definition: newgrf_spritegroup.h:209
Slope
Slope
Enumeration for the slope-type.
Definition: slope_type.h:48
HZ_ZON5
@ HZ_ZON5
center of town
Definition: house.h:77
GRFTempEngineData::ctt_exclude_mask
CargoTypes ctt_exclude_mask
Cargo types always excluded from the refit mask.
Definition: newgrf.cpp:321
GRFTempEngineData::defaultcargo_grf
const GRFFile * defaultcargo_grf
GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
Definition: newgrf.cpp:316
ResetCurrencies
void ResetCurrencies(bool preserve_custom)
Will fill _currency_specs array with default values from origin_currency_specs Called only from newgr...
Definition: currency.cpp:157
EngineIDMapping
Definition: engine_base.h:163
AirportTileTable
Tile-offset / AirportTileID pair.
Definition: newgrf_airport.h:23
IndustrySpec::appear_creation
byte appear_creation[NUM_LANDSCAPE]
Probability of appearance during map creation.
Definition: industrytype.h:134
GRFP_GRF_MASK
@ GRFP_GRF_MASK
Bitmask to get only the NewGRF supplied information.
Definition: newgrf_config.h:74
_loaded_newgrf_features
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition: newgrf.cpp:80
language.h
IndustryTileSpec::anim_production
byte anim_production
Animation frame to start when goods are produced.
Definition: industrytype.h:160
EngineInfo::retire_early
int8 retire_early
Number of years early to retire vehicle.
Definition: engine_type.h:144
GetNewEngineID
EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
Return the ID of a new engine.
Definition: newgrf.cpp:695
RailVehicleInfo::tractive_effort
byte tractive_effort
Tractive effort coefficient.
Definition: engine_type.h:59
GRFFile::traininfo_vehicle_width
uint traininfo_vehicle_width
Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details.
Definition: newgrf.h:143
EngineIDMapping::substitute_id
uint8 substitute_id
The (original) entity ID to use if this GRF is not available (currently not used)
Definition: engine_base.h:167
CargoChangeInfo
static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
Define properties for cargoes.
Definition: newgrf.cpp:2913
date_func.h
SoundEntry
Definition: sound_type.h:13
StationSpec::disallowed_platforms
byte disallowed_platforms
Bitmask of number of platforms available for the station.
Definition: newgrf_station.h:132
stdafx.h
GrfProcessingState::grfconfig
GRFConfig * grfconfig
Config of the currently processed GRF file.
Definition: newgrf.cpp:104
FioSeekTo
void FioSeekTo(size_t pos, int mode)
Seek in the current file.
Definition: fileio.cpp:79
TLF_NON_GROUND_FLAGS
@ TLF_NON_GROUND_FLAGS
Flags which do not work for the (first) ground sprite.
Definition: newgrf_commons.h:56
RoadType
RoadType
The different roadtypes we support.
Definition: road_type.h:22
VehicleType
VehicleType
Available vehicle types.
Definition: vehicle_type.h:21
IsLeapYear
static bool IsLeapYear(Year yr)
Checks whether the given year is a leap year or not.
Definition: date_func.h:30
landscape.h
ObjectSpec::enabled
bool enabled
Is this spec enabled?
Definition: newgrf_object.h:76
RailVehicleInfo::pow_wag_power
uint16 pow_wag_power
Extra power applied to consist if wagon should be powered.
Definition: engine_type.h:55
RailtypeInfo::toolbar_caption
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition: rail.h:174
OTTDByteReaderSignal
Definition: newgrf.cpp:210
PROP_AIRCRAFT_COST_FACTOR
@ PROP_AIRCRAFT_COST_FACTOR
Purchase cost.
Definition: newgrf_properties.h:48
IndustrySpec
Defines the data structure for constructing industry.
Definition: industrytype.h:107
RailVehicleInfo::weight
uint16 weight
Weight of vehicle (tons); For multiheaded engines the weight of each single engine.
Definition: engine_type.h:49
IndustryTileSpec::grf_prop
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:172
BSWAP32
static uint32 BSWAP32(uint32 x)
Perform a 32 bits endianness bitswap on x.
Definition: bitmath_func.hpp:380
SPR_RAILTYPE_TUNNEL_BASE
static const SpriteID SPR_RAILTYPE_TUNNEL_BASE
Tunnel sprites with grass only for custom railtype tunnel.
Definition: sprites.h:295
EngineClass
EngineClass
Type of rail engine.
Definition: engine_type.h:33
PALETTE_MODIFIER_TRANSPARENT
@ PALETTE_MODIFIER_TRANSPARENT
when a sprite is to be displayed transparently, this bit needs to be set.
Definition: sprites.h:1533
NEWGRF_DIR
@ NEWGRF_DIR
Subdirectory for all NewGRFs.
Definition: fileio_type.h:117
IgnoreIndustryProperty
static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
Ignore an industry property.
Definition: newgrf.cpp:3285
GRFTempEngineData::refittability
Refittability refittability
Did the newgrf set any refittability property? If not, default refittability will be applied.
Definition: newgrf.cpp:317
EngineInfo::misc_flags
byte misc_flags
Miscellaneous flags.
Definition: engine_type.h:142
HouseSpec::mail_generation
byte mail_generation
mail generation multiplier (tile based, as the acceptances below)
Definition: house.h:106
A5BLOCK_FIXED
@ A5BLOCK_FIXED
Only allow replacing a whole block of sprites. (TTDP compatible)
Definition: newgrf.cpp:6089
GRFTownName
Definition: newgrf_townname.h:35
A5BLOCK_ALLOW_OFFSET
@ A5BLOCK_ALLOW_OFFSET
Allow replacing any subset by specifiing an offset.
Definition: newgrf.cpp:6090
HouseSpec::population
byte population
population (Zero on other tiles in multi tile house.)
Definition: house.h:102
PROP_SHIP_RUNNING_COST_FACTOR
@ PROP_SHIP_RUNNING_COST_FACTOR
Yearly runningcost.
Definition: newgrf_properties.h:45
RailtypeInfo::powered_railtypes
RailTypes powered_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype generates power
Definition: rail.h:185
RAILVEH_WAGON
@ RAILVEH_WAGON
simple wagon, not motorized
Definition: engine_type.h:29
LanguageMap::Mapping
Mapping between NewGRF and OpenTTD IDs.
Definition: newgrf_text.h:60
BuildCargoTranslationMap
static void BuildCargoTranslationMap()
Construct the Cargo Mapping.
Definition: newgrf.cpp:8664
Utf8Decode
size_t Utf8Decode(WChar *c, const char *s)
Decode and consume the next UTF-8 encoded character.
Definition: string.cpp:481
HouseSpec::cargo_acceptance
byte cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition: house.h:107
RailtypeInfo::map_colour
byte map_colour
Colour on mini-map.
Definition: rail.h:243
WaterFeature::grffile
const GRFFile * grffile
NewGRF where 'group' belongs to.
Definition: newgrf_canal.h:24
_engine_offsets
const uint8 _engine_offsets[4]
Offset of the first engine of each vehicle type in original engine data.
Definition: engine.cpp:58
ShipVehicleInfo::old_refittable
bool old_refittable
Is ship refittable; only used during initialisation. Later use EngineInfo::refit_mask.
Definition: engine_type.h:72
AllowedSubtags::type
byte type
The type of the node, must be one of 'C', 'B' or 'T'.
Definition: newgrf.cpp:8076
GRFParameterInfo::first_bit
byte first_bit
First bit to use in the GRF parameter.
Definition: newgrf_config.h:141
BuildIndustriesLegend
void BuildIndustriesLegend()
Fills an array for the industries legends.
Definition: smallmap_gui.cpp:168
SetSnowLine
void SetSnowLine(byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS])
Set a variable snow line, as loaded from a newgrf file.
Definition: landscape.cpp:625
newgrf_object.h
BridgeSpec::min_length
byte min_length
the minimum length (not counting start and end tile)
Definition: bridge.h:43
IndustryProductionSpriteGroup::add_output
uint16 add_output[INDUSTRY_NUM_OUTPUTS]
Add this much output cargo when successful (unsigned, is indirect in cb version 1+)
Definition: newgrf_spritegroup.h:284
ObjectSpec::name
StringID name
The name for this object.
Definition: newgrf_object.h:62
ChangeGRFBlitter
static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
Callback function for 'INFO'->'BLTR' to set the blitter info.
Definition: newgrf.cpp:7864
FioGetPos
size_t FioGetPos()
Get position in the current file.
Definition: fileio.cpp:59
AirportSpec::size_x
byte size_x
size of airport in x direction
Definition: newgrf_airport.h:105
LoadNextSprite
bool LoadNextSprite(int load_index, byte file_slot, uint file_sprite_id, byte container_version)
Load a real or recolour sprite.
Definition: spritecache.cpp:550
FinaliseEngineArray
static void FinaliseEngineArray()
Check for invalid engines.
Definition: newgrf.cpp:8902
GRFParameterType
GRFParameterType
The possible types of a newgrf parameter.
Definition: newgrf_config.h:124
ChangeGRFNumUsedParams
static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
Callback function for 'INFO'->'NPAR' to set the number of valid parameters.
Definition: newgrf.cpp:7826
GRFTempEngineData::UNSET
@ UNSET
No properties assigned. Default refit masks shall be activated.
Definition: newgrf.cpp:307
ChangeGRFMinVersion
static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF.
Definition: newgrf.cpp:7899
TileLayoutRegisters::sprite_var10
uint8 sprite_var10
Value for variable 10 when resolving the sprite.
Definition: newgrf_commons.h:102
RAILTYPE_RAIL
@ RAILTYPE_RAIL
Standard non-electric rails.
Definition: rail_type.h:29
_generating_world
bool _generating_world
Whether we are generating the map or not.
Definition: genworld.cpp:60
TE_GOODS
@ TE_GOODS
Cargo behaves goods/candy-like.
Definition: cargotype.h:29
GCS_UNKNOWN
@ GCS_UNKNOWN
The status of this grf file is unknown.
Definition: newgrf_config.h:35
ConstructionSettings::max_bridge_length
uint16 max_bridge_length
maximum length of bridges
Definition: settings_type.h:320
ObjectSpec::clear_cost_multiplier
uint8 clear_cost_multiplier
Clear cost multiplier per tile.
Definition: newgrf_object.h:67
FioReadByte
byte FioReadByte()
Read a byte from the file.
Definition: fileio.cpp:107
LanguagePackHeader::GetGenderIndex
uint8 GetGenderIndex(const char *gender_str) const
Get the index for the given gender.
Definition: language.h:67
DeterministicSpriteGroupAdjust
Definition: newgrf_spritegroup.h:150
PriceBaseSpec
Describes properties of price bases.
Definition: economy_type.h:190
IndustryTileSpec::accepts_cargo
CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]
Cargo accepted by this tile.
Definition: industrytype.h:157
YearMonthDay::year
Year year
Year (0...)
Definition: date_type.h:104
string_func.h
IndustrySpec::enabled
bool enabled
entity still available (by default true).newgrf can disable it, though
Definition: industrytype.h:140
ObjectSpec::generate_amount
uint8 generate_amount
Number of objects which are attempted to be generated per 256^2 map during world generation.
Definition: newgrf_object.h:75
GRFFile::canal_local_properties
CanalProperties canal_local_properties[CF_END]
Canal properties as set by this NewGRF.
Definition: newgrf.h:138
GRFError
Information about why GRF had problems during initialisation.
Definition: newgrf_config.h:112
RoadTypeInfo::grffile
const GRFFile * grffile[ROTSG_END]
NewGRF providing the Action3 for the roadtype.
Definition: road.h:184
RailtypeInfo::acceleration_type
uint8 acceleration_type
Acceleration type of this rail type.
Definition: rail.h:223
ChangeGRFDescription
static bool ChangeGRFDescription(byte langid, const char *str)
Callback function for 'INFO'->'DESC' to add a translation to the newgrf description.
Definition: newgrf.cpp:7812
GCS_DISABLED
@ GCS_DISABLED
GRF file is disabled.
Definition: newgrf_config.h:36
StringID
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
SetUnicodeGlyph
static void SetUnicodeGlyph(FontSize size, WChar key, SpriteID sprite)
Map a SpriteID to the font size and key.
Definition: fontcache.h:176
CIR_DISABLED
@ CIR_DISABLED
GRF was disabled due to error.
Definition: newgrf.cpp:988
GRFParameterInfo::max_value
uint32 max_value
The maximal value of this parameter.
Definition: newgrf_config.h:138
AllocateRailType
RailType AllocateRailType(RailTypeLabel label)
Allocate a new rail type label.
Definition: rail_cmd.cpp:158
ORIGINAL_MAX_YEAR
static const Year ORIGINAL_MAX_YEAR
The maximum year of the original TTD.
Definition: date_type.h:53
vehicle_func.h
rev.h
CURRENCY_END
@ CURRENCY_END
always the last item
Definition: currency.h:68
LanguagePackHeader::GetCaseIndex
uint8 GetCaseIndex(const char *case_str) const
Get the index for the given case.
Definition: language.h:80
PROP_TRAIN_WEIGHT
@ PROP_TRAIN_WEIGHT
Weight in t (if dualheaded: for each single vehicle)
Definition: newgrf_properties.h:25
PROP_VEHICLE_LOAD_AMOUNT
@ PROP_VEHICLE_LOAD_AMOUNT
Loading speed.
Definition: newgrf_properties.h:19
GRFFile::GRFFile
GRFFile(const struct GRFConfig *config)
Constructor for GRFFile.
Definition: newgrf.cpp:8704
RailtypeInfo::flags
RailTypeFlags flags
Bit mask of rail type flags.
Definition: rail.h:208
VehicleSettings::dynamic_engines
bool dynamic_engines
enable dynamic allocation of engine data
Definition: settings_type.h:474
newgrf_sound.h
Clamp
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:77
RoadVehicleInfo::shorten_factor
byte shorten_factor
length on main map for this type is 8 - shorten_factor
Definition: engine_type.h:124
Pool::PoolItem<&_engine_pool >::Iterate
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:378
GRFFilePropsBase::spritegroup
const struct SpriteGroup * spritegroup[Tcnt]
pointer to the different sprites of the entity
Definition: newgrf_commons.h:321
GRFP_GRF_WINDOWS
@ GRFP_GRF_WINDOWS
The NewGRF says the Windows palette can be used.
Definition: newgrf_config.h:72
strings_func.h
TLF_VAR10_FLAGS
@ TLF_VAR10_FLAGS
Flags which refer to using multiple action-1-2-3 chains.
Definition: newgrf_commons.h:59
StationSpec
Station specification.
Definition: newgrf_station.h:117
CLEAN_RANDOMSOUNDS
@ CLEAN_RANDOMSOUNDS
Free the dynamically allocated sounds table.
Definition: industrytype.h:24
AirportSpec::enabled
bool enabled
Entity still available (by default true). Newgrf can disable it, though.
Definition: newgrf_airport.h:117
LanguageMap
Mapping of language data between a NewGRF and OpenTTD.
Definition: newgrf_text.h:58
PROP_TRAIN_SHORTEN_FACTOR
@ PROP_TRAIN_SHORTEN_FACTOR
Shorter vehicles.
Definition: newgrf_properties.h:28
IsHouseSpecValid
static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
Check if a given housespec is valid and disable it if it's not.
Definition: newgrf.cpp:8974
IndustrytilesChangeInfo
static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
Define properties for industry tiles.
Definition: newgrf.cpp:3147
RailVehicleInfo::max_speed
uint16 max_speed
Maximum speed (1 unit = 1/1.6 mph = 1 km-ish/h)
Definition: engine_type.h:47
FioCheckFileExists
bool FioCheckFileExists(const std::string &filename, Subdirectory subdir)
Check whether the given file exists.
Definition: fileio.cpp:266
GRFParameterInfo::value_names
SmallMap< uint32, GRFTextList > value_names
Names for each value.
Definition: newgrf_config.h:143
bridge.h
NEW_AIRPORT_OFFSET
@ NEW_AIRPORT_OFFSET
Number of the first newgrf airport.
Definition: airport.h:39
TileLayoutRegisters::palette
uint8 palette
Register specifying a signed offset for the palette.
Definition: newgrf_commons.h:95
GRFTempEngineData
Temporary engine data used when loading only.
Definition: newgrf.cpp:304
ResetNewGRFErrors
static void ResetNewGRFErrors()
Clear all NewGRF errors.
Definition: newgrf.cpp:8542
GRFConfig::name
GRFTextWrapper name
NOSAVE: GRF name (Action 0x08)
Definition: newgrf_config.h:160
ResetNewGRF
static void ResetNewGRF()
Reset and clear all NewGRFs.
Definition: newgrf.cpp:8531
GRFLoadedFeatures::tram
TramReplacement tram
In which way tram depots were replaced.
Definition: newgrf.h:178
TileLayoutRegisters::max_palette_offset
uint16 max_palette_offset
Maximum offset to add to the palette. (limited by size of the spriteset)
Definition: newgrf_commons.h:97
BridgeSpec::max_length
uint16 max_length
the maximum length (not counting start and end tile)
Definition: bridge.h:44
GRFParameterInfo::desc
GRFTextList desc
The description of this parameter.
Definition: newgrf_config.h:135
AllowedSubtags
Data structure to store the allowed id/type combinations for action 14.
Definition: newgrf.cpp:8018
FinaliseAirportsArray
static void FinaliseAirportsArray()
Add all new airports to the airport array.
Definition: newgrf.cpp:9206
IndustrySpec::cost_multiplier
uint8 cost_multiplier
Base construction cost multiplier.
Definition: industrytype.h:109
SHORE_REPLACE_ACTION_A
@ SHORE_REPLACE_ACTION_A
Shore sprites were replaced by ActionA (using grass tiles for the corner-shores).
Definition: newgrf.h:164
GCF_RESERVED
@ GCF_RESERVED
GRF file passed GLS_RESERVE stage.
Definition: newgrf_config.h:29
BridgeSpec::price
uint16 price
the price multiplier
Definition: bridge.h:45
SanitizeSpriteOffset
static uint16 SanitizeSpriteOffset(uint16 &num, uint16 offset, int max_sprites, const char *name)
Sanitize incoming sprite offsets for Action 5 graphics replacements.
Definition: newgrf.cpp:6066
GRFConfig::min_loadable_version
uint32 min_loadable_version
NOSAVE: Minimum compatible version a NewGRF can define.
Definition: newgrf_config.h:166
ObjectSpec::views
uint8 views
The number of views.
Definition: newgrf_object.h:74
TRAMWAY_REPLACE_DEPOT_WITH_TRACK
@ TRAMWAY_REPLACE_DEPOT_WITH_TRACK
Electrified depot graphics with tram track were loaded.
Definition: newgrf.h:170
IndustryTileSpec::animation
AnimationInfo animation
Information about the animation (is it looping, how many loops etc)
Definition: industrytype.h:169
AirportTileSpec::callback_mask
uint8 callback_mask
Bitmask telling which grf callback is set.
Definition: newgrf_airporttiles.h:69
MapSpriteMappingRecolour
static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
Map the colour modifiers of TTDPatch to those that Open is using.
Definition: newgrf.cpp:711
GetGlobalVariable
bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
Reads a variable common to VarAction2 and Action7/9/D.
Definition: newgrf.cpp:6236
RAILTYPE_END
@ RAILTYPE_END
Used for iterations.
Definition: rail_type.h:33
CanalProperties::flags
uint8 flags
Flags controlling display.
Definition: newgrf.h:41
PaletteID
uint32 PaletteID
The number of the palette.
Definition: gfx_type.h:18
CommonVehicleChangeInfo
static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
Define properties common to all vehicles.
Definition: newgrf.cpp:1003
ConstructionSettings::build_on_slopes
bool build_on_slopes
allow building on slopes
Definition: settings_type.h:318
RealSpriteGroup
Definition: newgrf_spritegroup.h:79
AllowedSubtags::subtags
AllowedSubtags * subtags
Pointer to a list of subtags, only valid if type == 'C' && !call_handler.
Definition: newgrf.cpp:8083
HZ_SUBARTC_ABOVE
@ HZ_SUBARTC_ABOVE
11 800 can appear in sub-arctic climate above the snow line
Definition: house.h:79
TextHandler
bool(* TextHandler)(byte, const char *str)
Type of callback function for text nodes.
Definition: newgrf.cpp:8008
Action5Type::block_type
Action5BlockType block_type
How is this Action5 type processed?
Definition: newgrf.cpp:6095
AirportSpec::grf_prop
struct GRFFileProps grf_prop
Properties related to the grf file.
Definition: newgrf_airport.h:118
CargoSpec::quantifier
StringID quantifier
Text for multiple units of cargo of this type.
Definition: cargotype.h:73
SPR_AIRPORT_PREVIEW_BASE
static const SpriteID SPR_AIRPORT_PREVIEW_BASE
Airport preview sprites.
Definition: sprites.h:242
Action5Type::min_sprites
uint16 min_sprites
If the Action5 contains less sprites, the whole block will be ignored.
Definition: newgrf.cpp:6097
GRFConfig::next
struct GRFConfig * next
NOSAVE: Next item in the linked list.
Definition: newgrf_config.h:177
industrytype.h
RAILVEH_MULTIHEAD
@ RAILVEH_MULTIHEAD
indicates a combination of two locomotives
Definition: engine_type.h:28
GetEngineLiveryScheme
LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
Determines the LiveryScheme for a vehicle.
Definition: vehicle.cpp:1862
InitializeSortedCargoSpecs
void InitializeSortedCargoSpecs()
Initialize the list of sorted cargo specifications.
Definition: cargotype.cpp:169
GrfProcessingState::AddSpriteSets
void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
Records new spritesets.
Definition: newgrf.cpp:135
SPR_OPENTTD_BASE
static const SpriteID SPR_OPENTTD_BASE
Extra graphic spritenumbers.
Definition: sprites.h:56
IndustrySpec::production_down_text
StringID production_down_text
Message appearing when the industry's production is decreasing.
Definition: industrytype.h:131
TRAMWAY_REPLACE_DEPOT_NONE
@ TRAMWAY_REPLACE_DEPOT_NONE
No tram depot graphics were loaded.
Definition: newgrf.h:169
RailVehicleInfo::user_def_data
byte user_def_data
Property 0x25: "User-defined bit mask" Used only for (very few) NewGRF vehicles.
Definition: engine_type.h:61
AlterVehicleListOrder
void AlterVehicleListOrder(EngineID engine, uint target)
Record a vehicle ListOrderChange.
Definition: newgrf_engine.cpp:1317
CargoSpec::classes
uint16 classes
Classes of this cargo type.
Definition: cargotype.h:78
RoadVehicleChangeInfo
static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for road vehicles.
Definition: newgrf.cpp:1340
AirportTileSpec::enabled
bool enabled
entity still available (by default true). newgrf can disable it, though
Definition: newgrf_airporttiles.h:71
IndustrySpec::cleanup_flag
uint8 cleanup_flag
flags indicating which data should be freed upon cleaning up
Definition: industrytype.h:139
IndustrySpec::appear_ingame
byte appear_ingame[NUM_LANDSCAPE]
Probability of appearance in game.
Definition: industrytype.h:133
IndustrySpec::grf_prop
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:141
TRAMWAY_REPLACE_DEPOT_NO_TRACK
@ TRAMWAY_REPLACE_DEPOT_NO_TRACK
Electrified depot graphics without tram track were loaded.
Definition: newgrf.h:171
RoadTypeInfo::map_colour
byte map_colour
Colour on mini-map.
Definition: road.h:154
NewGRFSpriteLayout::consistent_max_offset
uint consistent_max_offset
Number of sprites in all referenced spritesets.
Definition: newgrf_commons.h:120
HouseSpec::watched_cargoes
CargoTypes watched_cargoes
Cargo types watched for acceptance.
Definition: house.h:123
NUM_CARGO
@ NUM_CARGO
Maximal number of cargo types in a game.
Definition: cargo_type.h:64
IsSnowLineSet
bool IsSnowLineSet()
Has a snow line table already been loaded.
Definition: landscape.cpp:615
RailTypeFlags
RailTypeFlags
Railtype flags.
Definition: rail.h:25
RailtypeInfo::label
RailTypeLabel label
Unique 32 bit rail type identifier.
Definition: rail.h:233
StationClassID
StationClassID
Definition: newgrf_station.h:83
GetCargoTranslation
CargoID GetCargoTranslation(uint8 cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoID.
Definition: newgrf_cargo.cpp:91
IndustrySpec::prospecting_chance
uint32 prospecting_chance
Chance prospecting succeeds.
Definition: industrytype.h:111
ConstructionSettings::train_signal_side
byte train_signal_side
show signals on left / driving / right side
Definition: settings_type.h:323
HouseSpec::class_id
HouseClassID class_id
defines the class this house has (not grf file based)
Definition: house.h:119
GRFParameterInfo::name
GRFTextList name
The name of this parameter.
Definition: newgrf_config.h:134
GRFFile::cargo_map
uint8 cargo_map[NUM_CARGO]
Inverse cargo translation table (CargoID -> local ID)
Definition: newgrf.h:127
Pool::PoolItem<&_engine_pool >::CanAllocateItem
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
Definition: pool_type.hpp:299
IndustryTileLayoutTile
Definition of one tile in an industry tile layout.
Definition: industrytype.h:96
RailtypeInfo::build_caption
StringID build_caption
Caption of the build vehicle GUI for this rail type.
Definition: rail.h:176
VehicleSettings::disable_elrails
bool disable_elrails
when true, the elrails are disabled
Definition: settings_type.h:467
InitNewGRFFile
static void InitNewGRFFile(const GRFConfig *config)
Prepare loading a NewGRF file with its config.
Definition: newgrf.cpp:8687
CommitVehicleListOrderChanges
void CommitVehicleListOrderChanges()
Deternine default engine sorting and execute recorded ListOrderChanges from AlterVehicleListOrder.
Definition: newgrf_engine.cpp:1347
ShipVehicleInfo
Information about a ship vehicle.
Definition: engine_type.h:65
HouseSpec::building_availability
HouseZones building_availability
where can it be built (climates, zones)
Definition: house.h:110
NewGRFClass::name
StringID name
Name of this class.
Definition: newgrf_class.h:39
Subdirectory
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition: fileio_type.h:108
IndustryProductionSpriteGroup::version
uint8 version
Production callback version used, or 0xFF if marked invalid.
Definition: newgrf_spritegroup.h:279
AirportSpec::GetWithoutOverride
static AirportSpec * GetWithoutOverride(byte type)
Retrieve airport spec for the given airport.
Definition: newgrf_airport.cpp:119
TileLayoutFlags
TileLayoutFlags
Flags to enable register usage in sprite layouts.
Definition: newgrf_commons.h:33
CargoSpec::name
StringID name
Name of this type of cargo.
Definition: cargotype.h:70
PROP_ROADVEH_CARGO_CAPACITY
@ PROP_ROADVEH_CARGO_CAPACITY
Capacity.
Definition: newgrf_properties.h:33
ResetNewGRFData
void ResetNewGRFData()
Reset all NewGRF loaded data.
Definition: newgrf.cpp:8555
AircraftVehicleChangeInfo
static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for aircraft.
Definition: newgrf.cpp:1706
GRFFile::cargo_list
std::vector< CargoLabel > cargo_list
Cargo translation table (local ID -> label)
Definition: newgrf.h:126
GameCreationSettings::starting_year
Year starting_year
starting date
Definition: settings_type.h:293
PalSpriteID
Combination of a palette sprite and a 'real' sprite.
Definition: gfx_type.h:22
GRFConfig::url
GRFTextWrapper url
NOSAVE: URL belonging to this GRF.
Definition: newgrf_config.h:162
VSG_SCOPE_RELATIVE
@ VSG_SCOPE_RELATIVE
Relative position (vehicles only)
Definition: newgrf_spritegroup.h:105
ActivateOldTramDepot
static void ActivateOldTramDepot()
Replocate the old tram depot sprites to the new position, if no new ones were loaded.
Definition: newgrf.cpp:9500
RailtypeInfo::strings
struct RailtypeInfo::@41 strings
Strings associated with the rail type.
HZ_CLIMALL
@ HZ_CLIMALL
Bitmask of all climate bits.
Definition: house.h:84
RoadVehicleInfo::tractive_effort
uint8 tractive_effort
Coefficient of tractive effort.
Definition: engine_type.h:121
GrfProcessingState::stage
GrfLoadingStage stage
Current loading stage.
Definition: newgrf.cpp:98
ORIGINAL_SAMPLE_COUNT
static const uint ORIGINAL_SAMPLE_COUNT
The number of sounds in the original sample.cat.
Definition: sound_type.h:116
IndustrySpec::callback_mask
uint16 callback_mask
Bitmask of industry callbacks that have to be called.
Definition: industrytype.h:138
AnimationInfo::triggers
uint16 triggers
The triggers that trigger animation.
Definition: newgrf_animation_type.h:22
IgnoreObjectProperty
static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
Ignore properties for objects.
Definition: newgrf.cpp:3978
CHECK_NOTHING
@ CHECK_NOTHING
Always succeeds.
Definition: industrytype.h:40
AircraftVehicleInfo::mail_capacity
byte mail_capacity
Mail capacity (bags).
Definition: engine_type.h:105
CargoSpec::name_single
StringID name_single
Name of a single entity of this type of cargo.
Definition: cargotype.h:71
PTYPE_END
@ PTYPE_END
Invalid parameter type.
Definition: newgrf_config.h:127
IndustrySpec::random_sounds
const uint8 * random_sounds
array of random sounds.
Definition: industrytype.h:136
GrfProcessingState::GetNumEnts
uint GetNumEnts(byte feature, uint set) const
Returns the number of sprites in a spriteset.
Definition: newgrf.cpp:188
CargoSpec::abbrev
StringID abbrev
Two letter abbreviation for this cargo type.
Definition: cargotype.h:74
_default_refitmasks_rail
static const CargoLabel _default_refitmasks_rail[]
List of what cargo labels are refittable for the given the vehicle-type.
Definition: newgrf.cpp:8755
ReallocT
static T * ReallocT(T *t_ptr, size_t num_elements)
Simplified reallocation function that allocates the specified number of elements of the given type.
Definition: alloc_func.hpp:111
HouseSpec::processing_time
byte processing_time
Periodic refresh multiplier.
Definition: house.h:121
IndustrySpec::life_type
IndustryLifeType life_type
This is also known as Industry production flag, in newgrf specs.
Definition: industrytype.h:123
RoadVehicleInfo::weight
uint8 weight
Weight in 1/4t units.
Definition: engine_type.h:119
_palette_remap_grf
bool _palette_remap_grf[]
Whether the given NewGRFs must get a palette remap from windows to DOS or not.
Definition: gfxinit.cpp:30
Action5Type::name
const char * name
Name for error messages.
Definition: newgrf.cpp:6099
abs
static T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:21
stredup
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Definition: string.cpp:137
FinaliseHouseArray
static void FinaliseHouseArray()
Add all new houses to the house array.
Definition: newgrf.cpp:9047
GRFConfig::palette
uint8 palette
GRFPalette, bitset.
Definition: newgrf_config.h:173
CargoSpec::multiplier
uint16 multiplier
Capacity multiplier for vehicles. (8 fractional bits)
Definition: cargotype.h:61
IndustryTileSpec::callback_mask
uint8 callback_mask
Bitmask of industry tile callbacks that have to be called.
Definition: industrytype.h:168
_grm_cargoes
static uint32 _grm_cargoes[NUM_CARGO *2]
Contains the GRF ID of the owner of a cargo if it has been reserved.
Definition: newgrf.cpp:346
NewGRFSpriteLayout::Clone
void Clone(const DrawTileSeqStruct *source)
Clone the building sprites of a spritelayout.
Definition: newgrf_commons.cpp:586
error
void CDECL error(const char *s,...)
Error handling for fatal non-user errors.
Definition: openttd.cpp:131
StationSpec::cargo_threshold
uint16 cargo_threshold
Cargo threshold for choosing between little and lots of cargo.
Definition: newgrf_station.h:154
network.h
RailVehicleInfo::shorten_factor
byte shorten_factor
length on main map for this type is 8 - shorten_factor
Definition: engine_type.h:58
_grfconfig
GRFConfig * _grfconfig
First item in list of current GRF set up.
Definition: newgrf_config.cpp:170
RoadTypeInfo::cost_multiplier
uint16 cost_multiplier
Cost multiplier for building this road type.
Definition: road.h:129
SmallMap::Find
std::vector< Pair >::const_iterator Find(const T &key) const
Finds given key in this map.
Definition: smallmap_type.hpp:41
CurrencySpec::to_euro
Year to_euro
Year of switching to the Euro. May also be CF_NOEURO or CF_ISEURO.
Definition: currency.h:75
DrawTileSprites::seq
const DrawTileSeqStruct * seq
Array of child sprites. Terminated with a terminator entry.
Definition: sprite.h:60
CIR_UNKNOWN
@ CIR_UNKNOWN
Variable is unknown.
Definition: newgrf.cpp:990
GRFTempEngineData::NONEMPTY
@ NONEMPTY
GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not av...
Definition: newgrf.cpp:309
AllowedSubtags::id
uint32 id
The identifier for this node.
Definition: newgrf.cpp:8075
IndustrySpec::behaviour
IndustryBehaviour behaviour
How this industry will behave, and how others entities can use it.
Definition: industrytype.h:125
AnimationInfo::status
uint8 status
Status; 0: no looping, 1: looping, 0xFF: no animation.
Definition: newgrf_animation_type.h:20
ResetObjects
void ResetObjects()
This function initialize the spec arrays of objects.
Definition: newgrf_object.cpp:94
SetBit
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
Definition: bitmath_func.hpp:121
lengthof
#define lengthof(x)
Return the length of an fixed size array.
Definition: stdafx.h:367
HouseSpec::min_year
Year min_year
introduction year of the house
Definition: house.h:100
YearMonthDay
Data structure to convert between Date and triplet (year, month, and day).
Definition: date_type.h:103
StationSpec::grf_prop
GRFFilePropsBase< NUM_CARGO+3 > grf_prop
Properties related the the grf file.
Definition: newgrf_station.h:124
SPR_FLAGS_BASE
static const SpriteID SPR_FLAGS_BASE
Flags sprites (in same order as enum NetworkLanguage)
Definition: sprites.h:291
NewGRFClass::Get
static NewGRFClass * Get(Tid cls_id)
Get a particular class.
Definition: newgrf_class_func.h:103
RoadTypeInfo::max_speed
uint16 max_speed
Maximum speed for vehicles travelling on this road type.
Definition: road.h:139
InitializeGRFSpecial
static void InitializeGRFSpecial()
Initialize the TTDPatch flags.
Definition: newgrf.cpp:8313
DataHandler
bool(* DataHandler)(size_t, ByteReader *)
Type of callback function for binary nodes.
Definition: newgrf.cpp:8007
RandomizedSpriteGroup::lowest_randbit
byte lowest_randbit
Look for this in the per-object randomized bitmask:
Definition: newgrf_spritegroup.h:206
RailtypeInfo::new_loco
StringID new_loco
Name of an engine for this type of rail in the engine preview GUI.
Definition: rail.h:178
ActivateOldShore
static void ActivateOldShore()
Relocates the old shore sprites at new positions.
Definition: newgrf.cpp:9463
BridgeSpec::material
StringID material
the string that contains the bridge description
Definition: bridge.h:49
RoadVehicleInfo::power
uint8 power
Power in 10hp units.
Definition: engine_type.h:120
TileLayoutRegisters::flags
TileLayoutFlags flags
Flags defining which members are valid and to be used.
Definition: newgrf_commons.h:92
AirportSpec::depot_table
const HangarTileTable * depot_table
gives the position of the depots on the airports
Definition: newgrf_airport.h:103
SkipUnknownInfo
static bool SkipUnknownInfo(ByteReader *buf, byte type)
Try to skip the current node and all subnodes (if it's a branch node).
Definition: newgrf.cpp:8199
RailtypeInfo::compatible_railtypes
RailTypes compatible_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel
Definition: rail.h:188
CT_PURCHASE_OBJECT
static const CargoID CT_PURCHASE_OBJECT
Mapping of purchase for objects.
Definition: newgrf_object.h:159
newgrf_canal.h
TILE_HEIGHT
static const uint TILE_HEIGHT
Height of a height level in world coordinate AND in pixels in #ZOOM_LVL_BASE.
Definition: tile_type.h:16
IgnoreTownHouseProperty
static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
Ignore a house property.
Definition: newgrf.cpp:2255
RealSpriteGroup::num_loading
byte num_loading
Number of loading groups.
Definition: newgrf_spritegroup.h:91
CargoID
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:20
MemSetT
static void MemSetT(T *ptr, byte value, size_t num=1)
Type-safe version of memset().
Definition: mem_func.hpp:49
GrfProcessingState::file_index
uint file_index
File index of currently processed GRF file.
Definition: newgrf.cpp:102
VehicleSettings::never_expire_vehicles
bool never_expire_vehicles
never expire vehicles
Definition: settings_type.h:475
HouseSpec
Definition: house.h:98
GetNewgrfCurrencyIdConverted
byte GetNewgrfCurrencyIdConverted(byte grfcurr_id)
Will return the ottd's index correspondence to the ttdpatch's id.
Definition: currency.cpp:113
EF_RAIL_FLIPS
@ EF_RAIL_FLIPS
Rail vehicle can be flipped in the depot.
Definition: engine_type.h:157
GrfProcessingState::SpriteSet::num_sprites
uint num_sprites
Number of sprites in the set.
Definition: newgrf.cpp:90
NEW_AIRPORTTILE_OFFSET
static const uint NEW_AIRPORTTILE_OFFSET
offset of first newgrf airport tile
Definition: airport.h:24
RoadTypeFlags
RoadTypeFlags
Roadtype flags.
Definition: road.h:38
OverrideManagerBase::AddEntityID
virtual uint16 AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id)
Reserves a place in the mapping array for an entity to be installed.
Definition: newgrf_commons.cpp:123
PROP_SHIP_COST_FACTOR
@ PROP_SHIP_COST_FACTOR
Purchase cost.
Definition: newgrf_properties.h:42
ChangeInfoResult
ChangeInfoResult
Possible return values for the FeatureChangeInfo functions.
Definition: newgrf.cpp:986
engine_base.h
IndustryProductionSpriteGroup::cargo_output
CargoID cargo_output[INDUSTRY_NUM_OUTPUTS]
Which output cargoes to add to (only cb version 2)
Definition: newgrf_spritegroup.h:285
BridgeChangeInfo
static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
Define properties for bridges.
Definition: newgrf.cpp:2145
LiveryScheme
LiveryScheme
List of different livery schemes.
Definition: livery.h:20
fontcache.h
_object_mngr
ObjectOverrideManager _object_mngr
The override manager for our objects.
HouseZones
HouseZones
Definition: house.h:71
VehicleSettings::plane_speed
uint8 plane_speed
divisor for speed of aircraft
Definition: settings_type.h:472
RailtypeInfo::maintenance_multiplier
uint16 maintenance_multiplier
Cost multiplier for maintenance of this rail type.
Definition: rail.h:218
RailTypeChangeInfo
static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
Define properties for railtypes.
Definition: newgrf.cpp:4160
Engine::grf_prop
GRFFilePropsBase< NUM_CARGO+2 > grf_prop
Properties related the the grf file.
Definition: engine_base.h:58
RAILVEH_SINGLEHEAD
@ RAILVEH_SINGLEHEAD
indicates a "standalone" locomotive
Definition: engine_type.h:27
IndustryTileSpecialFlags
IndustryTileSpecialFlags
Flags for miscellaneous industry tile specialities.
Definition: industrytype.h:88
IndustrySpec::check_proc
byte check_proc
Index to a procedure to check for conflicting circumstances.
Definition: industrytype.h:113
ShipVehicleInfo::max_speed
uint16 max_speed
Maximum speed (1 unit = 1/3.2 mph = 0.5 km-ish/h)
Definition: engine_type.h:68
GRFTempEngineData::prop27_set
bool prop27_set
Did the NewGRF set property 27 (misc flags)?
Definition: newgrf.cpp:318
RailVehicleInfo::running_cost
byte running_cost
Running cost of engine; For multiheaded engines the sum of both running costs.
Definition: engine_type.h:50
EF_ROAD_TRAM
@ EF_ROAD_TRAM
Road vehicle is a tram/light rail vehicle.
Definition: engine_type.h:154
GetRailTypeByLabel
RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels)
Get the rail type for a given label.
Definition: rail.cpp:311
NEW_INDUSTRYTILEOFFSET
static const IndustryGfx NEW_INDUSTRYTILEOFFSET
original number of tiles
Definition: industry_type.h:32
GRFFilePropsBase::local_id
uint16 local_id
id defined by the grf file for this entity
Definition: newgrf_commons.h:319
newgrf_industries.h
PalSpriteID::pal
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:24
EconomySettings::inflation
bool inflation
disable inflation
Definition: settings_type.h:483
FinaliseCargoArray
static void FinaliseCargoArray()
Check for invalid cargoes.
Definition: newgrf.cpp:8951
LoadNewGRF
void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
Load all the NewGRFs.
Definition: newgrf.cpp:9754
GameSettings::construction
ConstructionSettings construction
construction of things in-game
Definition: settings_type.h:561
GrfProcessingState::IsValidSpriteSet
bool IsValidSpriteSet(byte feature, uint set) const
Check whether a specific set is defined.
Definition: newgrf.cpp:164
GameSettings::vehicle
VehicleSettings vehicle
options for vehicles
Definition: settings_type.h:568
FontSize
FontSize
Available font sizes.
Definition: gfx_type.h:206
TLF_PALETTE_REG_FLAGS
@ TLF_PALETTE_REG_FLAGS
Flags which require resolving the action-1-2-3 chain for the palette, even if it is no action-1 palet...
Definition: newgrf_commons.h:65
TLF_SPRITE
@ TLF_SPRITE
Add signed offset to sprite from register TileLayoutRegisters::sprite.
Definition: newgrf_commons.h:37
ClearTemporaryNewGRFData
static void ClearTemporaryNewGRFData(GRFFile *gf)
Reset all NewGRFData that was used only while processing data.
Definition: newgrf.cpp:418
EngineInfo::climates
byte climates
Climates supported by the engine.
Definition: engine_type.h:138
TLF_PALETTE
@ TLF_PALETTE
Add signed offset to palette from register TileLayoutRegisters::palette.
Definition: newgrf_commons.h:38
PTYPE_UINT_ENUM
@ PTYPE_UINT_ENUM
The parameter allows a range of numbers, each of which can have a special name.
Definition: newgrf_config.h:125
AirportSpec::nof_depots
byte nof_depots
the number of hangar tiles in this airport
Definition: newgrf_airport.h:104
PROP_AIRCRAFT_PASSENGER_CAPACITY
@ PROP_AIRCRAFT_PASSENGER_CAPACITY
Passenger Capacity.
Definition: newgrf_properties.h:51
PROP_SHIP_SPEED
@ PROP_SHIP_SPEED
Max. speed: 1 unit = 1/3.2 mph = 0.5 km-ish/h.
Definition: newgrf_properties.h:43
ClearSnowLine
void ClearSnowLine()
Clear the variable snow line table and free the memory.
Definition: landscape.cpp:677
ResetRoadTypes
void ResetRoadTypes()
Reset all road type information to its default values.
Definition: road_cmd.cpp:62
GRFPalette
GRFPalette
Information that can/has to be stored about a GRF's palette.
Definition: newgrf_config.h:59
StationSpec::callback_mask
byte callback_mask
Bitmask of station callbacks that have to be called.
Definition: newgrf_station.h:158
PROP_ROADVEH_POWER
@ PROP_ROADVEH_POWER
Power in 10 HP.
Definition: newgrf_properties.h:35
VEH_TRAIN
@ VEH_TRAIN
Train vehicle type.
Definition: vehicle_type.h:24
RandomizedSpriteGroup
Definition: newgrf_spritegroup.h:196
RailtypeInfo::group
const SpriteGroup * group[RTSG_END]
Sprite groups for resolving sprites.
Definition: rail.h:278
IndustrySpec::name
StringID name
Displayed name of the industry.
Definition: industrytype.h:127
ChangeGRFParamDefault
static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value.
Definition: newgrf.cpp:7995
IndustryBehaviour
IndustryBehaviour
Various industry behaviours mostly to represent original TTD specialities.
Definition: industrytype.h:61
PROP_TRAIN_COST_FACTOR
@ PROP_TRAIN_COST_FACTOR
Purchase cost (if dualheaded: sum of both vehicles)
Definition: newgrf_properties.h:26
IndustrySpec::new_industry_text
StringID new_industry_text
Message appearing when the industry is built.
Definition: industrytype.h:128
StationSpec::disallowed_lengths
byte disallowed_lengths
Bitmask of platform lengths available for the station.
Definition: newgrf_station.h:137
_misc_grf_features
byte _misc_grf_features
Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E.
Definition: newgrf.cpp:74
RailVehicleInfo::capacity
byte capacity
Cargo capacity of vehicle; For multiheaded engines the capacity of each single engine.
Definition: engine_type.h:53
IndustryProductionSpriteGroup::cargo_input
CargoID cargo_input[INDUSTRY_NUM_INPUTS]
Which input cargoes to take from (only cb version 2)
Definition: newgrf_spritegroup.h:282
DefineGotoLabel
static void DefineGotoLabel(ByteReader *buf)
Action 0x10 - Define goto label.
Definition: newgrf.cpp:7512
ByteReader
Class to read from a NewGRF file.
Definition: newgrf.cpp:213
LoadGRFSound
static void LoadGRFSound(size_t offs, SoundEntry *sound)
Load a sound from a file.
Definition: newgrf.cpp:7575
AllowedSubtags::AllowedSubtags
AllowedSubtags(uint32 id, BranchHandler handler)
Create a branch node with a callback handler.
Definition: newgrf.cpp:8054
TTDPStringIDToOTTDStringIDMapping
static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
Perform a mapping from TTDPatch's string IDs to OpenTTD's string IDs, but only for the ones we are aw...
Definition: newgrf.cpp:487
GRFFilePropsBase::grffile
const struct GRFFile * grffile
grf file that introduced this entity
Definition: newgrf_commons.h:320
PROP_AIRCRAFT_SPEED
@ PROP_AIRCRAFT_SPEED
Max. speed: 1 unit = 8 mph = 12.8 km-ish/h.
Definition: newgrf_properties.h:49
AirportTileSpec::name
StringID name
Tile Subname string, land information on this tile will give you "AirportName (TileSubname)".
Definition: newgrf_airporttiles.h:68
CanalProperties
Canal properties local to the NewGRF.
Definition: newgrf.h:39
ResetBridges
void ResetBridges()
Reset the data been eventually changed by the grf loaded.
Definition: tunnelbridge_cmd.cpp:83
RailtypeInfo::cost_multiplier
uint16 cost_multiplier
Cost multiplier for building this rail type.
Definition: rail.h:213
DateFract
uint16 DateFract
The fraction of a date we're in, i.e. the number of ticks since the last date changeover.
Definition: date_type.h:15
AllowedSubtags::data
DataHandler data
Callback function for a binary node, only valid if type == 'B'.
Definition: newgrf.cpp:8078
AirportTileTable::ti
TileIndexDiffC ti
Tile offset from the top-most airport tile.
Definition: newgrf_airport.h:24
GRFConfig::filename
char * filename
Filename - either with or without full path.
Definition: newgrf_config.h:159
EngineInfo::string_id
StringID string_id
Default name of engine.
Definition: engine_type.h:145
AircraftVehicleInfo
Information about a aircraft vehicle.
Definition: engine_type.h:97
GetLanguage
const LanguageMetadata * GetLanguage(byte newgrflangid)
Get the language with the given NewGRF language ID.
Definition: strings.cpp:1862
ObjectSpec::climate
uint8 climate
In which climates is this object available?
Definition: newgrf_object.h:64
free
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: stdafx.h:454
AirportSpec::table
const AirportTileTable *const * table
list of the tiles composing the airport
Definition: newgrf_airport.h:100
HangarTileTable
A list of all hangar tiles in an airport.
Definition: newgrf_airport.h:89
CT_INVALID
@ CT_INVALID
Invalid cargo type.
Definition: cargo_type.h:68
MapGRFStringID
StringID MapGRFStringID(uint32 grfid, StringID str)
Used when setting an object's property to map to the GRF's strings while taking in consideration the ...
Definition: newgrf.cpp:551
PROP_TRAIN_POWER
@ PROP_TRAIN_POWER
Power in hp (if dualheaded: sum of both vehicles)
Definition: newgrf_properties.h:22
AirportTileSpec::Get
static const AirportTileSpec * Get(StationGfx gfx)
Retrieve airport tile spec for the given airport tile.
Definition: newgrf_airporttiles.cpp:36
TownHouseChangeInfo
static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
Define properties for houses.
Definition: newgrf.cpp:2322
IndustryOverrideManager::SetEntitySpec
void SetEntitySpec(IndustrySpec *inds)
Method to install the new industry data in its proper slot The slot assignment is internal of this me...
Definition: newgrf_commons.cpp:260
PROP_TRAIN_CARGO_AGE_PERIOD
@ PROP_TRAIN_CARGO_AGE_PERIOD
Number of ticks before carried cargo is aged.
Definition: newgrf_properties.h:30
ResetIndustries
void ResetIndustries()
This function initialize the spec arrays of both industry and industry tiles.
Definition: industry_cmd.cpp:73
VEH_SHIP
@ VEH_SHIP
Ship vehicle type.
Definition: vehicle_type.h:26
VehicleSettings::freight_trains
uint8 freight_trains
value to multiply the weight of cargo by
Definition: settings_type.h:473
ChangeGRFPalette
static bool ChangeGRFPalette(size_t len, ByteReader *buf)
Callback function for 'INFO'->'PALS' to set the number of valid parameters.
Definition: newgrf.cpp:7838
LoadFontGlyph
static void LoadFontGlyph(ByteReader *buf)
Action 0x12.
Definition: newgrf.cpp:7693
PROP_ROADVEH_RUNNING_COST_FACTOR
@ PROP_ROADVEH_RUNNING_COST_FACTOR
Yearly runningcost.
Definition: newgrf_properties.h:32
SPR_TRACKS_FOR_SLOPES_BASE
static const SpriteID SPR_TRACKS_FOR_SLOPES_BASE
Sprites for 'highlighting' tracks on sloped land.
Definition: sprites.h:192
ResultSpriteGroup
Definition: newgrf_spritegroup.h:244
IndustryTileSpec::anim_next
byte anim_next
Next frame in an animation.
Definition: industrytype.h:161
IndustryTileSpec
Defines the data structure of each individual tile of an industry.
Definition: industrytype.h:156
GRFLoadedFeatures
Definition: newgrf.h:174
TLF_DRAWING_FLAGS
@ TLF_DRAWING_FLAGS
Flags which are still required after loading the GRF.
Definition: newgrf_commons.h:53
TLF_PALETTE_VAR10
@ TLF_PALETTE_VAR10
Resolve palette with a specific value in variable 10.
Definition: newgrf_commons.h:48
InitRailTypes
void InitRailTypes()
Resolve sprites of custom rail types.
Definition: rail_cmd.cpp:138
HouseSpec::remove_rating_decrease
uint16 remove_rating_decrease
rating decrease if removed
Definition: house.h:105
DisableGrf
static GRFError * DisableGrf(StringID message=STR_NULL, GRFConfig *config=nullptr)
Disable a GRF.
Definition: newgrf.cpp:435
AirportTileSpec::grf_prop
GRFFileProps grf_prop
properties related the the grf file
Definition: newgrf_airporttiles.h:72
TLF_SPRITE_REG_FLAGS
@ TLF_SPRITE_REG_FLAGS
Flags which require resolving the action-1-2-3 chain for the sprite, even if it is no action-1 sprite...
Definition: newgrf_commons.h:62
InitRoadTypes
void InitRoadTypes()
Resolve sprites of custom road types.
Definition: road_cmd.cpp:118
RoadTypeInfo::build_caption
StringID build_caption
Caption of the build vehicle GUI for this rail type.
Definition: road.h:103
GetFileByFilename
static GRFFile * GetFileByFilename(const char *filename)
Obtain a NewGRF file by its filename.
Definition: newgrf.cpp:409
GrfProcessingState::skip_sprites
int skip_sprites
Number of pseudo sprites to skip before processing the next one. (-1 to skip to end of file)
Definition: newgrf.cpp:109
ResetCustomStations
static void ResetCustomStations()
Reset and clear all NewGRF stations.
Definition: newgrf.cpp:8401
HZ_ZON1
@ HZ_ZON1
0..4 1,2,4,8,10 which town zones the building can be built in, Zone1 been the further suburb
Definition: house.h:73
TLF_SPRITE_VAR10
@ TLF_SPRITE_VAR10
Resolve sprite with a specific value in variable 10.
Definition: newgrf_commons.h:47
lastof
#define lastof(x)
Get the last element of an fixed size array.
Definition: stdafx.h:383
PROP_AIRCRAFT_RANGE
@ PROP_AIRCRAFT_RANGE
Aircraft range.
Definition: newgrf_properties.h:54
EconomySettings::allow_town_roads
bool allow_town_roads
towns are allowed to build roads (always allowed when generating world / in SE)
Definition: settings_type.h:501
MAX_NUM_CASES
static const uint8 MAX_NUM_CASES
Maximum number of supported cases.
Definition: language.h:21
_ttdpatch_flags
static uint32 _ttdpatch_flags[8]
32 * 8 = 256 flags.
Definition: newgrf.cpp:77
BuildLinkStatsLegend
void BuildLinkStatsLegend()
Populate legend table for the link stat view.
Definition: smallmap_gui.cpp:198
ChangeGRFParamDescription
static bool ChangeGRFParamDescription(byte langid, const char *str)
Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter.
Definition: newgrf.cpp:7928
EngineInfo::cargo_age_period
uint16 cargo_age_period
Number of ticks before carried cargo is aged.
Definition: engine_type.h:146
GrfProcessingState::nfo_line
uint32 nfo_line
Currently processed pseudo sprite number in the GRF.
Definition: newgrf.cpp:105
RoadTypeInfo::introduction_required_roadtypes
RoadTypes introduction_required_roadtypes
Bitmask of roadtypes that are required for this roadtype to be introduced at a given introduction_dat...
Definition: road.h:169
ReadSpriteLayout
static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
Read a spritelayout from the GRF.
Definition: newgrf.cpp:853
GetCargoIDByLabel
CargoID GetCargoIDByLabel(CargoLabel cl)
Get the cargo ID by cargo label.
Definition: cargotype.cpp:85
newgrf_cargo.h
SetYearEngineAgingStops
void SetYearEngineAgingStops()
Compute the value for _year_engine_aging_stops.
Definition: engine.cpp:612
RailtypeInfo::curve_speed
byte curve_speed
Multiplier for curve maximum speed advantage.
Definition: rail.h:203
MapLogY
static uint MapLogY()
Logarithm of the map size along the y side.
Definition: map_func.h:62
GRFFile::railtype_list
std::vector< RailTypeLabel > railtype_list
Railtype translation table.
Definition: newgrf.h:129
AirportSpec::catchment
byte catchment
catchment area of this airport
Definition: newgrf_airport.h:108
ReadSpriteLayoutSprite
static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags, bool invert_action1_flag, bool use_cur_spritesets, int feature, PalSpriteID *grf_sprite, uint16 *max_sprite_offset=nullptr, uint16 *max_palette_offset=nullptr)
Read a sprite and a palette from the GRF and convert them into a format suitable to OpenTTD.
Definition: newgrf.cpp:742
StationSpec::cargo_triggers
CargoTypes cargo_triggers
Bitmask of cargo types which cause trigger re-randomizing.
Definition: newgrf_station.h:156
FOR_EACH_SET_BIT
#define FOR_EACH_SET_BIT(bitpos_var, bitset_value)
Do an operation for each set set bit in a value.
Definition: bitmath_func.hpp:361
SpriteGroup
Definition: newgrf_spritegroup.h:57
GRFLabel
Definition: newgrf.h:97
SkipAct12
static void SkipAct12(ByteReader *buf)
Action 0x12 (SKIP)
Definition: newgrf.cpp:7724
SPR_ONEWAY_BASE
static const SpriteID SPR_ONEWAY_BASE
One way road sprites.
Definition: sprites.h:287
HouseSpec::grf_prop
GRFFileProps grf_prop
Properties related the the grf file.
Definition: house.h:114
AddStringForMapping
static void AddStringForMapping(StringID source, StringID *target)
Record a static StringID for getting translated later.
Definition: newgrf.cpp:474
GetGRFConfig
GRFConfig * GetGRFConfig(uint32 grfid, uint32 mask)
Retrieve a NewGRF from the current config by its grfid.
Definition: newgrf_config.cpp:810
ResetGenericCallbacks
void ResetGenericCallbacks()
Reset all generic feature callback sprite groups.
Definition: newgrf_generic.cpp:97
Action5Type
Information about a single action 5 type.
Definition: newgrf.cpp:6094
_currency_specs
CurrencySpec _currency_specs[CURRENCY_END]
Array of currencies used by the system.
Definition: currency.cpp:74
NamePart::id
byte id
If probability bit 7 is set.
Definition: newgrf_townname.h:23
LanguageMap::Mapping::newgrf_id
byte newgrf_id
NewGRF's internal ID for a case/gender.
Definition: newgrf_text.h:61
StationSpec::wires
byte wires
Bitmask of base tiles (0 - 7) which should contain elrail wires.
Definition: newgrf_station.h:163
AddGRFTextToList
static void AddGRFTextToList(GRFTextList &list, byte langid, const std::string &text_to_add)
Add a new text to a GRFText list.
Definition: newgrf_text.cpp:494
FindFirstBit
uint8 FindFirstBit(uint32 x)
Search the first set bit in a 32 bit variable.
Definition: bitmath_func.cpp:37
SetEngineGRF
void SetEngineGRF(EngineID engine, const GRFFile *file)
Tie a GRFFile entry to an engine, to allow us to retrieve GRF parameters etc during a game.
Definition: newgrf_engine.cpp:103
OrderSettings::gradual_loading
bool gradual_loading
load vehicles gradually
Definition: settings_type.h:452
GCF_STATIC
@ GCF_STATIC
GRF file is used statically (can be used in any MP game)
Definition: newgrf_config.h:25
NewGRFSpriteLayout::Allocate
void Allocate(uint num_sprites)
Allocate a spritelayout for num_sprites building sprites.
Definition: newgrf_commons.cpp:624
Action5Type::max_sprites
uint16 max_sprites
If the Action5 contains more sprites, only the first max_sprites sprites will be used.
Definition: newgrf.cpp:6098
GRFConfig::param_info
std::vector< GRFParameterInfo * > param_info
NOSAVE: extra information about the parameters.
Definition: newgrf_config.h:174
IndustryLifeType
IndustryLifeType
Available types of industry lifetimes.
Definition: industrytype.h:28
GRFFile
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:105
ObjectSpec::cls_id
ObjectClassID cls_id
The class to which this spec belongs.
Definition: newgrf_object.h:61
PROP_TRAIN_USER_DATA
@ PROP_TRAIN_USER_DATA
User defined data for vehicle variable 0x42.
Definition: newgrf_properties.h:29
ShipVehicleInfo::ocean_speed_frac
byte ocean_speed_frac
Fraction of maximum speed for ocean tiles.
Definition: engine_type.h:74
Engine::type
VehicleType type
Vehicle type, ie VEH_ROAD, VEH_TRAIN, etc.
Definition: engine_base.h:40
IgnoreIndustryTileProperty
static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
Ignore an industry tile property.
Definition: newgrf.cpp:3107
StationSpec::blocked
byte blocked
Bitmask of base tiles (0 - 7) which are blocked to trains.
Definition: newgrf_station.h:164
debug.h
GRFConfig::param
uint32 param[0x80]
GRF parameters.
Definition: newgrf_config.h:170
DAYS_TILL_ORIGINAL_BASE_YEAR
#define DAYS_TILL_ORIGINAL_BASE_YEAR
The offset in days from the '_date == 0' till 'ConvertYMDToDate(ORIGINAL_BASE_YEAR,...
Definition: date_type.h:80
GRFParameterInfo::min_value
uint32 min_value
The minimal value this parameter can have.
Definition: newgrf_config.h:137
TileLayoutSpriteGroup
Action 2 sprite layout for houses, industry tiles, objects and airport tiles.
Definition: newgrf_spritegroup.h:267
GRFConfig::GetName
const char * GetName() const
Get the name of this grf.
Definition: newgrf_config.cpp:104
RoadTypeInfo::maintenance_multiplier
uint16 maintenance_multiplier
Cost multiplier for maintenance of this road type.
Definition: road.h:134
PROP_ROADVEH_WEIGHT
@ PROP_ROADVEH_WEIGHT
Weight in 1/4 t.
Definition: newgrf_properties.h:36
TileLayoutRegisters::max_sprite_offset
uint16 max_sprite_offset
Maximum offset to add to the sprite. (limited by size of the spriteset)
Definition: newgrf_commons.h:96
SPR_TRAMWAY_BASE
static const SpriteID SPR_TRAMWAY_BASE
Tramway sprites.
Definition: sprites.h:266
engine_func.h
AirportTileSpec::animation
AnimationInfo animation
Information about the animation.
Definition: newgrf_airporttiles.h:67
EC_MONORAIL
@ EC_MONORAIL
Mono rail engine.
Definition: engine_type.h:37
WaterFeature::group
const SpriteGroup * group
Sprite group to start resolving.
Definition: newgrf_canal.h:23
INVALID_RAILTYPE
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition: rail_type.h:34
DrawTileSeqStruct
A tile child sprite and palette to draw for stations etc, with 3D bounding box.
Definition: sprite.h:25
ObjectSpec::flags
ObjectFlags flags
Flags/settings related to the object.
Definition: newgrf_object.h:70
RoadTypeChangeInfo
static ChangeInfoResult RoadTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf, RoadTramType rtt)
Define properties for roadtypes.
Definition: newgrf.cpp:4378
HouseOverrideManager::SetEntitySpec
void SetEntitySpec(const HouseSpec *hs)
Install the specs into the HouseSpecs array It will find itself the proper slot on which it will go.
Definition: newgrf_commons.cpp:176
RailtypeInfo::introduces_railtypes
RailTypes introduces_railtypes
Bitmask of which other railtypes are introduced when this railtype is introduced.
Definition: rail.h:263
MAX_YEAR
static const Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date,...
Definition: date_type.h:94
AllocaM
#define AllocaM(T, num_elements)
alloca() has to be called in the parent function, so define AllocaM() as a macro
Definition: alloc_func.hpp:132
SNOW_LINE_MONTHS
static const uint SNOW_LINE_MONTHS
Number of months in the snow line table.
Definition: landscape.h:16
CanalFeature
CanalFeature
List of different canal 'features'.
Definition: newgrf.h:25
TileIndexDiffC::x
int16 x
The x value of the coordinate.
Definition: map_type.h:58
ReadSpriteLayoutRegisters
static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bool is_parent, NewGRFSpriteLayout *dts, uint index)
Preprocess the TileLayoutFlags and read register modifiers from the GRF.
Definition: newgrf.cpp:800
GRFP_BLT_MASK
@ GRFP_BLT_MASK
Bitmask to only get the blitter information.
Definition: newgrf_config.h:78