OpenTTD

newgrf.cpp
Go to the documentation of this file.
1 /* $Id: newgrf.cpp 27989 2018-03-11 15:08:51Z frosch $ */
2
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
9
12 #include "stdafx.h"
13
14 #include <stdarg.h>
15 #include <algorithm>
16
17 #include "debug.h"
18 #include "fileio_func.h"
19 #include "engine_func.h"
20 #include "engine_base.h"
21 #include "bridge.h"
22 #include "town.h"
23 #include "newgrf_engine.h"
24 #include "newgrf_text.h"
25 #include "fontcache.h"
26 #include "currency.h"
27 #include "landscape.h"
28 #include "newgrf_cargo.h"
29 #include "newgrf_house.h"
30 #include "newgrf_sound.h"
31 #include "newgrf_station.h"
32 #include "industrytype.h"
33 #include "newgrf_canal.h"
34 #include "newgrf_townname.h"
35 #include "newgrf_industries.h"
36 #include "newgrf_airporttiles.h"
37 #include "newgrf_airport.h"
38 #include "newgrf_object.h"
39 #include "rev.h"
40 #include "fios.h"
41 #include "strings_func.h"
42 #include "date_func.h"
43 #include "string_func.h"
44 #include "network/network.h"
45 #include <map>
46 #include "smallmap_gui.h"
47 #include "genworld.h"
48 #include "error.h"
49 #include "vehicle_func.h"
50 #include "language.h"
51 #include "vehicle_base.h"
52
53 #include "table/strings.h"
54 #include "table/build_industry.h"
55
56 #include "safeguards.h"
57
58 /* TTDPatch extended GRF format codec
59 * (c) Petr Baudis 2004 (GPL'd)
60 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
61 *
62 * Contains portions of documentation by TTDPatch team.
63 * Thanks especially to Josef Drexler for the documentation as well as a lot
64 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
65 * served as subject to the initial testing of this codec. */
66
68 static SmallVector<GRFFile *, 16> _grf_files;
69
71 byte _misc_grf_features = 0;
72
74 static uint32 _ttdpatch_flags[8];
75
77 GRFLoadedFeatures _loaded_newgrf_features;
78
79 static const uint MAX_SPRITEGROUP = UINT8_MAX;
80
82 struct GrfProcessingState {
83 private:
85 struct SpriteSet {
86 SpriteID sprite;
87 uint num_sprites;
88 };
89
91 std::map<uint, SpriteSet> spritesets[GSF_END];
92
93 public:
94 /* Global state */
95 GrfLoadingStage stage;
96 SpriteID spriteid;
97
98 /* Local state in the file */
99 uint file_index;
100 GRFFile *grffile;
101 GRFConfig *grfconfig;
102 uint32 nfo_line;
103 byte grf_container_ver;
104
105 /* Kind of return values when processing certain actions */
106 int skip_sprites;
107
108 /* Currently referenceable spritegroups */
109 SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
110
112 void ClearDataForNextFile()
113 {
114 this->nfo_line = 0;
115 this->skip_sprites = 0;
116
117 for (uint i = 0; i < GSF_END; i++) {
118 this->spritesets[i].clear();
119 }
120
121 memset(this->spritegroups, 0, sizeof(this->spritegroups));
122 }
123
132 void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
133 {
134 assert(feature < GSF_END);
135 for (uint i = 0; i < numsets; i++) {
136 SpriteSet &set = this->spritesets[feature][first_set + i];
137 set.sprite = first_sprite + i * numents;
138 set.num_sprites = numents;
139 }
140 }
141
148 bool HasValidSpriteSets(byte feature) const
149 {
150 assert(feature < GSF_END);
151 return !this->spritesets[feature].empty();
152 }
153
161 bool IsValidSpriteSet(byte feature, uint set) const
162 {
163 assert(feature < GSF_END);
164 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
165 }
166
173 SpriteID GetSprite(byte feature, uint set) const
174 {
175 assert(IsValidSpriteSet(feature, set));
176 return this->spritesets[feature].find(set)->second.sprite;
177 }
178
185 uint GetNumEnts(byte feature, uint set) const
186 {
187 assert(IsValidSpriteSet(feature, set));
188 return this->spritesets[feature].find(set)->second.num_sprites;
189 }
190 };
191
192 static GrfProcessingState _cur;
193
194
201 template <VehicleType T>
202 static inline bool IsValidNewGRFImageIndex(uint8 image_index)
203 {
204 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
205 }
206
207 class OTTDByteReaderSignal { };
208
210 class ByteReader {
211 protected:
212 byte *data;
213 byte *end;
214
215 public:
216 ByteReader(byte *data, byte *end) : data(data), end(end) { }
217
218 inline byte ReadByte()
219 {
220 if (data < end) return *(data)++;
221 throw OTTDByteReaderSignal();
222 }
223
224 uint16 ReadWord()
225 {
226 uint16 val = ReadByte();
227 return val | (ReadByte() << 8);
228 }
229
230 uint16 ReadExtendedByte()
231 {
232 uint16 val = ReadByte();
233 return val == 0xFF ? ReadWord() : val;
234 }
235
236 uint32 ReadDWord()
237 {
238 uint32 val = ReadWord();
239 return val | (ReadWord() << 16);
240 }
241
242 uint32 ReadVarSize(byte size)
243 {
244 switch (size) {
245 case 1: return ReadByte();
246 case 2: return ReadWord();
247 case 4: return ReadDWord();
248 default:
249 NOT_REACHED();
250 return 0;
251 }
252 }
253
254 const char *ReadString()
255 {
256 char *string = reinterpret_cast<char *>(data);
257 size_t string_length = ttd_strnlen(string, Remaining());
258
259 if (string_length == Remaining()) {
260 /* String was not NUL terminated, so make sure it is now. */
261 string[string_length - 1] = '\0';
262 grfmsg(7, "String was not terminated with a zero byte.");
263 } else {
264 /* Increase the string length to include the NUL byte. */
265 string_length++;
266 }
267 Skip(string_length);
268
269 return string;
270 }
271
272 inline size_t Remaining() const
273 {
274 return end - data;
275 }
276
277 inline bool HasData(size_t count = 1) const
278 {
279 return data + count <= end;
280 }
281
282 inline byte *Data()
283 {
284 return data;
285 }
286
287 inline void Skip(size_t len)
288 {
289 data += len;
290 /* It is valid to move the buffer to exactly the end of the data,
291 * as there may not be any more data read. */
292 if (data > end) throw OTTDByteReaderSignal();
293 }
294 };
295
296 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
297
298 static const uint NUM_STATIONS_PER_GRF = 255;
299
301 struct GRFTempEngineData {
303 enum Refittability {
304 UNSET = 0,
305 EMPTY,
306 NONEMPTY,
307 };
308
309 uint16 cargo_allowed;
310 uint16 cargo_disallowed;
311 RailTypeLabel railtypelabel;
312 const GRFFile *defaultcargo_grf;
313 Refittability refittability;
314 bool prop27_set;
315 uint8 rv_max_speed;
316 uint32 ctt_include_mask;
317 uint32 ctt_exclude_mask;
318
323 void UpdateRefittability(bool non_empty)
324 {
325 if (non_empty) {
326 this->refittability = NONEMPTY;
327 } else if (this->refittability == UNSET) {
328 this->refittability = EMPTY;
329 }
330 }
331 };
332
333 static GRFTempEngineData *_gted;
334
339 static uint32 _grm_engines[256];
340
342 static uint32 _grm_cargoes[NUM_CARGO * 2];
343
344 struct GRFLocation {
345 uint32 grfid;
346 uint32 nfoline;
347
348 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
349
350 bool operator<(const GRFLocation &other) const
351 {
352 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
353 }
354
355 bool operator == (const GRFLocation &other) const
356 {
357 return this->grfid == other.grfid && this->nfoline == other.nfoline;
358 }
359 };
360
361 static std::map<GRFLocation, SpriteID> _grm_sprites;
362 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
363 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
364
375 void CDECL grfmsg(int severity, const char *str, ...)
376 {
377 char buf[1024];
378 va_list va;
379
380 va_start(va, str);
381 vseprintf(buf, lastof(buf), str, va);
382 va_end(va);
383
384 DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
385 }
386
392 static GRFFile *GetFileByGRFID(uint32 grfid)
393 {
394 const GRFFile * const *end = _grf_files.End();
395 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
396 if ((*file)->grfid == grfid) return *file;
397 }
398 return NULL;
399 }
400
406 static GRFFile *GetFileByFilename(const char *filename)
407 {
408 const GRFFile * const *end = _grf_files.End();
409 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
410 if (strcmp((*file)->filename, filename) == 0) return *file;
411 }
412 return NULL;
413 }
414
416 static void ClearTemporaryNewGRFData(GRFFile *gf)
417 {
418 /* Clear the GOTO labels used for GRF processing */
419 for (GRFLabel *l = gf->label; l != NULL;) {
420 GRFLabel *l2 = l->next;
421 free(l);
422 l = l2;
423 }
424 gf->label = NULL;
425 }
426
433 static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = NULL)
434 {
435 GRFFile *file;
436 if (config != NULL) {
437 file = GetFileByGRFID(config->ident.grfid);
438 } else {
439 config = _cur.grfconfig;
440 file = _cur.grffile;
441 }
442
443 config->status = GCS_DISABLED;
444 if (file != NULL) ClearTemporaryNewGRFData(file);
445 if (config == _cur.grfconfig) _cur.skip_sprites = -1;
446
447 if (message != STR_NULL) {
448 delete config->error;
449 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
450 if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
451 }
452
453 return config->error;
454 }
455
459 struct StringIDMapping {
460 uint32 grfid;
461 StringID source;
462 StringID *target;
463 };
464 typedef SmallVector<StringIDMapping, 16> StringIDMappingVector;
465 static StringIDMappingVector _string_to_grf_mapping;
466
472 static void AddStringForMapping(StringID source, StringID *target)
473 {
474 *target = STR_UNDEFINED;
475 StringIDMapping *item = _string_to_grf_mapping.Append();
476 item->grfid = _cur.grffile->grfid;
477 item->source = source;
478 item->target = target;
479 }
480
488 static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
489 {
490 /* StringID table for TextIDs 0x4E->0x6D */
491 static const StringID units_volume[] = {
492 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
493 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
494 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
495 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
496 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
497 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
498 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
499 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
500 };
501
502 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
503 assert(!IsInsideMM(str, 0xD000, 0xD7FF));
504
505 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
506 assert_compile(stringend - stringid == end - begin); \
507 if (str >= begin && str <= end) return str + (stringid - begin)
508
509 /* We have some changes in our cargo strings, resulting in some missing. */
510 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
511 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
512 if (str >= 0x004E && str <= 0x006D) return units_volume[str - 0x004E];
513 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
514 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
515 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
516
517 /* Map building names according to our lang file changes. There are several
518 * ranges of house ids, all of which need to be remapped to allow newgrfs
519 * to use original house names. */
520 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
521 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
522 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
523
524 /* Same thing for industries */
525 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
526 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
527 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
528 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
529 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
530
531 switch (str) {
532 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
533 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
534 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
535 }
536 #undef TEXTID_TO_STRINGID
537
538 if (str == STR_NULL) return STR_EMPTY;
539
540 DEBUG(grf, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
541
542 return STR_EMPTY;
543 }
544
552 StringID MapGRFStringID(uint32 grfid, StringID str)
553 {
554 if (IsInsideMM(str, 0xD800, 0xE000)) {
555 /* General text provided by NewGRF.
556 * In the specs this is called the 0xDCxx range (misc presistent texts),
557 * but we meanwhile extended the range to 0xD800-0xDFFF.
558 * Note: We are not involved in the "persistent" business, since we do not store
559 * any NewGRF strings in savegames. */
560 return GetGRFStringID(grfid, str);
561 } else if (IsInsideMM(str, 0xD000, 0xD800)) {
562 /* Callback text provided by NewGRF.
563 * In the specs this is called the 0xD0xx range (misc graphics texts).
564 * These texts can be returned by various callbacks.
565 *
566 * Due to how TTDP implements the GRF-local- to global-textid translation
567 * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
568 * We do not care about that difference and just mask out the 0x400 bit.
569 */
570 str &= ~0x400;
571 return GetGRFStringID(grfid, str);
572 } else {
573 /* The NewGRF wants to include/reference an original TTD string.
574 * Try our best to find an equivalent one. */
575 return TTDPStringIDToOTTDStringIDMapping(str);
576 }
577 }
578
579 static std::map<uint32, uint32> _grf_id_overrides;
580
586 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
587 {
588 _grf_id_overrides[source_grfid] = target_grfid;
589 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
590 }
591
600 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
601 {
602 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
603 * them use the same engine slots. */
604 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
605 if (_settings_game.vehicle.dynamic_engines) {
606 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
607 scope_grfid = file->grfid;
608 uint32 override = _grf_id_overrides[file->grfid];
609 if (override != 0) {
610 scope_grfid = override;
611 const GRFFile *grf_match = GetFileByGRFID(override);
612 if (grf_match == NULL) {
613 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
614 } else {
615 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
616 }
617 }
618
619 /* Check if the engine is registered in the override manager */
620 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
621 if (engine != INVALID_ENGINE) {
622 Engine *e = Engine::Get(engine);
623 if (e->grf_prop.grffile == NULL) e->grf_prop.grffile = file;
624 return e;
625 }
626 }
627
628 /* Check if there is an unreserved slot */
629 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
630 if (engine != INVALID_ENGINE) {
631 Engine *e = Engine::Get(engine);
632
633 if (e->grf_prop.grffile == NULL) {
634 e->grf_prop.grffile = file;
635 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
636 }
637
638 /* Reserve the engine slot */
639 if (!static_access) {
640 EngineIDMapping *eid = _engine_mngr.Get(engine);
641 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
642 }
643
644 return e;
645 }
646
647 if (static_access) return NULL;
648
649 if (!Engine::CanAllocateItem()) {
650 grfmsg(0, "Can't allocate any more engines");
651 return NULL;
652 }
653
654 size_t engine_pool_size = Engine::GetPoolSize();
655
656 /* ... it's not, so create a new one based off an existing engine */
657 Engine *e = new Engine(type, internal_id);
658 e->grf_prop.grffile = file;
659
660 /* Reserve the engine slot */
661 assert(_engine_mngr.Length() == e->index);
662 EngineIDMapping *eid = _engine_mngr.Append();
663 eid->type = type;
664 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
665 eid->internal_id = internal_id;
666 eid->substitute_id = min(internal_id, _engine_counts[type]); // substitute_id == _engine_counts[subtype] means "no substitute"
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 = NULL, uint16 *max_palette_offset = NULL)
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 != NULL) *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 != NULL) *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 == NULL) 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 != NULL) {
932 dts->consistent_max_offset = 0;
933 if (dts->registers == NULL) 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 uint32 TranslateRefitMask(uint32 refit_mask)
949 {
950 uint32 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 == NULL) 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.Length()) {
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.Length() == 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 uint32 &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 == NULL) 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 0x08: // Speed (1 unit is 0.5 kmh)
1353 rvi->max_speed = buf->ReadByte();
1354 break;
1355
1356 case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1357 rvi->running_cost = buf->ReadByte();
1358 break;
1359
1360 case 0x0A: // Running cost base
1361 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1362 break;
1363
1364 case 0x0E: { // Sprite ID
1365 uint8 spriteid = buf->ReadByte();
1366 uint8 orig_spriteid = spriteid;
1367
1368 /* cars have different custom id in the GRF file */
1369 if (spriteid == 0xFF) spriteid = 0xFD;
1370
1371 if (spriteid < 0xFD) spriteid >>= 1;
1372
1373 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1374 rvi->image_index = spriteid;
1375 } else {
1376 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1377 rvi->image_index = 0;
1378 }
1379 break;
1380 }
1381
1382 case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1383 rvi->capacity = buf->ReadByte();
1384 break;
1385
1386 case 0x10: { // Cargo type
1387 _gted[e->index].defaultcargo_grf = _cur.grffile;
1388 uint8 ctype = buf->ReadByte();
1389
1390 if (ctype == 0xFF) {
1391 /* 0xFF is specified as 'use first refittable' */
1392 ei->cargo_type = CT_INVALID;
1393 } else if (_cur.grffile->grf_version >= 8) {
1394 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1395 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1396 } else if (ctype < NUM_CARGO) {
1397 /* Use untranslated cargo. */
1398 ei->cargo_type = ctype;
1399 } else {
1400 ei->cargo_type = CT_INVALID;
1401 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1402 }
1403 break;
1404 }
1405
1406 case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1407 rvi->cost_factor = buf->ReadByte();
1408 break;
1409
1410 case 0x12: // SFX
1411 rvi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1412 break;
1413
1414 case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1415 rvi->power = buf->ReadByte();
1416 break;
1417
1418 case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1419 rvi->weight = buf->ReadByte();
1420 break;
1421
1422 case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1423 _gted[e->index].rv_max_speed = buf->ReadByte();
1424 break;
1425
1426 case 0x16: { // Cargoes available for refitting
1427 uint32 mask = buf->ReadDWord();
1428 _gted[e->index].UpdateRefittability(mask != 0);
1429 ei->refit_mask = TranslateRefitMask(mask);
1430 _gted[e->index].defaultcargo_grf = _cur.grffile;
1431 break;
1432 }
1433
1434 case 0x17: // Callback mask
1435 ei->callback_mask = buf->ReadByte();
1436 break;
1437
1438 case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1439 rvi->tractive_effort = buf->ReadByte();
1440 break;
1441
1442 case 0x19: // Air drag
1443 rvi->air_drag = buf->ReadByte();
1444 break;
1445
1446 case 0x1A: // Refit cost
1447 ei->refit_cost = buf->ReadByte();
1448 break;
1449
1450 case 0x1B: // Retire vehicle early
1451 ei->retire_early = buf->ReadByte();
1452 break;
1453
1454 case 0x1C: // Miscellaneous flags
1455 ei->misc_flags = buf->ReadByte();
1456 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1457 break;
1458
1459 case 0x1D: // Cargo classes allowed
1460 _gted[e->index].cargo_allowed = buf->ReadWord();
1461 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1462 _gted[e->index].defaultcargo_grf = _cur.grffile;
1463 break;
1464
1465 case 0x1E: // Cargo classes disallowed
1466 _gted[e->index].cargo_disallowed = buf->ReadWord();
1467 _gted[e->index].UpdateRefittability(false);
1468 break;
1469
1470 case 0x1F: // Long format introduction date (days since year 0)
1471 ei->base_intro = buf->ReadDWord();
1472 break;
1473
1474 case 0x20: // Alter purchase list sort order
1475 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1476 break;
1477
1478 case 0x21: // Visual effect
1479 rvi->visual_effect = buf->ReadByte();
1480 /* Avoid accidentally setting visual_effect to the default value
1481 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1482 if (rvi->visual_effect == VE_DEFAULT) {
1483 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1484 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1485 }
1486 break;
1487
1488 case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1489 ei->cargo_age_period = buf->ReadWord();
1490 break;
1491
1492 case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
1493 rvi->shorten_factor = buf->ReadByte();
1494 break;
1495
1496 case 0x24: // CTT refit include list
1497 case 0x25: { // CTT refit exclude list
1498 uint8 count = buf->ReadByte();
1499 _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
1500 if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
1501 uint32 &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1502 ctt = 0;
1503 while (count--) {
1504 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1505 if (ctype == CT_INVALID) continue;
1506 SetBit(ctt, ctype);
1507 }
1508 break;
1509 }
1510
1511 default:
1512 ret = CommonVehicleChangeInfo(ei, prop, buf);
1513 break;
1514 }
1515 }
1516
1517 return ret;
1518 }
1519
1528 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1529 {
1530 ChangeInfoResult ret = CIR_SUCCESS;
1531
1532 for (int i = 0; i < numinfo; i++) {
1533 Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1534 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1535
1536 EngineInfo *ei = &e->info;
1537 ShipVehicleInfo *svi = &e->u.ship;
1538
1539 switch (prop) {
1540 case 0x08: { // Sprite ID
1541 uint8 spriteid = buf->ReadByte();
1542 uint8 orig_spriteid = spriteid;
1543
1544 /* ships have different custom id in the GRF file */
1545 if (spriteid == 0xFF) spriteid = 0xFD;
1546
1547 if (spriteid < 0xFD) spriteid >>= 1;
1548
1549 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1550 svi->image_index = spriteid;
1551 } else {
1552 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1553 svi->image_index = 0;
1554 }
1555 break;
1556 }
1557
1558 case 0x09: // Refittable
1559 svi->old_refittable = (buf->ReadByte() != 0);
1560 break;
1561
1562 case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1563 svi->cost_factor = buf->ReadByte();
1564 break;
1565
1566 case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1567 svi->max_speed = buf->ReadByte();
1568 break;
1569
1570 case 0x0C: { // Cargo type
1571 _gted[e->index].defaultcargo_grf = _cur.grffile;
1572 uint8 ctype = buf->ReadByte();
1573
1574 if (ctype == 0xFF) {
1575 /* 0xFF is specified as 'use first refittable' */
1576 ei->cargo_type = CT_INVALID;
1577 } else if (_cur.grffile->grf_version >= 8) {
1578 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1579 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1580 } else if (ctype < NUM_CARGO) {
1581 /* Use untranslated cargo. */
1582 ei->cargo_type = ctype;
1583 } else {
1584 ei->cargo_type = CT_INVALID;
1585 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1586 }
1587 break;
1588 }
1589
1590 case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1591 svi->capacity = buf->ReadWord();
1592 break;
1593
1594 case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1595 svi->running_cost = buf->ReadByte();
1596 break;
1597
1598 case 0x10: // SFX
1599 svi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1600 break;
1601
1602 case 0x11: { // Cargoes available for refitting
1603 uint32 mask = buf->ReadDWord();
1604 _gted[e->index].UpdateRefittability(mask != 0);
1605 ei->refit_mask = TranslateRefitMask(mask);
1606 _gted[e->index].defaultcargo_grf = _cur.grffile;
1607 break;
1608 }
1609
1610 case 0x12: // Callback mask
1611 ei->callback_mask = buf->ReadByte();
1612 break;
1613
1614 case 0x13: // Refit cost
1615 ei->refit_cost = buf->ReadByte();
1616 break;
1617
1618 case 0x14: // Ocean speed fraction
1619 svi->ocean_speed_frac = buf->ReadByte();
1620 break;
1621
1622 case 0x15: // Canal speed fraction
1623 svi->canal_speed_frac = buf->ReadByte();
1624 break;
1625
1626 case 0x16: // Retire vehicle early
1627 ei->retire_early = buf->ReadByte();
1628 break;
1629
1630 case 0x17: // Miscellaneous flags
1631 ei->misc_flags = buf->ReadByte();
1632 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1633 break;
1634
1635 case 0x18: // Cargo classes allowed
1636 _gted[e->index].cargo_allowed = buf->ReadWord();
1637 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1638 _gted[e->index].defaultcargo_grf = _cur.grffile;
1639 break;
1640
1641 case 0x19: // Cargo classes disallowed
1642 _gted[e->index].cargo_disallowed = buf->ReadWord();
1643 _gted[e->index].UpdateRefittability(false);
1644 break;
1645
1646 case 0x1A: // Long format introduction date (days since year 0)
1647 ei->base_intro = buf->ReadDWord();
1648 break;
1649
1650 case 0x1B: // Alter purchase list sort order
1651 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1652 break;
1653
1654 case 0x1C: // Visual effect
1655 svi->visual_effect = buf->ReadByte();
1656 /* Avoid accidentally setting visual_effect to the default value
1657 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1658 if (svi->visual_effect == VE_DEFAULT) {
1659 assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1660 SB(svi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1661 }
1662 break;
1663
1664 case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1665 ei->cargo_age_period = buf->ReadWord();
1666 break;
1667
1668 case 0x1E: // CTT refit include list
1669 case 0x1F: { // CTT refit exclude list
1670 uint8 count = buf->ReadByte();
1671 _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
1672 if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
1673 uint32 &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1674 ctt = 0;
1675 while (count--) {
1676 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1677 if (ctype == CT_INVALID) continue;
1678 SetBit(ctt, ctype);
1679 }
1680 break;
1681 }
1682
1683 default:
1684 ret = CommonVehicleChangeInfo(ei, prop, buf);
1685 break;
1686 }
1687 }
1688
1689 return ret;
1690 }
1691
1700 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1701 {
1702 ChangeInfoResult ret = CIR_SUCCESS;
1703
1704 for (int i = 0; i < numinfo; i++) {
1705 Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1706 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1707
1708 EngineInfo *ei = &e->info;
1709 AircraftVehicleInfo *avi = &e->u.air;
1710
1711 switch (prop) {
1712 case 0x08: { // Sprite ID
1713 uint8 spriteid = buf->ReadByte();
1714 uint8 orig_spriteid = spriteid;
1715
1716 /* aircraft have different custom id in the GRF file */
1717 if (spriteid == 0xFF) spriteid = 0xFD;
1718
1719 if (spriteid < 0xFD) spriteid >>= 1;
1720
1721 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1722 avi->image_index = spriteid;
1723 } else {
1724 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1725 avi->image_index = 0;
1726 }
1727 break;
1728 }
1729
1730 case 0x09: // Helicopter
1731 if (buf->ReadByte() == 0) {
1732 avi->subtype = AIR_HELI;
1733 } else {
1734 SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1735 }
1736 break;
1737
1738 case 0x0A: // Large
1739 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1740 break;
1741
1742 case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1743 avi->cost_factor = buf->ReadByte();
1744 break;
1745
1746 case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1747 avi->max_speed = (buf->ReadByte() * 128) / 10;
1748 break;
1749
1750 case 0x0D: // Acceleration
1751 avi->acceleration = buf->ReadByte();
1752 break;
1753
1754 case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1755 avi->running_cost = buf->ReadByte();
1756 break;
1757
1758 case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1759 avi->passenger_capacity = buf->ReadWord();
1760 break;
1761
1762 case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1763 avi->mail_capacity = buf->ReadByte();
1764 break;
1765
1766 case 0x12: // SFX
1767 avi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1768 break;
1769
1770 case 0x13: { // Cargoes available for refitting
1771 uint32 mask = buf->ReadDWord();
1772 _gted[e->index].UpdateRefittability(mask != 0);
1773 ei->refit_mask = TranslateRefitMask(mask);
1774 _gted[e->index].defaultcargo_grf = _cur.grffile;
1775 break;
1776 }
1777
1778 case 0x14: // Callback mask
1779 ei->callback_mask = buf->ReadByte();
1780 break;
1781
1782 case 0x15: // Refit cost
1783 ei->refit_cost = buf->ReadByte();
1784 break;
1785
1786 case 0x16: // Retire vehicle early
1787 ei->retire_early = buf->ReadByte();
1788 break;
1789
1790 case 0x17: // Miscellaneous flags
1791 ei->misc_flags = buf->ReadByte();
1792 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1793 break;
1794
1795 case 0x18: // Cargo classes allowed
1796 _gted[e->index].cargo_allowed = buf->ReadWord();
1797 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1798 _gted[e->index].defaultcargo_grf = _cur.grffile;
1799 break;
1800
1801 case 0x19: // Cargo classes disallowed
1802 _gted[e->index].cargo_disallowed = buf->ReadWord();
1803 _gted[e->index].UpdateRefittability(false);
1804 break;
1805
1806 case 0x1A: // Long format introduction date (days since year 0)
1807 ei->base_intro = buf->ReadDWord();
1808 break;
1809
1810 case 0x1B: // Alter purchase list sort order
1811 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1812 break;
1813
1814 case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1815 ei->cargo_age_period = buf->ReadWord();
1816 break;
1817
1818 case 0x1D: // CTT refit include list
1819 case 0x1E: { // CTT refit exclude list
1820 uint8 count = buf->ReadByte();
1821 _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
1822 if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
1823 uint32 &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1824 ctt = 0;
1825 while (count--) {
1826 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1827 if (ctype == CT_INVALID) continue;
1828 SetBit(ctt, ctype);
1829 }
1830 break;
1831 }
1832
1833 case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
1834 avi->max_range = buf->ReadWord();
1835 break;
1836
1837 default:
1838 ret = CommonVehicleChangeInfo(ei, prop, buf);
1839 break;
1840 }
1841 }
1842
1843 return ret;
1844 }
1845
1854 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
1855 {
1856 ChangeInfoResult ret = CIR_SUCCESS;
1857
1858 if (stid + numinfo > NUM_STATIONS_PER_GRF) {
1859 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
1860 return CIR_INVALID_ID;
1861 }
1862
1863 /* Allocate station specs if necessary */
1864 if (_cur.grffile->stations == NULL) _cur.grffile->stations = CallocT<StationSpec*>(NUM_STATIONS_PER_GRF);
1865
1866 for (int i = 0; i < numinfo; i++) {
1867 StationSpec *statspec = _cur.grffile->stations[stid + i];
1868
1869 /* Check that the station we are modifying is defined. */
1870 if (statspec == NULL && prop != 0x08) {
1871 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1872 return CIR_INVALID_ID;
1873 }
1874
1875 switch (prop) {
1876 case 0x08: { // Class ID
1877 StationSpec **spec = &_cur.grffile->stations[stid + i];
1878
1879 /* Property 0x08 is special; it is where the station is allocated */
1880 if (*spec == NULL) *spec = CallocT<StationSpec>(1);
1881
1882 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1883 uint32 classid = buf->ReadDWord();
1884 (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
1885 break;
1886 }
1887
1888 case 0x09: // Define sprite layout
1889 statspec->tiles = buf->ReadExtendedByte();
1890 delete[] statspec->renderdata; // delete earlier loaded stuff
1891 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1892
1893 for (uint t = 0; t < statspec->tiles; t++) {
1894 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1895 dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
1896
1897 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1898 buf->Skip(4);
1899 extern const DrawTileSprites _station_display_datas_rail[8];
1900 dts->Clone(&_station_display_datas_rail[t % 8]);
1901 continue;
1902 }
1903
1904 ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
1905 /* On error, bail out immediately. Temporary GRF data was already freed */
1906 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1907
1908 static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
1909 tmp_layout.Clear();
1910 for (;;) {
1911 /* no relative bounding box support */
1912 DrawTileSeqStruct *dtss = tmp_layout.Append();
1913 MemSetT(dtss, 0);
1914
1915 dtss->delta_x = buf->ReadByte();
1916 if (dtss->IsTerminator()) break;
1917 dtss->delta_y = buf->ReadByte();
1918 dtss->delta_z = buf->ReadByte();
1919 dtss->size_x = buf->ReadByte();
1920 dtss->size_y = buf->ReadByte();
1921 dtss->size_z = buf->ReadByte();
1922
1923 ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss->image);
1924 /* On error, bail out immediately. Temporary GRF data was already freed */
1925 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1926 }
1927 dts->Clone(tmp_layout.Begin());
1928 }
1929 break;
1930
1931 case 0x0A: { // Copy sprite layout
1932 byte srcid = buf->ReadByte();
1933 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1934
1935 if (srcstatspec == NULL) {
1936 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1937 continue;
1938 }
1939
1940 delete[] statspec->renderdata; // delete earlier loaded stuff
1941
1942 statspec->tiles = srcstatspec->tiles;
1943 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1944 for (uint t = 0; t < statspec->tiles; t++) {
1945 statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
1946 }
1947 break;
1948 }
1949
1950 case 0x0B: // Callback mask
1951 statspec->callback_mask = buf->ReadByte();
1952 break;
1953
1954 case 0x0C: // Disallowed number of platforms
1955 statspec->disallowed_platforms = buf->ReadByte();
1956 break;
1957
1958 case 0x0D: // Disallowed platform lengths
1959 statspec->disallowed_lengths = buf->ReadByte();
1960 break;
1961
1962 case 0x0E: // Define custom layout
1963 statspec->copied_layouts = false;
1964
1965 while (buf->HasData()) {
1966 byte length = buf->ReadByte();
1967 byte number = buf->ReadByte();
1968 StationLayout layout;
1969 uint l, p;
1970
1971 if (length == 0 || number == 0) break;
1972
1973 if (length > statspec->lengths) {
1974 statspec->platforms = ReallocT(statspec->platforms, length);
1975 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
1976
1977 statspec->layouts = ReallocT(statspec->layouts, length);
1978 memset(statspec->layouts + statspec->lengths, 0,
1979 (length - statspec->lengths) * sizeof(*statspec->layouts));
1980
1981 statspec->lengths = length;
1982 }
1983 l = length - 1; // index is zero-based
1984
1985 if (number > statspec->platforms[l]) {
1986 statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
1987 /* We expect NULL being 0 here, but C99 guarantees that. */
1988 memset(statspec->layouts[l] + statspec->platforms[l], 0,
1989 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
1990
1991 statspec->platforms[l] = number;
1992 }
1993
1994 p = 0;
1995 layout = MallocT<byte>(length * number);
1996 try {
1997 for (l = 0; l < length; l++) {
1998 for (p = 0; p < number; p++) {
1999 layout[l * number + p] = buf->ReadByte();
2000 }
2001 }
2002 } catch (...) {
2003 free(layout);
2004 throw;
2005 }
2006
2007 l--;
2008 p--;
2009 free(statspec->layouts[l][p]);
2010 statspec->layouts[l][p] = layout;
2011 }
2012 break;
2013
2014 case 0x0F: { // Copy custom layout
2015 byte srcid = buf->ReadByte();
2016 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
2017
2018 if (srcstatspec == NULL) {
2019 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2020 continue;
2021 }
2022
2023 statspec->lengths = srcstatspec->lengths;
2024 statspec->platforms = srcstatspec->platforms;
2025 statspec->layouts = srcstatspec->layouts;
2026 statspec->copied_layouts = true;
2027 break;
2028 }
2029
2030 case 0x10: // Little/lots cargo threshold
2031 statspec->cargo_threshold = buf->ReadWord();
2032 break;
2033
2034 case 0x11: // Pylon placement
2035 statspec->pylons = buf->ReadByte();
2036 break;
2037
2038 case 0x12: // Cargo types for random triggers
2039 statspec->cargo_triggers = buf->ReadDWord();
2040 if (_cur.grffile->grf_version >= 7) {
2041 statspec->cargo_triggers = TranslateRefitMask(statspec->cargo_triggers);
2042 }
2043 break;
2044
2045 case 0x13: // General flags
2046 statspec->flags = buf->ReadByte();
2047 break;
2048
2049 case 0x14: // Overhead wire placement
2050 statspec->wires = buf->ReadByte();
2051 break;
2052
2053 case 0x15: // Blocked tiles
2054 statspec->blocked = buf->ReadByte();
2055 break;
2056
2057 case 0x16: // Animation info
2058 statspec->animation.frames = buf->ReadByte();
2059 statspec->animation.status = buf->ReadByte();
2060 break;
2061
2062 case 0x17: // Animation speed
2063 statspec->animation.speed = buf->ReadByte();
2064 break;
2065
2066 case 0x18: // Animation triggers
2067 statspec->animation.triggers = buf->ReadWord();
2068 break;
2069
2070 case 0x1A: // Advanced sprite layout
2071 statspec->tiles = buf->ReadExtendedByte();
2072 delete[] statspec->renderdata; // delete earlier loaded stuff
2073 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
2074
2075 for (uint t = 0; t < statspec->tiles; t++) {
2076 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
2077 uint num_building_sprites = buf->ReadByte();
2078 /* On error, bail out immediately. Temporary GRF data was already freed */
2079 if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED;
2080 }
2081 break;
2082
2083 default:
2084 ret = CIR_UNKNOWN;
2085 break;
2086 }
2087 }
2088
2089 return ret;
2090 }
2091
2100 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
2101 {
2102 ChangeInfoResult ret = CIR_SUCCESS;
2103
2104 if (id + numinfo > CF_END) {
2105 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id + numinfo, CF_END);
2106 return CIR_INVALID_ID;
2107 }
2108
2109 for (int i = 0; i < numinfo; i++) {
2110 CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
2111
2112 switch (prop) {
2113 case 0x08:
2114 cp->callback_mask = buf->ReadByte();
2115 break;
2116
2117 case 0x09:
2118 cp->flags = buf->ReadByte();
2119 break;
2120
2121 default:
2122 ret = CIR_UNKNOWN;
2123 break;
2124 }
2125 }
2126
2127 return ret;
2128 }
2129
2138 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
2139 {
2140 ChangeInfoResult ret = CIR_SUCCESS;
2141
2142 if (brid + numinfo > MAX_BRIDGES) {
2143 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
2144 return CIR_INVALID_ID;
2145 }
2146
2147 for (int i = 0; i < numinfo; i++) {
2148 BridgeSpec *bridge = &_bridge[brid + i];
2149
2150 switch (prop) {
2151 case 0x08: { // Year of availability
2152 /* We treat '0' as always available */
2153 byte year = buf->ReadByte();
2154 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
2155 break;
2156 }
2157
2158 case 0x09: // Minimum length
2159 bridge->min_length = buf->ReadByte();
2160 break;
2161
2162 case 0x0A: // Maximum length
2163 bridge->max_length = buf->ReadByte();
2164 if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
2165 break;
2166
2167 case 0x0B: // Cost factor
2168 bridge->price = buf->ReadByte();
2169 break;
2170
2171 case 0x0C: // Maximum speed
2172 bridge->speed = buf->ReadWord();
2173 break;
2174
2175 case 0x0D: { // Bridge sprite tables
2176 byte tableid = buf->ReadByte();
2177 byte numtables = buf->ReadByte();
2178
2179 if (bridge->sprite_table == NULL) {
2180 /* Allocate memory for sprite table pointers and zero out */
2181 bridge->sprite_table = CallocT<PalSpriteID*>(7);
2182 }
2183
2184 for (; numtables-- != 0; tableid++) {
2185 if (tableid >= 7) { // skip invalid data
2186 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2187 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2188 continue;
2189 }
2190
2191 if (bridge->sprite_table[tableid] == NULL) {
2192 bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
2193 }
2194
2195 for (byte sprite = 0; sprite < 32; sprite++) {
2196 SpriteID image = buf->ReadWord();
2197 PaletteID pal = buf->ReadWord();
2198
2199 bridge->sprite_table[tableid][sprite].sprite = image;
2200 bridge->sprite_table[tableid][sprite].pal = pal;
2201
2202 MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
2203 }
2204 }
2205 break;
2206 }
2207
2208 case 0x0E: // Flags; bit 0 - disable far pillars
2209 bridge->flags = buf->ReadByte();
2210 break;
2211
2212 case 0x0F: // Long format year of availability (year since year 0)
2213 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
2214 break;
2215
2216 case 0x10: { // purchase string
2217 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2218 if (newone != STR_UNDEFINED) bridge->material = newone;
2219 break;
2220 }
2221
2222 case 0x11: // description of bridge with rails or roads
2223 case 0x12: {
2224 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2225 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
2226 break;
2227 }
2228
2229 case 0x13: // 16 bits cost multiplier
2230 bridge->price = buf->ReadWord();
2231 break;
2232
2233 default:
2234 ret = CIR_UNKNOWN;
2235 break;
2236 }
2237 }
2238
2239 return ret;
2240 }
2241
2248 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
2249 {
2250 ChangeInfoResult ret = CIR_SUCCESS;
2251
2252 switch (prop) {
2253 case 0x09:
2254 case 0x0B:
2255 case 0x0C:
2256 case 0x0D:
2257 case 0x0E:
2258 case 0x0F:
2259 case 0x11:
2260 case 0x14:
2261 case 0x15:
2262 case 0x16:
2263 case 0x18:
2264 case 0x19:
2265 case 0x1A:
2266 case 0x1B:
2267 case 0x1C:
2268 case 0x1D:
2269 case 0x1F:
2270 buf->ReadByte();
2271 break;
2272
2273 case 0x0A:
2274 case 0x10:
2275 case 0x12:
2276 case 0x13:
2277 case 0x21:
2278 case 0x22:
2279 buf->ReadWord();
2280 break;
2281
2282 case 0x1E:
2283 buf->ReadDWord();
2284 break;
2285
2286 case 0x17:
2287 for (uint j = 0; j < 4; j++) buf->ReadByte();
2288 break;
2289
2290 case 0x20: {
2291 byte count = buf->ReadByte();
2292 for (byte j = 0; j < count; j++) buf->ReadByte();
2293 break;
2294 }
2295
2296 default:
2297 ret = CIR_UNKNOWN;
2298 break;
2299 }
2300 return ret;
2301 }
2302
2311 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2312 {
2313 ChangeInfoResult ret = CIR_SUCCESS;
2314
2315 if (hid + numinfo > NUM_HOUSES_PER_GRF) {
2316 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
2317 return CIR_INVALID_ID;
2318 }
2319
2320 /* Allocate house specs if they haven't been allocated already. */
2321 if (_cur.grffile->housespec == NULL) {
2322 _cur.grffile->housespec = CallocT<HouseSpec*>(NUM_HOUSES_PER_GRF);
2323 }
2324
2325 for (int i = 0; i < numinfo; i++) {
2326 HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2327
2328 if (prop != 0x08 && housespec == NULL) {
2329 /* If the house property 08 is not yet set, ignore this property */
2330 ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2331 if (cir > ret) ret = cir;
2332 continue;
2333 }
2334
2335 switch (prop) {
2336 case 0x08: { // Substitute building type, and definition of a new house
2337 HouseSpec **house = &_cur.grffile->housespec[hid + i];
2338 byte subs_id = buf->ReadByte();
2339
2340 if (subs_id == 0xFF) {
2341 /* Instead of defining a new house, a substitute house id
2342 * of 0xFF disables the old house with the current id. */
2343 HouseSpec::Get(hid + i)->enabled = false;
2344 continue;
2345 } else if (subs_id >= NEW_HOUSE_OFFSET) {
2346 /* The substitute id must be one of the original houses. */
2347 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2348 continue;
2349 }
2350
2351 /* Allocate space for this house. */
2352 if (*house == NULL) *house = CallocT<HouseSpec>(1);
2353
2354 housespec = *house;
2355
2356 MemCpyT(housespec, HouseSpec::Get(subs_id));
2357
2358 housespec->enabled = true;
2359 housespec->grf_prop.local_id = hid + i;
2360 housespec->grf_prop.subst_id = subs_id;
2361 housespec->grf_prop.grffile = _cur.grffile;
2362 housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2363 housespec->random_colour[1] = 0x08; // for all new houses
2364 housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2365 housespec->random_colour[3] = 0x06;
2366
2367 /* Make sure that the third cargo type is valid in this
2368 * climate. This can cause problems when copying the properties
2369 * of a house that accepts food, where the new house is valid
2370 * in the temperate climate. */
2371 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2372 housespec->cargo_acceptance[2] = 0;
2373 }
2374
2375 _loaded_newgrf_features.has_newhouses = true;
2376 break;
2377 }
2378
2379 case 0x09: // Building flags
2380 housespec->building_flags = (BuildingFlags)buf->ReadByte();
2381 break;
2382
2383 case 0x0A: { // Availability years
2384 uint16 years = buf->ReadWord();
2385 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2386 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2387 break;
2388 }
2389
2390 case 0x0B: // Population
2391 housespec->population = buf->ReadByte();
2392 break;
2393
2394 case 0x0C: // Mail generation multiplier
2395 housespec->mail_generation = buf->ReadByte();
2396 break;
2397
2398 case 0x0D: // Passenger acceptance
2399 case 0x0E: // Mail acceptance
2400 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2401 break;
2402
2403 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2404 int8 goods = buf->ReadByte();
2405
2406 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2407 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2408 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2409 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2410
2411 /* Make sure the cargo type is valid in this climate. */
2412 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2413
2414 housespec->accepts_cargo[2] = cid;
2415 housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2416 break;
2417 }
2418
2419 case 0x10: // Local authority rating decrease on removal
2420 housespec->remove_rating_decrease = buf->ReadWord();
2421 break;
2422
2423 case 0x11: // Removal cost multiplier
2424 housespec->removal_cost = buf->ReadByte();
2425 break;
2426
2427 case 0x12: // Building name ID
2428 AddStringForMapping(buf->ReadWord(), &housespec->building_name);
2429 break;
2430
2431 case 0x13: // Building availability mask
2432 housespec->building_availability = (HouseZones)buf->ReadWord();
2433 break;
2434
2435 case 0x14: // House callback mask
2436 housespec->callback_mask |= buf->ReadByte();
2437 break;
2438
2439 case 0x15: { // House override byte
2440 byte override = buf->ReadByte();
2441
2442 /* The house being overridden must be an original house. */
2443 if (override >= NEW_HOUSE_OFFSET) {
2444 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2445 continue;
2446 }
2447
2448 _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2449 break;
2450 }
2451
2452 case 0x16: // Periodic refresh multiplier
2453 housespec->processing_time = min(buf->ReadByte(), 63);
2454 break;
2455
2456 case 0x17: // Four random colours to use
2457 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2458 break;
2459
2460 case 0x18: // Relative probability of appearing
2461 housespec->probability = buf->ReadByte();
2462 break;
2463
2464 case 0x19: // Extra flags
2465 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2466 break;
2467
2468 case 0x1A: // Animation frames
2469 housespec->animation.frames = buf->ReadByte();
2470 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2471 SB(housespec->animation.frames, 7, 1, 0);
2472 break;
2473
2474 case 0x1B: // Animation speed
2475 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2476 break;
2477
2478 case 0x1C: // Class of the building type
2479 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2480 break;
2481
2482 case 0x1D: // Callback mask part 2
2483 housespec->callback_mask |= (buf->ReadByte() << 8);
2484 break;
2485
2486 case 0x1E: { // Accepted cargo types
2487 uint32 cargotypes = buf->ReadDWord();
2488
2489 /* Check if the cargo types should not be changed */
2490 if (cargotypes == 0xFFFFFFFF) break;
2491
2492 for (uint j = 0; j < 3; j++) {
2493 /* Get the cargo number from the 'list' */
2494 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2495 CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2496
2497 if (cargo == CT_INVALID) {
2498 /* Disable acceptance of invalid cargo type */
2499 housespec->cargo_acceptance[j] = 0;
2500 } else {
2501 housespec->accepts_cargo[j] = cargo;
2502 }
2503 }
2504 break;
2505 }
2506
2507 case 0x1F: // Minimum life span
2508 housespec->minimum_life = buf->ReadByte();
2509 break;
2510
2511 case 0x20: { // Cargo acceptance watch list
2512 byte count = buf->ReadByte();
2513 for (byte j = 0; j < count; j++) {
2514 CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2515 if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
2516 }
2517 break;
2518 }
2519
2520 case 0x21: // long introduction year
2521 housespec->min_year = buf->ReadWord();
2522 break;
2523
2524 case 0x22: // long maximum year
2525 housespec->max_year = buf->ReadWord();
2526 break;
2527
2528 default:
2529 ret = CIR_UNKNOWN;
2530 break;
2531 }
2532 }
2533
2534 return ret;
2535 }
2536
2543 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2544 {
2545 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2546 const GRFFile *grffile = GetFileByGRFID(grfid);
2547 return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
2548 }
2549
2559 template <typename T>
2560 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
2561 {
2562 if (gvid != 0) {
2563 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
2564 return CIR_INVALID_ID;
2565 }
2566
2567 translation_table.Clear();
2568 for (int i = 0; i < numinfo; i++) {
2569 uint32 item = buf->ReadDWord();
2570 *translation_table.Append() = BSWAP32(item);
2571 }
2572
2573 return CIR_SUCCESS;
2574 }
2575
2584 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2585 {
2586 /* Properties which are handled as a whole */
2587 switch (prop) {
2588 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2589 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2590
2591 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2592 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2593
2594 default:
2595 break;
2596 }
2597
2598 /* Properties which are handled per item */
2599 ChangeInfoResult ret = CIR_SUCCESS;
2600 for (int i = 0; i < numinfo; i++) {
2601 switch (prop) {
2602 case 0x08: { // Cost base factor
2603 int factor = buf->ReadByte();
2604 uint price = gvid + i;
2605
2606 if (price < PR_END) {
2607 _cur.grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
2608 } else {
2609 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2610 }
2611 break;
2612 }
2613
2614 case 0x0A: { // Currency display names
2615 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2616 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2617
2618 if ((newone != STR_UNDEFINED) && (curidx < CURRENCY_END)) {
2619 _currency_specs[curidx].name = newone;
2620 }
2621 break;
2622 }
2623
2624 case 0x0B: { // Currency multipliers
2625 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2626 uint32 rate = buf->ReadDWord();
2627
2628 if (curidx < CURRENCY_END) {
2629 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2630 * which OTTD does not. For this reason, divide grf value by 1000,
2631 * to be compatible */
2632 _currency_specs[curidx].rate = rate / 1000;
2633 } else {
2634 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2635 }
2636 break;
2637 }
2638
2639 case 0x0C: { // Currency options
2640 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2641 uint16 options = buf->ReadWord();
2642
2643 if (curidx < CURRENCY_END) {
2644 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
2645 _currency_specs[curidx].separator[1] = '\0';
2646 /* By specifying only one bit, we prevent errors,
2647 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2648 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
2649 } else {
2650 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2651 }
2652 break;
2653 }
2654
2655 case 0x0D: { // Currency prefix symbol
2656 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2657 uint32 tempfix = buf->ReadDWord();
2658
2659 if (curidx < CURRENCY_END) {
2660 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
2661 _currency_specs[curidx].prefix[4] = 0;
2662 } else {
2663 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2664 }
2665 break;
2666 }
2667
2668 case 0x0E: { // Currency suffix symbol
2669 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2670 uint32 tempfix = buf->ReadDWord();
2671
2672 if (curidx < CURRENCY_END) {
2673 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
2674 _currency_specs[curidx].suffix[4] = 0;
2675 } else {
2676 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2677 }
2678 break;
2679 }
2680
2681 case 0x0F: { // Euro introduction dates
2682 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2683 Year year_euro = buf->ReadWord();
2684
2685 if (curidx < CURRENCY_END) {
2686 _currency_specs[curidx].to_euro = year_euro;
2687 } else {
2688 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2689 }
2690 break;
2691 }
2692
2693 case 0x10: // Snow line height table
2694 if (numinfo > 1 || IsSnowLineSet()) {
2695 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2696 } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
2697 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2698 } else {
2699 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2700
2701 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2702 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2703 table[i][j] = buf->ReadByte();
2704 if (_cur.grffile->grf_version >= 8) {
2705 if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 256;
2706 } else {
2707 if (table[i][j] >= 128) {
2708 /* no snow */
2709 table[i][j] = 0xFF;
2710 } else {
2711 table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 128;
2712 }
2713 }
2714 }
2715 }
2716 SetSnowLine(table);
2717 }
2718 break;
2719
2720 case 0x11: // GRF match for engine allocation
2721 /* This is loaded during the reservation stage, so just skip it here. */
2722 /* Each entry is 8 bytes. */
2723 buf->Skip(8);
2724 break;
2725
2726 case 0x13: // Gender translation table
2727 case 0x14: // Case translation table
2728 case 0x15: { // Plural form translation
2729 uint curidx = gvid + i; // The current index, i.e. language.
2730 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL;
2731 if (lang == NULL) {
2732 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2733 /* Skip over the data. */
2734 if (prop == 0x15) {
2735 buf->ReadByte();
2736 } else {
2737 while (buf->ReadByte() != 0) {
2738 buf->ReadString();
2739 }
2740 }
2741 break;
2742 }
2743
2744 if (_cur.grffile->language_map == NULL) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2745
2746 if (prop == 0x15) {
2747 uint plural_form = buf->ReadByte();
2748 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2749 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2750 } else {
2751 _cur.grffile->language_map[curidx].plural_form = plural_form;
2752 }
2753 break;
2754 }
2755
2756 byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2757 while (newgrf_id != 0) {
2758 const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2759
2760 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2761 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2762 * is just a subset of UTF8, or they need the bigger UTF8 characters
2763 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2764 WChar c;
2765 size_t len = Utf8Decode(&c, name);
2766 if (c == NFO_UTF8_IDENTIFIER) name += len;
2767
2768 LanguageMap::Mapping map;
2769 map.newgrf_id = newgrf_id;
2770 if (prop == 0x13) {
2771 map.openttd_id = lang->GetGenderIndex(name);
2772 if (map.openttd_id >= MAX_NUM_GENDERS) {
2773 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2774 } else {
2775 *_cur.grffile->language_map[curidx].gender_map.Append() = map;
2776 }
2777 } else {
2778 map.openttd_id = lang->GetCaseIndex(name);
2779 if (map.openttd_id >= MAX_NUM_CASES) {
2780 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2781 } else {
2782 *_cur.grffile->language_map[curidx].case_map.Append() = map;
2783 }
2784 }
2785 newgrf_id = buf->ReadByte();
2786 }
2787 break;
2788 }
2789
2790 default:
2791 ret = CIR_UNKNOWN;
2792 break;
2793 }
2794 }
2795
2796 return ret;
2797 }
2798
2799 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2800 {
2801 /* Properties which are handled as a whole */
2802 switch (prop) {
2803 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2804 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2805
2806 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2807 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2808
2809 default:
2810 break;
2811 }
2812
2813 /* Properties which are handled per item */
2814 ChangeInfoResult ret = CIR_SUCCESS;
2815 for (int i = 0; i < numinfo; i++) {
2816 switch (prop) {
2817 case 0x08: // Cost base factor
2818 case 0x15: // Plural form translation
2819 buf->ReadByte();
2820 break;
2821
2822 case 0x0A: // Currency display names
2823 case 0x0C: // Currency options
2824 case 0x0F: // Euro introduction dates
2825 buf->ReadWord();
2826 break;
2827
2828 case 0x0B: // Currency multipliers
2829 case 0x0D: // Currency prefix symbol
2830 case 0x0E: // Currency suffix symbol
2831 buf->ReadDWord();
2832 break;
2833
2834 case 0x10: // Snow line height table
2835 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
2836 break;
2837
2838 case 0x11: { // GRF match for engine allocation
2839 uint32 s = buf->ReadDWord();
2840 uint32 t = buf->ReadDWord();
2841 SetNewGRFOverride(s, t);
2842 break;
2843 }
2844
2845 case 0x13: // Gender translation table
2846 case 0x14: // Case translation table
2847 while (buf->ReadByte() != 0) {
2848 buf->ReadString();
2849 }
2850 break;
2851
2852 default:
2853 ret = CIR_UNKNOWN;
2854 break;
2855 }
2856 }
2857
2858 return ret;
2859 }
2860
2861
2870 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
2871 {
2872 ChangeInfoResult ret = CIR_SUCCESS;
2873
2874 if (cid + numinfo > NUM_CARGO) {
2875 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
2876 return CIR_INVALID_ID;
2877 }
2878
2879 for (int i = 0; i < numinfo; i++) {
2880 CargoSpec *cs = CargoSpec::Get(cid + i);
2881
2882 switch (prop) {
2883 case 0x08: // Bit number of cargo
2884 cs->bitnum = buf->ReadByte();
2885 if (cs->IsValid()) {
2886 cs->grffile = _cur.grffile;
2887 SetBit(_cargo_mask, cid + i);
2888 } else {
2889 ClrBit(_cargo_mask, cid + i);
2890 }
2891 break;
2892
2893 case 0x09: // String ID for cargo type name
2894 AddStringForMapping(buf->ReadWord(), &cs->name);
2895 break;
2896
2897 case 0x0A: // String for 1 unit of cargo
2898 AddStringForMapping(buf->ReadWord(), &cs->name_single);
2899 break;
2900
2901 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2902 case 0x1B: // String for cargo units
2903 /* String for units of cargo. This is different in OpenTTD
2904 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2905 * Property 1B is used to set OpenTTD's behaviour. */
2906 AddStringForMapping(buf->ReadWord(), &cs->units_volume);
2907 break;
2908
2909 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2910 case 0x1C: // String for any amount of cargo
2911 /* Strings for an amount of cargo. This is different in OpenTTD
2912 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2913 * Property 1C is used to set OpenTTD's behaviour. */
2914 AddStringForMapping(buf->ReadWord(), &cs->quantifier);
2915 break;
2916
2917 case 0x0D: // String for two letter cargo abbreviation
2918 AddStringForMapping(buf->ReadWord(), &cs->abbrev);
2919 break;
2920
2921 case 0x0E: // Sprite ID for cargo icon
2922 cs->sprite = buf->ReadWord();
2923 break;
2924
2925 case 0x0F: // Weight of one unit of cargo
2926 cs->weight = buf->ReadByte();
2927 break;
2928
2929 case 0x10: // Used for payment calculation
2930 cs->transit_days[0] = buf->ReadByte();
2931 break;
2932
2933 case 0x11: // Used for payment calculation
2934 cs->transit_days[1] = buf->ReadByte();
2935 break;
2936
2937 case 0x12: // Base cargo price
2938 cs->initial_payment = buf->ReadDWord();
2939 break;
2940
2941 case 0x13: // Colour for station rating bars
2942 cs->rating_colour = buf->ReadByte();
2943 break;
2944
2945 case 0x14: // Colour for cargo graph
2946 cs->legend_colour = buf->ReadByte();
2947 break;
2948
2949 case 0x15: // Freight status
2950 cs->is_freight = (buf->ReadByte() != 0);
2951 break;
2952
2953 case 0x16: // Cargo classes
2954 cs->classes = buf->ReadWord();
2955 break;
2956
2957 case 0x17: // Cargo label
2958 cs->label = buf->ReadDWord();
2959 cs->label = BSWAP32(cs->label);
2960 break;
2961
2962 case 0x18: { // Town growth substitute type
2963 uint8 substitute_type = buf->ReadByte();
2964
2965 switch (substitute_type) {
2966 case 0x00: cs->town_effect = TE_PASSENGERS; break;
2967 case 0x02: cs->town_effect = TE_MAIL; break;
2968 case 0x05: cs->town_effect = TE_GOODS; break;
2969 case 0x09: cs->town_effect = TE_WATER; break;
2970 case 0x0B: cs->town_effect = TE_FOOD; break;
2971 default:
2972 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
2973 FALLTHROUGH;
2974 case 0xFF: cs->town_effect = TE_NONE; break;
2975 }
2976 break;
2977 }
2978
2979 case 0x19: // Town growth coefficient
2980 cs->multipliertowngrowth = buf->ReadWord();
2981 break;
2982
2983 case 0x1A: // Bitmask of callbacks to use
2984 cs->callback_mask = buf->ReadByte();
2985 break;
2986
2987 case 0x1D: // Vehicle capacity muliplier
2988 cs->multiplier = max<uint16>(1u, buf->ReadWord());
2989 break;
2990
2991 default:
2992 ret = CIR_UNKNOWN;
2993 break;
2994 }
2995 }
2996
2997 return ret;
2998 }
2999
3000
3009 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
3010 {
3011 ChangeInfoResult ret = CIR_SUCCESS;
3012
3013 if (_cur.grffile->sound_offset == 0) {
3014 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3015 return CIR_INVALID_ID;
3016 }
3017
3018 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
3019 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
3020 return CIR_INVALID_ID;
3021 }
3022
3023 for (int i = 0; i < numinfo; i++) {
3024 SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
3025
3026 switch (prop) {
3027 case 0x08: // Relative volume
3028 sound->volume = buf->ReadByte();
3029 break;
3030
3031 case 0x09: // Priority
3032 sound->priority = buf->ReadByte();
3033 break;
3034
3035 case 0x0A: { // Override old sound
3036 SoundID orig_sound = buf->ReadByte();
3037
3038 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
3039 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
3040 } else {
3041 SoundEntry *old_sound = GetSound(orig_sound);
3042
3043 /* Literally copy the data of the new sound over the original */
3044 *old_sound = *sound;
3045 }
3046 break;
3047 }
3048
3049 default:
3050 ret = CIR_UNKNOWN;
3051 break;
3052 }
3053 }
3054
3055 return ret;
3056 }
3057
3064 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
3065 {
3066 ChangeInfoResult ret = CIR_SUCCESS;
3067
3068 switch (prop) {
3069 case 0x09:
3070 case 0x0D:
3071 case 0x0E:
3072 case 0x10:
3073 case 0x11:
3074 case 0x12:
3075 buf->ReadByte();
3076 break;
3077
3078 case 0x0A:
3079 case 0x0B:
3080 case 0x0C:
3081 case 0x0F:
3082 buf->ReadWord();
3083 break;
3084
3085 default:
3086 ret = CIR_UNKNOWN;
3087 break;
3088 }
3089 return ret;
3090 }
3091
3100 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
3101 {
3102 ChangeInfoResult ret = CIR_SUCCESS;
3103
3104 if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
3105 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
3106 return CIR_INVALID_ID;
3107 }
3108
3109 /* Allocate industry tile specs if they haven't been allocated already. */
3110 if (_cur.grffile->indtspec == NULL) {
3111 _cur.grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES_PER_GRF);
3112 }
3113
3114 for (int i = 0; i < numinfo; i++) {
3115 IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
3116
3117 if (prop != 0x08 && tsp == NULL) {
3118 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
3119 if (cir > ret) ret = cir;
3120 continue;
3121 }
3122
3123 switch (prop) {
3124 case 0x08: { // Substitute industry tile type
3125 IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i];
3126 byte subs_id = buf->ReadByte();
3127
3128 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
3129 /* The substitute id must be one of the original industry tile. */
3130 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3131 continue;
3132 }
3133
3134 /* Allocate space for this industry. */
3135 if (*tilespec == NULL) {
3136 *tilespec = CallocT<IndustryTileSpec>(1);
3137 tsp = *tilespec;
3138
3139 memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
3140 tsp->enabled = true;
3141
3142 /* A copied tile should not have the animation infos copied too.
3143 * The anim_state should be left untouched, though
3144 * It is up to the author to animate them himself */
3145 tsp->anim_production = INDUSTRYTILE_NOANIM;
3146 tsp->anim_next = INDUSTRYTILE_NOANIM;
3147
3148 tsp->grf_prop.local_id = indtid + i;
3149 tsp->grf_prop.subst_id = subs_id;
3150 tsp->grf_prop.grffile = _cur.grffile;
3151 _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3152 }
3153 break;
3154 }
3155
3156 case 0x09: { // Industry tile override
3157 byte ovrid = buf->ReadByte();
3158
3159 /* The industry being overridden must be an original industry. */
3160 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
3161 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3162 continue;
3163 }
3164
3165 _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
3166 break;
3167 }
3168
3169 case 0x0A: // Tile acceptance
3170 case 0x0B:
3171 case 0x0C: {
3172 uint16 acctp = buf->ReadWord();
3173 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
3174 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
3175 break;
3176 }
3177
3178 case 0x0D: // Land shape flags
3179 tsp->slopes_refused = (Slope)buf->ReadByte();
3180 break;
3181
3182 case 0x0E: // Callback mask
3183 tsp->callback_mask = buf->ReadByte();
3184 break;
3185
3186 case 0x0F: // Animation information
3187 tsp->animation.frames = buf->ReadByte();
3188 tsp->animation.status = buf->ReadByte();
3189 break;
3190
3191 case 0x10: // Animation speed
3192 tsp->animation.speed = buf->ReadByte();
3193 break;
3194
3195 case 0x11: // Triggers for callback 25
3196 tsp->animation.triggers = buf->ReadByte();
3197 break;
3198
3199 case 0x12: // Special flags
3200 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
3201 break;
3202
3203 default:
3204 ret = CIR_UNKNOWN;
3205 break;
3206 }
3207 }
3208
3209 return ret;
3210 }
3211
3218 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
3219 {
3220 ChangeInfoResult ret = CIR_SUCCESS;
3221
3222 switch (prop) {
3223 case 0x09:
3224 case 0x0B:
3225 case 0x0F:
3226 case 0x12:
3227 case 0x13:
3228 case 0x14:
3229 case 0x17:
3230 case 0x18:
3231 case 0x19:
3232 case 0x21:
3233 case 0x22:
3234 buf->ReadByte();
3235 break;
3236
3237 case 0x0C:
3238 case 0x0D:
3239 case 0x0E:
3240 case 0x10:
3241 case 0x1B:
3242 case 0x1F:
3243 case 0x24:
3244 buf->ReadWord();
3245 break;
3246
3247 case 0x11:
3248 case 0x1A:
3249 case 0x1C:
3250 case 0x1D:
3251 case 0x1E:
3252 case 0x20:
3253 case 0x23:
3254 buf->ReadDWord();
3255 break;
3256
3257 case 0x0A: {
3258 byte num_table = buf->ReadByte();
3259 for (byte j = 0; j < num_table; j++) {
3260 for (uint k = 0;; k++) {
3261 byte x = buf->ReadByte();
3262 if (x == 0xFE && k == 0) {
3263 buf->ReadByte();
3264 buf->ReadByte();
3265 break;
3266 }
3267
3268 byte y = buf->ReadByte();
3269 if (x == 0 && y == 0x80) break;
3270
3271 byte gfx = buf->ReadByte();
3272 if (gfx == 0xFE) buf->ReadWord();
3273 }
3274 }
3275 break;
3276 }
3277
3278 case 0x16:
3279 for (byte j = 0; j < 3; j++) buf->ReadByte();
3280 break;
3281
3282 case 0x15: {
3283 byte number_of_sounds = buf->ReadByte();
3284 for (uint8 j = 0; j < number_of_sounds; j++) {
3285 buf->ReadByte();
3286 }
3287 break;
3288 }
3289
3290 default:
3291 ret = CIR_UNKNOWN;
3292 break;
3293 }
3294 return ret;
3295 }
3296
3303 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
3304 {
3305 for (int i = 0; i < size - 1; i++) {
3306 for (int j = i + 1; j < size; j++) {
3307 if (layout[i].ti.x == layout[j].ti.x &&
3308 layout[i].ti.y == layout[j].ti.y) {
3309 return false;
3310 }
3311 }
3312 }
3313 return true;
3314 }
3315
3317 static void CleanIndustryTileTable(IndustrySpec *ind)
3318 {
3319 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
3320 for (int j = 0; j < ind->num_table; j++) {
3321 /* remove the individual layouts */
3322 free(ind->table[j]);
3323 }
3324 /* remove the layouts pointers */
3325 free(ind->table);
3326 ind->table = NULL;
3327 }
3328 }
3329
3338 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3339 {
3340 ChangeInfoResult ret = CIR_SUCCESS;
3341
3342 if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
3343 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
3344 return CIR_INVALID_ID;
3345 }
3346
3347 /* Allocate industry specs if they haven't been allocated already. */
3348 if (_cur.grffile->industryspec == NULL) {
3349 _cur.grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES_PER_GRF);
3350 }
3351
3352 for (int i = 0; i < numinfo; i++) {
3353 IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3354
3355 if (prop != 0x08 && indsp == NULL) {
3356 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3357 if (cir > ret) ret = cir;
3358 continue;
3359 }
3360
3361 switch (prop) {
3362 case 0x08: { // Substitute industry type
3363 IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i];
3364 byte subs_id = buf->ReadByte();
3365
3366 if (subs_id == 0xFF) {
3367 /* Instead of defining a new industry, a substitute industry id
3368 * of 0xFF disables the old industry with the current id. */
3369 _industry_specs[indid + i].enabled = false;
3370 continue;
3371 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3372 /* The substitute id must be one of the original industry. */
3373 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3374 continue;
3375 }
3376
3377 /* Allocate space for this industry.
3378 * Only need to do it once. If ever it is called again, it should not
3379 * do anything */
3380 if (*indspec == NULL) {
3381 *indspec = CallocT<IndustrySpec>(1);
3382 indsp = *indspec;
3383
3384 memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
3385 indsp->enabled = true;
3386 indsp->grf_prop.local_id = indid + i;
3387 indsp->grf_prop.subst_id = subs_id;
3388 indsp->grf_prop.grffile = _cur.grffile;
3389 /* If the grf industry needs to check its surounding upon creation, it should
3390 * rely on callbacks, not on the original placement functions */
3391 indsp->check_proc = CHECK_NOTHING;
3392 }
3393 break;
3394 }
3395
3396 case 0x09: { // Industry type override
3397 byte ovrid = buf->ReadByte();
3398
3399 /* The industry being overridden must be an original industry. */
3400 if (ovrid >= NEW_INDUSTRYOFFSET) {
3401 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3402 continue;
3403 }
3404 indsp->grf_prop.override = ovrid;
3405 _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3406 break;
3407 }
3408
3409 case 0x0A: { // Set industry layout(s)
3410 byte new_num_layouts = buf->ReadByte(); // Number of layaouts
3411 /* We read the total size in bytes, but we can't rely on the
3412 * newgrf to provide a sane value. First assume the value is
3413 * sane but later on we make sure we enlarge the array if the
3414 * newgrf contains more data. Each tile uses either 3 or 5
3415 * bytes, so to play it safe we assume 3. */
3416 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
3417 IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(new_num_layouts); // Table with tiles to compose an industry
3418 IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles); // Temporary array to read the tile layouts from the GRF
3419 uint size;
3420 const IndustryTileTable *copy_from;
3421
3422 try {
3423 for (byte j = 0; j < new_num_layouts; j++) {
3424 for (uint k = 0;; k++) {
3425 if (k >= def_num_tiles) {
3426 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3427 /* Size reported by newgrf was not big enough so enlarge the array. */
3428 def_num_tiles *= 2;
3429 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
3430 }
3431
3432 itt[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3433
3434 if (itt[k].ti.x == 0xFE && k == 0) {
3435 /* This means we have to borrow the layout from an old industry */
3436 IndustryType type = buf->ReadByte(); // industry holding required layout
3437 byte laynbr = buf->ReadByte(); // layout number to borrow
3438
3439 copy_from = _origin_industry_specs[type].table[laynbr];
3440 for (size = 1;; size++) {
3441 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
3442 }
3443 break;
3444 }
3445
3446 itt[k].ti.y = buf->ReadByte(); // Or table definition finalisation
3447
3448 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
3449 /* Not the same terminator. The one we are using is rather
3450 x = -80, y = x . So, adjust it. */
3451 itt[k].ti.x = -0x80;
3452 itt[k].ti.y = 0;
3453 itt[k].gfx = 0;
3454
3455 size = k + 1;
3456 copy_from = itt;
3457 break;
3458 }
3459
3460 itt[k].gfx = buf->ReadByte();
3461
3462 if (itt[k].gfx == 0xFE) {
3463 /* Use a new tile from this GRF */
3464 int local_tile_id = buf->ReadWord();
3465
3466 /* Read the ID from the _industile_mngr. */
3467 int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3468
3469 if (tempid == INVALID_INDUSTRYTILE) {
3470 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3471 } else {
3472 /* Declared as been valid, can be used */
3473 itt[k].gfx = tempid;
3474 size = k + 1;
3475 copy_from = itt;
3476 }
3477 } else if (itt[k].gfx == 0xFF) {
3478 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
3479 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
3480
3481 /* When there were only 256x256 maps, TileIndex was a uint16 and
3482 * itt[k].ti was just a TileIndexDiff that was added to it.
3483 * As such negative "x" values were shifted into the "y" position.
3484 * x = -1, y = 1 -> x = 255, y = 0
3485 * Since GRF version 8 the position is interpreted as pair of independent int8.
3486 * For GRF version < 8 we need to emulate the old shifting behaviour.
3487 */
3488 if (_cur.grffile->grf_version < 8 && itt[k].ti.x < 0) itt[k].ti.y += 1;
3489 }
3490 }
3491
3492 if (!ValidateIndustryLayout(copy_from, size)) {
3493 /* The industry layout was not valid, so skip this one. */
3494 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3495 new_num_layouts--;
3496 j--;
3497 } else {
3498 tile_table[j] = CallocT<IndustryTileTable>(size);
3499 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3500 }
3501 }
3502 } catch (...) {
3503 for (int i = 0; i < new_num_layouts; i++) {
3504 free(tile_table[i]);
3505 }
3506 free(tile_table);
3507 free(itt);
3508 throw;
3509 }
3510
3511 /* Clean the tile table if it was already set by a previous prop A. */
3512 CleanIndustryTileTable(indsp);
3513 /* Install final layout construction in the industry spec */
3514 indsp->num_table = new_num_layouts;
3515 indsp->table = tile_table;
3516 SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
3517 free(itt);
3518 break;
3519 }
3520
3521 case 0x0B: // Industry production flags
3522 indsp->life_type = (IndustryLifeType)buf->ReadByte();
3523 break;
3524
3525 case 0x0C: // Industry closure message
3526 AddStringForMapping(buf->ReadWord(), &indsp->closure_text);
3527 break;
3528
3529 case 0x0D: // Production increase message
3530 AddStringForMapping(buf->ReadWord(), &indsp->production_up_text);
3531 break;
3532
3533 case 0x0E: // Production decrease message
3534 AddStringForMapping(buf->ReadWord(), &indsp->production_down_text);
3535 break;
3536
3537 case 0x0F: // Fund cost multiplier
3538 indsp->cost_multiplier = buf->ReadByte();
3539 break;
3540
3541 case 0x10: // Production cargo types
3542 for (byte j = 0; j < 2; j++) {
3543 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3544 }
3545 break;
3546
3547 case 0x11: // Acceptance cargo types
3548 for (byte j = 0; j < 3; j++) {
3549 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3550 }
3551 buf->ReadByte(); // Unnused, eat it up
3552 break;
3553
3554 case 0x12: // Production multipliers
3555 case 0x13:
3556 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3557 break;
3558
3559 case 0x14: // Minimal amount of cargo distributed
3560 indsp->minimal_cargo = buf->ReadByte();
3561 break;
3562
3563 case 0x15: { // Random sound effects
3564 indsp->number_of_sounds = buf->ReadByte();
3565 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
3566
3567 try {
3568 for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
3569 sounds[j] = buf->ReadByte();
3570 }
3571 } catch (...) {
3572 free(sounds);
3573 throw;
3574 }
3575
3576 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3577 free(indsp->random_sounds);
3578 }
3579 indsp->random_sounds = sounds;
3580 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
3581 break;
3582 }
3583
3584 case 0x16: // Conflicting industry types
3585 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3586 break;
3587
3588 case 0x17: // Probability in random game
3589 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3590 break;
3591
3592 case 0x18: // Probability during gameplay
3593 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3594 break;
3595
3596 case 0x19: // Map colour
3597 indsp->map_colour = buf->ReadByte();
3598 break;
3599
3600 case 0x1A: // Special industry flags to define special behavior
3601 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3602 break;
3603
3604 case 0x1B: // New industry text ID
3605 AddStringForMapping(buf->ReadWord(), &indsp->new_industry_text);
3606 break;
3607
3608 case 0x1C: // Input cargo multipliers for the three input cargo types
3609 case 0x1D:
3610 case 0x1E: {
3611 uint32 multiples = buf->ReadDWord();
3612 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3613 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3614 break;
3615 }
3616
3617 case 0x1F: // Industry name
3618 AddStringForMapping(buf->ReadWord(), &indsp->name);
3619 break;
3620
3621 case 0x20: // Prospecting success chance
3622 indsp->prospecting_chance = buf->ReadDWord();
3623 break;
3624
3625 case 0x21: // Callback mask
3626 case 0x22: { // Callback additional mask
3627 byte aflag = buf->ReadByte();
3628 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3629 break;
3630 }
3631
3632 case 0x23: // removal cost multiplier
3633 indsp->removal_cost_multiplier = buf->ReadDWord();
3634 break;
3635
3636 case 0x24: { // name for nearby station
3637 uint16 str = buf->ReadWord();
3638 if (str == 0) {
3639 indsp->station_name = STR_NULL;
3640 } else {
3641 AddStringForMapping(str, &indsp->station_name);
3642 }
3643 break;
3644 }
3645
3646 default:
3647 ret = CIR_UNKNOWN;
3648 break;
3649 }
3650 }
3651
3652 return ret;
3653 }
3654
3660 static void DuplicateTileTable(AirportSpec *as)
3661 {
3662 AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
3663 for (int i = 0; i < as->num_table; i++) {
3664 uint num_tiles = 1;
3665 const AirportTileTable *it = as->table[0];
3666 do {
3667 num_tiles++;
3668 } while ((++it)->ti.x != -0x80);
3669 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3670 MemCpyT(table_list[i], as->table[i], num_tiles);
3671 }
3672 as->table = table_list;
3673 HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
3674 MemCpyT(depot_table, as->depot_table, as->nof_depots);
3675 as->depot_table = depot_table;
3676 Direction *rotation = MallocT<Direction>(as->num_table);
3677 MemCpyT(rotation, as->rotation, as->num_table);
3678 as->rotation = rotation;
3679 }
3680
3689 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3690 {
3691 ChangeInfoResult ret = CIR_SUCCESS;
3692
3693 if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
3694 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
3695 return CIR_INVALID_ID;
3696 }
3697
3698 /* Allocate industry specs if they haven't been allocated already. */
3699 if (_cur.grffile->airportspec == NULL) {
3700 _cur.grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS_PER_GRF);
3701 }
3702
3703 for (int i = 0; i < numinfo; i++) {
3704 AirportSpec *as = _cur.grffile->airportspec[airport + i];
3705
3706 if (as == NULL && prop != 0x08 && prop != 0x09) {
3707 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3708 return CIR_INVALID_ID;
3709 }
3710
3711 switch (prop) {
3712 case 0x08: { // Modify original airport
3713 byte subs_id = buf->ReadByte();
3714
3715 if (subs_id == 0xFF) {
3716 /* Instead of defining a new airport, an airport id
3717 * of 0xFF disables the old airport with the current id. */
3718 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3719 continue;
3720 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3721 /* The substitute id must be one of the original airports. */
3722 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3723 continue;
3724 }
3725
3726 AirportSpec **spec = &_cur.grffile->airportspec[airport + i];
3727 /* Allocate space for this airport.
3728 * Only need to do it once. If ever it is called again, it should not
3729 * do anything */
3730 if (*spec == NULL) {
3731 *spec = MallocT<AirportSpec>(1);
3732 as = *spec;
3733
3734 memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
3735 as->enabled = true;
3736 as->grf_prop.local_id = airport + i;
3737 as->grf_prop.subst_id = subs_id;
3738 as->grf_prop.grffile = _cur.grffile;
3739 /* override the default airport */
3740 _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3741 /* Create a copy of the original tiletable so it can be freed later. */
3742 DuplicateTileTable(as);
3743 }
3744 break;
3745 }
3746
3747 case 0x0A: { // Set airport layout
3748 free(as->rotation);
3749 as->num_table = buf->ReadByte(); // Number of layaouts
3750 as->rotation = MallocT<Direction>(as->num_table);
3751 uint32 defsize = buf->ReadDWord(); // Total size of the definition
3752 AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3753 AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
3754 int size;
3755 const AirportTileTable *copy_from;
3756 try {
3757 for (byte j = 0; j < as->num_table; j++) {
3758 const_cast<Direction&>(as->rotation[j]) = (Direction)buf->ReadByte();
3759 for (int k = 0;; k++) {
3760 att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3761 att[k].ti.y = buf->ReadByte();
3762
3763 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3764 /* Not the same terminator. The one we are using is rather
3765 * x = -80, y = 0 . So, adjust it. */
3766 att[k].ti.x = -0x80;
3767 att[k].ti.y = 0;
3768 att[k].gfx = 0;
3769
3770 size = k + 1;
3771 copy_from = att;
3772 break;
3773 }
3774
3775 att[k].gfx = buf->ReadByte();
3776
3777 if (att[k].gfx == 0xFE) {
3778 /* Use a new tile from this GRF */
3779 int local_tile_id = buf->ReadWord();
3780
3781 /* Read the ID from the _airporttile_mngr. */
3782 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3783
3784 if (tempid == INVALID_AIRPORTTILE) {
3785 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3786 } else {
3787 /* Declared as been valid, can be used */
3788 att[k].gfx = tempid;
3789 size = k + 1;
3790 copy_from = att;
3791 }
3792 } else if (att[k].gfx == 0xFF) {
3793 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3794 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3795 }
3796
3797 if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
3798 as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
3799 as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
3800 } else {
3801 as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
3802 as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
3803 }
3804 }
3805 tile_table[j] = CallocT<AirportTileTable>(size);
3806 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3807 }
3808 /* Install final layout construction in the airport spec */
3809 as->table = tile_table;
3810 free(att);
3811 } catch (...) {
3812 for (int i = 0; i < as->num_table; i++) {
3813 free(tile_table[i]);
3814 }
3815 free(tile_table);
3816 free(att);
3817 throw;
3818 }
3819 break;
3820 }
3821
3822 case 0x0C:
3823 as->min_year = buf->ReadWord();
3824 as->max_year = buf->ReadWord();
3825 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3826 break;
3827
3828 case 0x0D:
3829 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3830 break;
3831
3832 case 0x0E:
3833 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3834 break;
3835
3836 case 0x0F:
3837 as->noise_level = buf->ReadByte();
3838 break;
3839
3840 case 0x10:
3841 AddStringForMapping(buf->ReadWord(), &as->name);
3842 break;
3843
3844 case 0x11: // Maintenance cost factor
3845 as->maintenance_cost = buf->ReadWord();
3846 break;
3847
3848 default:
3849 ret = CIR_UNKNOWN;
3850 break;
3851 }
3852 }
3853
3854 return ret;
3855 }
3856
3863 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
3864 {
3865 ChangeInfoResult ret = CIR_SUCCESS;
3866
3867 switch (prop) {
3868 case 0x0B:
3869 case 0x0C:
3870 case 0x0D:
3871 case 0x12:
3872 case 0x14:
3873 case 0x16:
3874 case 0x17:
3875 buf->ReadByte();
3876 break;
3877
3878 case 0x09:
3879 case 0x0A:
3880 case 0x10:
3881 case 0x11:
3882 case 0x13:
3883 case 0x15:
3884 buf->ReadWord();
3885 break;
3886
3887 case 0x08:
3888 case 0x0E:
3889 case 0x0F:
3890 buf->ReadDWord();
3891 break;
3892
3893 default:
3894 ret = CIR_UNKNOWN;
3895 break;
3896 }
3897
3898 return ret;
3899 }
3900
3909 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
3910 {
3911 ChangeInfoResult ret = CIR_SUCCESS;
3912
3913 if (id + numinfo > NUM_OBJECTS_PER_GRF) {
3914 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
3915 return CIR_INVALID_ID;
3916 }
3917
3918 /* Allocate object specs if they haven't been allocated already. */
3919 if (_cur.grffile->objectspec == NULL) {
3920 _cur.grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS_PER_GRF);
3921 }
3922
3923 for (int i = 0; i < numinfo; i++) {
3924 ObjectSpec *spec = _cur.grffile->objectspec[id + i];
3925
3926 if (prop != 0x08 && spec == NULL) {
3927 /* If the object property 08 is not yet set, ignore this property */
3928 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
3929 if (cir > ret) ret = cir;
3930 continue;
3931 }
3932
3933 switch (prop) {
3934 case 0x08: { // Class ID
3935 ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
3936
3937 /* Allocate space for this object. */
3938 if (*ospec == NULL) {
3939 *ospec = CallocT<ObjectSpec>(1);
3940 (*ospec)->views = 1; // Default for NewGRFs that don't set it.
3941 }
3942
3943 /* Swap classid because we read it in BE. */
3944 uint32 classid = buf->ReadDWord();
3945 (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
3946 (*ospec)->enabled = true;
3947 break;
3948 }
3949
3950 case 0x09: { // Class name
3951 ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
3952 AddStringForMapping(buf->ReadWord(), &objclass->name);
3953 break;
3954 }
3955
3956 case 0x0A: // Object name
3957 AddStringForMapping(buf->ReadWord(), &spec->name);
3958 break;
3959
3960 case 0x0B: // Climate mask
3961 spec->climate = buf->ReadByte();
3962 break;
3963
3964 case 0x0C: // Size
3965 spec->size = buf->ReadByte();
3966 break;
3967
3968 case 0x0D: // Build cost multipler
3969 spec->build_cost_multiplier = buf->ReadByte();
3970 spec->clear_cost_multiplier = spec->build_cost_multiplier;
3971 break;
3972
3973 case 0x0E: // Introduction date
3974 spec->introduction_date = buf->ReadDWord();
3975 break;
3976
3977 case 0x0F: // End of life
3978 spec->end_of_life_date = buf->ReadDWord();
3979 break;
3980
3981 case 0x10: // Flags
3982 spec->flags = (ObjectFlags)buf->ReadWord();
3983 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
3984 break;
3985
3986 case 0x11: // Animation info
3987 spec->animation.frames = buf->ReadByte();
3988 spec->animation.status = buf->ReadByte();
3989 break;
3990
3991 case 0x12: // Animation speed
3992 spec->animation.speed = buf->ReadByte();
3993 break;
3994
3995 case 0x13: // Animation triggers
3996 spec->animation.triggers = buf->ReadWord();
3997 break;
3998
3999 case 0x14: // Removal cost multiplier
4000 spec->clear_cost_multiplier = buf->ReadByte();
4001 break;
4002
4003 case 0x15: // Callback mask
4004 spec->callback_mask = buf->ReadWord();
4005 break;
4006
4007 case 0x16: // Building height
4008 spec->height = buf->ReadByte();
4009 break;
4010
4011 case 0x17: // Views
4012 spec->views = buf->ReadByte();
4013 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
4014 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
4015 spec->views = 1;
4016 }
4017 break;
4018
4019 case 0x18: // Amount placed on 256^2 map on map creation
4020 spec->generate_amount = buf->ReadByte();
4021 break;
4022
4023 default:
4024 ret = CIR_UNKNOWN;
4025 break;
4026 }
4027 }
4028
4029 return ret;
4030 }
4031
4040 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4041 {
4042 ChangeInfoResult ret = CIR_SUCCESS;
4043
4044 extern RailtypeInfo _railtypes[RAILTYPE_END];
4045
4046 if (id + numinfo > RAILTYPE_END) {
4047 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4048 return CIR_INVALID_ID;
4049 }
4050
4051 for (int i = 0; i < numinfo; i++) {
4052 RailType rt = _cur.grffile->railtype_map[id + i];
4053 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
4054
4055 RailtypeInfo *rti = &_railtypes[rt];
4056
4057 switch (prop) {
4058 case 0x08: // Label of rail type
4059 /* Skipped here as this is loaded during reservation stage. */
4060 buf->ReadDWord();
4061 break;
4062
4063 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4064 uint16 str = buf->ReadWord();
4065 AddStringForMapping(str, &rti->strings.toolbar_caption);
4066 if (_cur.grffile->grf_version < 8) {
4067 AddStringForMapping(str, &rti->strings.name);
4068 }
4069 break;
4070 }
4071
4072 case 0x0A: // Menu text of railtype
4073 AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4074 break;
4075
4076 case 0x0B: // Build window caption
4077 AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4078 break;
4079
4080 case 0x0C: // Autoreplace text
4081 AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4082 break;
4083
4084 case 0x0D: // New locomotive text
4085 AddStringForMapping(buf->ReadWord(), &rti->strings.new_loco);
4086 break;
4087
4088 case 0x0E: // Compatible railtype list
4089 case 0x0F: // Powered railtype list
4090 case 0x18: // Railtype list required for date introduction
4091 case 0x19: // Introduced railtype list
4092 {
4093 /* Rail type compatibility bits are added to the existing bits
4094 * to allow multiple GRFs to modify compatibility with the
4095 * default rail types. */
4096 int n = buf->ReadByte();
4097 for (int j = 0; j != n; j++) {
4098 RailTypeLabel label = buf->ReadDWord();
4099 RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
4100 if (rt != INVALID_RAILTYPE) {
4101 switch (prop) {
4102 case 0x0F: SetBit(rti->powered_railtypes, rt); FALLTHROUGH; // Powered implies compatible.
4103 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
4104 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
4105 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
4106 }
4107 }
4108 }
4109 break;
4110 }
4111
4112 case 0x10: // Rail Type flags
4113 rti->flags = (RailTypeFlags)buf->ReadByte();
4114 break;
4115
4116 case 0x11: // Curve speed advantage
4117 rti->curve_speed = buf->ReadByte();
4118 break;
4119
4120 case 0x12: // Station graphic
4121 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
4122 break;
4123
4124 case 0x13: // Construction cost factor
4125 rti->cost_multiplier = buf->ReadWord();
4126 break;
4127
4128 case 0x14: // Speed limit
4129 rti->max_speed = buf->ReadWord();
4130 break;
4131
4132 case 0x15: // Acceleration model
4133 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
4134 break;
4135
4136 case 0x16: // Map colour
4137 rti->map_colour = buf->ReadByte();
4138 break;
4139
4140 case 0x17: // Introduction date
4141 rti->introduction_date = buf->ReadDWord();
4142 break;
4143
4144 case 0x1A: // Sort order
4145 rti->sorting_order = buf->ReadByte();
4146 break;
4147
4148 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4149 AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4150 break;
4151
4152 case 0x1C: // Maintenance cost factor
4153 rti->maintenance_multiplier = buf->ReadWord();
4154 break;
4155
4156 case 0x1D: // Alternate rail type label list
4157 /* Skipped here as this is loaded during reservation stage. */
4158 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4159 break;
4160
4161 default:
4162 ret = CIR_UNKNOWN;
4163 break;
4164 }
4165 }
4166
4167 return ret;
4168 }
4169
4170 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4171 {
4172 ChangeInfoResult ret = CIR_SUCCESS;
4173
4174 extern RailtypeInfo _railtypes[RAILTYPE_END];
4175
4176 if (id + numinfo > RAILTYPE_END) {
4177 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4178 return CIR_INVALID_ID;
4179 }
4180
4181 for (int i = 0; i < numinfo; i++) {
4182 switch (prop) {
4183 case 0x08: // Label of rail type
4184 {
4185 RailTypeLabel rtl = buf->ReadDWord();
4186 rtl = BSWAP32(rtl);
4187
4188 RailType rt = GetRailTypeByLabel(rtl, false);
4189 if (rt == INVALID_RAILTYPE) {
4190 /* Set up new rail type */
4191 rt = AllocateRailType(rtl);
4192 }
4193
4194 _cur.grffile->railtype_map[id + i] = rt;
4195 break;
4196 }
4197
4198 case 0x09: // Toolbar caption of railtype
4199 case 0x0A: // Menu text
4200 case 0x0B: // Build window caption
4201 case 0x0C: // Autoreplace text
4202 case 0x0D: // New loco
4203 case 0x13: // Construction cost
4204 case 0x14: // Speed limit
4205 case 0x1B: // Name of railtype
4206 case 0x1C: // Maintenance cost factor
4207 buf->ReadWord();
4208 break;
4209
4210 case 0x1D: // Alternate rail type label list
4211 if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
4212 int n = buf->ReadByte();
4213 for (int j = 0; j != n; j++) {
4214 *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord());
4215 }
4216 break;
4217 }
4218 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
4219 FALLTHROUGH;
4220
4221 case 0x0E: // Compatible railtype list
4222 case 0x0F: // Powered railtype list
4223 case 0x18: // Railtype list required for date introduction
4224 case 0x19: // Introduced railtype list
4225 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4226 break;
4227
4228 case 0x10: // Rail Type flags
4229 case 0x11: // Curve speed advantage
4230 case 0x12: // Station graphic
4231 case 0x15: // Acceleration model
4232 case 0x16: // Map colour
4233 case 0x1A: // Sort order
4234 buf->ReadByte();
4235 break;
4236
4237 case 0x17: // Introduction date
4238 buf->ReadDWord();
4239 break;
4240
4241 default:
4242 ret = CIR_UNKNOWN;
4243 break;
4244 }
4245 }
4246
4247 return ret;
4248 }
4249
4250 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
4251 {
4252 ChangeInfoResult ret = CIR_SUCCESS;
4253
4254 if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
4255 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
4256 return CIR_INVALID_ID;
4257 }
4258
4259 /* Allocate airport tile specs if they haven't been allocated already. */
4260 if (_cur.grffile->airtspec == NULL) {
4261 _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES_PER_GRF);
4262 }
4263
4264 for (int i = 0; i < numinfo; i++) {
4265 AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
4266
4267 if (prop != 0x08 && tsp == NULL) {
4268 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4269 return CIR_INVALID_ID;
4270 }
4271
4272 switch (prop) {
4273 case 0x08: { // Substitute airport tile type
4274 AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
4275 byte subs_id = buf->ReadByte();
4276
4277 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
4278 /* The substitute id must be one of the original airport tiles. */
4279 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4280 continue;
4281 }
4282
4283 /* Allocate space for this airport tile. */
4284 if (*tilespec == NULL) {
4285 *tilespec = CallocT<AirportTileSpec>(1);
4286 tsp = *tilespec;
4287
4288 memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
4289 tsp->enabled = true;
4290
4291 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
4292
4293 tsp->grf_prop.local_id = airtid + i;
4294 tsp->grf_prop.subst_id = subs_id;
4295 tsp->grf_prop.grffile = _cur.grffile;
4296 _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
4297 }
4298 break;
4299 }
4300
4301 case 0x09: { // Airport tile override
4302 byte override = buf->ReadByte();
4303
4304 /* The airport tile being overridden must be an original airport tile. */
4305 if (override >= NEW_AIRPORTTILE_OFFSET) {
4306 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
4307 continue;
4308 }
4309
4310 _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
4311 break;
4312 }
4313
4314 case 0x0E: // Callback mask
4315 tsp->callback_mask = buf->ReadByte();
4316 break;
4317
4318 case 0x0F: // Animation information
4319 tsp->animation.frames = buf->ReadByte();
4320 tsp->animation.status = buf->ReadByte();
4321 break;
4322
4323 case 0x10: // Animation speed
4324 tsp->animation.speed = buf->ReadByte();
4325 break;
4326
4327 case 0x11: // Animation triggers
4328 tsp->animation.triggers = buf->ReadByte();
4329 break;
4330
4331 default:
4332 ret = CIR_UNKNOWN;
4333 break;
4334 }
4335 }
4336
4337 return ret;
4338 }
4339
4340 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4341 {
4342 switch (cir) {
4343 default: NOT_REACHED();
4344
4345 case CIR_DISABLED:
4346 /* Error has already been printed; just stop parsing */
4347 return true;
4348
4349 case CIR_SUCCESS:
4350 return false;
4351
4352 case CIR_UNHANDLED:
4353 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4354 return false;
4355
4356 case CIR_UNKNOWN:
4357 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4358 FALLTHROUGH;
4359
4360 case CIR_INVALID_ID: {
4361 /* No debug message for an invalid ID, as it has already been output */
4362 GRFError *error = DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4363 if (cir != CIR_INVALID_ID) error->param_value[1] = property;
4364 return true;
4365 }
4366 }
4367 }
4368
4369 /* Action 0x00 */
4370 static void FeatureChangeInfo(ByteReader *buf)
4371 {
4372 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4373 *
4374 * B feature
4375 * B num-props how many properties to change per vehicle/station
4376 * B num-info how many vehicles/stations to change
4377 * E id ID of first vehicle/station to change, if num-info is
4378 * greater than one, this one and the following
4379 * vehicles/stations will be changed
4380 * B property what property to change, depends on the feature
4381 * V new-info new bytes of info (variable size; depends on properties) */
4382
4383 static const VCI_Handler handler[] = {
4384 /* GSF_TRAINS */ RailVehicleChangeInfo,
4385 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4386 /* GSF_SHIPS */ ShipVehicleChangeInfo,
4387 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4388 /* GSF_STATIONS */ StationChangeInfo,
4389 /* GSF_CANALS */ CanalChangeInfo,
4390 /* GSF_BRIDGES */ BridgeChangeInfo,
4391 /* GSF_HOUSES */ TownHouseChangeInfo,
4392 /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4393 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4394 /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4395 /* GSF_CARGOES */ NULL, // Cargo is handled during reservation
4396 /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4397 /* GSF_AIRPORTS */ AirportChangeInfo,
4398 /* GSF_SIGNALS */ NULL,
4399 /* GSF_OBJECTS */ ObjectChangeInfo,
4400 /* GSF_RAILTYPES */ RailTypeChangeInfo,
4401 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4402 };
4403
4404 uint8 feature = buf->ReadByte();
4405 uint8 numprops = buf->ReadByte();
4406 uint numinfo = buf->ReadByte();
4407 uint engine = buf->ReadExtendedByte();
4408
4409 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4410 feature, numprops, engine, numinfo);
4411
4412 if (feature >= lengthof(handler) || handler[feature] == NULL) {
4413 if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
4414 return;
4415 }
4416
4417 /* Mark the feature as used by the grf */
4418 SetBit(_cur.grffile->grf_features, feature);
4419
4420 while (numprops-- && buf->HasData()) {
4421 uint8 prop = buf->ReadByte();
4422
4423 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4424 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
4425 }
4426 }
4427
4428 /* Action 0x00 (GLS_SAFETYSCAN) */
4429 static void SafeChangeInfo(ByteReader *buf)
4430 {
4431 uint8 feature = buf->ReadByte();
4432 uint8 numprops = buf->ReadByte();
4433 uint numinfo = buf->ReadByte();
4434 buf->ReadExtendedByte(); // id
4435
4436 if (feature == GSF_BRIDGES && numprops == 1) {
4437 uint8 prop = buf->ReadByte();
4438 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4439 * is considered safe. */
4440 if (prop == 0x0D) return;
4441 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4442 uint8 prop = buf->ReadByte();
4443 /* Engine ID Mappings are safe, if the source is static */
4444 if (prop == 0x11) {
4445 bool is_safe = true;
4446 for (uint i = 0; i < numinfo; i++) {
4447 uint32 s = buf->ReadDWord();
4448 buf->ReadDWord(); // dest
4449 const GRFConfig *grfconfig = GetGRFConfig(s);
4450 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
4451 is_safe = false;
4452 break;
4453 }
4454 }
4455 if (is_safe) return;
4456 }
4457 }
4458
4459 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4460
4461 /* Skip remainder of GRF */
4462 _cur.skip_sprites = -1;
4463 }
4464
4465 /* Action 0x00 (GLS_RESERVE) */
4466 static void ReserveChangeInfo(ByteReader *buf)
4467 {
4468 uint8 feature = buf->ReadByte();
4469
4470 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
4471
4472 uint8 numprops = buf->ReadByte();
4473 uint8 numinfo = buf->ReadByte();
4474 uint8 index = buf->ReadExtendedByte();
4475
4476 while (numprops-- && buf->HasData()) {
4477 uint8 prop = buf->ReadByte();
4478 ChangeInfoResult cir = CIR_SUCCESS;
4479
4480 switch (feature) {
4481 default: NOT_REACHED();
4482 case GSF_CARGOES:
4483 cir = CargoChangeInfo(index, numinfo, prop, buf);
4484 break;
4485
4486 case GSF_GLOBALVAR:
4487 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4488 break;
4489
4490 case GSF_RAILTYPES:
4491 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4492 break;
4493 }
4494
4495 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
4496 }
4497 }
4498
4499 /* Action 0x01 */
4500 static void NewSpriteSet(ByteReader *buf)
4501 {
4502 /* Basic format: <01> <feature> <num-sets> <num-ent>
4503 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4504 *
4505 * B feature feature to define sprites for
4506 * 0, 1, 2, 3: veh-type, 4: train stations
4507 * E first-set first sprite set to define
4508 * B num-sets number of sprite sets (extended byte in extended format)
4509 * E num-ent how many entries per sprite set
4510 * For vehicles, this is the number of different
4511 * vehicle directions in each sprite set
4512 * Set num-dirs=8, unless your sprites are symmetric.
4513 * In that case, use num-dirs=4.
4514 */
4515
4516 uint8 feature = buf->ReadByte();
4517 uint16 num_sets = buf->ReadByte();
4518 uint16 first_set = 0;
4519
4520 if (num_sets == 0 && buf->HasData(3)) {
4521 /* Extended Action1 format.
4522 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4523 first_set = buf->ReadExtendedByte();
4524 num_sets = buf->ReadExtendedByte();
4525 }
4526 uint16 num_ents = buf->ReadExtendedByte();
4527
4528 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4529
4530 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4531 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4532 );
4533
4534 for (int i = 0; i < num_sets * num_ents; i++) {
4535 _cur.nfo_line++;
4536 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
4537 }
4538 }
4539
4540 /* Action 0x01 (SKIP) */
4541 static void SkipAct1(ByteReader *buf)
4542 {
4543 buf->ReadByte();
4544 uint16 num_sets = buf->ReadByte();
4545
4546 if (num_sets == 0 && buf->HasData(3)) {
4547 /* Extended Action1 format.
4548 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4549 buf->ReadExtendedByte(); // first_set
4550 num_sets = buf->ReadExtendedByte();
4551 }
4552 uint16 num_ents = buf->ReadExtendedByte();
4553
4554 _cur.skip_sprites = num_sets * num_ents;
4555
4556 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
4557 }
4558
4559 /* Helper function to either create a callback or link to a previously
4560 * defined spritegroup. */
4561 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4562 {
4563 if (HasBit(groupid, 15)) {
4564 assert(CallbackResultSpriteGroup::CanAllocateItem());
4565 return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
4566 }
4567
4568 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4569 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4570 return NULL;
4571 }
4572
4573 return _cur.spritegroups[groupid];
4574 }
4575
4584 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4585 {
4586 if (HasBit(spriteid, 15)) {
4587 assert(CallbackResultSpriteGroup::CanAllocateItem());
4588 return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
4589 }
4590
4591 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4592 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4593 return NULL;
4594 }
4595
4596 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4597 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4598
4599 /* Ensure that the sprites are loeded */
4600 assert(spriteset_start + num_sprites <= _cur.spriteid);
4601
4602 assert(ResultSpriteGroup::CanAllocateItem());
4603 return new ResultSpriteGroup(spriteset_start, num_sprites);
4604 }
4605
4606 /* Action 0x02 */
4607 static void NewSpriteGroup(ByteReader *buf)
4608 {
4609 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4610 *
4611 * B feature see action 1
4612 * B set-id ID of this particular definition
4613 * B type/num-entries
4614 * if 80 or greater, this is a randomized or variational
4615 * list definition, see below
4616 * otherwise it specifies a number of entries, the exact
4617 * meaning depends on the feature
4618 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4619 SpriteGroup *act_group = NULL;
4620
4621 uint8 feature = buf->ReadByte();
4622 uint8 setid = buf->ReadByte();
4623 uint8 type = buf->ReadByte();
4624
4625 /* Sprite Groups are created here but they are allocated from a pool, so
4626 * we do not need to delete anything if there is an exception from the
4627 * ByteReader. */
4628
4629 switch (type) {
4630 /* Deterministic Sprite Group */
4631 case 0x81: // Self scope, byte
4632 case 0x82: // Parent scope, byte
4633 case 0x85: // Self scope, word
4634 case 0x86: // Parent scope, word
4635 case 0x89: // Self scope, dword
4636 case 0x8A: // Parent scope, dword
4637 {
4638 byte varadjust;
4639 byte varsize;
4640
4641 assert(DeterministicSpriteGroup::CanAllocateItem());
4642 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
4643 act_group = group;
4644 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4645
4646 switch (GB(type, 2, 2)) {
4647 default: NOT_REACHED();
4648 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
4649 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
4650 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
4651 }
4652
4653 static SmallVector<DeterministicSpriteGroupAdjust, 16> adjusts;
4654 adjusts.Clear();
4655
4656 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4657 * from the outset, so we shall have to keep reallocing. */
4658 do {
4659 DeterministicSpriteGroupAdjust *adjust = adjusts.Append();
4660
4661 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4662 adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
4663 adjust->variable = buf->ReadByte();
4664 if (adjust->variable == 0x7E) {
4665 /* Link subroutine group */
4666 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
4667 } else {
4668 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
4669 }
4670
4671 varadjust = buf->ReadByte();
4672 adjust->shift_num = GB(varadjust, 0, 5);
4673 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
4674 adjust->and_mask = buf->ReadVarSize(varsize);
4675
4676 if (adjust->type != DSGA_TYPE_NONE) {
4677 adjust->add_val = buf->ReadVarSize(varsize);
4678 adjust->divmod_val = buf->ReadVarSize(varsize);
4679 } else {
4680 adjust->add_val = 0;
4681 adjust->divmod_val = 0;
4682 }
4683
4684 /* Continue reading var adjusts while bit 5 is set. */
4685 } while (HasBit(varadjust, 5));
4686
4687 group->num_adjusts = adjusts.Length();
4688 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
4689 MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts);
4690
4691 std::vector<DeterministicSpriteGroupRange> ranges;
4692 ranges.resize(buf->ReadByte());
4693 for (uint i = 0; i < ranges.size(); i++) {
4694 ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4695 ranges[i].low = buf->ReadVarSize(varsize);
4696 ranges[i].high = buf->ReadVarSize(varsize);
4697 }
4698
4699 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4700 group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
4701 /* nvar == 0 is a special case -- we turn our value into a callback result */
4702 group->calculated_result = ranges.size() == 0;
4703
4704 /* Sort ranges ascending. When ranges overlap, this may required clamping or splitting them */
4705 std::vector<uint32> bounds;
4706 for (uint i = 0; i < ranges.size(); i++) {
4707 bounds.push_back(ranges[i].low);
4708 if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
4709 }
4710 std::sort(bounds.begin(), bounds.end());
4711 bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
4712
4713 std::vector<const SpriteGroup *> target;
4714 for (uint j = 0; j < bounds.size(); ++j) {
4715 uint32 v = bounds[j];
4716 const SpriteGroup *t = group->default_group;
4717 for (uint i = 0; i < ranges.size(); i++) {
4718 if (ranges[i].low <= v && v <= ranges[i].high) {
4719 t = ranges[i].group;
4720 break;
4721 }
4722 }
4723 target.push_back(t);
4724 }
4725 assert(target.size() == bounds.size());
4726
4727 std::vector<DeterministicSpriteGroupRange> optimised;
4728 for (uint j = 0; j < bounds.size(); ) {
4729 if (target[j] != group->default_group) {
4730 DeterministicSpriteGroupRange r;
4731 r.group = target[j];
4732 r.low = bounds[j];
4733 while (j < bounds.size() && target[j] == r.group) {
4734 j++;
4735 }
4736 r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
4737 optimised.push_back(r);
4738 } else {
4739 j++;
4740 }
4741 }
4742
4743 group->num_ranges = optimised.size();
4744 if (group->num_ranges > 0) {
4745 group->ranges = MallocT<DeterministicSpriteGroupRange>(group->num_ranges);
4746 MemCpyT(group->ranges, &optimised.front(), group->num_ranges);
4747 }
4748 break;
4749 }
4750
4751 /* Randomized Sprite Group */
4752 case 0x80: // Self scope
4753 case 0x83: // Parent scope
4754 case 0x84: // Relative scope
4755 {
4756 assert(RandomizedSpriteGroup::CanAllocateItem());
4757 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
4758 act_group = group;
4759 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4760
4761 if (HasBit(type, 2)) {
4762 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
4763 group->count = buf->ReadByte();
4764 }
4765
4766 uint8 triggers = buf->ReadByte();
4767 group->triggers = GB(triggers, 0, 7);
4768 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
4769 group->lowest_randbit = buf->ReadByte();
4770 group->num_groups = buf->ReadByte();
4771 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
4772
4773 for (uint i = 0; i < group->num_groups; i++) {
4774 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
4775 }
4776
4777 break;
4778 }
4779
4780 /* Neither a variable or randomized sprite group... must be a real group */
4781 default:
4782 {
4783 switch (feature) {
4784 case GSF_TRAINS:
4785 case GSF_ROADVEHICLES:
4786 case GSF_SHIPS:
4787 case GSF_AIRCRAFT:
4788 case GSF_STATIONS:
4789 case GSF_CANALS:
4790 case GSF_CARGOES:
4791 case GSF_AIRPORTS:
4792 case GSF_RAILTYPES:
4793 {
4794 byte num_loaded = type;
4795 byte num_loading = buf->ReadByte();
4796
4797 if (!_cur.HasValidSpriteSets(feature)) {
4798 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4799 return;
4800 }
4801
4802 assert(RealSpriteGroup::CanAllocateItem());
4803 RealSpriteGroup *group = new RealSpriteGroup();
4804 act_group = group;
4805
4806 group->num_loaded = num_loaded;
4807 group->num_loading = num_loading;
4808 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
4809 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
4810
4811 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4812 setid, num_loaded, num_loading);
4813
4814 for (uint i = 0; i < num_loaded; i++) {
4815 uint16 spriteid = buf->ReadWord();
4816 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4817 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
4818 }
4819
4820 for (uint i = 0; i < num_loading; i++) {
4821 uint16 spriteid = buf->ReadWord();
4822 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4823 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
4824 }
4825
4826 break;
4827 }
4828
4829 case GSF_HOUSES:
4830 case GSF_AIRPORTTILES:
4831 case GSF_OBJECTS:
4832 case GSF_INDUSTRYTILES: {
4833 byte num_building_sprites = max((uint8)1, type);
4834
4835 assert(TileLayoutSpriteGroup::CanAllocateItem());
4836 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
4837 act_group = group;
4838
4839 /* On error, bail out immediately. Temporary GRF data was already freed */
4840 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
4841 break;
4842 }
4843
4844 case GSF_INDUSTRIES: {
4845 if (type > 1) {
4846 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
4847 break;
4848 }
4849
4850 assert(IndustryProductionSpriteGroup::CanAllocateItem());
4851 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
4852 act_group = group;
4853 group->version = type;
4854 if (type == 0) {
4855 for (uint i = 0; i < 3; i++) {
4856 group->subtract_input[i] = (int16)buf->ReadWord(); // signed
4857 }
4858 for (uint i = 0; i < 2; i++) {
4859 group->add_output[i] = buf->ReadWord(); // unsigned
4860 }
4861 group->again = buf->ReadByte();
4862 } else {
4863 for (uint i = 0; i < 3; i++) {
4864 group->subtract_input[i] = buf->ReadByte();
4865 }
4866 for (uint i = 0; i < 2; i++) {
4867 group->add_output[i] = buf->ReadByte();
4868 }
4869 group->again = buf->ReadByte();
4870 }
4871 break;
4872 }
4873
4874 /* Loading of Tile Layout and Production Callback groups would happen here */
4875 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
4876 }
4877 }
4878 }
4879
4880 _cur.spritegroups[setid] = act_group;
4881 }
4882
4883 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
4884 {
4885 if (feature == GSF_OBJECTS) {
4886 switch (ctype) {
4887 case 0: return 0;
4888 case 0xFF: return CT_PURCHASE_OBJECT;
4889 default:
4890 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
4891 return CT_INVALID;
4892 }
4893 }
4894 /* Special cargo types for purchase list and stations */
4895 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
4896 if (ctype == 0xFF) return CT_PURCHASE;
4897
4898 if (_cur.grffile->cargo_list.Length() == 0) {
4899 /* No cargo table, so use bitnum values */
4900 if (ctype >= 32) {
4901 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
4902 return CT_INVALID;
4903 }
4904
4905 const CargoSpec *cs;
4906 FOR_ALL_CARGOSPECS(cs) {
4907 if (cs->bitnum == ctype) {
4908 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
4909 return cs->Index();
4910 }
4911 }
4912
4913 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
4914 return CT_INVALID;
4915 }
4916
4917 /* Check if the cargo type is out of bounds of the cargo translation table */
4918 if (ctype >= _cur.grffile->cargo_list.Length()) {
4919 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1);
4920 return CT_INVALID;
4921 }
4922
4923 /* Look up the cargo label from the translation table */
4924 CargoLabel cl = _cur.grffile->cargo_list[ctype];
4925 if (cl == 0) {
4926 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
4927 return CT_INVALID;
4928 }
4929
4930 ctype = GetCargoIDByLabel(cl);
4931 if (ctype == CT_INVALID) {
4932 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));
4933 return CT_INVALID;
4934 }
4935
4936 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);
4937 return ctype;
4938 }
4939
4940
4941 static bool IsValidGroupID(uint16 groupid, const char *function)
4942 {
4943 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4944 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
4945 return false;
4946 }
4947
4948 return true;
4949 }
4950
4951 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
4952 {
4953 static EngineID *last_engines;
4954 static uint last_engines_count;
4955 bool wagover = false;
4956
4957 /* Test for 'wagon override' flag */
4958 if (HasBit(idcount, 7)) {
4959 wagover = true;
4960 /* Strip off the flag */
4961 idcount = GB(idcount, 0, 7);
4962
4963 if (last_engines_count == 0) {
4964 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4965 return;
4966 }
4967
4968 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4969 last_engines_count, idcount);
4970 } else {
4971 if (last_engines_count != idcount) {
4972 last_engines = ReallocT(last_engines, idcount);
4973 last_engines_count = idcount;
4974 }
4975 }
4976
4977 EngineID *engines = AllocaM(EngineID, idcount);
4978 for (uint i = 0; i < idcount; i++) {
4979 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
4980 if (e == NULL) {
4981 /* No engine could be allocated?!? Deal with it. Okay,
4982 * this might look bad. Also make sure this NewGRF
4983 * gets disabled, as a half loaded one is bad. */
4984 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
4985 return;
4986 }
4987
4988 engines[i] = e->index;
4989 if (!wagover) last_engines[i] = engines[i];
4990 }
4991
4992 uint8 cidcount = buf->ReadByte();
4993 for (uint c = 0; c < cidcount; c++) {
4994 uint8 ctype = buf->ReadByte();
4995 uint16 groupid = buf->ReadWord();
4996 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
4997
4998 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
4999
5000 ctype = TranslateCargo(feature, ctype);
5001 if (ctype == CT_INVALID) continue;
5002
5003 for (uint i = 0; i < idcount; i++) {
5004 EngineID engine = engines[i];
5005
5006 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5007
5008 if (wagover) {
5009 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5010 } else {
5011 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5012 }
5013 }
5014 }
5015
5016 uint16 groupid = buf->ReadWord();
5017 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
5018
5019 grfmsg(8, "-- Default group id 0x%04X", groupid);
5020
5021 for (uint i = 0; i < idcount; i++) {
5022 EngineID engine = engines[i];
5023
5024 if (wagover) {
5025 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5026 } else {
5027 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5028 SetEngineGRF(engine, _cur.grffile);
5029 }
5030 }
5031 }
5032
5033
5034 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
5035 {
5036 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
5037 for (uint i = 0; i < idcount; i++) {
5038 cfs[i] = (CanalFeature)buf->ReadByte();
5039 }
5040
5041 uint8 cidcount = buf->ReadByte();
5042 buf->Skip(cidcount * 3);
5043
5044 uint16 groupid = buf->ReadWord();
5045 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
5046
5047 for (uint i = 0; i < idcount; i++) {
5048 CanalFeature cf = cfs[i];
5049
5050 if (cf >= CF_END) {
5051 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5052 continue;
5053 }
5054
5055 _water_feature[cf].grffile = _cur.grffile;
5056 _water_feature[cf].group = _cur.spritegroups[groupid];
5057 }
5058 }
5059
5060
5061 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
5062 {
5063 uint8 *stations = AllocaM(uint8, idcount);
5064 for (uint i = 0; i < idcount; i++) {
5065 stations[i] = buf->ReadByte();
5066 }
5067
5068 uint8 cidcount = buf->ReadByte();
5069 for (uint c = 0; c < cidcount; c++) {
5070 uint8 ctype = buf->ReadByte();
5071 uint16 groupid = buf->ReadWord();
5072 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
5073
5074 ctype = TranslateCargo(GSF_STATIONS, ctype);
5075 if (ctype == CT_INVALID) continue;
5076
5077 for (uint i = 0; i < idcount; i++) {
5078 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5079
5080 if (statspec == NULL) {
5081 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5082 continue;
5083 }
5084
5085 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5086 }
5087 }
5088
5089 uint16 groupid = buf->ReadWord();
5090 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
5091
5092 for (uint i = 0; i < idcount; i++) {
5093 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5094
5095 if (statspec == NULL) {
5096 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5097 continue;
5098 }
5099
5100 if (statspec->grf_prop.grffile != NULL) {
5101 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5102 continue;
5103 }
5104
5105 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
5106 statspec->grf_prop.grffile = _cur.grffile;
5107 statspec->grf_prop.local_id = stations[i];
5108 StationClass::Assign(statspec);
5109 }
5110 }
5111
5112
5113 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
5114 {
5115 uint8 *houses = AllocaM(uint8, idcount);
5116 for (uint i = 0; i < idcount; i++) {
5117 houses[i] = buf->ReadByte();
5118 }
5119
5120 /* Skip the cargo type section, we only care about the default group */
5121 uint8 cidcount = buf->ReadByte();
5122 buf->Skip(cidcount * 3);
5123
5124 uint16 groupid = buf->ReadWord();
5125 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
5126
5127 if (_cur.grffile->housespec == NULL) {
5128 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5129 return;
5130 }
5131
5132 for (uint i = 0; i < idcount; i++) {
5133 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
5134
5135 if (hs == NULL) {
5136 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5137 continue;
5138 }
5139
5140 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5141 }
5142 }
5143
5144 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5145 {
5146 uint8 *industries = AllocaM(uint8, idcount);
5147 for (uint i = 0; i < idcount; i++) {
5148 industries[i] = buf->ReadByte();
5149 }
5150
5151 /* Skip the cargo type section, we only care about the default group */
5152 uint8 cidcount = buf->ReadByte();
5153 buf->Skip(cidcount * 3);
5154
5155 uint16 groupid = buf->ReadWord();
5156 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5157
5158 if (_cur.grffile->industryspec == NULL) {
5159 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5160 return;
5161 }
5162
5163 for (uint i = 0; i < idcount; i++) {
5164 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5165
5166 if (indsp == NULL) {
5167 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5168 continue;
5169 }
5170
5171 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5172 }
5173 }
5174
5175 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5176 {
5177 uint8 *indtiles = AllocaM(uint8, idcount);
5178 for (uint i = 0; i < idcount; i++) {
5179 indtiles[i] = buf->ReadByte();
5180 }
5181
5182 /* Skip the cargo type section, we only care about the default group */
5183 uint8 cidcount = buf->ReadByte();
5184 buf->Skip(cidcount * 3);
5185
5186 uint16 groupid = buf->ReadWord();
5187 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5188
5189 if (_cur.grffile->indtspec == NULL) {
5190 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5191 return;
5192 }
5193
5194 for (uint i = 0; i < idcount; i++) {
5195 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5196
5197 if (indtsp == NULL) {
5198 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5199 continue;
5200 }
5201
5202 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5203 }
5204 }
5205
5206 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5207 {
5208 CargoID *cargoes = AllocaM(CargoID, idcount);
5209 for (uint i = 0; i < idcount; i++) {
5210 cargoes[i] = buf->ReadByte();
5211 }
5212
5213 /* Skip the cargo type section, we only care about the default group */
5214 uint8 cidcount = buf->ReadByte();
5215 buf->Skip(cidcount * 3);
5216
5217 uint16 groupid = buf->ReadWord();
5218 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5219
5220 for (uint i = 0; i < idcount; i++) {
5221 CargoID cid = cargoes[i];
5222
5223 if (cid >= NUM_CARGO) {
5224 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5225 continue;
5226 }
5227
5228 CargoSpec *cs = CargoSpec::Get(cid);
5229 cs->grffile = _cur.grffile;
5230 cs->group = _cur.spritegroups[groupid];
5231 }
5232 }
5233
5234 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5235 {
5236 if (_cur.grffile->objectspec == NULL) {
5237 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5238 return;
5239 }
5240
5241 uint8 *objects = AllocaM(uint8, idcount);
5242 for (uint i = 0; i < idcount; i++) {
5243 objects[i] = buf->ReadByte();
5244 }
5245
5246 uint8 cidcount = buf->ReadByte();
5247 for (uint c = 0; c < cidcount; c++) {
5248 uint8 ctype = buf->ReadByte();
5249 uint16 groupid = buf->ReadWord();
5250 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5251
5252 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5253 if (ctype == CT_INVALID) continue;
5254
5255 for (uint i = 0; i < idcount; i++) {
5256 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5257
5258 if (spec == NULL) {
5259 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5260 continue;
5261 }
5262
5263 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5264 }
5265 }
5266
5267 uint16 groupid = buf->ReadWord();
5268 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5269
5270 for (uint i = 0; i < idcount; i++) {
5271 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5272
5273 if (spec == NULL) {
5274 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5275 continue;
5276 }
5277
5278 if (spec->grf_prop.grffile != NULL) {
5279 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5280 continue;
5281 }
5282
5283 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5284 spec->grf_prop.grffile = _cur.grffile;
5285 spec->grf_prop.local_id = objects[i];
5286 }
5287 }
5288
5289 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5290 {
5291 uint8 *railtypes = AllocaM(uint8, idcount);
5292 for (uint i = 0; i < idcount; i++) {
5293 railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
5294 }
5295
5296 uint8 cidcount = buf->ReadByte();
5297 for (uint c = 0; c < cidcount; c++) {
5298 uint8 ctype = buf->ReadByte();
5299 uint16 groupid = buf->ReadWord();
5300 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5301
5302 if (ctype >= RTSG_END) continue;
5303
5304 extern RailtypeInfo _railtypes[RAILTYPE_END];
5305 for (uint i = 0; i < idcount; i++) {
5306 if (railtypes[i] != INVALID_RAILTYPE) {
5307 RailtypeInfo *rti = &_railtypes[railtypes[i]];
5308
5309 rti->grffile[ctype] = _cur.grffile;
5310 rti->group[ctype] = _cur.spritegroups[groupid];
5311 }
5312 }
5313 }
5314
5315 /* Railtypes do not use the default group. */
5316 buf->ReadWord();
5317 }
5318
5319 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5320 {
5321 uint8 *airports = AllocaM(uint8, idcount);
5322 for (uint i = 0; i < idcount; i++) {
5323 airports[i] = buf->ReadByte();
5324 }
5325
5326 /* Skip the cargo type section, we only care about the default group */
5327 uint8 cidcount = buf->ReadByte();
5328 buf->Skip(cidcount * 3);
5329
5330 uint16 groupid = buf->ReadWord();
5331 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5332
5333 if (_cur.grffile->airportspec == NULL) {
5334 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5335 return;
5336 }
5337
5338 for (uint i = 0; i < idcount; i++) {
5339 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5340
5341 if (as == NULL) {
5342 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5343 continue;
5344 }
5345
5346 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5347 }
5348 }
5349
5350 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5351 {
5352 uint8 *airptiles = AllocaM(uint8, idcount);
5353 for (uint i = 0; i < idcount; i++) {
5354 airptiles[i] = buf->ReadByte();
5355 }
5356
5357 /* Skip the cargo type section, we only care about the default group */
5358 uint8 cidcount = buf->ReadByte();
5359 buf->Skip(cidcount * 3);
5360
5361 uint16 groupid = buf->ReadWord();
5362 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5363
5364 if (_cur.grffile->airtspec == NULL) {
5365 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5366 return;
5367 }
5368
5369 for (uint i = 0; i < idcount; i++) {
5370 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5371
5372 if (airtsp == NULL) {
5373 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5374 continue;
5375 }
5376
5377 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5378 }
5379 }
5380
5381
5382 /* Action 0x03 */
5383 static void FeatureMapSpriteGroup(ByteReader *buf)
5384 {
5385 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5386 * id-list := [<id>] [id-list]
5387 * cargo-list := <cargo-type> <cid> [cargo-list]
5388 *
5389 * B feature see action 0
5390 * B n-id bits 0-6: how many IDs this definition applies to
5391 * bit 7: if set, this is a wagon override definition (see below)
5392 * B ids the IDs for which this definition applies
5393 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5394 * can be zero, in that case the def-cid is used always
5395 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5396 * W cid cargo ID (sprite group ID) for this type of cargo
5397 * W def-cid default cargo ID (sprite group ID) */
5398
5399 uint8 feature = buf->ReadByte();
5400 uint8 idcount = buf->ReadByte();
5401
5402 /* If idcount is zero, this is a feature callback */
5403 if (idcount == 0) {
5404 /* Skip number of cargo ids? */
5405 buf->ReadByte();
5406 uint16 groupid = buf->ReadWord();
5407 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
5408
5409 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
5410
5411 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5412 return;
5413 }
5414
5415 /* Mark the feature as used by the grf (generic callbacks do not count) */
5416 SetBit(_cur.grffile->grf_features, feature);
5417
5418 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
5419
5420 switch (feature) {
5421 case GSF_TRAINS:
5422 case GSF_ROADVEHICLES:
5423 case GSF_SHIPS:
5424 case GSF_AIRCRAFT:
5425 VehicleMapSpriteGroup(buf, feature, idcount);
5426 return;
5427
5428 case GSF_CANALS:
5429 CanalMapSpriteGroup(buf, idcount);
5430 return;
5431
5432 case GSF_STATIONS:
5433 StationMapSpriteGroup(buf, idcount);
5434 return;
5435
5436 case GSF_HOUSES:
5437 TownHouseMapSpriteGroup(buf, idcount);
5438 return;
5439
5440 case GSF_INDUSTRIES:
5441 IndustryMapSpriteGroup(buf, idcount);
5442 return;
5443
5444 case GSF_INDUSTRYTILES:
5445 IndustrytileMapSpriteGroup(buf, idcount);
5446 return;
5447
5448 case GSF_CARGOES:
5449 CargoMapSpriteGroup(buf, idcount);
5450 return;
5451
5452 case GSF_AIRPORTS:
5453 AirportMapSpriteGroup(buf, idcount);
5454 return;
5455
5456 case GSF_OBJECTS:
5457 ObjectMapSpriteGroup(buf, idcount);
5458 break;
5459
5460 case GSF_RAILTYPES:
5461 RailTypeMapSpriteGroup(buf, idcount);
5462 break;
5463
5464 case GSF_AIRPORTTILES:
5465 AirportTileMapSpriteGroup(buf, idcount);
5466 return;
5467
5468 default:
5469 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
5470 return;
5471 }
5472 }
5473
5474 /* Action 0x04 */
5475 static void FeatureNewName(ByteReader *buf)
5476 {
5477 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5478 *
5479 * B veh-type see action 0 (as 00..07, + 0A
5480 * But IF veh-type = 48, then generic text
5481 * B language-id If bit 6 is set, This is the extended language scheme,
5482 * with up to 64 language.
5483 * Otherwise, it is a mapping where set bits have meaning
5484 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5485 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5486 * B num-veh number of vehicles which are getting a new name
5487 * B/W offset number of the first vehicle that gets a new name
5488 * Byte : ID of vehicle to change
5489 * Word : ID of string to change/add
5490 * S data new texts, each of them zero-terminated, after
5491 * which the next name begins. */
5492
5493 bool new_scheme = _cur.grffile->grf_version >= 7;
5494
5495 uint8 feature = buf->ReadByte();
5496 uint8 lang = buf->ReadByte();
5497 uint8 num = buf->ReadByte();
5498 bool generic = HasBit(lang, 7);
5499 uint16 id;
5500 if (generic) {
5501 id = buf->ReadWord();
5502 } else if (feature <= GSF_AIRCRAFT) {
5503 id = buf->ReadExtendedByte();
5504 } else {
5505 id = buf->ReadByte();
5506 }
5507
5508 ClrBit(lang, 7);
5509
5510 uint16 endid = id + num;
5511
5512 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5513 id, endid, feature, lang);
5514
5515 for (; id < endid && buf->HasData(); id++) {
5516 const char *name = buf->ReadString();
5517 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5518
5519 switch (feature) {
5520 case GSF_TRAINS:
5521 case GSF_ROADVEHICLES:
5522 case GSF_SHIPS:
5523 case GSF_AIRCRAFT:
5524 if (!generic) {
5525 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
5526 if (e == NULL) break;
5527 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
5528 e->info.string_id = string;
5529 } else {
5530 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5531 }
5532 break;
5533
5534 default:
5535 if (IsInsideMM(id, 0xD000, 0xD400) || IsInsideMM(id, 0xD800, 0xE000)) {
5536 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5537 break;
5538 }
5539
5540 switch (GB(id, 8, 8)) {
5541 case 0xC4: // Station class name
5542 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5543 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5544 } else {
5545 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
5546 StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5547 }
5548 break;
5549
5550 case 0xC5: // Station name
5551 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5552 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5553 } else {
5554 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5555 }
5556 break;
5557
5558 case 0xC7: // Airporttile name
5559 if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
5560 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
5561 } else {
5562 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5563 }
5564 break;
5565
5566 case 0xC9: // House name
5567 if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
5568 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
5569 } else {
5570 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5571 }
5572 break;
5573
5574 default:
5575 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
5576 break;
5577 }
5578 break;
5579 }
5580 }
5581 }
5582
5591 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
5592 {
5593
5594 if (offset >= max_sprites) {
5595 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
5596 uint orig_num = num;
5597 num = 0;
5598 return orig_num;
5599 }
5600
5601 if (offset + num > max_sprites) {
5602 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
5603 uint orig_num = num;
5604 num = max(max_sprites - offset, 0);
5605 return orig_num - num;
5606 }
5607
5608 return 0;
5609 }
5610
5611
5613 enum Action5BlockType {
5614 A5BLOCK_FIXED,
5615 A5BLOCK_ALLOW_OFFSET,
5616 A5BLOCK_INVALID,
5617 };
5619 struct Action5Type {
5620 Action5BlockType block_type;
5621 SpriteID sprite_base;
5622 uint16 min_sprites;
5623 uint16 max_sprites;
5624 const char *name;
5625 };
5626
5628 static const Action5Type _action5_types[] = {
5629 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5630 /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
5631 /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
5632 /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
5633 /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
5634 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
5635 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Rail catenary graphics" },
5636 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
5637 /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5638 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
5639 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
5640 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
5641 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
5642 /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5643 /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
5644 /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5645 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
5646 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
5647 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
5648 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
5649 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
5650 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
5651 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
5652 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
5653 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
5654 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET, SPR_PALETTE_BASE, 1, PALETTE_SPRITE_COUNT, "Palette" },
5655 };
5656
5657 /* Action 0x05 */
5658 static void GraphicsNew(ByteReader *buf)
5659 {
5660 /* <05> <graphics-type> <num-sprites> <other data...>
5661 *
5662 * B graphics-type What set of graphics the sprites define.
5663 * E num-sprites How many sprites are in this set?
5664 * V other data Graphics type specific data. Currently unused. */
5665 /* TODO */
5666
5667 uint8 type = buf->ReadByte();
5668 uint16 num = buf->ReadExtendedByte();
5669 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
5670 ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
5671
5672 if ((type == 0x0D) && (num == 10) && HasBit(_cur.grfconfig->flags, GCF_SYSTEM)) {
5673 /* Special not-TTDP-compatible case used in openttd.grf
5674 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5675 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5676 LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_S
5677 LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_W
5678 LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_WSE
5679 LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_N
5680 LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NWS
5681 LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_ENW
5682 LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_SEN
5683 LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_E
5684 LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_EW
5685 LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NS
5686 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
5687 return;
5688 }
5689
5690 /* Supported type? */
5691 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
5692 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
5693 _cur.skip_sprites = num;
5694 return;
5695 }
5696
5697 const Action5Type *action5_type = &_action5_types[type];
5698
5699 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5700 * except for the long version of the shore type:
5701 * Ignore offset if not allowed */
5702 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
5703 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
5704 offset = 0;
5705 }
5706
5707 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5708 * This does not make sense, if <offset> is allowed */
5709 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
5710 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);
5711 _cur.skip_sprites = num;
5712 return;
5713 }
5714
5715 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5716 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
5717 SpriteID replace = action5_type->sprite_base + offset;
5718
5719 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5720 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);
5721
5722 for (; num > 0; num--) {
5723 _cur.nfo_line++;
5724 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
5725 }
5726
5727 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
5728
5729 _cur.skip_sprites = skip_num;
5730 }
5731
5732 /* Action 0x05 (SKIP) */
5733 static void SkipAct5(ByteReader *buf)
5734 {
5735 /* Ignore type byte */
5736 buf->ReadByte();
5737
5738 /* Skip the sprites of this action */
5739 _cur.skip_sprites = buf->ReadExtendedByte();
5740
5741 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
5742 }
5743
5755 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
5756 {
5757 switch (param) {
5758 case 0x00: // current date
5759 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
5760 return true;
5761
5762 case 0x01: // current year
5763 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
5764 return true;
5765
5766 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)
5767 YearMonthDay ymd;
5768 ConvertDateToYMD(_date, &ymd);
5769 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
5770 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
5771 return true;
5772 }
5773
5774 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5775 *value = _settings_game.game_creation.landscape;
5776 return true;
5777
5778 case 0x06: // road traffic side, bit 4 clear=left, set=right
5779 *value = _settings_game.vehicle.road_side << 4;
5780 return true;
5781
5782 case 0x09: // date fraction
5783 *value = _date_fract * 885;
5784 return true;
5785
5786 case 0x0A: // animation counter
5787 *value = _tick_counter;
5788 return true;
5789
5790 case 0x0B: { // TTDPatch version
5791 uint major = 2;
5792 uint minor = 6;
5793 uint revision = 1; // special case: 2.0.1 is 2.0.10
5794 uint build = 1382;
5795 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
5796 return true;
5797 }
5798
5799 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5800 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
5801 return true;
5802
5803 case 0x0E: // Y-offset for train sprites
5804 *value = _cur.grffile->traininfo_vehicle_pitch;
5805 return true;
5806
5807 case 0x0F: // Rail track type cost factors
5808 *value = 0;
5809 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
5810 if (_settings_game.vehicle.disable_elrails) {
5811 /* skip elrail multiplier - disabled */
5812 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
5813 } else {
5814 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
5815 /* Skip monorail multiplier - no space in result */
5816 }
5817 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
5818 return true;
5819
5820 case 0x11: // current rail tool type
5821 *value = 0; // constant fake value to avoid desync
5822 return true;
5823
5824 case 0x12: // Game mode
5825 *value = _game_mode;
5826 return true;
5827
5828 /* case 0x13: // Tile refresh offset to left not implemented */
5829 /* case 0x14: // Tile refresh offset to right not implemented */
5830 /* case 0x15: // Tile refresh offset upwards not implemented */
5831 /* case 0x16: // Tile refresh offset downwards not implemented */
5832 /* case 0x17: // temperate snow line not implemented */
5833
5834 case 0x1A: // Always -1
5835 *value = UINT_MAX;
5836 return true;
5837
5838 case 0x1B: // Display options
5839 *value = 0x3F; // constant fake value to avoid desync
5840 return true;
5841
5842 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5843 *value = 1;
5844 return true;
5845
5846 case 0x1E: // Miscellaneous GRF features
5847 *value = _misc_grf_features;
5848
5849 /* Add the local flags */
5850 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
5851 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
5852 return true;
5853
5854 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5855
5856 case 0x20: { // snow line height
5857 byte snowline = GetSnowLine();
5858 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= _settings_game.construction.max_heightlevel) {
5859 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
5860 } else {
5861 /* No snow */
5862 *value = 0xFF;
5863 }
5864 return true;
5865 }
5866
5867 case 0x21: // OpenTTD version
5868 *value = _openttd_newgrf_version;
5869 return true;
5870
5871 case 0x22: // difficulty level
5872 *value = SP_CUSTOM;
5873 return true;
5874
5875 case 0x23: // long format date
5876 *value = _date;
5877 return true;
5878
5879 case 0x24: // long format year
5880 *value = _cur_year;
5881 return true;
5882
5883 default: return false;
5884 }
5885 }
5886
5887 static uint32 GetParamVal(byte param, uint32 *cond_val)
5888 {
5889 /* First handle variable common with VarAction2 */
5890 uint32 value;
5891 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
5892
5893 /* Non-common variable */
5894 switch (param) {
5895 case 0x84: { // GRF loading stage
5896 uint32 res = 0;
5897
5898 if (_cur.stage > GLS_INIT) SetBit(res, 0);
5899 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
5900 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
5901 return res;
5902 }
5903
5904 case 0x85: // TTDPatch flags, only for bit tests
5905 if (cond_val == NULL) {
5906 /* Supported in Action 0x07 and 0x09, not 0x0D */
5907 return 0;
5908 } else {
5909 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
5910 *cond_val %= 0x20;
5911 return param_val;
5912 }
5913
5914 case 0x88: // GRF ID check
5915 return 0;
5916
5917 /* case 0x99: Global ID offset not implemented */
5918
5919 default:
5920 /* GRF Parameter */
5921 if (param < 0x80) return _cur.grffile->GetParam(param);
5922
5923 /* In-game variable. */
5924 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
5925 return UINT_MAX;
5926 }
5927 }
5928
5929 /* Action 0x06 */
5930 static void CfgApply(ByteReader *buf)
5931 {
5932 /* <06> <param-num> <param-size> <offset> ... <FF>
5933 *
5934 * B param-num Number of parameter to substitute (First = "zero")
5935 * Ignored if that parameter was not specified in newgrf.cfg
5936 * B param-size How many bytes to replace. If larger than 4, the
5937 * bytes of the following parameter are used. In that
5938 * case, nothing is applied unless *all* parameters
5939 * were specified.
5940 * B offset Offset into data from beginning of next sprite
5941 * to place where parameter is to be stored. */
5942
5943 /* Preload the next sprite */
5944 size_t pos = FioGetPos();
5945 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
5946 uint8 type = FioReadByte();
5947 byte *preload_sprite = NULL;
5948
5949 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5950 if (type == 0xFF) {
5951 preload_sprite = MallocT<byte>(num);
5952 FioReadBlock(preload_sprite, num);
5953 }
5954
5955 /* Reset the file position to the start of the next sprite */
5956 FioSeekTo(pos, SEEK_SET);
5957
5958 if (type != 0xFF) {
5959 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5960 free(preload_sprite);
5961 return;
5962 }
5963
5964 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
5965 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
5966 if (it != _grf_line_to_action6_sprite_override.end()) {
5967 free(preload_sprite);
5968 preload_sprite = _grf_line_to_action6_sprite_override[location];
5969 } else {
5970 _grf_line_to_action6_sprite_override[location] = preload_sprite;
5971 }
5972
5973 /* Now perform the Action 0x06 on our data. */
5974
5975 for (;;) {
5976 uint i;
5977 uint param_num;
5978 uint param_size;
5979 uint offset;
5980 bool add_value;
5981
5982 /* Read the parameter to apply. 0xFF indicates no more data to change. */
5983 param_num = buf->ReadByte();
5984 if (param_num == 0xFF) break;
5985
5986 /* Get the size of the parameter to use. If the size covers multiple
5987 * double words, sequential parameter values are used. */
5988 param_size = buf->ReadByte();
5989
5990 /* Bit 7 of param_size indicates we should add to the original value
5991 * instead of replacing it. */
5992 add_value = HasBit(param_size, 7);
5993 param_size = GB(param_size, 0, 7);
5994
5995 /* Where to apply the data to within the pseudo sprite data. */
5996 offset = buf->ReadExtendedByte();
5997
5998 /* If the parameter is a GRF parameter (not an internal variable) check
5999 * if it (and all further sequential parameters) has been defined. */
6000 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
6001 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6002 break;
6003 }
6004
6005 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6006
6007 bool carry = false;
6008 for (i = 0; i < param_size && offset + i < num; i++) {
6009 uint32 value = GetParamVal(param_num + i / 4, NULL);
6010 /* Reset carry flag for each iteration of the variable (only really
6011 * matters if param_size is greater than 4) */
6012 if (i % 4 == 0) carry = false;
6013
6014 if (add_value) {
6015 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6016 preload_sprite[offset + i] = GB(new_value, 0, 8);
6017 /* Check if the addition overflowed */
6018 carry = new_value >= 256;
6019 } else {
6020 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
6021 }
6022 }
6023 }
6024 }
6025
6035 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
6036 {
6037 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
6038 error->data = stredup(_cur.grfconfig->GetName());
6039 }
6040
6041 /* Action 0x07
6042 * Action 0x09 */
6043 static void SkipIf(ByteReader *buf)
6044 {
6045 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6046 *
6047 * B param-num
6048 * B param-size
6049 * B condition-type
6050 * V value
6051 * B num-sprites */
6052 /* TODO: More params. More condition types. */
6053 uint32 cond_val = 0;
6054 uint32 mask = 0;
6055 bool result;
6056
6057 uint8 param = buf->ReadByte();
6058 uint8 paramsize = buf->ReadByte();
6059 uint8 condtype = buf->ReadByte();
6060
6061 if (condtype < 2) {
6062 /* Always 1 for bit tests, the given value should be ignored. */
6063 paramsize = 1;
6064 }
6065
6066 switch (paramsize) {
6067 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6068 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6069 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6070 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6071 default: break;
6072 }
6073
6074 if (param < 0x80 && _cur.grffile->param_end <= param) {
6075 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6076 return;
6077 }
6078
6079 uint32 param_val = GetParamVal(param, &cond_val);
6080
6081 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
6082
6083 /*
6084 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6085 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6086 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6087 * So, when the condition type is one of those, the specific variable
6088 * 0x88 code is skipped, so the "general" code for the cargo
6089 * availability conditions kicks in.
6090 */
6091 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
6092 /* GRF ID checks */
6093
6094 GRFConfig *c = GetGRFConfig(cond_val, mask);
6095
6096 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6097 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6098 c = NULL;
6099 }
6100
6101 if (condtype != 10 && c == NULL) {
6102 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6103 return;
6104 }
6105
6106 switch (condtype) {
6107 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6108 case 0x06: // Is GRFID active?
6109 result = c->status == GCS_ACTIVATED;
6110 break;
6111
6112 case 0x07: // Is GRFID non-active?
6113 result = c->status != GCS_ACTIVATED;
6114 break;
6115
6116 case 0x08: // GRFID is not but will be active?
6117 result = c->status == GCS_INITIALISED;
6118 break;
6119
6120 case 0x09: // GRFID is or will be active?
6121 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6122 break;
6123
6124 case 0x0A: // GRFID is not nor will be active
6125 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6126 result = c == NULL || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6127 break;
6128
6129 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
6130 }
6131 } else {
6132 /* Parameter or variable tests */
6133 switch (condtype) {
6134 case 0x00: result = !!(param_val & (1 << cond_val));
6135 break;
6136 case 0x01: result = !(param_val & (1 << cond_val));
6137 break;
6138 case 0x02: result = (param_val & mask) == cond_val;
6139 break;
6140 case 0x03: result = (param_val & mask) != cond_val;
6141 break;
6142 case 0x04: result = (param_val & mask) < cond_val;
6143 break;
6144 case 0x05: result = (param_val & mask) > cond_val;
6145 break;
6146 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6147 break;
6148 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6149 break;
6150 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6151 break;
6152 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6153 break;
6154
6155 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
6156 }
6157 }
6158
6159 if (!result) {
6160 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6161 return;
6162 }
6163
6164 uint8 numsprites = buf->ReadByte();
6165
6166 /* numsprites can be a GOTO label if it has been defined in the GRF
6167 * file. The jump will always be the first matching label that follows
6168 * the current nfo_line. If no matching label is found, the first matching
6169 * label in the file is used. */
6170 GRFLabel *choice = NULL;
6171 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
6172 if (label->label != numsprites) continue;
6173
6174 /* Remember a goto before the current line */
6175 if (choice == NULL) choice = label;
6176 /* If we find a label here, this is definitely good */
6177 if (label->nfo_line > _cur.nfo_line) {
6178 choice = label;
6179 break;
6180 }
6181 }
6182
6183 if (choice != NULL) {
6184 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6185 FioSeekTo(choice->pos, SEEK_SET);
6186 _cur.nfo_line = choice->nfo_line;
6187 return;
6188 }
6189
6190 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6191 _cur.skip_sprites = numsprites;
6192 if (_cur.skip_sprites == 0) {
6193 /* Zero means there are no sprites to skip, so
6194 * we use -1 to indicate that all further
6195 * sprites should be skipped. */
6196 _cur.skip_sprites = -1;
6197
6198 /* If an action 8 hasn't been encountered yet, disable the grf. */
6199 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6200 DisableGrf();
6201 }
6202 }
6203 }
6204
6205
6206 /* Action 0x08 (GLS_FILESCAN) */
6207 static void ScanInfo(ByteReader *buf)
6208 {
6209 uint8 grf_version = buf->ReadByte();
6210 uint32 grfid = buf->ReadDWord();
6211 const char *name = buf->ReadString();
6212
6213 _cur.grfconfig->ident.grfid = grfid;
6214
6215 if (grf_version < 2 || grf_version > 8) {
6216 SetBit(_cur.grfconfig->flags, GCF_INVALID);
6217 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);
6218 }
6219
6220 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6221 if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6222
6223 AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
6224
6225 if (buf->HasData()) {
6226 const char *info = buf->ReadString();
6227 AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
6228 }
6229
6230 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6231 _cur.skip_sprites = -1;
6232 }
6233
6234 /* Action 0x08 */
6235 static void GRFInfo(ByteReader *buf)
6236 {
6237 /* <08> <version> <grf-id> <name> <info>
6238 *
6239 * B version newgrf version, currently 06
6240 * 4*B grf-id globally unique ID of this .grf file
6241 * S name name of this .grf set
6242 * S info string describing the set, and e.g. author and copyright */
6243
6244 uint8 version = buf->ReadByte();
6245 uint32 grfid = buf->ReadDWord();
6246 const char *name = buf->ReadString();
6247
6248 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6249 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6250 return;
6251 }
6252
6253 if (_cur.grffile->grfid != grfid) {
6254 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));
6255 _cur.grffile->grfid = grfid;
6256 }
6257
6258 _cur.grffile->grf_version = version;
6259 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6260
6261 /* Do swap the GRFID for displaying purposes since people expect that */
6262 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);
6263 }
6264
6265 /* Action 0x0A */
6266 static void SpriteReplace(ByteReader *buf)
6267 {
6268 /* <0A> <num-sets> <set1> [<set2> ...]
6269 * <set>: <num-sprites> <first-sprite>
6270 *
6271 * B num-sets How many sets of sprites to replace.
6272 * Each set:
6273 * B num-sprites How many sprites are in this set
6274 * W first-sprite First sprite number to replace */
6275
6276 uint8 num_sets = buf->ReadByte();
6277
6278 for (uint i = 0; i < num_sets; i++) {
6279 uint8 num_sprites = buf->ReadByte();
6280 uint16 first_sprite = buf->ReadWord();
6281
6282 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6283 i, num_sprites, first_sprite
6284 );
6285
6286 for (uint j = 0; j < num_sprites; j++) {
6287 int load_index = first_sprite + j;
6288 _cur.nfo_line++;
6289 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6290
6291 /* Shore sprites now located at different addresses.
6292 * So detect when the old ones get replaced. */
6293 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6294 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
6295 }
6296 }
6297 }
6298 }
6299
6300 /* Action 0x0A (SKIP) */
6301 static void SkipActA(ByteReader *buf)
6302 {
6303 uint8 num_sets = buf->ReadByte();
6304
6305 for (uint i = 0; i < num_sets; i++) {
6306 /* Skip the sprites this replaces */
6307 _cur.skip_sprites += buf->ReadByte();
6308 /* But ignore where they go */
6309 buf->ReadWord();
6310 }
6311
6312 grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
6313 }
6314
6315 /* Action 0x0B */
6316 static void GRFLoadError(ByteReader *buf)
6317 {
6318 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6319 *
6320 * B severity 00: notice, contine loading grf file
6321 * 01: warning, continue loading grf file
6322 * 02: error, but continue loading grf file, and attempt
6323 * loading grf again when loading or starting next game
6324 * 03: error, abort loading and prevent loading again in
6325 * the future (only when restarting the patch)
6326 * B language-id see action 4, use 1F for built-in error messages
6327 * B message-id message to show, see below
6328 * S message for custom messages (message-id FF), text of the message
6329 * not present for built-in messages.
6330 * V data additional data for built-in (or custom) messages
6331 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6332
6333 static const StringID msgstr[] = {
6334 STR_NEWGRF_ERROR_VERSION_NUMBER,
6335 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6336 STR_NEWGRF_ERROR_UNSET_SWITCH,
6337 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6338 STR_NEWGRF_ERROR_LOAD_BEFORE,
6339 STR_NEWGRF_ERROR_LOAD_AFTER,
6340 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6341 };
6342
6343 static const StringID sevstr[] = {
6344 STR_NEWGRF_ERROR_MSG_INFO,
6345 STR_NEWGRF_ERROR_MSG_WARNING,
6346 STR_NEWGRF_ERROR_MSG_ERROR,
6347 STR_NEWGRF_ERROR_MSG_FATAL
6348 };
6349
6350 byte severity = buf->ReadByte();
6351 byte lang = buf->ReadByte();
6352 byte message_id = buf->ReadByte();
6353
6354 /* Skip the error if it isn't valid for the current language. */
6355 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
6356
6357 /* Skip the error until the activation stage unless bit 7 of the severity
6358 * is set. */
6359 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6360 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6361 return;
6362 }
6363 ClrBit(severity, 7);
6364
6365 if (severity >= lengthof(sevstr)) {
6366 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6367 severity = 2;
6368 } else if (severity == 3) {
6369 /* This is a fatal error, so make sure the GRF is deactivated and no
6370 * more of it gets loaded. */
6371 DisableGrf();
6372
6373 /* Make sure we show fatal errors, instead of silly infos from before */
6374 delete _cur.grfconfig->error;
6375 _cur.grfconfig->error = NULL;
6376 }
6377
6378 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6379 grfmsg(7, "GRFLoadError: Invalid message id.");
6380 return;
6381 }
6382
6383 if (buf->Remaining() <= 1) {
6384 grfmsg(7, "GRFLoadError: No message data supplied.");
6385 return;
6386 }
6387
6388 /* For now we can only show one message per newgrf file. */
6389 if (_cur.grfconfig->error != NULL) return;
6390
6391 GRFError *error = new GRFError(sevstr[severity]);
6392
6393 if (message_id == 0xFF) {
6394 /* This is a custom error message. */
6395 if (buf->HasData()) {
6396 const char *message = buf->ReadString();
6397
6398 error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, NULL, SCC_RAW_STRING_POINTER);
6399 } else {
6400 grfmsg(7, "GRFLoadError: No custom message supplied.");
6401 error->custom_message = stredup("");
6402 }
6403 } else {
6404 error->message = msgstr[message_id];
6405 }
6406
6407 if (buf->HasData()) {
6408 const char *data = buf->ReadString();
6409
6410 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6411 } else {
6412 grfmsg(7, "GRFLoadError: No message data supplied.");
6413 error->data = stredup("");
6414 }
6415
6416 /* Only two parameter numbers can be used in the string. */
6417 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6418 uint param_number = buf->ReadByte();
6419 error->param_value[i] = _cur.grffile->GetParam(param_number);
6420 }
6421
6422 _cur.grfconfig->error = error;
6423 }
6424
6425 /* Action 0x0C */
6426 static void GRFComment(ByteReader *buf)
6427 {
6428 /* <0C> [<ignored...>]
6429 *
6430 * V ignored Anything following the 0C is ignored */
6431
6432 if (!buf->HasData()) return;
6433
6434 const char *text = buf->ReadString();
6435 grfmsg(2, "GRFComment: %s", text);
6436 }
6437
6438 /* Action 0x0D (GLS_SAFETYSCAN) */
6439 static void SafeParamSet(ByteReader *buf)
6440 {
6441 uint8 target = buf->ReadByte();
6442
6443 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6444 if (target < 0x80 || target == 0x9E) return;
6445
6446 /* GRM could be unsafe, but as here it can only happen after other GRFs
6447 * are loaded, it should be okay. If the GRF tried to use the slots it
6448 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6449 * sprites is considered safe. */
6450
6451 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6452
6453 /* Skip remainder of GRF */
6454 _cur.skip_sprites = -1;
6455 }
6456
6457
6458 static uint32 GetPatchVariable(uint8 param)
6459 {
6460 switch (param) {
6461 /* start year - 1920 */
6462 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
6463
6464 /* freight trains weight factor */
6465 case 0x0E: return _settings_game.vehicle.freight_trains;
6466
6467 /* empty wagon speed increase */
6468 case 0x0F: return 0;
6469
6470 /* plane speed factor; our patch option is reversed from TTDPatch's,
6471 * the following is good for 1x, 2x and 4x (most common?) and...
6472 * well not really for 3x. */
6473 case 0x10:
6474 switch (_settings_game.vehicle.plane_speed) {
6475 default:
6476 case 4: return 1;
6477 case 3: return 2;
6478 case 2: return 2;
6479 case 1: return 4;
6480 }
6481
6482
6483 /* 2CC colourmap base sprite */
6484 case 0x11: return SPR_2CCMAP_BASE;
6485
6486 /* map size: format = -MABXYSS
6487 * M : the type of map
6488 * bit 0 : set : squared map. Bit 1 is now not relevant
6489 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6490 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6491 * clear : X is the bigger edge.
6492 * A : minimum edge(log2) of the map
6493 * B : maximum edge(log2) of the map
6494 * XY : edges(log2) of each side of the map.
6495 * SS : combination of both X and Y, thus giving the size(log2) of the map
6496 */
6497 case 0x13: {
6498 byte map_bits = 0;
6499 byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6500 byte log_Y = MapLogY() - 6;
6501 byte max_edge = max(log_X, log_Y);
6502
6503 if (log_X == log_Y) { // we have a squared map, since both edges are identical
6504 SetBit(map_bits, 0);
6505 } else {
6506 if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
6507 }
6508
6509 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
6510 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
6511 }
6512
6513 /* The maximum height of the map. */
6514 case 0x14:
6515 return _settings_game.construction.max_heightlevel;
6516
6517 /* Extra foundations base sprite */
6518 case 0x15:
6519 return SPR_SLOPES_BASE;
6520
6521 /* Shore base sprite */
6522 case 0x16:
6523 return SPR_SHORE_BASE;
6524
6525 default:
6526 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
6527 return 0;
6528 }
6529 }
6530
6531
6532 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
6533 {
6534 uint start = 0;
6535 uint size = 0;
6536
6537 if (op == 6) {
6538 /* Return GRFID of set that reserved ID */
6539 return grm[_cur.grffile->GetParam(target)];
6540 }
6541
6542 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6543 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
6544
6545 for (uint i = start; i < num_ids; i++) {
6546 if (grm[i] == 0) {
6547 size++;
6548 } else {
6549 if (op == 2 || op == 3) break;
6550 start = i + 1;
6551 size = 0;
6552 }
6553
6554 if (size == count) break;
6555 }
6556
6557 if (size == count) {
6558 /* Got the slot... */
6559 if (op == 0 || op == 3) {
6560 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
6561 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
6562 }
6563 return start;
6564 }
6565
6566 /* Unable to allocate */
6567 if (op != 4 && op != 5) {
6568 /* Deactivate GRF */
6569 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
6570 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6571 return UINT_MAX;
6572 }
6573
6574 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
6575 return UINT_MAX;
6576 }
6577
6578
6580 static void ParamSet(ByteReader *buf)
6581 {
6582 /* <0D> <target> <operation> <source1> <source2> [<data>]
6583 *
6584 * B target parameter number where result is stored
6585 * B operation operation to perform, see below
6586 * B source1 first source operand
6587 * B source2 second source operand
6588 * D data data to use in the calculation, not necessary
6589 * if both source1 and source2 refer to actual parameters
6590 *
6591 * Operations
6592 * 00 Set parameter equal to source1
6593 * 01 Addition, source1 + source2
6594 * 02 Subtraction, source1 - source2
6595 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6596 * 04 Signed multiplication, source1 * source2 (both signed)
6597 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6598 * signed quantity; left shift if positive and right shift if
6599 * negative, source1 is unsigned)
6600 * 06 Signed bit shift, source1 by source2
6601 * (source2 like in 05, and source1 as well)
6602 */
6603
6604 uint8 target = buf->ReadByte();
6605 uint8 oper = buf->ReadByte();
6606 uint32 src1 = buf->ReadByte();
6607 uint32 src2 = buf->ReadByte();
6608
6609 uint32 data = 0;
6610 if (buf->Remaining() >= 4) data = buf->ReadDWord();
6611
6612 /* You can add 80 to the operation to make it apply only if the target
6613 * is not defined yet. In this respect, a parameter is taken to be
6614 * defined if any of the following applies:
6615 * - it has been set to any value in the newgrf(w).cfg parameter list
6616 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6617 * an earlier action D */
6618 if (HasBit(oper, 7)) {
6619 if (target < 0x80 && target < _cur.grffile->param_end) {
6620 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
6621 return;
6622 }
6623
6624 oper = GB(oper, 0, 7);
6625 }
6626
6627 if (src2 == 0xFE) {
6628 if (GB(data, 0, 8) == 0xFF) {
6629 if (data == 0x0000FFFF) {
6630 /* Patch variables */
6631 src1 = GetPatchVariable(src1);
6632 } else {
6633 /* GRF Resource Management */
6634 uint8 op = src1;
6635 uint8 feature = GB(data, 8, 8);
6636 uint16 count = GB(data, 16, 16);
6637
6638 if (_cur.stage == GLS_RESERVE) {
6639 if (feature == 0x08) {
6640 /* General sprites */
6641 if (op == 0) {
6642 /* Check if the allocated sprites will fit below the original sprite limit */
6643 if (_cur.spriteid + count >= 16384) {
6644 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
6645 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6646 return;
6647 }
6648
6649 /* Reserve space at the current sprite ID */
6650 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
6651 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
6652 _cur.spriteid += count;
6653 }
6654 }
6655 /* Ignore GRM result during reservation */
6656 src1 = 0;
6657 } else if (_cur.stage == GLS_ACTIVATION) {
6658 switch (feature) {
6659 case 0x00: // Trains
6660 case 0x01: // Road Vehicles
6661 case 0x02: // Ships
6662 case 0x03: // Aircraft
6663 if (!_settings_game.vehicle.dynamic_engines) {
6664 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
6665 if (_cur.skip_sprites == -1) return;
6666 } else {
6667 /* GRM does not apply for dynamic engine allocation. */
6668 switch (op) {
6669 case 2:
6670 case 3:
6671 src1 = _cur.grffile->GetParam(target);
6672 break;
6673
6674 default:
6675 src1 = 0;
6676 break;
6677 }
6678 }
6679 break;
6680
6681 case 0x08: // General sprites
6682 switch (op) {
6683 case 0:
6684 /* Return space reserved during reservation stage */
6685 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
6686 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
6687 break;
6688
6689 case 1:
6690 src1 = _cur.spriteid;
6691 break;
6692
6693 default:
6694 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
6695 return;
6696 }
6697 break;
6698
6699 case 0x0B: // Cargo
6700 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6701 src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
6702 if (_cur.skip_sprites == -1) return;
6703 break;
6704
6705 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
6706 }
6707 } else {
6708 /* Ignore GRM during initialization */
6709 src1 = 0;
6710 }
6711 }
6712 } else {
6713 /* Read another GRF File's parameter */
6714 const GRFFile *file = GetFileByGRFID(data);
6715 GRFConfig *c = GetGRFConfig(data);
6716 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6717 /* Disable the read GRF if it is a static NewGRF. */
6718 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6719 src1 = 0;
6720 } else if (file == NULL || c == NULL || c->status == GCS_DISABLED) {
6721 src1 = 0;
6722 } else if (src1 == 0xFE) {
6723 src1 = c->version;
6724 } else {
6725 src1 = file->GetParam(src1);
6726 }
6727 }
6728 } else {
6729 /* The source1 and source2 operands refer to the grf parameter number
6730 * like in action 6 and 7. In addition, they can refer to the special
6731 * variables available in action 7, or they can be FF to use the value
6732 * of <data>. If referring to parameters that are undefined, a value
6733 * of 0 is used instead. */
6734 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
6735 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
6736 }
6737
6738 /* TODO: You can access the parameters of another GRF file by using
6739 * source2=FE, source1=the other GRF's parameter number and data=GRF
6740 * ID. This is only valid with operation 00 (set). If the GRF ID
6741 * cannot be found, a value of 0 is used for the parameter value
6742 * instead. */
6743
6744 uint32 res;
6745 switch (oper) {
6746 case 0x00:
6747 res = src1;
6748 break;
6749
6750 case 0x01:
6751 res = src1 + src2;
6752 break;
6753
6754 case 0x02:
6755 res = src1 - src2;
6756 break;
6757
6758 case 0x03:
6759 res = src1 * src2;
6760 break;
6761
6762 case 0x04:
6763 res = (int32)src1 * (int32)src2;
6764 break;
6765
6766 case 0x05:
6767 if ((int32)src2 < 0) {
6768 res = src1 >> -(int32)src2;
6769 } else {
6770 res = src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6771 }
6772 break;
6773
6774 case 0x06:
6775 if ((int32)src2 < 0) {
6776 res = (int32)src1 >> -(int32)src2;
6777 } else {
6778 res = (int32)src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6779 }
6780 break;
6781
6782 case 0x07: // Bitwise AND
6783 res = src1 & src2;
6784 break;
6785
6786 case 0x08: // Bitwise OR
6787 res = src1 | src2;
6788 break;
6789
6790 case 0x09: // Unsigned division
6791 if (src2 == 0) {
6792 res = src1;
6793 } else {
6794 res = src1 / src2;
6795 }
6796 break;
6797
6798 case 0x0A: // Signed divison
6799 if (src2 == 0) {
6800 res = src1;
6801 } else {
6802 res = (int32)src1 / (int32)src2;
6803 }
6804 break;
6805
6806 case 0x0B: // Unsigned modulo
6807 if (src2 == 0) {
6808 res = src1;
6809 } else {
6810 res = src1 % src2;
6811 }
6812 break;
6813
6814 case 0x0C: // Signed modulo
6815 if (src2 == 0) {
6816 res = src1;
6817 } else {
6818 res = (int32)src1 % (int32)src2;
6819 }
6820 break;
6821
6822 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
6823 }
6824
6825 switch (target) {
6826 case 0x8E: // Y-Offset for train sprites
6827 _cur.grffile->traininfo_vehicle_pitch = res;
6828 break;
6829
6830 case 0x8F: { // Rail track type cost factors
6831 extern RailtypeInfo _railtypes[RAILTYPE_END];
6832 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
6833 if (_settings_game.vehicle.disable_elrails) {
6834 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
6835 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
6836 } else {
6837 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
6838 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
6839 }
6840 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
6841 break;
6842 }
6843
6844 /* @todo implement */
6845 case 0x93: // Tile refresh offset to left
6846 case 0x94: // Tile refresh offset to right
6847 case 0x95: // Tile refresh offset upwards
6848 case 0x96: // Tile refresh offset downwards
6849 case 0x97: // Snow line height
6850 case 0x99: // Global ID offset
6851 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6852 break;
6853
6854 case 0x9E: // Miscellaneous GRF features
6855 /* Set train list engine width */
6856 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
6857 /* Remove the local flags from the global flags */
6858 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
6859
6860 /* Only copy safe bits for static grfs */
6861 if (HasBit(_cur.grfconfig->flags, GCF_STATIC)) {
6862 uint32 safe_bits = 0;
6863 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
6864
6865 _misc_grf_features = (_misc_grf_features & ~safe_bits) | (res & safe_bits);
6866 } else {
6867 _misc_grf_features = res;
6868 }
6869 break;
6870
6871 case 0x9F: // locale-dependent settings
6872 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6873 break;
6874
6875 default:
6876 if (target < 0x80) {
6877 _cur.grffile->param[target] = res;
6878 /* param is zeroed by default */
6879 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
6880 } else {
6881 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
6882 }
6883 break;
6884 }
6885 }
6886
6887 /* Action 0x0E (GLS_SAFETYSCAN) */
6888 static void SafeGRFInhibit(ByteReader *buf)
6889 {
6890 /* <0E> <num> <grfids...>
6891 *
6892 * B num Number of GRFIDs that follow
6893 * D grfids GRFIDs of the files to deactivate */
6894
6895 uint8 num = buf->ReadByte();
6896
6897 for (uint i = 0; i < num; i++) {
6898 uint32 grfid = buf->ReadDWord();
6899
6900 /* GRF is unsafe it if tries to deactivate other GRFs */
6901 if (grfid != _cur.grfconfig->ident.grfid) {
6902 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6903
6904 /* Skip remainder of GRF */
6905 _cur.skip_sprites = -1;
6906
6907 return;
6908 }
6909 }
6910 }
6911
6912 /* Action 0x0E */
6913 static void GRFInhibit(ByteReader *buf)
6914 {
6915 /* <0E> <num> <grfids...>
6916 *
6917 * B num Number of GRFIDs that follow
6918 * D grfids GRFIDs of the files to deactivate */
6919
6920 uint8 num = buf->ReadByte();
6921
6922 for (uint i = 0; i < num; i++) {
6923 uint32 grfid = buf->ReadDWord();
6924 GRFConfig *file = GetGRFConfig(grfid);
6925
6926 /* Unset activation flag */
6927 if (file != NULL && file != _cur.grfconfig) {
6928 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
6929 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
6930 error->data = stredup(_cur.grfconfig->GetName());
6931 }
6932 }
6933 }
6934
6936 static void FeatureTownName(ByteReader *buf)
6937 {
6938 /* <0F> <id> <style-name> <num-parts> <parts>
6939 *
6940 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6941 * V style-name Name of the style (only for final definition)
6942 * B num-parts Number of parts in this definition
6943 * V parts The parts */
6944
6945 uint32 grfid = _cur.grffile->grfid;
6946
6947 GRFTownName *townname = AddGRFTownName(grfid);
6948
6949 byte id = buf->ReadByte();
6950 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
6951
6952 if (HasBit(id, 7)) {
6953 /* Final definition */
6954 ClrBit(id, 7);
6955 bool new_scheme = _cur.grffile->grf_version >= 7;
6956
6957 byte lang = buf->ReadByte();
6958
6959 byte nb_gen = townname->nb_gen;
6960 do {
6961 ClrBit(lang, 7);
6962
6963 const char *name = buf->ReadString();
6964
6965 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
6966 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
6967 free(lang_name);
6968
6969 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6970
6971 lang = buf->ReadByte();
6972 } while (lang != 0);
6973 townname->id[nb_gen] = id;
6974 townname->nb_gen++;
6975 }
6976
6977 byte nb = buf->ReadByte();
6978 grfmsg(6, "FeatureTownName: %u parts", nb);
6979
6980 townname->nbparts[id] = nb;
6981 townname->partlist[id] = CallocT<NamePartList>(nb);
6982
6983 for (int i = 0; i < nb; i++) {
6984 byte nbtext = buf->ReadByte();
6985 townname->partlist[id][i].bitstart = buf->ReadByte();
6986 townname->partlist[id][i].bitcount = buf->ReadByte();
6987 townname->partlist[id][i].maxprob = 0;
6988 townname->partlist[id][i].partcount = nbtext;
6989 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
6990 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);
6991
6992 for (int j = 0; j < nbtext; j++) {
6993 byte prob = buf->ReadByte();
6994
6995 if (HasBit(prob, 7)) {
6996 byte ref_id = buf->ReadByte();
6997
6998 if (townname->nbparts[ref_id] == 0) {
6999 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7000 DelGRFTownName(grfid);
7001 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
7002 return;
7003 }
7004
7005 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7006 townname->partlist[id][i].parts[j].data.id = ref_id;
7007 } else {
7008 const char *text = buf->ReadString();
7009 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
7010 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
7011 }
7012 townname->partlist[id][i].parts[j].prob = prob;
7013 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
7014 }
7015 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
7016 }
7017 }
7018
7020 static void DefineGotoLabel(ByteReader *buf)
7021 {
7022 /* <10> <label> [<comment>]
7023 *
7024 * B label The label to define
7025 * V comment Optional comment - ignored */
7026
7027 byte nfo_label = buf->ReadByte();
7028
7029 GRFLabel *label = MallocT<GRFLabel>(1);
7030 label->label = nfo_label;
7031 label->nfo_line = _cur.nfo_line;
7032 label->pos = FioGetPos();
7033 label->next = NULL;
7034
7035 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7036 if (_cur.grffile->label == NULL) {
7037 _cur.grffile->label = label;
7038 } else {
7039 /* Attach the label to the end of the list */
7040 GRFLabel *l;
7041 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
7042 l->next = label;
7043 }
7044
7045 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7046 }
7047
7052 static void ImportGRFSound(SoundEntry *sound)
7053 {
7054 const GRFFile *file;
7055 uint32 grfid = FioReadDword();
7056 SoundID sound_id = FioReadWord();
7057
7058 file = GetFileByGRFID(grfid);
7059 if (file == NULL || file->sound_offset == 0) {
7060 grfmsg(1, "ImportGRFSound: Source file not available");
7061 return;
7062 }
7063
7064 if (sound_id >= file->num_sounds) {
7065 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
7066 return;
7067 }
7068
7069 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7070
7071 *sound = *GetSound(file->sound_offset + sound_id);
7072
7073 /* Reset volume and priority, which TTDPatch doesn't copy */
7074 sound->volume = 128;
7075 sound->priority = 0;
7076 }
7077
7083 static void LoadGRFSound(size_t offs, SoundEntry *sound)
7084 {
7085 /* Set default volume and priority */
7086 sound->volume = 0x80;
7087 sound->priority = 0;
7088
7089 if (offs != SIZE_MAX) {
7090 /* Sound is present in the NewGRF. */
7091 sound->file_slot = _cur.file_index;
7092 sound->file_offset = offs;
7093 sound->grf_container_ver = _cur.grf_container_ver;
7094 }
7095 }
7096
7097 /* Action 0x11 */
7098 static void GRFSound(ByteReader *buf)
7099 {
7100 /* <11> <num>
7101 *
7102 * W num Number of sound files that follow */
7103
7104 uint16 num = buf->ReadWord();
7105 if (num == 0) return;
7106
7107 SoundEntry *sound;
7108 if (_cur.grffile->sound_offset == 0) {
7109 _cur.grffile->sound_offset = GetNumSounds();
7110 _cur.grffile->num_sounds = num;
7111 sound = AllocateSound(num);
7112 } else {
7113 sound = GetSound(_cur.grffile->sound_offset);
7114 }
7115
7116 for (int i = 0; i < num; i++) {
7117 _cur.nfo_line++;
7118
7119 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7120 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7121 bool invalid = i >= _cur.grffile->num_sounds;
7122
7123 size_t offs = FioGetPos();
7124
7125 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7126 byte type = FioReadByte();
7127
7128 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7129 /* Reference to sprite section. */
7130 if (invalid) {
7131 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7132 FioSkipBytes(len);
7133 } else if (len != 4) {
7134 grfmsg(1, "GRFSound: Invalid sprite section import");
7135 FioSkipBytes(len);
7136 } else {
7137 uint32 id = FioReadDword();
7138 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7139 }
7140 continue;
7141 }
7142
7143 if (type != 0xFF) {
7144 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7145 FioSkipBytes(7);
7146 SkipSpriteData(type, len - 8);
7147 continue;
7148 }
7149
7150 if (invalid) {
7151 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7152 FioSkipBytes(len);
7153 }
7154
7155 byte action = FioReadByte();
7156 switch (action) {
7157 case 0xFF:
7158 /* Allocate sound only in init stage. */
7159 if (_cur.stage == GLS_INIT) {
7160 if (_cur.grf_container_ver >= 2) {
7161 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7162 } else {
7163 LoadGRFSound(offs, sound + i);
7164 }
7165 }
7166 FioSkipBytes(len - 1); // already read <action>
7167 break;
7168
7169 case 0xFE:
7170 if (_cur.stage == GLS_ACTIVATION) {
7171 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7172 * importing sounds, so this is probably all wrong... */
7173 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7174 ImportGRFSound(sound + i);
7175 } else {
7176 FioSkipBytes(len - 1); // already read <action>
7177 }
7178 break;
7179
7180 default:
7181 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7182 FioSkipBytes(len - 1); // already read <action>
7183 break;
7184 }
7185 }
7186 }
7187
7188 /* Action 0x11 (SKIP) */
7189 static void SkipAct11(ByteReader *buf)
7190 {
7191 /* <11> <num>
7192 *
7193 * W num Number of sound files that follow */
7194
7195 _cur.skip_sprites = buf->ReadWord();
7196
7197 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
7198 }
7199
7201 static void LoadFontGlyph(ByteReader *buf)
7202 {
7203 /* <12> <num_def> <font_size> <num_char> <base_char>
7204 *
7205 * B num_def Number of definitions
7206 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7207 * B num_char Number of consecutive glyphs
7208 * W base_char First character index */
7209
7210 uint8 num_def = buf->ReadByte();
7211
7212 for (uint i = 0; i < num_def; i++) {
7213 FontSize size = (FontSize)buf->ReadByte();
7214 uint8 num_char = buf->ReadByte();
7215 uint16 base_char = buf->ReadWord();
7216
7217 if (size >= FS_END) {
7218 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7219 }
7220
7221 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7222
7223 for (uint c = 0; c < num_char; c++) {
7224 if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
7225 _cur.nfo_line++;
7226 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7227 }
7228 }
7229 }
7230
7232 static void SkipAct12(ByteReader *buf)
7233 {
7234 /* <12> <num_def> <font_size> <num_char> <base_char>
7235 *
7236 * B num_def Number of definitions
7237 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7238 * B num_char Number of consecutive glyphs
7239 * W base_char First character index */
7240
7241 uint8 num_def = buf->ReadByte();
7242
7243 for (uint i = 0; i < num_def; i++) {
7244 /* Ignore 'size' byte */
7245 buf->ReadByte();
7246
7247 /* Sum up number of characters */
7248 _cur.skip_sprites += buf->ReadByte();
7249
7250 /* Ignore 'base_char' word */
7251 buf->ReadWord();
7252 }
7253
7254 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
7255 }
7256
7258 static void TranslateGRFStrings(ByteReader *buf)
7259 {
7260 /* <13> <grfid> <num-ent> <offset> <text...>
7261 *
7262 * 4*B grfid The GRFID of the file whose texts are to be translated
7263 * B num-ent Number of strings
7264 * W offset First text ID
7265 * S text... Zero-terminated strings */
7266
7267 uint32 grfid = buf->ReadDWord();
7268 const GRFConfig *c = GetGRFConfig(grfid);
7269 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7270 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7271 return;
7272 }
7273
7274 if (c->status == GCS_INITIALISED) {
7275 /* If the file is not active but will be activated later, give an error
7276 * and disable this file. */
7277 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
7278
7279 char tmp[256];
7280 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
7281 error->data = stredup(tmp);
7282
7283 return;
7284 }
7285
7286 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7287 * to be added as a generic string, thus the language id of 0x7F. For this to work
7288 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7289 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7290 * not change anything if a string has been provided specifically for this language. */
7291 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7292 byte num_strings = buf->ReadByte();
7293 uint16 first_id = buf->ReadWord();
7294
7295 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7296 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7297 return;
7298 }
7299
7300 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7301 const char *string = buf->ReadString();
7302
7303 if (StrEmpty(string)) {
7304 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7305 continue;
7306 }
7307
7308 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7309 }
7310 }
7311
7313 static bool ChangeGRFName(byte langid, const char *str)
7314 {
7315 AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
7316 return true;
7317 }
7318
7320 static bool ChangeGRFDescription(byte langid, const char *str)
7321 {
7322 AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
7323 return true;
7324 }
7325
7327 static bool ChangeGRFURL(byte langid, const char *str)
7328 {
7329 AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str);
7330 return true;
7331 }
7332
7334 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7335 {
7336 if (len != 1) {
7337 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7338 buf->Skip(len);
7339 } else {
7340 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7341 }
7342 return true;
7343 }
7344
7346 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7347 {
7348 if (len != 1) {
7349 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7350 buf->Skip(len);
7351 } else {
7352 char data = buf->ReadByte();
7353 GRFPalette pal = GRFP_GRF_UNSET;
7354 switch (data) {
7355 case '*':
7356 case 'A': pal = GRFP_GRF_ANY; break;
7357 case 'W': pal = GRFP_GRF_WINDOWS; break;
7358 case 'D': pal = GRFP_GRF_DOS; break;
7359 default:
7360 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7361 break;
7362 }
7363 if (pal != GRFP_GRF_UNSET) {
7364 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7365 _cur.grfconfig->palette |= pal;
7366 }
7367 }
7368 return true;
7369 }
7370
7372 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7373 {
7374 if (len != 1) {
7375 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7376 buf->Skip(len);
7377 } else {
7378 char data = buf->ReadByte();
7379 GRFPalette pal = GRFP_BLT_UNSET;
7380 switch (data) {
7381 case '8': pal = GRFP_BLT_UNSET; break;
7382 case '3': pal = GRFP_BLT_32BPP; break;
7383 default:
7384 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7385 return true;
7386 }
7387 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7388 _cur.grfconfig->palette |= pal;
7389 }
7390 return true;
7391 }
7392
7394 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7395 {
7396 if (len != 4) {
7397 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7398 buf->Skip(len);
7399 } else {
7400 /* Set min_loadable_version as well (default to minimal compatibility) */
7401 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7402 }
7403 return true;
7404 }
7405
7407 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7408 {
7409 if (len != 4) {
7410 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7411 buf->Skip(len);
7412 } else {
7413 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7414 if (_cur.grfconfig->version == 0) {
7415 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7416 _cur.grfconfig->min_loadable_version = 0;
7417 }
7418 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7419 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7420 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
7421 }
7422 }
7423 return true;
7424 }
7425
7426 static GRFParameterInfo *_cur_parameter;
7427
7429 static bool ChangeGRFParamName(byte langid, const char *str)
7430 {
7431 AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
7432 return true;
7433 }
7434
7436 static bool ChangeGRFParamDescription(byte langid, const char *str)
7437 {
7438 AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
7439 return true;
7440 }
7441
7443 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7444 {
7445 if (len != 1) {
7446 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7447 buf->Skip(len);
7448 } else {
7449 GRFParameterType type = (GRFParameterType)buf->ReadByte();
7450 if (type < PTYPE_END) {
7451 _cur_parameter->type = type;
7452 } else {
7453 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7454 }
7455 }
7456 return true;
7457 }
7458
7460 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7461 {
7462 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7463 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7464 buf->Skip(len);
7465 } else if (len != 8) {
7466 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7467 buf->Skip(len);
7468 } else {
7469 _cur_parameter->min_value = buf->ReadDWord();
7470 _cur_parameter->max_value = buf->ReadDWord();
7471 }
7472 return true;
7473 }
7474
7476 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7477 {
7478 if (len < 1 || len > 3) {
7479 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7480 buf->Skip(len);
7481 } else {
7482 byte param_nr = buf->ReadByte();
7483 if (param_nr >= lengthof(_cur.grfconfig->param)) {
7484 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7485 buf->Skip(len - 1);
7486 } else {
7487 _cur_parameter->param_nr = param_nr;
7488 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
7489 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7490 }
7491 }
7492
7493 return true;
7494 }
7495
7497 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7498 {
7499 if (len != 4) {
7500 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7501 buf->Skip(len);
7502 } else {
7503 _cur_parameter->def_value = buf->ReadDWord();
7504 }
7505 _cur.grfconfig->has_param_defaults = true;
7506 return true;
7507 }
7508
7509 typedef bool (*DataHandler)(size_t, ByteReader *);
7510 typedef bool (*TextHandler)(byte, const char *str);
7511 typedef bool (*BranchHandler)(ByteReader *);
7512
7520 struct AllowedSubtags {
7522 AllowedSubtags() :
7523 id(0),
7524 type(0)
7525 {}
7526
7532 AllowedSubtags(uint32 id, DataHandler handler) :
7533 id(id),
7534 type('B')
7535 {
7536 this->handler.data = handler;
7537 }
7538
7544 AllowedSubtags(uint32 id, TextHandler handler) :
7545 id(id),
7546 type('T')
7547 {
7548 this->handler.text = handler;
7549 }
7550
7556 AllowedSubtags(uint32 id, BranchHandler handler) :
7557 id(id),
7558 type('C')
7559 {
7560 this->handler.call_handler = true;
7561 this->handler.u.branch = handler;
7562 }
7563
7569 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
7570 id(id),
7571 type('C')
7572 {
7573 this->handler.call_handler = false;
7574 this->handler.u.subtags = subtags;
7575 }
7576
7577 uint32 id;
7578 byte type;
7579 union {
7580 DataHandler data;
7581 TextHandler text;
7582 struct {
7583 union {
7584 BranchHandler branch;
7585 AllowedSubtags *subtags;
7586 } u;
7587 bool call_handler;
7588 };
7589 } handler;
7590 };
7591
7592 static bool SkipUnknownInfo(ByteReader *buf, byte type);
7593 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
7594
7601 static bool ChangeGRFParamValueNames(ByteReader *buf)
7602 {
7603 byte type = buf->ReadByte();
7604 while (type != 0) {
7605 uint32 id = buf->ReadDWord();
7606 if (type != 'T' || id > _cur_parameter->max_value) {
7607 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7608 if (!SkipUnknownInfo(buf, type)) return false;
7609 type = buf->ReadByte();
7610 continue;
7611 }
7612
7613 byte langid = buf->ReadByte();
7614 const char *name_string = buf->ReadString();
7615
7616 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
7617 if (val_name != _cur_parameter->value_names.End()) {
7618 AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
7619 } else {
7620 GRFText *list = NULL;
7621 AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
7622 _cur_parameter->value_names.Insert(id, list);
7623 }
7624
7625 type = buf->ReadByte();
7626 }
7627 return true;
7628 }
7629
7631 AllowedSubtags _tags_parameters[] = {
7632 AllowedSubtags('NAME', ChangeGRFParamName),
7633 AllowedSubtags('DESC', ChangeGRFParamDescription),
7634 AllowedSubtags('TYPE', ChangeGRFParamType),
7635 AllowedSubtags('LIMI', ChangeGRFParamLimits),
7636 AllowedSubtags('MASK', ChangeGRFParamMask),
7637 AllowedSubtags('VALU', ChangeGRFParamValueNames),
7638 AllowedSubtags('DFLT', ChangeGRFParamDefault),
7639 AllowedSubtags()
7640 };
7641
7648 static bool HandleParameterInfo(ByteReader *buf)
7649 {
7650 byte type = buf->ReadByte();
7651 while (type != 0) {
7652 uint32 id = buf->ReadDWord();
7653 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
7654 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7655 if (!SkipUnknownInfo(buf, type)) return false;
7656 type = buf->ReadByte();
7657 continue;
7658 }
7659
7660 if (id >= _cur.grfconfig->param_info.Length()) {
7661 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
7662 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
7663 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
7664 }
7665 if (_cur.grfconfig->param_info[id] == NULL) {
7666 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
7667 }
7668 _cur_parameter = _cur.grfconfig->param_info[id];
7669 /* Read all parameter-data and process each node. */
7670 if (!HandleNodes(buf, _tags_parameters)) return false;
7671 type = buf->ReadByte();
7672 }
7673 return true;
7674 }
7675
7677 AllowedSubtags _tags_info[] = {
7678 AllowedSubtags('NAME', ChangeGRFName),
7679 AllowedSubtags('DESC', ChangeGRFDescription),
7680 AllowedSubtags('URL_', ChangeGRFURL),
7681 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
7682 AllowedSubtags('PALS', ChangeGRFPalette),
7683 AllowedSubtags('BLTR', ChangeGRFBlitter),
7684 AllowedSubtags('VRSN', ChangeGRFVersion),
7685 AllowedSubtags('MINV', ChangeGRFMinVersion),
7686 AllowedSubtags('PARA', HandleParameterInfo),
7687 AllowedSubtags()
7688 };
7689
7691 AllowedSubtags _tags_root[] = {
7692 AllowedSubtags('INFO', _tags_info),
7693 AllowedSubtags()
7694 };
7695
7696
7703 static bool SkipUnknownInfo(ByteReader *buf, byte type)
7704 {
7705 /* type and id are already read */
7706 switch (type) {
7707 case 'C': {
7708 byte new_type = buf->ReadByte();
7709 while (new_type != 0) {
7710 buf->ReadDWord(); // skip the id
7711 if (!SkipUnknownInfo(buf, new_type)) return false;
7712 new_type = buf->ReadByte();
7713 }
7714 break;
7715 }
7716
7717 case 'T':
7718 buf->ReadByte(); // lang
7719 buf->ReadString(); // actual text
7720 break;
7721
7722 case 'B': {
7723 uint16 size = buf->ReadWord();
7724 buf->Skip(size);
7725 break;
7726 }
7727
7728 default:
7729 return false;
7730 }
7731
7732 return true;
7733 }
7734
7743 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
7744 {
7745 uint i = 0;
7746 AllowedSubtags *tag;
7747 while ((tag = &subtags[i++])->type != 0) {
7748 if (tag->id != BSWAP32(id) || tag->type != type) continue;
7749 switch (type) {
7750 default: NOT_REACHED();
7751
7752 case 'T': {
7753 byte langid = buf->ReadByte();
7754 return tag->handler.text(langid, buf->ReadString());
7755 }
7756
7757 case 'B': {
7758 size_t len = buf->ReadWord();
7759 if (buf->Remaining() < len) return false;
7760 return tag->handler.data(len, buf);
7761 }
7762
7763 case 'C': {
7764 if (tag->handler.call_handler) {
7765 return tag->handler.u.branch(buf);
7766 }
7767 return HandleNodes(buf, tag->handler.u.subtags);
7768 }
7769 }
7770 }
7771 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
7772 return SkipUnknownInfo(buf, type);
7773 }
7774
7781 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
7782 {
7783 byte type = buf->ReadByte();
7784 while (type != 0) {
7785 uint32 id = buf->ReadDWord();
7786 if (!HandleNode(type, id, buf, subtags)) return false;
7787 type = buf->ReadByte();
7788 }
7789 return true;
7790 }
7791
7796 static void StaticGRFInfo(ByteReader *buf)
7797 {
7798 /* <14> <type> <id> <text/data...> */
7799 HandleNodes(buf, _tags_root);
7800 }
7801
7807 static void GRFUnsafe(ByteReader *buf)
7808 {
7809 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7810
7811 /* Skip remainder of GRF */
7812 _cur.skip_sprites = -1;
7813 }
7814
7815
7817 static void InitializeGRFSpecial()
7818 {
7819 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
7820 | (1 << 0x0D) // newairports
7821 | (1 << 0x0E) // largestations
7822 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
7823 | (0 << 0x10) // loadtime
7824 | (1 << 0x12) // presignals
7825 | (1 << 0x13) // extpresignals
7826 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
7827 | (1 << 0x1B) // multihead
7828 | (1 << 0x1D) // lowmemory
7829 | (1 << 0x1E); // generalfixes
7830
7831 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
7832 | (1 << 0x08) // mammothtrains
7833 | (1 << 0x09) // trainrefit
7834 | (0 << 0x0B) // subsidiaries
7835 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
7836 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7837 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7838 | (1 << 0x14) // bridgespeedlimits
7839 | (1 << 0x16) // eternalgame
7840 | (1 << 0x17) // newtrains
7841 | (1 << 0x18) // newrvs
7842 | (1 << 0x19) // newships
7843 | (1 << 0x1A) // newplanes
7844 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7845 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
7846
7847 _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
7848 | (1 << 0x03) // semaphores
7849 | (1 << 0x0A) // newobjects
7850 | (0 << 0x0B) // enhancedgui
7851 | (0 << 0x0C) // newagerating
7852 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
7853 | (1 << 0x0E) // fullloadany
7854 | (1 << 0x0F) // planespeed
7855 | (0 << 0x10) // moreindustriesperclimate - obsolete
7856 | (0 << 0x11) // moretoylandfeatures
7857 | (1 << 0x12) // newstations
7858 | (1 << 0x13) // tracktypecostdiff
7859 | (1 << 0x14) // manualconvert
7860 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
7861 | (1 << 0x16) // canals
7862 | (1 << 0x17) // newstartyear
7863 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
7864 | (1 << 0x19) // newhouses
7865 | (1 << 0x1A) // newbridges
7866 | (1 << 0x1B) // newtownnames
7867 | (1 << 0x1C) // moreanimation
7868 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
7869 | (1 << 0x1E) // newshistory
7870 | (0 << 0x1F); // custombridgeheads
7871
7872 _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
7873 | (1 << 0x01) // windowsnap
7874 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
7875 | (1 << 0x03) // pathbasedsignalling
7876 | (0 << 0x04) // aichoosechance
7877 | (1 << 0x05) // resolutionwidth
7878 | (1 << 0x06) // resolutionheight
7879 | (1 << 0x07) // newindustries
7880 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
7881 | (0 << 0x09) // townroadbranchprob
7882 | (0 << 0x0A) // tempsnowline
7883 | (1 << 0x0B) // newcargo
7884 | (1 << 0x0C) // enhancemultiplayer
7885 | (1 << 0x0D) // onewayroads
7886 | (1 << 0x0E) // irregularstations
7887 | (1 << 0x0F) // statistics
7888 | (1 << 0x10) // newsounds
7889 | (1 << 0x11) // autoreplace
7890 | (1 << 0x12) // autoslope
7891 | (0 << 0x13) // followvehicle
7892 | (1 << 0x14) // trams
7893 | (0 << 0x15) // enhancetunnels
7894 | (1 << 0x16) // shortrvs
7895 | (1 << 0x17) // articulatedrvs
7896 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
7897 | (1 << 0x1E) // variablerunningcosts
7898 | (1 << 0x1F); // any switch is on
7899 }
7900
7902 static void ResetCustomStations()
7903 {
7904 const GRFFile * const *end = _grf_files.End();
7905 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7906 StationSpec **&stations = (*file)->stations;
7907 if (stations == NULL) continue;
7908 for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
7909 if (stations[i] == NULL) continue;
7910 StationSpec *statspec = stations[i];
7911
7912 delete[] statspec->renderdata;
7913
7914 /* Release platforms and layouts */
7915 if (!statspec->copied_layouts) {
7916 for (uint l = 0; l < statspec->lengths; l++) {
7917 for (uint p = 0; p < statspec->platforms[l]; p++) {
7918 free(statspec->layouts[l][p]);
7919 }
7920 free(statspec->layouts[l]);
7921 }
7922 free(statspec->layouts);
7923 free(statspec->platforms);
7924 }
7925
7926 /* Release this station */
7927 free(statspec);
7928 }
7929
7930 /* Free and reset the station data */
7931 free(stations);
7932 stations = NULL;
7933 }
7934 }
7935
7937 static void ResetCustomHouses()
7938 {
7939 const GRFFile * const *end = _grf_files.End();
7940 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7941 HouseSpec **&housespec = (*file)->housespec;
7942 if (housespec == NULL) continue;
7943 for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
7944 free(housespec[i]);
7945 }
7946
7947 free(housespec);
7948 housespec = NULL;
7949 }
7950 }
7951
7953 static void ResetCustomAirports()
7954 {
7955 const GRFFile * const *end = _grf_files.End();
7956 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7957 AirportSpec **aslist = (*file)->airportspec;
7958 if (aslist != NULL) {
7959 for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
7960 AirportSpec *as = aslist[i];
7961
7962 if (as != NULL) {
7963 /* We need to remove the tiles layouts */
7964 for (int j = 0; j < as->num_table; j++) {
7965 /* remove the individual layouts */
7966 free(as->table[j]);
7967 }
7968 free(as->table);
7969 free(as->depot_table);
7970 free(as->rotation);
7971
7972 free(as);
7973 }
7974 }
7975 free(aslist);
7976 (*file)->airportspec = NULL;
7977 }
7978
7979 AirportTileSpec **&airporttilespec = (*file)->airtspec;
7980 if (airporttilespec != NULL) {
7981 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
7982 free(airporttilespec[i]);
7983 }
7984 free(airporttilespec);
7985 airporttilespec = NULL;
7986 }
7987 }
7988 }
7989
7991 static void ResetCustomIndustries()
7992 {
7993 const GRFFile * const *end = _grf_files.End();
7994 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7995 IndustrySpec **&industryspec = (*file)->industryspec;
7996 IndustryTileSpec **&indtspec = (*file)->indtspec;
7997
7998 /* We are verifiying both tiles and industries specs loaded from the grf file
7999 * First, let's deal with industryspec */
8000 if (industryspec != NULL) {
8001 for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8002 IndustrySpec *ind = industryspec[i];
8003 if (ind == NULL) continue;
8004
8005 /* We need to remove the sounds array */
8006 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
8007 free(ind->random_sounds);
8008 }
8009
8010 /* We need to remove the tiles layouts */
8011 CleanIndustryTileTable(ind);
8012
8013 free(ind);
8014 }
8015
8016 free(industryspec);
8017 industryspec = NULL;
8018 }
8019
8020 if (indtspec == NULL) continue;
8021 for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8022 free(indtspec[i]);
8023 }
8024
8025 free(indtspec);
8026 indtspec = NULL;
8027 }
8028 }
8029
8031 static void ResetCustomObjects()
8032 {
8033 const GRFFile * const *end = _grf_files.End();
8034 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8035 ObjectSpec **&objectspec = (*file)->objectspec;
8036 if (objectspec == NULL) continue;
8037 for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8038 free(objectspec[i]);
8039 }
8040
8041 free(objectspec);
8042 objectspec = NULL;
8043 }
8044 }
8045
8047 static void ResetNewGRF()
8048 {
8049 const GRFFile * const *end = _grf_files.End();
8050 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8051 delete *file;
8052 }
8053
8054 _grf_files.Clear();
8055 _cur.grffile = NULL;
8056 }
8057
8059 static void ResetNewGRFErrors()
8060 {
8061 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
8062 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
8063 delete c->error;
8064 c->error = NULL;
8065 }
8066 }
8067 }
8068
8073 void ResetNewGRFData()
8074 {
8075 CleanUpStrings();
8076 CleanUpGRFTownNames();
8077
8078 /* Copy/reset original engine info data */
8079 SetupEngines();
8080
8081 /* Copy/reset original bridge info data */
8082 ResetBridges();
8083
8084 /* Reset rail type information */
8085 ResetRailTypes();
8086
8087 /* Allocate temporary refit/cargo class data */
8088 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
8089
8090 /* Fill rail type label temporary data for default trains */
8091 Engine *e;
8092 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
8093 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
8094 }
8095
8096 /* Reset GRM reservations */
8097 memset(&_grm_engines, 0, sizeof(_grm_engines));
8098 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
8099
8100 /* Reset generic feature callback lists */
8101 ResetGenericCallbacks();
8102
8103 /* Reset price base data */
8104 ResetPriceBaseMultipliers();
8105
8106 /* Reset the curencies array */
8107 ResetCurrencies();
8108
8109 /* Reset the house array */
8110 ResetCustomHouses();
8111 ResetHouses();
8112
8113 /* Reset the industries structures*/
8114 ResetCustomIndustries();
8115 ResetIndustries();
8116
8117 /* Reset the objects. */
8118 ObjectClass::Reset();
8119 ResetCustomObjects();
8120 ResetObjects();
8121
8122 /* Reset station classes */
8123 StationClass::Reset();
8124 ResetCustomStations();
8125
8126 /* Reset airport-related structures */
8127 AirportClass::Reset();
8128 ResetCustomAirports();
8129 AirportSpec::ResetAirports();
8130 AirportTileSpec::ResetAirportTiles();
8131
8132 /* Reset canal sprite groups and flags */
8133 memset(_water_feature, 0, sizeof(_water_feature));
8134
8135 /* Reset the snowline table. */
8136 ClearSnowLine();
8137
8138 /* Reset NewGRF files */
8139 ResetNewGRF();
8140
8141 /* Reset NewGRF errors. */
8142 ResetNewGRFErrors();
8143
8144 /* Set up the default cargo types */
8145 SetupCargoForClimate(_settings_game.game_creation.landscape);
8146
8147 /* Reset misc GRF features and train list display variables */
8148 _misc_grf_features = 0;
8149
8150 _loaded_newgrf_features.has_2CC = false;
8151 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8152 _loaded_newgrf_features.has_newhouses = false;
8153 _loaded_newgrf_features.has_newindustries = false;
8154 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
8155
8156 /* Clear all GRF overrides */
8157 _grf_id_overrides.clear();
8158
8159 InitializeSoundPool();
8160 _spritegroup_pool.CleanPool();
8161 }
8162
8166 void ResetPersistentNewGRFData()
8167 {
8168 /* Reset override managers */
8169 _engine_mngr.ResetToDefaultMapping();
8170 _house_mngr.ResetMapping();
8171 _industry_mngr.ResetMapping();
8172 _industile_mngr.ResetMapping();
8173 _airport_mngr.ResetMapping();
8174 _airporttile_mngr.ResetMapping();
8175 }
8176
8181 static void BuildCargoTranslationMap()
8182 {
8183 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8184
8185 for (CargoID c = 0; c < NUM_CARGO; c++) {
8186 const CargoSpec *cs = CargoSpec::Get(c);
8187 if (!cs->IsValid()) continue;
8188
8189 if (_cur.grffile->cargo_list.Length() == 0) {
8190 /* Default translation table, so just a straight mapping to bitnum */
8191 _cur.grffile->cargo_map[c] = cs->bitnum;
8192 } else {
8193 /* Check the translation table for this cargo's label */
8194 int index = _cur.grffile->cargo_list.FindIndex(cs->label);
8195 if (index >= 0) _cur.grffile->cargo_map[c] = index;
8196 }
8197 }
8198 }
8199
8204 static void InitNewGRFFile(const GRFConfig *config)
8205 {
8206 GRFFile *newfile = GetFileByFilename(config->filename);
8207 if (newfile != NULL) {
8208 /* We already loaded it once. */
8209 _cur.grffile = newfile;
8210 return;
8211 }
8212
8213 newfile = new GRFFile(config);
8214 *_grf_files.Append() = _cur.grffile = newfile;
8215 }
8216
8221 GRFFile::GRFFile(const GRFConfig *config)
8222 {
8223 this->filename = stredup(config->filename);
8224 this->grfid = config->ident.grfid;
8225
8226 /* Initialise local settings to defaults */
8227 this->traininfo_vehicle_pitch = 0;
8228 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8229
8230 /* Mark price_base_multipliers as 'not set' */
8231 for (Price i = PR_BEGIN; i < PR_END; i++) {
8232 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8233 }
8234
8235 /* Initialise rail type map with default rail types */
8236 memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
8237 this->railtype_map[0] = RAILTYPE_RAIL;
8238 this->railtype_map[1] = RAILTYPE_ELECTRIC;
8239 this->railtype_map[2] = RAILTYPE_MONO;
8240 this->railtype_map[3] = RAILTYPE_MAGLEV;
8241
8242 /* Copy the initial parameter list
8243 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8244 assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8245
8246 assert(config->num_params <= lengthof(config->param));
8247 this->param_end = config->num_params;
8248 if (this->param_end > 0) {
8249 MemCpyT(this->param, config->param, this->param_end);
8250 }
8251 }
8252
8253 GRFFile::~GRFFile()
8254 {
8255 free(this->filename);
8256 delete[] this->language_map;
8257 }
8258
8259
8264 static const CargoLabel _default_refitmasks_rail[] = {
8265 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8266 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8267 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8268 'PLST', 'FZDR',
8269 0 };
8270
8271 static const CargoLabel _default_refitmasks_road[] = {
8272 0 };
8273
8274 static const CargoLabel _default_refitmasks_ships[] = {
8275 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8276 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8277 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8278 'PLST', 'FZDR',
8279 0 };
8280
8281 static const CargoLabel _default_refitmasks_aircraft[] = {
8282 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8283 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8284 0 };
8285
8286 static const CargoLabel * const _default_refitmasks[] = {
8287 _default_refitmasks_rail,
8288 _default_refitmasks_road,
8289 _default_refitmasks_ships,
8290 _default_refitmasks_aircraft,
8291 };
8292
8293
8297 static void CalculateRefitMasks()
8298 {
8299 Engine *e;
8300
8301 FOR_ALL_ENGINES(e) {
8302 EngineID engine = e->index;
8303 EngineInfo *ei = &e->info;
8304 bool only_defaultcargo;
8305
8306 /* Did the newgrf specify any refitting? If not, use defaults. */
8307 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8308 uint32 mask = 0;
8309 uint32 not_mask = 0;
8310 uint32 xor_mask = ei->refit_mask;
8311
8312 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8313 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8314 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8315
8316 if (_gted[engine].cargo_allowed != 0) {
8317 /* Build up the list of cargo types from the set cargo classes. */
8318 const CargoSpec *cs;
8319 FOR_ALL_CARGOSPECS(cs) {
8320 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8321 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8322 }
8323 }
8324
8325 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8326
8327 /* Apply explicit refit includes/excludes. */
8328 ei->refit_mask |= _gted[engine].ctt_include_mask;
8329 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8330 } else {
8331 uint32 xor_mask = 0;
8332
8333 /* Don't apply default refit mask to wagons nor engines with no capacity */
8334 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8335 const CargoLabel *cl = _default_refitmasks[e->type];
8336 for (uint i = 0;; i++) {
8337 if (cl[i] == 0) break;
8338
8339 CargoID cargo = GetCargoIDByLabel(cl[i]);
8340 if (cargo == CT_INVALID) continue;
8341
8342 SetBit(xor_mask, cargo);
8343 }
8344 }
8345
8346 ei->refit_mask = xor_mask & _cargo_mask;
8347
8348 /* If the mask is zero, the vehicle shall only carry the default cargo */
8349 only_defaultcargo = (ei->refit_mask == 0);
8350 }
8351
8352 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8353 if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8354
8355 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8356 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8357 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8358 ei->cargo_type = CT_INVALID;
8359 }
8360
8361 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8362 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8363 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8364 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8365 const uint8 *cargo_map_for_first_refittable = NULL;
8366 {
8367 const GRFFile *file = _gted[engine].defaultcargo_grf;
8368 if (file == NULL) file = e->GetGRF();
8369 if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
8370 cargo_map_for_first_refittable = file->cargo_map;
8371 }
8372 }
8373
8374 if (cargo_map_for_first_refittable != NULL) {
8375 /* Use first refittable cargo from cargo translation table */
8376 byte best_local_slot = 0xFF;
8377 CargoID cargo_type;
8378 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8379 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8380 if (local_slot < best_local_slot) {
8381 best_local_slot = local_slot;
8382 ei->cargo_type = cargo_type;
8383 }
8384 }
8385 }
8386
8387 if (ei->cargo_type == CT_INVALID) {
8388 /* Use first refittable cargo slot */
8389 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8390 }
8391 }
8392 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8393
8394 /* Clear refit_mask for not refittable ships */
8395 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8396 ei->refit_mask = 0;
8397 }
8398 }
8399 }
8400
8402 static void FinaliseCanals()
8403 {
8404 for (uint i = 0; i < CF_END; i++) {
8405 if (_water_feature[i].grffile != NULL) {
8406 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
8407 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
8408 }
8409 }
8410 }
8411
8413 static void FinaliseEngineArray()
8414 {
8415 Engine *e;
8416
8417 FOR_ALL_ENGINES(e) {
8418 if (e->GetGRF() == NULL) {
8419 const EngineIDMapping &eid = _engine_mngr[e->index];
8420 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8421 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8422 }
8423 }
8424
8425 /* When the train does not set property 27 (misc flags), but it
8426 * is overridden by a NewGRF graphically we want to disable the
8427 * flipping possibility. */
8428 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
8429 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8430 }
8431
8432 /* Skip wagons, there livery is defined via the engine */
8433 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8434 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
8435 SetBit(_loaded_newgrf_features.used_liveries, ls);
8436 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8437
8438 if (e->type == VEH_TRAIN) {
8439 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8440 switch (ls) {
8441 case LS_STEAM:
8442 case LS_DIESEL:
8443 case LS_ELECTRIC:
8444 case LS_MONORAIL:
8445 case LS_MAGLEV:
8446 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8447 break;
8448
8449 case LS_DMU:
8450 case LS_EMU:
8451 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8452 break;
8453
8454 default: NOT_REACHED();
8455 }
8456 }
8457 }
8458 }
8459 }
8460
8462 static void FinaliseCargoArray()
8463 {
8464 for (CargoID c = 0; c < NUM_CARGO; c++) {
8465 CargoSpec *cs = CargoSpec::Get(c);
8466 if (!cs->IsValid()) {
8467 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8468 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8469 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8470 }
8471 }
8472 }
8473
8485 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8486 {
8487 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8488 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8489 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8490 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8491 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8492 hs->enabled = false;
8493 if (filename != NULL) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", filename, hs->grf_prop.local_id);
8494 return false;
8495 }
8496
8497 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8498 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8499 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8500 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8501 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8502 hs->enabled = false;
8503 if (filename != NULL) DEBUG(grf, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", filename, hs->grf_prop.local_id);
8504 return false;
8505 }
8506
8507 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8508 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8509 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8510 hs->enabled = false;
8511 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);
8512 return false;
8513 }
8514
8515 /* Make sure that additional parts of multitile houses are not available. */
8516 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
8517 hs->enabled = false;
8518 if (filename != NULL) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d without a size but marked it as available. Disabling house.", filename, hs->grf_prop.local_id);
8519 return false;
8520 }
8521
8522 return true;
8523 }
8524
8531 static void EnsureEarlyHouse(HouseZones bitmask)
8532 {
8533 Year min_year = MAX_YEAR;
8534
8535 for (int i = 0; i < NUM_HOUSES; i++) {
8536 HouseSpec *hs = HouseSpec::Get(i);
8537 if (hs == NULL || !hs->enabled) continue;
8538 if ((hs->building_availability & bitmask) != bitmask) continue;
8539 if (hs->min_year < min_year) min_year = hs->min_year;
8540 }
8541
8542 if (min_year == 0) return;
8543
8544 for (int i = 0; i < NUM_HOUSES; i++) {
8545 HouseSpec *hs = HouseSpec::Get(i);
8546 if (hs == NULL || !hs->enabled) continue;
8547 if ((hs->building_availability & bitmask) != bitmask) continue;
8548 if (hs->min_year == min_year) hs->min_year = 0;
8549 }
8550 }
8551
8558 static void FinaliseHouseArray()
8559 {
8560 /* If there are no houses with start dates before 1930, then all houses
8561 * with start dates of 1930 have them reset to 0. This is in order to be
8562 * compatible with TTDPatch, where if no houses have start dates before
8563 * 1930 and the date is before 1930, the game pretends that this is 1930.
8564 * If there have been any houses defined with start dates before 1930 then
8565 * the dates are left alone.
8566 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8567 * minimum introduction date to 0.
8568 */
8569 const GRFFile * const *end = _grf_files.End();
8570 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8571 HouseSpec **&housespec = (*file)->housespec;
8572 if (housespec == NULL) continue;
8573
8574 for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8575 HouseSpec *hs = housespec[i];
8576
8577 if (hs == NULL) continue;
8578
8579 const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : NULL);
8580 const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : NULL);
8581 const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : NULL);
8582
8583 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
8584
8585 _house_mngr.SetEntitySpec(hs);
8586 }
8587 }
8588
8589 for (int i = 0; i < NUM_HOUSES; i++) {
8590 HouseSpec *hs = HouseSpec::Get(i);
8591 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : NULL);
8592 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : NULL);
8593 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : NULL);
8594
8595 /* We need to check all houses again to we are sure that multitile houses
8596 * did get consecutive IDs and none of the parts are missing. */
8597 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
8598 /* GetHouseNorthPart checks 3 houses that are directly before
8599 * it in the house pool. If any of those houses have multi-tile
8600 * flags set it assumes it's part of a multitile house. Since
8601 * we can have invalid houses in the pool marked as disabled, we
8602 * don't want to have them influencing valid tiles. As such set
8603 * building_flags to zero here to make sure any house following
8604 * this one in the pool is properly handled as 1x1 house. */
8605 hs->building_flags = TILE_NO_FLAG;
8606 }
8607 }
8608
8609 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
8610 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
8611 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
8612 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
8613 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
8614 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
8615
8616 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
8617 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
8618 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
8619 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
8620 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
8621 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
8622 }
8623 }
8624
8630 static void FinaliseIndustriesArray()
8631 {
8632 const GRFFile * const *end = _grf_files.End();
8633 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8634 IndustrySpec **&industryspec = (*file)->industryspec;
8635 IndustryTileSpec **&indtspec = (*file)->indtspec;
8636 if (industryspec != NULL) {
8637 for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8638 IndustrySpec *indsp = industryspec[i];
8639
8640 if (indsp != NULL && indsp->enabled) {
8641 StringID strid;
8642 /* process the conversion of text at the end, so to be sure everything will be fine
8643 * and available. Check if it does not return undefind marker, which is a very good sign of a
8644 * substitute industry who has not changed the string been examined, thus using it as such */
8645 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
8646 if (strid != STR_UNDEFINED) indsp->name = strid;
8647
8648 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
8649 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
8650
8651 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
8652 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
8653
8654 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
8655 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
8656
8657 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
8658 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
8659
8660 if (indsp->station_name != STR_NULL) {
8661 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8662 * station's name. Don't want to lose the value, therefore, do not process. */
8663 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
8664 if (strid != STR_UNDEFINED) indsp->station_name = strid;
8665 }
8666
8667 _industry_mngr.SetEntitySpec(indsp);
8668 _loaded_newgrf_features.has_newindustries = true;
8669 }
8670 }
8671 }
8672
8673 if (indtspec != NULL) {
8674 for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8675 IndustryTileSpec *indtsp = indtspec[i];
8676 if (indtsp != NULL) {
8677 _industile_mngr.SetEntitySpec(indtsp);
8678 }
8679 }
8680 }
8681 }
8682
8683 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
8684 IndustrySpec *indsp = &_industry_specs[j];
8685 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
8686 for (uint i = 0; i < 3; i++) {
8687 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
8688 }
8689 }
8690 if (!indsp->enabled) {
8691 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
8692 }
8693 }
8694 }
8695
8701 static void FinaliseObjectsArray()
8702 {
8703 const GRFFile * const *end = _grf_files.End();
8704 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8705 ObjectSpec **&objectspec = (*file)->objectspec;
8706 if (objectspec != NULL) {
8707 for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8708 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
8709 _object_mngr.SetEntitySpec(objectspec[i]);
8710 }
8711 }
8712 }
8713 }
8714 }
8715
8721 static void FinaliseAirportsArray()
8722 {
8723 const GRFFile * const *end = _grf_files.End();
8724 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8725 AirportSpec **&airportspec = (*file)->airportspec;
8726 if (airportspec != NULL) {
8727 for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8728 if (airportspec[i] != NULL && airportspec[i]->enabled) {
8729 _airport_mngr.SetEntitySpec(airportspec[i]);
8730 }
8731 }
8732 }
8733
8734 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8735 if (airporttilespec != NULL) {
8736 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8737 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
8738 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
8739 }
8740 }
8741 }
8742 }
8743 }
8744
8745 /* Here we perform initial decoding of some special sprites (as are they
8746 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8747 * partial implementation yet).
8748 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8749 * a crafted invalid GRF file. We should tell that to the user somehow, or
8750 * better make this more robust in the future. */
8751 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
8752 {
8753 /* XXX: There is a difference between staged loading in TTDPatch and
8754 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8755 * during stage 1, whilst action 3 is carried out during stage 2 (to
8756 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8757 * IDs are valid only within a given set (action 1) block, and may be
8758 * overwritten after action 3 associates them. But overwriting happens
8759 * in an earlier stage than associating, so... We just process actions
8760 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8761 * --pasky
8762 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8763 * is not in memory and scanning the file every time would be too expensive.
8764 * In other stages we skip action 0x10 since it's already dealt with. */
8765 static const SpecialSpriteHandler handlers[][GLS_END] = {
8766 /* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
8767 /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
8768 /* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
8769 /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
8770 /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
8771 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
8772 /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
8773 /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
8774 /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
8775 /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
8776 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
8777 /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
8778 /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
8779 /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
8780 /* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
8781 /* 0x0F */ { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
8782 /* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
8783 /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
8784 /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
8785 /* 0x13 */ { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
8786 /* 0x14 */ { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
8787 };
8788
8789 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
8790
8791 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
8792 if (it == _grf_line_to_action6_sprite_override.end()) {
8793 /* No preloaded sprite to work with; read the
8794 * pseudo sprite content. */
8795 FioReadBlock(buf, num);
8796 } else {
8797 /* Use the preloaded sprite data. */
8798 buf = _grf_line_to_action6_sprite_override[location];
8799 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8800
8801 /* Skip the real (original) content of this action. */
8802 FioSeekTo(num, SEEK_CUR);
8803 }
8804
8805 ByteReader br(buf, buf + num);
8806 ByteReader *bufp = &br;
8807
8808 try {
8809 byte action = bufp->ReadByte();
8810
8811 if (action == 0xFF) {
8812 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8813 } else if (action == 0xFE) {
8814 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8815 } else if (action >= lengthof(handlers)) {
8816 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
8817 } else if (handlers[action][stage] == NULL) {
8818 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
8819 } else {
8820 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
8821 handlers[action][stage](bufp);
8822 }
8823 } catch (...) {
8824 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8825 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
8826 }
8827 }
8828
8829
8831 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8832
8837 byte GetGRFContainerVersion()
8838 {
8839 size_t pos = FioGetPos();
8840
8841 if (FioReadWord() == 0) {
8842 /* Check for GRF container version 2, which is identified by the bytes
8843 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8844 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
8845 if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
8846 }
8847
8848 return 2;
8849 }
8850
8851 /* Container version 1 has no header, rewind to start. */
8852 FioSeekTo(pos, SEEK_SET);
8853 return 1;
8854 }
8855
8863 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
8864 {
8865 const char *filename = config->filename;
8866
8867 /* A .grf file is activated only if it was active when the game was
8868 * started. If a game is loaded, only its active .grfs will be
8869 * reactivated, unless "loadallgraphics on" is used. A .grf file is
8870 * considered active if its action 8 has been processed, i.e. its
8871 * action 8 hasn't been skipped using an action 7.
8872 *
8873 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
8874 * carried out. All others are ignored, because they only need to be
8875 * processed once at initialization. */
8876 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
8877 _cur.grffile = GetFileByFilename(filename);
8878 if (_cur.grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
8879 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
8880 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
8881 }
8882
8883 if (file_index >= MAX_FILE_SLOTS) {
8884 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of file slots has been reached", filename);
8885 config->status = GCS_DISABLED;
8886 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
8887 return;
8888 }
8889
8890 FioOpenFile(file_index, filename, subdir);
8891 _cur.file_index = file_index; // XXX
8892 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
8893
8894 _cur.grfconfig = config;
8895
8896 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
8897
8898 _cur.grf_container_ver = GetGRFContainerVersion();
8899 if (_cur.grf_container_ver == 0) {
8900 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8901 return;
8902 }
8903
8904 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
8905 /* We need the sprite offsets in the init stage for NewGRF sounds
8906 * and in the activation stage for real sprites. */
8907 ReadGRFSpriteOffsets(_cur.grf_container_ver);
8908 } else {
8909 /* Skip sprite section offset if present. */
8910 if (_cur.grf_container_ver >= 2) FioReadDword();
8911 }
8912
8913 if (_cur.grf_container_ver >= 2) {
8914 /* Read compression value. */
8915 byte compression = FioReadByte();
8916 if (compression != 0) {
8917 DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
8918 return;
8919 }
8920 }
8921
8922 /* Skip the first sprite; we don't care about how many sprites this
8923 * does contain; newest TTDPatches and George's longvehicles don't
8924 * neither, apparently. */
8925 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
8926 if (num == 4 && FioReadByte() == 0xFF) {
8927 FioReadDword();
8928 } else {
8929 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8930 return;
8931 }
8932
8933 _cur.ClearDataForNextFile();
8934
8935 ReusableBuffer<byte> buf;
8936
8937 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
8938 byte type = FioReadByte();
8939 _cur.nfo_line++;
8940
8941 if (type == 0xFF) {
8942 if (_cur.skip_sprites == 0) {
8943 DecodeSpecialSprite(buf.Allocate(num), num, stage);
8944
8945 /* Stop all processing if we are to skip the remaining sprites */
8946 if (_cur.skip_sprites == -1) break;
8947
8948 continue;
8949 } else {
8950 FioSkipBytes(num);
8951 }
8952 } else {
8953 if (_cur.skip_sprites == 0) {
8954 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8955 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
8956 break;
8957 }
8958
8959 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
8960 /* Reference to data section. Container version >= 2 only. */
8961 FioSkipBytes(num);
8962 } else {
8963 FioSkipBytes(7);
8964 SkipSpriteData(type, num - 8);
8965 }
8966 }
8967
8968 if (_cur.skip_sprites > 0) _cur.skip_sprites--;
8969 }
8970 }
8971
8979 static void ActivateOldShore()
8980 {
8981 /* Use default graphics, if no shore sprites were loaded.
8982 * Should not happen, as the base set's extra grf should include some. */
8983 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
8984
8985 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
8986 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
8987 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
8988 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
8989 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
8990 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
8991 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
8992 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
8993 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
8994 }
8995
8996 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
8997 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
8998 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
8999 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
9000 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
9001 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
9002 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
9003 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
9004 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
9005
9006 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
9007 * If they would be used somewhen, then these grass tiles will most like not look as needed */
9008 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
9009 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
9010 }
9011 }
9012
9016 static void FinalisePriceBaseMultipliers()
9017 {
9018 extern const PriceBaseSpec _price_base_specs[];
9020 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9021
9022 /* Evaluate grf overrides */
9023 int num_grfs = _grf_files.Length();
9024 int *grf_overrides = AllocaM(int, num_grfs);
9025 for (int i = 0; i < num_grfs; i++) {
9026 grf_overrides[i] = -1;
9027
9028 GRFFile *source = _grf_files[i];
9029 uint32 override = _grf_id_overrides[source->grfid];
9030 if (override == 0) continue;
9031
9032 GRFFile *dest = GetFileByGRFID(override);
9033 if (dest == NULL) continue;
9034
9035 grf_overrides[i] = _grf_files.FindIndex(dest);
9036 assert(grf_overrides[i] >= 0);
9037 }
9038
9039 /* Override features and price base multipliers of earlier loaded grfs */
9040 for (int i = 0; i < num_grfs; i++) {
9041 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
9042 GRFFile *source = _grf_files[i];
9043 GRFFile *dest = _grf_files[grf_overrides[i]];
9044
9045 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9046 source->grf_features |= features;
9047 dest->grf_features |= features;
9048
9049 for (Price p = PR_BEGIN; p < PR_END; p++) {
9050 /* No price defined -> nothing to do */
9051 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
9052 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9053 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9054 }
9055 }
9056
9057 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9058 for (int i = num_grfs - 1; i >= 0; i--) {
9059 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
9060 GRFFile *source = _grf_files[i];
9061 GRFFile *dest = _grf_files[grf_overrides[i]];
9062
9063 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9064 source->grf_features |= features;
9065 dest->grf_features |= features;
9066
9067 for (Price p = PR_BEGIN; p < PR_END; p++) {
9068 /* Already a price defined -> nothing to do */
9069 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
9070 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9071 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9072 }
9073 }
9074
9075 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9076 for (int i = 0; i < num_grfs; i++) {
9077 if (grf_overrides[i] < 0) continue;
9078 GRFFile *source = _grf_files[i];
9079 GRFFile *dest = _grf_files[grf_overrides[i]];
9080
9081 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9082 source->grf_features |= features;
9083 dest->grf_features |= features;
9084
9085 for (Price p = PR_BEGIN; p < PR_END; p++) {
9086 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
9087 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
9088 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9089 }
9090 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
9091 }
9092 }
9093
9094 /* Apply fallback prices for grf version < 8 */
9095 const GRFFile * const *end = _grf_files.End();
9096 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9097 if ((*file)->grf_version >= 8) continue;
9098 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9099 for (Price p = PR_BEGIN; p < PR_END; p++) {
9100 Price fallback_price = _price_base_specs[p].fallback_price;
9101 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9102 /* No price multiplier has been set.
9103 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9104 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9105 }
9106 }
9107 }
9108
9109 /* Decide local/global scope of price base multipliers */
9110 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9111 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9112 for (Price p = PR_BEGIN; p < PR_END; p++) {
9113 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9114 /* No multiplier was set; set it to a neutral value */
9115 price_base_multipliers[p] = 0;
9116 } else {
9117 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
9118 /* The grf does not define any objects of the feature,
9119 * so it must be a difficulty setting. Apply it globally */
9120 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
9121 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9122 price_base_multipliers[p] = 0;
9123 } else {
9124 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
9125 }
9126 }
9127 }
9128 }
9129 }
9130
9131 extern void InitGRFTownGeneratorNames();
9132
9134 static void AfterLoadGRFs()
9135 {
9136 for (StringIDMapping *it = _string_to_grf_mapping.Begin(); it != _string_to_grf_mapping.End(); it++) {
9137 *it->target = MapGRFStringID(it->grfid, it->source);
9138 }
9139 _string_to_grf_mapping.Clear();
9140
9141 /* Free the action 6 override sprites. */
9142 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9143 free((*it).second);
9144 }
9145 _grf_line_to_action6_sprite_override.clear();
9146
9147 /* Polish cargoes */
9148 FinaliseCargoArray();
9149
9150 /* Pre-calculate all refit masks after loading GRF files. */
9151 CalculateRefitMasks();
9152
9153 /* Polish engines */
9154 FinaliseEngineArray();
9155
9156 /* Set the actually used Canal properties */
9157 FinaliseCanals();
9158
9159 /* Add all new houses to the house array. */
9160 FinaliseHouseArray();
9161
9162 /* Add all new industries to the industry array. */
9163 FinaliseIndustriesArray();
9164
9165 /* Add all new objects to the object array. */
9166 FinaliseObjectsArray();
9167
9168 InitializeSortedCargoSpecs();
9169
9170 /* Sort the list of industry types. */
9171 SortIndustryTypes();
9172
9173 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9174 BuildIndustriesLegend();
9175
9176 /* Build the routemap legend, based on the available cargos */
9177 BuildLinkStatsLegend();
9178
9179 /* Add all new airports to the airports array. */
9180 FinaliseAirportsArray();
9181 BindAirportSpecs();
9182
9183 /* Update the townname generators list */
9184 InitGRFTownGeneratorNames();
9185
9186 /* Run all queued vehicle list order changes */
9187 CommitVehicleListOrderChanges();
9188
9189 /* Load old shore sprites in new position, if they were replaced by ActionA */
9190 ActivateOldShore();
9191
9192 /* Set up custom rail types */
9193 InitRailTypes();
9194
9195 Engine *e;
9196 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
9197 if (_gted[e->index].rv_max_speed != 0) {
9198 /* Set RV maximum speed from the mph/0.8 unit value */
9199 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9200 }
9201 }
9202
9203 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
9204 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9205 if (railtype == INVALID_RAILTYPE) {
9206 /* Rail type is not available, so disable this engine */
9207 e->info.climates = 0;
9208 } else {
9209 e->u.rail.railtype = railtype;
9210 }
9211 }
9212
9213 SetYearEngineAgingStops();
9214
9215 FinalisePriceBaseMultipliers();
9216
9217 /* Deallocate temporary loading data */
9218 free(_gted);
9219 _grm_sprites.clear();
9220 }
9221
9228 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9229 {
9230 /* In case of networking we need to "sync" the start values
9231 * so all NewGRFs are loaded equally. For this we use the
9232 * start date of the game and we set the counters, etc. to
9233 * 0 so they're the same too. */
9234 Date date = _date;
9235 Year year = _cur_year;
9236 DateFract date_fract = _date_fract;
9237 uint16 tick_counter = _tick_counter;
9238 byte display_opt = _display_opt;
9239
9240 if (_networking) {
9241 _cur_year = _settings_game.game_creation.starting_year;
9242 _date = ConvertYMDToDate(_cur_year, 0, 1);
9243 _date_fract = 0;
9244 _tick_counter = 0;
9245 _display_opt = 0;
9246 }
9247
9248 InitializeGRFSpecial();
9249
9250 ResetNewGRFData();
9251
9252 /*
9253 * Reset the status of all files, so we can 'retry' to load them.
9254 * This is needed when one for example rearranges the NewGRFs in-game
9255 * and a previously disabled NewGRF becomes useable. If it would not
9256 * be reset, the NewGRF would remain disabled even though it should
9257 * have been enabled.
9258 */
9259 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9260 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9261 }
9262
9263 _cur.spriteid = load_index;
9264
9265 /* Load newgrf sprites
9266 * in each loading stage, (try to) open each file specified in the config
9267 * and load information from it. */
9268 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9269 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9270 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9271 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9272 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9273 }
9274
9275 if (stage == GLS_RESERVE) {
9276 static const uint32 overrides[][2] = {
9277 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9278 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9279 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9280 };
9281 for (size_t i = 0; i < lengthof(overrides); i++) {
9282 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9283 }
9284 }
9285
9286 uint slot = file_index;
9287 uint num_non_static = 0;
9288
9289 _cur.stage = stage;
9290 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9291 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9292 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9293
9294 Subdirectory subdir = slot < file_index + num_baseset ? BASESET_DIR : NEWGRF_DIR;
9295 if (!FioCheckFileExists(c->filename, subdir)) {
9296 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9297 c->status = GCS_NOT_FOUND;
9298 continue;
9299 }
9300
9301 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
9302
9303 if (!HasBit(c->flags, GCF_STATIC) && !HasBit(c->flags, GCF_SYSTEM)) {
9304 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
9305 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
9306 c->status = GCS_DISABLED;
9307 c->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9308 continue;
9309 }
9310 num_non_static++;
9311 }
9312 LoadNewGRFFile(c, slot++, stage, subdir);
9313 if (stage == GLS_RESERVE) {
9314 SetBit(c->flags, GCF_RESERVED);
9315 } else if (stage == GLS_ACTIVATION) {
9316 ClrBit(c->flags, GCF_RESERVED);
9317 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9318 ClearTemporaryNewGRFData(_cur.grffile);
9319 BuildCargoTranslationMap();
9320 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9321 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9322 /* We're not going to activate this, so free whatever data we allocated */
9323 ClearTemporaryNewGRFData(_cur.grffile);
9324 }
9325 }
9326 }
9327
9328 /* Pseudo sprite processing is finished; free temporary stuff */
9329 _cur.ClearDataForNextFile();
9330
9331 /* Call any functions that should be run after GRFs have been loaded. */
9332 AfterLoadGRFs();
9333
9334 /* Now revert back to the original situation */
9335 _cur_year = year;
9336 _date = date;
9337 _date_fract = date_fract;
9338 _tick_counter = tick_counter;
9339 _display_opt = display_opt;
9340 }
ResetBridges
void ResetBridges()
Reset the data been eventually changed by the grf loaded.
Definition: tunnelbridge_cmd.cpp:83
VehicleSettings::disable_elrails
bool disable_elrails
when true, the elrails are disabled
Definition: settings_type.h:454
HouseSpec::enabled
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition: house.h:111
CargoSpec::grffile
const struct GRFFile * grffile
NewGRF where #group belongs to.
Definition: cargotype.h:80
ShipVehicleInfo
Information about a ship vehicle.
Definition: engine_type.h:66
AllowedSubtags::text
TextHandler text
Callback function for a text node, only valid if type == &#39;T&#39;.
Definition: newgrf.cpp:7581
RAILTYPE_END
Used for iterations.
Definition: rail_type.h:35
strings_func.h
Functions related to OTTD&#39;s strings.
GameSettings::vehicle
VehicleSettings vehicle
options for vehicles
Definition: settings_type.h:552
FinaliseEngineArray
static void FinaliseEngineArray()
Check for invalid engines.
Definition: newgrf.cpp:8413
AirportSpec::ttd_airport_type
TTDPAirportType ttd_airport_type
ttdpatch airport type (Small/Large/Helipad/Oilrig)
Definition: newgrf_airport.h:114
PaletteID
uint32 PaletteID
The number of the palette.
Definition: gfx_type.h:20
GrfProcessingState::ClearDataForNextFile
void ClearDataForNextFile()
Clear temporary data before processing the next file in the current loading stage.
Definition: newgrf.cpp:112
ByteReader
Class to read from a NewGRF file.
Definition: newgrf.cpp:210
IgnoreIndustryTileProperty
static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
Ignore an industry tile property.
Definition: newgrf.cpp:3064
SPR_SHORE_BASE
static const SpriteID SPR_SHORE_BASE
shore tiles - action 05-0D
Definition: sprites.h:213
RailtypeInfo::group
const SpriteGroup * group[RTSG_END]
Sprite groups for resolving sprites.
Definition: rail.h:270
ConstructionSettings::max_heightlevel
uint8 max_heightlevel
maximum allowed heightlevel
Definition: settings_type.h:300
RailTypeFlags
RailTypeFlags
Railtype flags.
Definition: rail.h:26
HouseSpec::probability
byte probability
Relative probability of appearing (16 is the standard value)
Definition: house.h:117
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:77
LanguageMap::case_map
SmallVector< Mapping, 1 > case_map
Mapping of NewGRF and OpenTTD IDs for cases.
Definition: newgrf_text.h:61
CIR_DISABLED
GRF was disabled due to error.
Definition: newgrf.cpp:988
RandomizedSpriteGroup::groups
const SpriteGroup ** groups
Take the group with appropriate index:
Definition: newgrf_spritegroup.h:209
IndustryTileSpec::acceptance
uint8 acceptance[3]
Level of acceptance per cargo type.
Definition: industrytype.h:150
_networking
bool _networking
are we in networking mode?
Definition: network.cpp:56
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:298
PROP_ROADVEH_SHORTEN_FACTOR
Shorter vehicles.
Definition: newgrf_properties.h:42
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:317
newgrf_engine.h
Functions for NewGRF engines.
LanguagePackHeader::GetCaseIndex
uint8 GetCaseIndex(const char *case_str) const
Get the index for the given case.
Definition: language.h:82
IndustrySpec::enabled
bool enabled
entity still available (by default true).newgrf can disable it, though
Definition: industrytype.h:135
ObjectFlags
ObjectFlags
Various object behaviours.
Definition: newgrf_object.h:26
OBJECT_FLAG_2CC_COLOUR
Object wants 2CC colour mapping.
Definition: newgrf_object.h:36
SortIndustryTypes
void SortIndustryTypes()
Initialize the list of sorted industry types.
Definition: industry_gui.cpp:182
GetRailTypeInfo
static const RailtypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition: rail.h:296
BridgeSpec::avail_year
Year avail_year
the year where it becomes available
Definition: bridge.h:44
ResetCustomObjects
static void ResetCustomObjects()
Reset and clear all NewObjects.
Definition: newgrf.cpp:8031
RailtypeInfo::grffile
const GRFFile * grffile[RTSG_END]
NewGRF providing the Action3 for the railtype.
Definition: rail.h:265
ObjectSpec::flags
ObjectFlags flags
Flags/settings related to the object.
Definition: newgrf_object.h:72
FinaliseIndustriesArray
static void FinaliseIndustriesArray()
Add all new industries to the industry array.
Definition: newgrf.cpp:8630
GRFFile::language_map
struct LanguageMap * language_map
Mappings related to the languages.
Definition: newgrf.h:133
TLF_CHILD_Y_OFFSET
Add signed offset to child sprite Y positions from register TileLayoutRegisters::delta.child[1].
Definition: newgrf_commons.h:47
AfterLoadGRFs
static void AfterLoadGRFs()
Finish loading NewGRFs and execute needed post-processing.
Definition: newgrf.cpp:9134
SPR_TRACKS_FOR_SLOPES_BASE
static const SpriteID SPR_TRACKS_FOR_SLOPES_BASE
Sprites for &#39;highlighting&#39; tracks on sloped land.
Definition: sprites.h:187
GRFError::param_value
uint32 param_value[2]
Values of GRF parameters to show for message and custom_message.
Definition: newgrf_config.h:112
CargoSpec::weight
uint8 weight
Weight of a single unit of this cargo type in 1/16 ton (62.5 kg).
Definition: cargotype.h:61
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:645
AlterVehicleListOrder
void AlterVehicleListOrder(EngineID engine, uint target)
Record a vehicle ListOrderChange.
Definition: newgrf_engine.cpp:1196
ResetCustomAirports
static void ResetCustomAirports()
Reset and clear all NewGRF airports.
Definition: newgrf.cpp:7953
AllowedSubtags::AllowedSubtags
AllowedSubtags(uint32 id, DataHandler handler)
Create a binary leaf node.
Definition: newgrf.cpp:7532
LiveryScheme
LiveryScheme
List of different livery schemes.
Definition: livery.h:22
PTYPE_UINT_ENUM
The parameter allows a range of numbers, each of which can have a special name.
Definition: newgrf_config.h:117
RAILTYPE_MONO
Monorail.
Definition: rail_type.h:33
AirportTileTable::ti
TileIndexDiffC ti
Tile offset from the top-most airport tile.
Definition: newgrf_airport.h:26
_grfconfig
GRFConfig * _grfconfig
First item in list of current GRF set up.
Definition: newgrf_config.cpp:192
GameCreationSettings::landscape
byte landscape
the landscape we&#39;re currently in
Definition: settings_type.h:288
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:151
AirportSpec::size_y
byte size_y
size of airport in y direction
Definition: newgrf_airport.h:108
RailType
RailType
Enumeration for all possible railtypes.
Definition: rail_type.h:29
PROP_AIRCRAFT_RANGE
Aircraft range.
Definition: newgrf_properties.h:56
Subdirectory
Subdirectory
The different kinds of subdirectories OpenTTD uses.
Definition: fileio_type.h:110
IndustrySpec::map_colour
byte map_colour
colour used for the small map
Definition: industrytype.h:121
ResetNewGRF
static void ResetNewGRF()
Reset and clear all NewGRFs.
Definition: newgrf.cpp:8047
LanguageMap::plural_form
int plural_form
The plural form used for this language.
Definition: newgrf_text.h:62
AirportSpec::GetWithoutOverride
static AirportSpec * GetWithoutOverride(byte type)
Retrieve airport spec for the given airport.
Definition: newgrf_airport.cpp:117
AnimationInfo::triggers
uint16 triggers
The triggers that trigger animation.
Definition: newgrf_animation_type.h:24
DIR_E
East.
Definition: direction_type.h:30
RailtypeInfo::toolbar_caption
StringID toolbar_caption
Caption in the construction toolbar GUI for this rail type.
Definition: rail.h:166
GCF_INIT_ONLY
GRF file is processed up to GLS_INIT.
Definition: newgrf_config.h:29
EngineIDMapping::grfid
uint32 grfid
The GRF ID of the file the entity belongs to.
Definition: engine_base.h:149
LanguageMap::Mapping::newgrf_id
byte newgrf_id
NewGRF&#39;s internal ID for a case/gender.
Definition: newgrf_text.h:50
Action5Type::block_type
Action5BlockType block_type
How is this Action5 type processed?
Definition: newgrf.cpp:5620
GRFLabel
Definition: newgrf.h:96
SmallMap::Find
const Pair * Find(const T &key) const
Finds given key in this map.
Definition: smallmap_type.hpp:57
_display_opt
byte _display_opt
What do we want to draw/do?
Definition: transparency_gui.cpp:28
GameSettings::economy
EconomySettings economy
settings to change the economy
Definition: settings_type.h:553
ObjectSpec::build_cost_multiplier
uint8 build_cost_multiplier
Build cost multiplier per tile.
Definition: newgrf_object.h:68
CargoSpec::is_freight
bool is_freight
Cargo type is considered to be freight (affects train freight multiplier).
Definition: cargotype.h:66
GrfProcessingState::nfo_line
uint32 nfo_line
Currently processed pseudo sprite number in the GRF.
Definition: newgrf.cpp:102
DAYS_TILL_ORIGINAL_BASE_YEAR
#define DAYS_TILL_ORIGINAL_BASE_YEAR
The offset in days from the &#39;_date == 0&#39; till &#39;ConvertYMDToDate(ORIGINAL_BASE_YEAR, 0, 1)&#39;.
Definition: date_type.h:82
NewGRFSpriteLayout::Allocate
void Allocate(uint num_sprites)
Allocate a spritelayout for num_sprites building sprites.
Definition: newgrf_commons.cpp:626
TileLayoutFlags
TileLayoutFlags
Flags to enable register usage in sprite layouts.
Definition: newgrf_commons.h:35
RailtypeInfo::curve_speed
byte curve_speed
Multiplier for curve maximum speed advantage.
Definition: rail.h:195
OTTDByteReaderSignal
Definition: newgrf.cpp:207
Action5Type::max_sprites
uint16 max_sprites
If the Action5 contains more sprites, only the first max_sprites sprites will be used.
Definition: newgrf.cpp:5623
FinaliseObjectsArray
static void FinaliseObjectsArray()
Add all new objects to the object array.
Definition: newgrf.cpp:8701
PROP_TRAIN_SPEED
Max. speed: 1 unit = 1/1.6 mph = 1 km-ish/h.
Definition: newgrf_properties.h:23
Pool::PoolItem<&_engine_pool >::Get
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:246
WaterFeature::grffile
const GRFFile * grffile
NewGRF where &#39;group&#39; belongs to.
Definition: newgrf_canal.h:26
AllowedSubtags::AllowedSubtags
AllowedSubtags(uint32 id, AllowedSubtags *subtags)
Create a branch node with a list of sub-nodes.
Definition: newgrf.cpp:7569
SPR_ONEWAY_BASE
static const SpriteID SPR_ONEWAY_BASE
One way road sprites.
Definition: sprites.h:280
ShipVehicleInfo::ocean_speed_frac
byte ocean_speed_frac
Fraction of maximum speed for ocean tiles.
Definition: engine_type.h:75
date_func.h
Functions related to dates.
PROP_TRAIN_POWER
Power in hp (if dualheaded: sum of both vehicles)
Definition: newgrf_properties.h:24
IsInsideMM
static bool IsInsideMM(const T x, const uint min, const uint max)
Checks if a value is in an interval.
Definition: math_func.hpp:266
YearMonthDay::day
Day day
Day (1..31)
Definition: date_type.h:106
GetCargoIDByLabel
CargoID GetCargoIDByLabel(CargoLabel cl)
Get the cargo ID by cargo label.
Definition: cargotype.cpp:88
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:2560
ORIGINAL_MAX_YEAR
static const Year ORIGINAL_MAX_YEAR
The maximum year of the original TTD.
Definition: date_type.h:55
_currency_specs
CurrencySpec _currency_specs[CURRENCY_END]
Array of currencies used by the system.
Definition: currency.cpp:68
newgrf_industries.h
Functions for NewGRF industries.
RAILTYPE_MAGLEV
Maglev.
Definition: rail_type.h:34
currency.h
Functions to handle different currencies.
_engine_offsets
const uint8 _engine_offsets[4]
Offset of the first engine of each vehicle type in original engine data.
Definition: engine.cpp:60
GrfProcessingState::SpriteSet::sprite
SpriteID sprite
SpriteID of the first sprite of the set.
Definition: newgrf.cpp:86
GRFParameterInfo::type
GRFParameterType type
The type of this parameter.
Definition: newgrf_config.h:129
GRFTempEngineData::UpdateRefittability
void UpdateRefittability(bool non_empty)
Update the summary refittability on setting a refittability property.
Definition: newgrf.cpp:323
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:250
MapLogX
static uint MapLogX()
Logarithm of the map size along the X side.
Definition: map_func.h:53
IndustrySpec::prospecting_chance
uint32 prospecting_chance
Chance prospecting succeeds.
Definition: industrytype.h:106
BridgeSpec::sprite_table
PalSpriteID ** sprite_table
table of sprites for drawing the bridge
Definition: bridge.h:53
EngineIDMapping
Definition: engine_base.h:148
ShipVehicleChangeInfo
static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for ships.
Definition: newgrf.cpp:1528
RailtypeInfo::flags
RailTypeFlags flags
Bit mask of rail type flags.
Definition: rail.h:200
_grf_cont_v2_sig
const byte _grf_cont_v2_sig[8]
Signature of a container version 2 GRF.
ChangeGRFParamMask
static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;PARAM&#39;->param_num->&#39;MASK&#39; to set the parameter and bits to use...
Definition: newgrf.cpp:7476
IgnoreObjectProperty
static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
Ignore properties for objects.
Definition: newgrf.cpp:3863
CLEAN_RANDOMSOUNDS
Free the dynamically allocated sounds table.
Definition: industrytype.h:24
debug.h
Functions related to debugging.
SetBit
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
Definition: bitmath_func.hpp:123
StringIDMapping::grfid
uint32 grfid
Source NewGRF.
Definition: newgrf.cpp:460
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:125
GrfProcessingState::grfconfig
GRFConfig * grfconfig
Config of the currently processed GRF file.
Definition: newgrf.cpp:101
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:600
NamePart::text
char * text
If probability bit 7 is clear.
Definition: newgrf_townname.h:23
INVALID_INDUSTRYTILE
static const IndustryGfx INVALID_INDUSTRYTILE
one above amount is considered invalid
Definition: industry_type.h:36
TLF_BB_XY_OFFSET
Add signed offset to bounding box X and Y positions from register TileLayoutRegisters::delta.parent[0..1].
Definition: newgrf_commons.h:43
GetCargoTranslation
CargoID GetCargoTranslation(uint8 cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoID.
Definition: newgrf_cargo.cpp:78
ImportGRFSound
static void ImportGRFSound(SoundEntry *sound)
Process a sound import from another GRF file.
Definition: newgrf.cpp:7052
FinaliseCanals
static void FinaliseCanals()
Set to use the correct action0 properties for each canal feature.
Definition: newgrf.cpp:8402
GRFPalette
GRFPalette
Information that can/has to be stored about a GRF&#39;s palette.
Definition: newgrf_config.h:60
BridgeSpec::flags
byte flags
bit 0 set: disable drawing of far pillars.
Definition: bridge.h:54
TranslateTTDPatchCodes
char * TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newlines, const char *str, int *olen, StringControlCode byte80)
Translate TTDPatch string codes into something OpenTTD can handle (better).
Definition: newgrf_text.cpp:336
FioReadWord
uint16 FioReadWord()
Read a word (16 bits) from the file (in low endian format).
Definition: fileio.cpp:166
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:74
Engine::grf_prop
GRFFilePropsBase< NUM_CARGO+2 > grf_prop
Properties related the the grf file.
Definition: engine_base.h:60
ObjectSpec::grf_prop
GRFFilePropsBase< 2 > grf_prop
Properties related the the grf file.
Definition: newgrf_object.h:62
EF_RAIL_FLIPS
Rail vehicle can be flipped in the depot.
Definition: engine_type.h:157
GRFP_BLT_32BPP
The NewGRF prefers a 32 bpp blitter.
Definition: newgrf_config.h:78
GRFFile::GRFFile
GRFFile(const struct GRFConfig *config)
Constructor for GRFFile.
Definition: newgrf.cpp:8221
ORIGINAL_SAMPLE_COUNT
static const uint ORIGINAL_SAMPLE_COUNT
The number of sounds in the original sample.cat.
Definition: sound_type.h:118
GCS_INITIALISED
GRF file has been initialised.
Definition: newgrf_config.h:39
CargoSpec
Specification of a cargo type.
Definition: cargotype.h:56
StationSpec
Station specification.
Definition: newgrf_station.h:117
ChangeGRFParamLimits
static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;PARAM&#39;->param_num->&#39;LIMI&#39; to set the min/max value of a parameter...
Definition: newgrf.cpp:7460
CanalFeature
CanalFeature
List of different canal &#39;features&#39;.
Definition: newgrf.h:26
GRFUnsafe
static void GRFUnsafe(ByteReader *buf)
Set the current NewGRF as unsafe for static use.
Definition: newgrf.cpp:7807
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:545
GRFParameterInfo::def_value
uint32 def_value
Default value of this parameter.
Definition: newgrf_config.h:132
PROP_TRAIN_RUNNING_COST_FACTOR
Yearly runningcost (if dualheaded: sum of both vehicles)
Definition: newgrf_properties.h:25
IndustrySpec::life_type
IndustryLifeType life_type
This is also known as Industry production flag, in newgrf specs.
Definition: industrytype.h:118
RoadVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:124
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:50
IsSnowLineSet
bool IsSnowLineSet()
Has a snow line table already been loaded.
Definition: landscape.cpp:535
GRFConfig::status
GRFStatus status
NOSAVE: GRFStatus, enum.
Definition: newgrf_config.h:169
PROP_TRAIN_SHORTEN_FACTOR
Shorter vehicles.
Definition: newgrf_properties.h:30
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:99
vehicle_func.h
Functions related to vehicles.
GRFTextWrapper::text
struct GRFText * text
The actual text.
Definition: newgrf_config.h:146
TLF_SPRITE_VAR10
Resolve sprite with a specific value in variable 10.
Definition: newgrf_commons.h:49
BuildCargoTranslationMap
static void BuildCargoTranslationMap()
Construct the Cargo Mapping.
Definition: newgrf.cpp:8181
AirportSpec::depot_table
const HangarTileTable * depot_table
gives the position of the depots on the airports
Definition: newgrf_airport.h:105
INVALID_AIRPORTTILE
static const uint INVALID_AIRPORTTILE
id for an invalid airport tile
Definition: airport.h:27
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:64
IndustrySpec::callback_mask
uint16 callback_mask
Bitmask of industry callbacks that have to be called.
Definition: industrytype.h:133
IndustryTileSpec::accepts_cargo
CargoID accepts_cargo[3]
Cargo accepted by this tile.
Definition: industrytype.h:149
A5BLOCK_ALLOW_OFFSET
Allow replacing any subset by specifiing an offset.
Definition: newgrf.cpp:5615
GRFFile::grf_features
uint32 grf_features
Bitset of GrfSpecFeature the grf uses.
Definition: newgrf.h:138
CHECK_NOTHING
Always succeeds.
Definition: industrytype.h:41
Price
Price
Enumeration of all base prices for use with Prices.
Definition: economy_type.h:67
PalSpriteID
Combination of a palette sprite and a &#39;real&#39; sprite.
Definition: gfx_type.h:24
SP_CUSTOM
No profile, special "custom" highscore.
Definition: settings_type.h:35
HouseSpec::removal_cost
byte removal_cost
cost multiplier for removing it
Definition: house.h:103
GrfProcessingState::HasValidSpriteSets
bool HasValidSpriteSets(byte feature) const
Check whether there are any valid spritesets for a feature.
Definition: newgrf.cpp:148
IndustrySpec::removal_cost_multiplier
uint32 removal_cost_multiplier
Base removal cost multiplier.
Definition: industrytype.h:105
HouseSpec::cargo_acceptance
byte cargo_acceptance[3]
acceptance level for the cargo slots
Definition: house.h:107
StationSpec::cargo_triggers
uint32 cargo_triggers
Bitmask of cargo types which cause trigger re-randomizing.
Definition: newgrf_station.h:156
SmallVector::Clear
void Clear()
Remove all items from the list.
Definition: smallvec_type.hpp:98
PROP_TRAIN_COST_FACTOR
Purchase cost (if dualheaded: sum of both vehicles)
Definition: newgrf_properties.h:28
GCF_STATIC
GRF file is used statically (can be used in any MP game)
Definition: newgrf_config.h:26
newgrf_townname.h
Header of Action 0F "universal holder" structure and functions.
StationSettings::never_expire_airports
bool never_expire_airports
never expire airports
Definition: settings_type.h:519
WaterFeature::flags
uint8 flags
Flags controlling display.
Definition: newgrf_canal.h:28
GrfProcessingState::GetNumEnts
uint GetNumEnts(byte feature, uint set) const
Returns the number of sprites in a spriteset.
Definition: newgrf.cpp:185
_tags_info
AllowedSubtags _tags_info[]
Action14 tags for the INFO node.
Definition: newgrf.cpp:7677
GRFConfig::num_valid_params
uint8 num_valid_params
NOSAVE: Number of valid parameters (action 0x14)
Definition: newgrf_config.h:173
GRFError::custom_message
char * custom_message
Custom message (if present)
Definition: newgrf_config.h:108
SmallVector::Begin
const T * Begin() const
Get the pointer to the first item (const)
Definition: smallvec_type.hpp:272
TLF_PALETTE
Add signed offset to palette from register TileLayoutRegisters::palette.
Definition: newgrf_commons.h:40
TLF_NON_GROUND_FLAGS
Flags which do not work for the (first) ground sprite.
Definition: newgrf_commons.h:58
RailtypeInfo::alternate_labels
RailTypeLabelList alternate_labels
Rail type labels this type provides in addition to the main label.
Definition: rail.h:230
MAX_FILE_SLOTS
Maximum number of slots.
Definition: fios.h:94
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
FinaliseCargoArray
static void FinaliseCargoArray()
Check for invalid cargoes.
Definition: newgrf.cpp:8462
EngineOverrideManager::GetID
EngineID GetID(VehicleType type, uint16 grf_local_id, uint32 grfid)
Looks up an EngineID in the EngineOverrideManager.
Definition: engine.cpp:511
SmallMap::Insert
bool Insert(const T &key, const U &data)
Adds new item to this map.
Definition: smallmap_type.hpp:122
EngineClass
EngineClass
Type of rail engine.
Definition: engine_type.h:34
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.net/tiki-index.php?page=BaseCosts.
Definition: newgrf.cpp:966
CommitVehicleListOrderChanges
void CommitVehicleListOrderChanges()
Deternine default engine sorting and execute recorded ListOrderChanges from AlterVehicleListOrder.
Definition: newgrf_engine.cpp:1228
ResetPersistentNewGRFData
void ResetPersistentNewGRFData()
Reset NewGRF data which is stored persistently in savegames.
Definition: newgrf.cpp:8166
CargoSpec::name_single
StringID name_single
Name of a single entity of this type of cargo.
Definition: cargotype.h:72
GRFConfig::error
GRFError * error
NOSAVE: Error/Warning during GRF loading (Action 0x0B)
Definition: newgrf_config.h:164
SNOW_LINE_MONTHS
static const uint SNOW_LINE_MONTHS
Number of months in the snow line table.
Definition: landscape.h:18
BridgeSpec::speed
uint16 speed
maximum travel speed (1 unit = 1/1.6 mph = 1 km-ish/h)
Definition: bridge.h:48
TLF_SPRITE
Add signed offset to sprite from register TileLayoutRegisters::sprite.
Definition: newgrf_commons.h:39
ObjectSpec
Allow incrementing of ObjectClassID variables.
Definition: newgrf_object.h:60
fileio_func.h
Functions for Standard In/Out file operations.
ObjectSpec::end_of_life_date
Date end_of_life_date
When can&#39;t this object be built anymore.
Definition: newgrf_object.h:71
ActivateOldShore
static void ActivateOldShore()
Relocates the old shore sprites at new positions.
Definition: newgrf.cpp:8979
HangarTileTable
A list of all hangar tiles in an airport.
Definition: newgrf_airport.h:91
industrytype.h
Industry type specs.
Utf8Decode
size_t Utf8Decode(WChar *c, const char *s)
Decode and consume the next UTF-8 encoded character.
Definition: string.cpp:437
GRFP_GRF_UNSET
The NewGRF provided no information.
Definition: newgrf_config.h:71
CT_PURCHASE_OBJECT
static const CargoID CT_PURCHASE_OBJECT
Mapping of purchase for objects.
Definition: newgrf_object.h:157
GRFParameterInfo::param_nr
byte param_nr
GRF parameter to store content in.
Definition: newgrf_config.h:133
TE_WATER
Cargo behaves water-like.
Definition: cargotype.h:31
CargoSpec::abbrev
StringID abbrev
Two letter abbreviation for this cargo type.
Definition: cargotype.h:75
PROP_SHIP_CARGO_CAPACITY
Capacity.
Definition: newgrf_properties.h:46
lastof
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:50
ChangeGRFParamName
static bool ChangeGRFParamName(byte langid, const char *str)
Callback function for &#39;INFO&#39;->&#39;PARAM&#39;->param_num->&#39;NAME&#39; to set the name of a parameter.
Definition: newgrf.cpp:7429
SPR_AQUEDUCT_BASE
static const SpriteID SPR_AQUEDUCT_BASE
Sprites for the Aqueduct.
Definition: sprites.h:175
SmallVector
Simple vector template class.
Definition: smallvec_type.hpp:29
GetGRFStringID
StringID GetGRFStringID(uint32 grfid, StringID stringid)
Returns the index for this stringid associated with its grfID.
Definition: newgrf_text.cpp:702
ChangeInfoResult
ChangeInfoResult
Possible return values for the FeatureChangeInfo functions.
Definition: newgrf.cpp:986
CleanIndustryTileTable
static void CleanIndustryTileTable(IndustrySpec *ind)
Clean the tile table of the IndustrySpec if it&#39;s needed.
Definition: newgrf.cpp:3317
GCS_NOT_FOUND
GRF file was not found in the local cache.
Definition: newgrf_config.h:38
genworld.h
Functions related to world/map generation.
RailtypeInfo::compatible_railtypes
RailTypes compatible_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel ...
Definition: rail.h:180
GRFTempEngineData::UNSET
No properties assigned. Default refit masks shall be activated.
Definition: newgrf.cpp:304
PROP_TRAIN_CARGO_AGE_PERIOD
Number of ticks before carried cargo is aged.
Definition: newgrf_properties.h:32
TE_GOODS
Cargo behaves goods/candy-like.
Definition: cargotype.h:30
CargoSpec::quantifier
StringID quantifier
Text for multiple units of cargo of this type.
Definition: cargotype.h:74
MapLogY
static uint MapLogY()
Logarithm of the map size along the y side.
Definition: map_func.h:64
VSG_SCOPE_RELATIVE
Relative position (vehicles only)
Definition: newgrf_spritegroup.h:105
RailTypeChangeInfo
static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
Define properties for railtypes.
Definition: newgrf.cpp:4040
ObjectSpec::introduction_date
Date introduction_date
From when can this object be built.
Definition: newgrf_object.h:70
IndustrySpec::table
const IndustryTileTable *const * table
List of the tiles composing the industry.
Definition: industrytype.h:102
RAILTYPE_RAIL
Standard non-electric rails.
Definition: rail_type.h:31
NewGRFSpriteLayout::AllocateRegisters
void AllocateRegisters()
Allocate memory for register modifiers.
Definition: newgrf_commons.cpp:638
CallbackResultSpriteGroup
Definition: newgrf_spritegroup.h:218
CanalProperties::flags
uint8 flags
Flags controlling display.
Definition: newgrf.h:42
RealSpriteGroup::num_loaded
byte num_loaded
Number of loaded groups.
Definition: newgrf_spritegroup.h:90
GetEngineLiveryScheme
LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v)
Determines the LiveryScheme for a vehicle.
Definition: vehicle.cpp:1786
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
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:134
PROP_TRAIN_TRACTIVE_EFFORT
Tractive effort coefficient in 1/256.
Definition: newgrf_properties.h:29
GRFTempEngineData::refittability
Refittability refittability
Did the newgrf set any refittability property? If not, default refittability will be applied...
Definition: newgrf.cpp:313
GRFConfig::ident
GRFIdentifier ident
grfid and md5sum to uniquely identify newgrfs
Definition: newgrf_config.h:158
AirportChangeInfo
static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
Define properties for airports.
Definition: newgrf.cpp:3689
LoadNewGRF
void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
Load all the NewGRFs.
Definition: newgrf.cpp:9228
RailVehicleInfo::pow_wag_weight
byte pow_wag_weight
Extra weight applied to consist if wagon should be powered.
Definition: engine_type.h:57
Year
int32 Year
Type for the year, note: 0 based, i.e. starts at the year 0.
Definition: date_type.h:20
DisableGrf
static GRFError * DisableGrf(StringID message=STR_NULL, GRFConfig *config=NULL)
Disable a GRF.
Definition: newgrf.cpp:433
HouseSpec::callback_mask
uint16 callback_mask
Bitmask of house callbacks that have to be called.
Definition: house.h:115
StringIDMapping::source
StringID source
Source StringID (GRF local).
Definition: newgrf.cpp:461
BASESET_DIR
Subdirectory for all base data (base sets, intro game)
Definition: fileio_type.h:118
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:5591
max
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:26
CargoSpec::classes
uint16 classes
Classes of this cargo type.
Definition: cargotype.h:79
ChangeGRFPalette
static bool ChangeGRFPalette(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;PALS&#39; to set the number of valid parameters.
Definition: newgrf.cpp:7346
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:486
ChangeGRFDescription
static bool ChangeGRFDescription(byte langid, const char *str)
Callback function for &#39;INFO&#39;->&#39;DESC&#39; to add a translation to the newgrf description.
Definition: newgrf.cpp:7320
FioReadByte
byte FioReadByte()
Read a byte from the file.
Definition: fileio.cpp:133
DeterministicSpriteGroup
Definition: newgrf_spritegroup.h:170
GRFFile::label
GRFLabel * label
Pointer to the first label. This is a linked list, not an array.
Definition: newgrf.h:123
AnimationInfo::status
uint8 status
Status; 0: no looping, 1: looping, 0xFF: no animation.
Definition: newgrf_animation_type.h:22
VehicleSettings::never_expire_vehicles
bool never_expire_vehicles
never expire vehicles
Definition: settings_type.h:462
_cur_year
Year _cur_year
Current year, starting at 0.
Definition: date.cpp:26
BridgeSpec
Struct containing information about a single bridge type.
Definition: bridge.h:43
GRFFile::GetParam
uint32 GetParam(uint number) const
Get GRF Parameter with range checking.
Definition: newgrf.h:145
RailtypeInfo::strings
struct RailtypeInfo::@39 strings
Strings associated with the rail type.
StationSpec::tiles
uint tiles
Number of tile layouts.
Definition: newgrf_station.h:147
OrderSettings::improved_load
bool improved_load
improved loading algorithm
Definition: settings_type.h:438
DefineGotoLabel
static void DefineGotoLabel(ByteReader *buf)
Action 0x10 - Define goto label.
Definition: newgrf.cpp:7020
GCS_DISABLED
GRF file is disabled.
Definition: newgrf_config.h:37
AirportSpec::min_year
Year min_year
first year the airport is available
Definition: newgrf_airport.h:111
SmallVector::End
const T * End() const
Get the pointer behind the last valid item (const)
Definition: smallvec_type.hpp:292
GRFConfig::param_info
SmallVector< GRFParameterInfo *, 4 > param_info
NOSAVE: extra information about the parameters.
Definition: newgrf_config.h:175
LoadGRFSound
static void LoadGRFSound(size_t offs, SoundEntry *sound)
Load a sound from a file.
Definition: newgrf.cpp:7083
EngineInfo::base_intro
Date base_intro
Basic date of engine introduction (without random parts).
Definition: engine_type.h:133
TTDPStringIDToOTTDStringIDMapping
static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
Perform a mapping from TTDPatch&#39;s string IDs to OpenTTD&#39;s string IDs, but only for the ones we are aw...
Definition: newgrf.cpp:488
GRFParameterType
GRFParameterType
The possible types of a newgrf parameter.
Definition: newgrf_config.h:116
AirportSpec::nof_depots
byte nof_depots
the number of hangar tiles in this airport
Definition: newgrf_airport.h:106
build_industry.h
Tables with default industry layouts and behaviours.
RailtypeInfo::menu_text
StringID menu_text
Name of this rail type in the main toolbar dropdown.
Definition: rail.h:167
GameSettings::station
StationSettings station
settings related to station management
Definition: settings_type.h:555
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:101
IndustrySpec::production_down_text
StringID production_down_text
Message appearing when the industry&#39;s production is decreasing.
Definition: industrytype.h:126
RailtypeInfo::new_loco
StringID new_loco
Name of an engine for this type of rail in the engine preview GUI.
Definition: rail.h:170
GRFConfig::next
struct GRFConfig * next
NOSAVE: Next item in the linked list.
Definition: newgrf_config.h:178
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:24
CargoSpec::name
StringID name
Name of this type of cargo.
Definition: cargotype.h:71
AirportSpec::maintenance_cost
uint16 maintenance_cost
maintenance cost multiplier
Definition: newgrf_airport.h:117
EngineInfo::lifelength
Year lifelength
Lifetime of a single vehicle.
Definition: engine_type.h:134
NUM_HOUSES
static const HouseID NUM_HOUSES
Total number of houses.
Definition: house.h:31
LanguageMetadata
Metadata about a single language.
Definition: language.h:94
InitGRFTownGeneratorNames
void InitGRFTownGeneratorNames()
Allocate memory for the NewGRF town names.
Definition: settings_gui.cpp:76
GrfProcessingState::SpriteSet
Definition of a single Action1 spriteset.
Definition: newgrf.cpp:85
SoundEntry::grf_container_ver
byte grf_container_ver
NewGRF container version if the sound is from a NewGRF.
Definition: sound_type.h:24
Direction
Direction
Defines the 8 directions on the map.
Definition: direction_type.h:26
IndustrySpec::name
StringID name
Displayed name of the industry.
Definition: industrytype.h:122
EC_MAGLEV
Maglev engine.
Definition: engine_type.h:39
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:60
HouseZones
HouseZones
Definition: house.h:71
GrfProcessingState::SpriteSet::num_sprites
uint num_sprites
Number of sprites in the set.
Definition: newgrf.cpp:87
DrawTileSprites::seq
const DrawTileSeqStruct * seq
Array of child sprites. Terminated with a terminator entry.
Definition: sprite.h:62
AirportSpec::table
const AirportTileTable *const * table
list of the tiles composing the airport
Definition: newgrf_airport.h:102
AircraftVehicleInfo::max_speed
uint16 max_speed
Maximum speed (1 unit = 8 mph = 12.8 km-ish/h)
Definition: engine_type.h:105
ShipVehicleInfo::max_speed
uint16 max_speed
Maximum speed (1 unit = 1/3.2 mph = 0.5 km-ish/h)
Definition: engine_type.h:69
SHORE_REPLACE_NONE
No shore sprites were replaced.
Definition: newgrf.h:155
RandomizedSpriteGroup::lowest_randbit
byte lowest_randbit
Look for this in the per-object randomized bitmask:
Definition: newgrf_spritegroup.h:206
GrfProcessingState
Temporary data during loading of GRFs.
Definition: newgrf.cpp:82
_bridge
BridgeSpec _bridge[MAX_BRIDGES]
The specification of all bridges.
Definition: tunnelbridge_cmd.cpp:49
GetGRFSpriteOffset
size_t GetGRFSpriteOffset(uint32 id)
Get the file offset for a specific sprite in the sprite section of a GRF.
Definition: spritecache.cpp:486
IndustryTileSpec::special_flags
IndustryTileSpecialFlags special_flags
Bitmask of extra flags used by the tile.
Definition: industrytype.h:162
Action5Type::sprite_base
SpriteID sprite_base
Load the sprites starting from this sprite.
Definition: newgrf.cpp:5621
RailtypeInfo::build_caption
StringID build_caption
Caption of the build vehicle GUI for this rail type.
Definition: rail.h:168
RailtypeInfo
This struct contains all the info that is needed to draw and construct tracks.
Definition: rail.h:116
EC_MONORAIL
Mono rail engine.
Definition: engine_type.h:38
GetLanguage
const LanguageMetadata * GetLanguage(byte newgrflangid)
Get the language with the given NewGRF language ID.
Definition: strings.cpp:1875
newgrf_airport.h
NewGRF handling of airports.
SmallVector::Append
T * Append(uint to_add=1)
Append an item and return it.
Definition: smallvec_type.hpp:134
FinaliseAirportsArray
static void FinaliseAirportsArray()
Add all new airports to the airport array.
Definition: newgrf.cpp:8721
HouseSpec::building_availability
HouseZones building_availability
where can it be built (climates, zones)
Definition: house.h:110
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:2543
IndustryLifeType
IndustryLifeType
Available types of industry lifetimes.
Definition: industrytype.h:29
EC_DIESEL
Diesel rail engine.
Definition: engine_type.h:36
GrfProcessingState::grffile
GRFFile * grffile
Currently processed GRF file.
Definition: newgrf.cpp:100
RealSpriteGroup
Definition: newgrf_spritegroup.h:79
HouseSpec::population
byte population
population (Zero on other tiles in multi tile house.)
Definition: house.h:102
ObjectSpec::size
uint8 size
The size of this objects; low nibble for X, high nibble for Y.
Definition: newgrf_object.h:67
newgrf_object.h
Functions related to NewGRF objects.
ResetIndustries
void ResetIndustries()
This function initialize the spec arrays of both industry and industry tiles.
Definition: industry_cmd.cpp:72
CargoSpec::multiplier
uint16 multiplier
Capacity multiplier for vehicles. (8 fractional bits)
Definition: cargotype.h:62
GRFFile::price_base_multipliers
PriceMultipliers price_base_multipliers
Price base multipliers as set by the grf.
Definition: newgrf.h:139
TileIndexDiffC::y
int16 y
The y value of the coordinate.
Definition: map_type.h:60
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:27
IndustrySpec::cleanup_flag
uint8 cleanup_flag
flags indicating which data should be freed upon cleaning up
Definition: industrytype.h:134
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:104
GrfProcessingState::grf_container_ver
byte grf_container_ver
Container format of the current GRF file.
Definition: newgrf.cpp:103
IndustryTileSpec::slopes_refused
Slope slopes_refused
slope pattern on which this tile cannot be built
Definition: industrytype.h:151
CommonVehicleChangeInfo
static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
Define properties common to all vehicles.
Definition: newgrf.cpp:1003
fontcache.h
Functions to read fonts from files and cache them.
IndustrySpec::random_sounds
const uint8 * random_sounds
array of random sounds.
Definition: industrytype.h:131
StringIDMapping::target
StringID * target
Destination for mapping result.
Definition: newgrf.cpp:462
AircraftVehicleChangeInfo
static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for aircraft.
Definition: newgrf.cpp:1700
TLF_DODRAW
Only draw sprite if value of register TileLayoutRegisters::dodraw is non-zero.
Definition: newgrf_commons.h:38
SetPriceBaseMultiplier
void SetPriceBaseMultiplier(Price price, int factor)
Change a price base by the given factor.
Definition: economy.cpp:899
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:80
GRFParameterInfo::desc
struct GRFText * desc
The description of this parameter.
Definition: newgrf_config.h:128
LanguageMap::Mapping
Mapping between NewGRF and OpenTTD IDs.
Definition: newgrf_text.h:49
AirportSpec::catchment
byte catchment
catchment area of this airport
Definition: newgrf_airport.h:110
newgrf_text.h
Header of Action 04 "universal holder" structure and functions.
ObjectSpec::height
uint8 height
The height of this structure, in heightlevels; max MAX_TILE_HEIGHT.
Definition: newgrf_object.h:75
GrfProcessingState::stage
GrfLoadingStage stage
Current loading stage.
Definition: newgrf.cpp:95
ResetObjects
void ResetObjects()
This function initialize the spec arrays of objects.
Definition: newgrf_object.cpp:96
ReadGRFSpriteOffsets
void ReadGRFSpriteOffsets(byte container_version)
Parse the sprite section of GRFs.
Definition: spritecache.cpp:495
PROP_TRAIN_USER_DATA
User defined data for vehicle variable 0x42.
Definition: newgrf_properties.h:31
VEH_AIRCRAFT
Aircraft vehicle type.
Definition: vehicle_type.h:27
AirportSpec::noise_level
byte noise_level
noise that this airport generates
Definition: newgrf_airport.h:109
NewGRFClass
Struct containing information relating to NewGRF classes for stations and airports.
Definition: newgrf_class.h:21
GRFLoadedFeatures::shore
ShoreReplacement shore
It which way shore sprites were replaced.
Definition: newgrf.h:166
string_func.h
Functions related to low-level strings.
StationSpec::pylons
byte pylons
Bitmask of base tiles (0 - 7) which should contain elrail pylons.
Definition: newgrf_station.h:162
VehicleSettings::freight_trains
uint8 freight_trains
value to multiply the weight of cargo by
Definition: settings_type.h:460
GRFTempEngineData::prop27_set
bool prop27_set
Did the NewGRF set property 27 (misc flags)?
Definition: newgrf.cpp:314
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
TileLayoutRegisters::palette_var10
uint8 palette_var10
Value for variable 10 when resolving the palette.
Definition: newgrf_commons.h:105
GRFFile::param_end
uint param_end
one more than the highest set parameter
Definition: newgrf.h:121
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=NULL, uint16 *max_palette_offset=NULL)
Read a sprite and a palette from the GRF and convert them into a format suitable to OpenTTD...
Definition: newgrf.cpp:742
NewGRFSpriteLayout::Clone
void Clone(const DrawTileSeqStruct *source)
Clone the building sprites of a spritelayout.
Definition: newgrf_commons.cpp:588
VE_TYPE_START
First bit used for the type of effect.
Definition: vehicle_base.h:83
GRFFile::traininfo_vehicle_pitch
int traininfo_vehicle_pitch
Vertical offset for draing train images in depot GUI and vehicle details.
Definition: newgrf.h:135
ObjectSpec::enabled
bool enabled
Is this spec enabled?
Definition: newgrf_object.h:78
EngineInfo
Information about a vehicle.
Definition: engine_type.h:132
FinaliseHouseArray
static void FinaliseHouseArray()
Add all new houses to the house array.
Definition: newgrf.cpp:8558
EngineIDMapping::internal_id
uint16 internal_id
The internal ID within the GRF file.
Definition: engine_base.h:150
GRFConfig::num_params
uint8 num_params
Number of used parameters.
Definition: newgrf_config.h:172
CalculateRefitMasks
static void CalculateRefitMasks()
Precalculate refit masks from cargo classes for all vehicles.
Definition: newgrf.cpp:8297
PROP_SHIP_RUNNING_COST_FACTOR
Yearly runningcost.
Definition: newgrf_properties.h:47
HouseSpec::mail_generation
byte mail_generation
mail generation multiplier (tile based, as the acceptances below)
Definition: house.h:106
BranchHandler
bool(* BranchHandler)(ByteReader *)
Type of callback function for branch nodes.
Definition: newgrf.cpp:7511
PROP_AIRCRAFT_PASSENGER_CAPACITY
Passenger Capacity.
Definition: newgrf_properties.h:53
error.h
Functions related to errors.
AllocateRailType
RailType AllocateRailType(RailTypeLabel label)
Allocate a new rail type label.
Definition: rail_cmd.cpp:157
DrawTileSeqStruct::IsTerminator
bool IsTerminator() const
Check whether this is a sequence terminator.
Definition: sprite.h:43
_grf_files
static SmallVector< GRFFile *, 16 > _grf_files
List of all loaded GRF files.
Definition: newgrf.cpp:68
RealSpriteGroup::loaded
const SpriteGroup ** loaded
List of loaded groups (can be SpriteIDs or Callback results)
Definition: newgrf_spritegroup.h:92
SmallVector::Length
uint Length() const
Get the number of items in the list.
Definition: smallvec_type.hpp:262
AircraftVehicleInfo::subtype
byte subtype
Type of aircraft.
Definition: engine_type.h:102
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:98
SetupEngines
void SetupEngines()
Initialise the engine pool with the data from the original vehicles.
Definition: engine.cpp:545
_date_fract
DateFract _date_fract
Fractional part of the day.
Definition: date.cpp:29
_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:339
ConstructionSettings::train_signal_side
byte train_signal_side
show signals on left / driving / right side
Definition: settings_type.h:306
GRFP_GRF_ANY
The NewGRF says any palette can be used.
Definition: newgrf_config.h:74
SHORE_REPLACE_ACTION_5
Shore sprites were replaced by Action5.
Definition: newgrf.h:156
GCF_SYSTEM
GRF file is an openttd-internal system grf.
Definition: newgrf_config.h:24
Pool::PoolItem<&_engine_pool >::GetPoolSize
static size_t GetPoolSize()
Returns first unused index.
Definition: pool_type.hpp:267
DIR_W
West.
Definition: direction_type.h:34
HouseSpec::class_id
HouseClassID class_id
defines the class this house has (not grf file based)
Definition: house.h:119
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition: newgrf_config.h:153
SetYearEngineAgingStops
void SetYearEngineAgingStops()
Compute the value for _year_engine_aging_stops.
Definition: engine.cpp:617
EngineInfo::retire_early
int8 retire_early
Number of years early to retire vehicle.
Definition: engine_type.h:144
DrawTileSprites
Ground palette sprite of a tile, together with its sprite layout.
Definition: sprite.h:60
ReadByte
byte ReadByte(LoadgameState *ls)
Reads a byte from the buffer and decompress if needed.
Definition: oldloader.cpp:77
NEW_AIRPORT_OFFSET
Number of the first newgrf airport.
Definition: airport.h:41
AddGRFTextToList
void AddGRFTextToList(GRFText **list, GRFText *text_to_add)
Add a GRFText to a GRFText list.
Definition: newgrf_text.cpp:578
SmallPair
Simple pair of data.
Definition: smallmap_type.hpp:24
engine_func.h
Functions related to engines.
VehicleSettings::road_side
byte road_side
the side of the road vehicles drive on
Definition: settings_type.h:464
AllowedSubtags::id
uint32 id
The identifier for this node.
Definition: newgrf.cpp:7577
DeterministicSpriteGroupAdjust
Definition: newgrf_spritegroup.h:150
StationChangeInfo
static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
Define properties for stations.
Definition: newgrf.cpp:1854
VehicleType
VehicleType
Available vehicle types.
Definition: vehicle_type.h:21
GRFFile::railtype_list
SmallVector< RailTypeLabel, 4 > railtype_list
Railtype translation table.
Definition: newgrf.h:128
BridgeChangeInfo
static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
Define properties for bridges.
Definition: newgrf.cpp:2138
RailVehicleInfo::engclass
EngineClass engclass
Class of engine for this vehicle.
Definition: engine_type.h:53
NewGRFSpriteLayout::consistent_max_offset
uint consistent_max_offset
Number of sprites in all referenced spritesets.
Definition: newgrf_commons.h:122
ChangeGRFURL
static bool ChangeGRFURL(byte langid, const char *str)
Callback function for &#39;INFO&#39;->&#39;URL_&#39; to set the newgrf url.
Definition: newgrf.cpp:7327
AirportSpec::rotation
const Direction * rotation
the rotation of each tiletable
Definition: newgrf_airport.h:103
ObjectChangeInfo
static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
Define properties for objects.
Definition: newgrf.cpp:3909
RailVehicleInfo::pow_wag_power
uint16 pow_wag_power
Extra power applied to consist if wagon should be powered.
Definition: engine_type.h:56
PROP_ROADVEH_RUNNING_COST_FACTOR
Yearly runningcost.
Definition: newgrf_properties.h:34
RailVehicleInfo::max_speed
uint16 max_speed
Maximum speed (1 unit = 1/1.6 mph = 1 km-ish/h)
Definition: engine_type.h:48
newgrf_house.h
Functions related to NewGRF houses.
GRFP_USE_MASK
Bitmask to get only the use palette use states.
Definition: newgrf_config.h:69
RandomizedSpriteGroup
Definition: newgrf_spritegroup.h:196
GRFConfig::has_param_defaults
bool has_param_defaults
NOSAVE: did this newgrf specify any defaults for it&#39;s parameters.
Definition: newgrf_config.h:176
DuplicateTileTable
static void DuplicateTileTable(AirportSpec *as)
Create a copy of the tile table so it can be freed later without problems.
Definition: newgrf.cpp:3660
ClearSnowLine
void ClearSnowLine()
Clear the variable snow line table and free the memory.
Definition: landscape.cpp:597
EngineInfo::callback_mask
byte callback_mask
Bitmask of vehicle callbacks that have to be called.
Definition: engine_type.h:143
RAILVEH_WAGON
simple wagon, not motorized
Definition: engine_type.h:30
StationSpec::grf_prop
GRFFilePropsBase< NUM_CARGO+3 > grf_prop
Properties related the the grf file.
Definition: newgrf_station.h:124
DeterministicSpriteGroupAdjustOperation
DeterministicSpriteGroupAdjustOperation
Definition: newgrf_spritegroup.h:123
GetNewGRFSoundID
SoundID GetNewGRFSoundID(const GRFFile *file, SoundID sound_id)
Resolve NewGRF sound ID.
Definition: newgrf_sound.cpp:170
GRFParameterInfo::num_bit
byte num_bit
Number of bits to use for this parameter.
Definition: newgrf_config.h:135
GRFParameterInfo::value_names
SmallMap< uint32, struct GRFText *, 8 > value_names
Names for each value.
Definition: newgrf_config.h:136
AirportSpec::ResetAirports
static void ResetAirports()
This function initializes the airportspec array.
Definition: newgrf_airport.cpp:135
ObjectSpec::animation
AnimationInfo animation
Information about the animation.
Definition: newgrf_object.h:73
PROP_TRAIN_CARGO_CAPACITY
Capacity (if dualheaded: for each single vehicle)
Definition: newgrf_properties.h:26
StaticGRFInfo
static void StaticGRFInfo(ByteReader *buf)
Handle Action 0x14.
Definition: newgrf.cpp:7796
LanguageMap
Mapping of language data between a NewGRF and OpenTTD.
Definition: newgrf_text.h:47
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
AirportTileSpec::ResetAirportTiles
static void ResetAirportTiles()
This function initializes the tile array of AirportTileSpec.
Definition: newgrf_airporttiles.cpp:59
ResetCustomIndustries
static void ResetCustomIndustries()
Reset and clear all NewGRF industries.
Definition: newgrf.cpp:7991
GCF_COPY
The data is copied from a grf in _all_grfs.
Definition: newgrf_config.h:28
ResultSpriteGroup
Definition: newgrf_spritegroup.h:244
PROP_ROADVEH_WEIGHT
Weight in 1/4 t.
Definition: newgrf_properties.h:38
YearMonthDay
Data structure to convert between Date and triplet (year, month, and day).
Definition: date_type.h:103
GrfProcessingState::IsValidSpriteSet
bool IsValidSpriteSet(byte feature, uint set) const
Check whether a specific set is defined.
Definition: newgrf.cpp:161
HouseSpec::processing_time
byte processing_time
Periodic refresh multiplier.
Definition: house.h:121
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:178
usererror
void CDECL usererror(const char *s,...)
Error handling for fatal user errors.
Definition: openttd.cpp:90
safeguards.h
A number of safeguards to prevent using unsafe methods.
TileIndexDiffC::x
int16 x
The x value of the coordinate.
Definition: map_type.h:59
FeatureTownName
static void FeatureTownName(ByteReader *buf)
Action 0x0F - Define Town names.
Definition: newgrf.cpp:6936
ObjectSpec::callback_mask
uint16 callback_mask
Bitmask of requested/allowed callbacks.
Definition: newgrf_object.h:74
RailtypeInfo::acceleration_type
uint8 acceleration_type
Acceleration type of this rail type.
Definition: rail.h:215
FioSeekTo
void FioSeekTo(size_t pos, int mode)
Seek in the current file.
Definition: fileio.cpp:88
GRFError
Information about why GRF had problems during initialisation.
Definition: newgrf_config.h:103
SpriteGroup
Definition: newgrf_spritegroup.h:58
GRFParameterInfo::max_value
uint32 max_value
The maximal value of this parameter.
Definition: newgrf_config.h:131
TE_NONE
Cargo has no effect.
Definition: cargotype.h:27
MapNewGRFIndustryType
IndustryType MapNewGRFIndustryType(IndustryType grf_type, uint32 grf_id)
Map the GRF local type to an industry type.
Definition: newgrf_industries.cpp:41
RailtypeInfo::introduces_railtypes
RailTypes introduces_railtypes
Bitmask of which other railtypes are introduced when this railtype is introduced. ...
Definition: rail.h:255
EF_USES_2CC
Vehicle uses two company colours.
Definition: engine_type.h:155
NEW_INDUSTRYTILEOFFSET
static const IndustryGfx NEW_INDUSTRYTILEOFFSET
original number of tiles
Definition: industry_type.h:34
IndustrySpec::new_industry_text
StringID new_industry_text
Message appearing when the industry is built.
Definition: industrytype.h:123
PROP_ROADVEH_SPEED
Max. speed: 1 unit = 1/0.8 mph = 2 km-ish/h.
Definition: newgrf_properties.h:39
WaterFeature::group
const SpriteGroup * group
Sprite group to start resolving.
Definition: newgrf_canal.h:25
LoadNewGRFFile
void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
Load a particular NewGRF.
Definition: newgrf.cpp:8863
VehicleSettings::dynamic_engines
bool dynamic_engines
enable dynamic allocation of engine data
Definition: settings_type.h:461
ReusableBuffer::Allocate
T * Allocate(size_t count)
Get buffer of at least count times T.
Definition: alloc_type.hpp:107
RailVehicleChangeInfo
static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for rail vehicles.
Definition: newgrf.cpp:1046
MapGRFStringID
StringID MapGRFStringID(uint32 grfid, StringID str)
Used when setting an object&#39;s property to map to the GRF&#39;s strings while taking in consideration the ...
Definition: newgrf.cpp:552
HouseSpec::random_colour
byte random_colour[4]
4 "random" colours
Definition: house.h:116
_action5_types
static const Action5Type _action5_types[]
The information about action 5 types.
Definition: newgrf.cpp:5628
CargoSpec::callback_mask
uint8 callback_mask
Bitmask of cargo callbacks that have to be called.
Definition: cargotype.h:69
ShipVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:74
GrfProcessingState::skip_sprites
int skip_sprites
Number of psuedo sprites to skip before processing the next one. (-1 to skip to end of file) ...
Definition: newgrf.cpp:106
RailtypeInfo::sorting_order
byte sorting_order
The sorting order of this railtype for the toolbar dropdown.
Definition: rail.h:260
Engine::type
VehicleType type
Vehicle type, ie VEH_ROAD, VEH_TRAIN, etc.
Definition: engine_base.h:42
GRFTempEngineData::Refittability
Refittability
Summary state of refittability properties.
Definition: newgrf.cpp:303
CargoSpec::label
CargoLabel label
Unique label of the cargo type.
Definition: cargotype.h:58
HouseSpec::accepts_cargo
CargoID accepts_cargo[3]
3 input cargo slots
Definition: house.h:108
AirportSpec::num_table
byte num_table
number of elements in the table
Definition: newgrf_airport.h:104
ChangeGRFParamValueNames
static bool ChangeGRFParamValueNames(ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;PARA&#39;->param_num->&#39;VALU&#39; to set the names of some parameter values (ty...
Definition: newgrf.cpp:7601
LoadFontGlyph
static void LoadFontGlyph(ByteReader *buf)
Action 0x12.
Definition: newgrf.cpp:7201
ObjectSpec::views
uint8 views
The number of views.
Definition: newgrf_object.h:76
operator==
bool operator==(const MultiMapIterator< Tmap_iter1, Tlist_iter1, Tkey, Tvalue1, Tcompare > &iter1, const MultiMapIterator< Tmap_iter2, Tlist_iter2, Tkey, Tvalue2, Tcompare > &iter2)
Compare two MultiMap iterators.
Definition: multimap.hpp:205
CleanUpStrings
void CleanUpStrings()
House cleaning.
Definition: newgrf_text.cpp:797
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:18
language.h
Information about languages and their files.
CargoChangeInfo
static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
Define properties for cargoes.
Definition: newgrf.cpp:2870
RailVehicleInfo::capacity
byte capacity
Cargo capacity of vehicle; For multiheaded engines the capacity of each single engine.
Definition: engine_type.h:54
GRFConfig::flags
uint8 flags
NOSAVE: GCF_Flags, bitset.
Definition: newgrf_config.h:168
stredup
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Definition: string.cpp:126
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:113
RoadVehicleInfo::tractive_effort
uint8 tractive_effort
Coefficient of tractive effort.
Definition: engine_type.h:122
ChangeGRFParamDefault
static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;PARAM&#39;->param_num->&#39;DFLT&#39; to set the default value.
Definition: newgrf.cpp:7497
PROP_SHIP_CARGO_AGE_PERIOD
Number of ticks before carried cargo is aged.
Definition: newgrf_properties.h:48
TileLayoutRegisters::sprite_var10
uint8 sprite_var10
Value for variable 10 when resolving the sprite.
Definition: newgrf_commons.h:104
DateFract
uint16 DateFract
The fraction of a date we&#39;re in, i.e. the number of ticks since the last date changeover.
Definition: date_type.h:17
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:23
GCF_INVALID
GRF is unusable with this version of OpenTTD.
Definition: newgrf_config.h:31
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:136
RailVehicleInfo::cost_factor
byte cost_factor
Purchase cost factor; For multiheaded engines the sum of both engine prices.
Definition: engine_type.h:46
AllowedSubtags::AllowedSubtags
AllowedSubtags(uint32 id, TextHandler handler)
Create a text leaf node.
Definition: newgrf.cpp:7544
AirportTileSpec::name
StringID name
Tile Subname string, land information on this tile will give you "AirportName (TileSubname)".
Definition: newgrf_airporttiles.h:66
CanalChangeInfo
static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
Define properties for water features.
Definition: newgrf.cpp:2100
ConstructionSettings::max_bridge_length
uint16 max_bridge_length
maximum length of bridges
Definition: settings_type.h:303
GRFP_BLT_UNSET
The NewGRF provided no information or doesn&#39;t care about a 32 bpp blitter.
Definition: newgrf_config.h:77
RailtypeInfo::max_speed
uint16 max_speed
Maximum speed for vehicles travelling on this rail type.
Definition: rail.h:220
IsValidNewGRFImageIndex
static bool IsValidNewGRFImageIndex(uint8 image_index)
Helper to check whether an image index is valid for a particular NewGRF vehicle.
Definition: newgrf.cpp:202
BridgeSpec::min_length
byte min_length
the minimum length (not counting start and end tile)
Definition: bridge.h:45
EngineInfo::misc_flags
byte misc_flags
Miscellaneous flags.
Definition: engine_type.h:142
SPRITE_MODIFIER_CUSTOM_SPRITE
Set when a sprite originates from an Action 1.
Definition: sprites.h:1506
IndustriesChangeInfo
static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
Define properties for industries.
Definition: newgrf.cpp:3338
IndustrySpec
Defines the data structure for constructing industry.
Definition: industrytype.h:101
RailVehicleInfo::shorten_factor
byte shorten_factor
length on main map for this type is 8 - shorten_factor
Definition: engine_type.h:59
TileLayoutRegisters::sprite
uint8 sprite
Register specifying a signed offset for the sprite.
Definition: newgrf_commons.h:96
TLF_BB_Z_OFFSET
Add signed offset to bounding box Z positions from register TileLayoutRegisters::delta.parent[2].
Definition: newgrf_commons.h:44
HandleNode
static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
Handle the nodes of an Action14.
Definition: newgrf.cpp:7743
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:7587
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:89
YearMonthDay::year
Year year
Year (0...)
Definition: date_type.h:104
MAX_NUM_GENDERS
static const uint8 MAX_NUM_GENDERS
Maximum number of supported genders.
Definition: language.h:22
PROP_ROADVEH_POWER
Power in 10 HP.
Definition: newgrf_properties.h:37
RailVehicleInfo::air_drag
byte air_drag
Coefficient of air drag.
Definition: engine_type.h:61
IndustryTileSpec::grf_prop
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:164
AddStringForMapping
static void AddStringForMapping(StringID source, StringID *target)
Record a static StringID for getting translated later.
Definition: newgrf.cpp:472
GRFTownName
Definition: newgrf_townname.h:36
AirportTileSpec::Get
static const AirportTileSpec * Get(StationGfx gfx)
Retrieve airport tile spec for the given airport tile.
Definition: newgrf_airporttiles.cpp:38
FioReadBlock
void FioReadBlock(void *ptr, size_t size)
Read a block.
Definition: fileio.cpp:187
ChangeGRFVersion
static bool ChangeGRFVersion(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;VRSN&#39; to the version of the NewGRF.
Definition: newgrf.cpp:7394
_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:32
PROP_AIRCRAFT_MAIL_CAPACITY
Mail Capacity.
Definition: newgrf_properties.h:54
GRFTempEngineData::ctt_include_mask
uint32 ctt_include_mask
Cargo types always included in the refit mask.
Definition: newgrf.cpp:316
AirportTileTable::gfx
StationGfx gfx
AirportTile to use for this tile.
Definition: newgrf_airport.h:27
GetNewEngineID
EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
Return the ID of a new engine.
Definition: newgrf.cpp:695
RoadVehicleInfo::weight
uint8 weight
Weight in 1/4t units.
Definition: engine_type.h:120
StationSpec::wires
byte wires
Bitmask of base tiles (0 - 7) which should contain elrail wires.
Definition: newgrf_station.h:163
DrawTileSeqStruct::IsParentSprite
bool IsParentSprite() const
Check whether this is a parent sprite with a boundingbox.
Definition: sprite.h:49
HouseSpec::building_name
StringID building_name
building name
Definition: house.h:104
network.h
Basic functions/variables used all over the place.
RealSpriteGroup::loading
const SpriteGroup ** loading
List of loading groups (can be SpriteIDs or Callback results)
Definition: newgrf_spritegroup.h:93
A5BLOCK_INVALID
unknown/not-implemented type
Definition: newgrf.cpp:5616
LanguageMap::Mapping::openttd_id
byte openttd_id
OpenTTD&#39;s internal ID for a case/gender.
Definition: newgrf_text.h:51
TLF_DRAWING_FLAGS
Flags which are still required after loading the GRF.
Definition: newgrf_commons.h:55
ANIM_STATUS_NO_ANIMATION
static const uint8 ANIM_STATUS_NO_ANIMATION
There is no animation.
Definition: newgrf_animation_type.h:17
ChangeGRFMinVersion
static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;MINV&#39; to the minimum compatible version of the NewGRF.
Definition: newgrf.cpp:7407
GrfProcessingState::GetSprite
SpriteID GetSprite(byte feature, uint set) const
Returns the first sprite of a spriteset.
Definition: newgrf.cpp:173
AllowedSubtags::AllowedSubtags
AllowedSubtags()
Create empty subtags object used to identify the end of a list.
Definition: newgrf.cpp:7522
IndustryTileTable
Definition: industrytype.h:93
GRFFile::cargo_map
uint8 cargo_map[NUM_CARGO]
Inverse cargo translation table (CargoID -> local ID)
Definition: newgrf.h:126
SetNewGRFOverride
static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
Set the override for a NewGRF.
Definition: newgrf.cpp:586
lengthof
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
VEH_ROAD
Road vehicle type.
Definition: vehicle_type.h:25
CT_INVALID
Invalid cargo type.
Definition: cargo_type.h:70
IndustrySpec::behaviour
IndustryBehaviour behaviour
How this industry will behave, and how others entities can use it.
Definition: industrytype.h:120
MAX_NUM_CASES
static const uint8 MAX_NUM_CASES
Maximum number of supported cases.
Definition: language.h:23
CURRENCY_END
always the last item
Definition: currency.h:61
_ttdpatch_flags
static uint32 _ttdpatch_flags[8]
32 * 8 = 256 flags.
Definition: newgrf.cpp:74
IndustrySpec::appear_ingame
byte appear_ingame[NUM_LANDSCAPE]
Probability of appearance in game.
Definition: industrytype.h:128
IndustrySpec::grf_prop
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:136
GRFError::message
StringID message
Default message.
Definition: newgrf_config.h:110
min
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:42
GetNewgrfCurrencyIdConverted
byte GetNewgrfCurrencyIdConverted(byte grfcurr_id)
Will return the ottd&#39;s index correspondence to the ttdpatch&#39;s id.
Definition: currency.cpp:107
SPRITE_WIDTH
number of bits for the sprite number
Definition: sprites.h:1494
VSG_SCOPE_SELF
Resolved object itself.
Definition: newgrf_spritegroup.h:103
RailtypeInfo::label
RailTypeLabel label
Unique 32 bit rail type identifier.
Definition: rail.h:225
GRFText
Element of the linked list.
Definition: newgrf_text.cpp:66
VehicleSettings::plane_speed
uint8 plane_speed
divisor for speed of aircraft
Definition: settings_type.h:459
FioCheckFileExists
bool FioCheckFileExists(const char *filename, Subdirectory subdir)
Check whether the given file exists.
Definition: fileio.cpp:312
HouseSpec::max_year
Year max_year
last year it can be built
Definition: house.h:101
NewGRFSpriteLayout
NewGRF supplied spritelayout.
Definition: newgrf_commons.h:115
BridgeSpec::transport_name
StringID transport_name[2]
description of the bridge, when built for road or rail
Definition: bridge.h:52
ORIGINAL_BASE_YEAR
static const Year ORIGINAL_BASE_YEAR
The minimum starting year/base year of the original TTD.
Definition: date_type.h:51
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:31
HZ_CLIMALL
Bitmask of all climate bits.
Definition: house.h:84
StringID
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:18
_engine_counts
const uint8 _engine_counts[4]
Number of engines of each vehicle type in original engine data.
Definition: engine.cpp:52
ConstructionSettings::build_on_slopes
bool build_on_slopes
allow building on slopes
Definition: settings_type.h:301
SkipSpriteData
bool SkipSpriteData(byte type, uint16 num)
Skip the given amount of sprite graphics data.
Definition: spritecache.cpp:98
RailVehicleInfo::power
uint16 power
Power of engine (hp); For multiheaded engines the sum of both engine powers.
Definition: engine_type.h:49
YearMonthDay::month
Month month
Month (0..11)
Definition: date_type.h:105
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:67
TLF_KNOWN_FLAGS
Known flags. Any unknown set flag will disable the GRF.
Definition: newgrf_commons.h:52
GRFFilePropsBase::spritegroup
const struct SpriteGroup * spritegroup[Tcnt]
pointer to the different sprites of the entity
Definition: newgrf_commons.h:321
BuildLinkStatsLegend
void BuildLinkStatsLegend()
Populate legend table for the link stat view.
Definition: smallmap_gui.cpp:206
ChangeGRFBlitter
static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;BLTR&#39; to set the blitter info.
Definition: newgrf.cpp:7372
HouseSpec::building_flags
BuildingFlags building_flags
some flags that describe the house (size, stadium etc...)
Definition: house.h:109
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:4584
IndustrytilesChangeInfo
static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
Define properties for industry tiles.
Definition: newgrf.cpp:3100
GrfProcessingState::spriteid
SpriteID spriteid
First available SpriteID for loading realsprites.
Definition: newgrf.cpp:96
PriceBaseSpec::fallback_price
Price fallback_price
Fallback price multiplier for new prices but old grfs.
Definition: economy_type.h:188
DSGA_OP_ADD
a + b
Definition: newgrf_spritegroup.h:124
CurrencySpec::to_euro
Year to_euro
Year of switching to the Euro. May also be CF_NOEURO or CF_ISEURO.
Definition: currency.h:68
GRFLoadedFeatures::has_newhouses
bool has_newhouses
Set if there are any newhouses loaded.
Definition: newgrf.h:164
DeterministicSpriteGroupRange
Definition: newgrf_spritegroup.h:163
_water_feature
WaterFeature _water_feature[CF_END]
Table of canal &#39;feature&#39; sprite groups.
Definition: newgrf_canal.cpp:22
newgrf_airporttiles.h
NewGRF handling of airport tiles.
AllocateSound
SoundEntry * AllocateSound(uint num)
Allocate sound slots.
Definition: newgrf_sound.cpp:33
NEWGRF_DIR
Subdirectory for all NewGRFs.
Definition: fileio_type.h:119
Engine
Definition: engine_base.h:23
_tags_parameters
AllowedSubtags _tags_parameters[]
Action14 parameter tags.
Definition: newgrf.cpp:7631
LanguagePackHeader::GetGenderIndex
uint8 GetGenderIndex(const char *gender_str) const
Get the index for the given gender.
Definition: language.h:69
BridgeSpec::price
uint16 price
the price multiplier
Definition: bridge.h:47
RailVehicleInfo
Information about a rail vehicle.
Definition: engine_type.h:43
IsLeapYear
static bool IsLeapYear(Year yr)
Checks whether the given year is a leap year or not.
Definition: date_func.h:32
GCS_UNKNOWN
The status of this grf file is unknown.
Definition: newgrf_config.h:36
SHORE_REPLACE_ACTION_A
Shore sprites were replaced by ActionA (using grass tiles for the corner-shores). ...
Definition: newgrf.h:157
SPR_RAILTYPE_TUNNEL_BASE
static const SpriteID SPR_RAILTYPE_TUNNEL_BASE
Tunnel sprites with grass only for custom railtype tunnel.
Definition: sprites.h:288
VEH_SHIP
Ship vehicle type.
Definition: vehicle_type.h:26
Clamp
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:139
RailtypeInfo::replace_text
StringID replace_text
Text used in the autoreplace GUI.
Definition: rail.h:169
GRFConfig::version
uint32 version
NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown.
Definition: newgrf_config.h:166
MemCpyT
static void MemCpyT(T *destination, const T *source, size_t num=1)
Type-safe version of memcpy().
Definition: mem_func.hpp:25
ObjectSpec::name
StringID name
The name for this object.
Definition: newgrf_object.h:64
FinalisePriceBaseMultipliers
static void FinalisePriceBaseMultipliers()
Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them...
Definition: newgrf.cpp:9016
HouseSpec::watched_cargoes
uint32 watched_cargoes
Cargo types watched for acceptance.
Definition: house.h:123
IndustrySpec::input_cargo_multiplier
uint16 input_cargo_multiplier[3][2]
Input cargo multipliers (multiply amount of incoming cargo for the produced cargoes) ...
Definition: industrytype.h:117
DEBUG
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:39
FindFirstBit
uint8 FindFirstBit(uint32 x)
Search the first set bit in a 32 bit variable.
Definition: bitmath_func.cpp:39
MAX_LANG
static const uint MAX_LANG
Maximum number of languages supported by the game, and the NewGRF specs.
Definition: strings_type.h:21
IndustryTileSpec::callback_mask
uint8 callback_mask
Bitmask of industry tile callbacks that have to be called.
Definition: industrytype.h:160
GRFFileProps::override
uint16 override
id of the entity been replaced by
Definition: newgrf_commons.h:333
GRFLocation
Definition: newgrf.cpp:344
HouseExtraFlags
HouseExtraFlags
Definition: house.h:88
NUM_CARGO
Maximal number of cargo types in a game.
Definition: cargo_type.h:66
FioOpenFile
void FioOpenFile(int slot, const char *filename, Subdirectory subdir)
Open a slotted file.
Definition: fileio.cpp:250
CIR_UNKNOWN
Variable is unknown.
Definition: newgrf.cpp:990
CanalProperties::callback_mask
uint8 callback_mask
Bitmask of canal callbacks that have to be called.
Definition: newgrf.h:41
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
GRFConfig::url
GRFTextWrapper * url
NOSAVE: URL belonging to this GRF.
Definition: newgrf_config.h:163
BindAirportSpecs
void BindAirportSpecs()
Tie all airportspecs to their class.
Definition: newgrf_airport.cpp:147
_tick_counter
uint16 _tick_counter
Ever incrementing (and sometimes wrapping) tick counter for setting off various events.
Definition: date.cpp:30
GCF_RESERVED
GRF file passed GLS_RESERVE stage.
Definition: newgrf_config.h:30
ResetCustomHouses
static void ResetCustomHouses()
Reset and clear all NewGRF houses.
Definition: newgrf.cpp:7937
ParamSet
static void ParamSet(ByteReader *buf)
Action 0x0D: Set parameter.
Definition: newgrf.cpp:6580
AllowedSubtags::subtags
AllowedSubtags * subtags
Pointer to a list of subtags, only valid if type == &#39;C&#39; && !call_handler.
Definition: newgrf.cpp:7585
TLF_PALETTE_VAR10
Resolve palette with a specific value in variable 10.
Definition: newgrf_commons.h:50
RealSpriteGroup::num_loading
byte num_loading
Number of loading groups.
Definition: newgrf_spritegroup.h:91
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&#39;s not.
Definition: newgrf.cpp:8485
TE_PASSENGERS
Cargo behaves passenger-like.
Definition: cargotype.h:28
TileLayoutRegisters
Additional modifiers for items in sprite layouts.
Definition: newgrf_commons.h:93
ChangeGRFNumUsedParams
static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;NPAR&#39; to set the number of valid parameters.
Definition: newgrf.cpp:7334
GRFP_GRF_WINDOWS
The NewGRF says the Windows palette can be used.
Definition: newgrf_config.h:73
newgrf_canal.h
Handling of NewGRF canals.
PriceBaseSpec
Describes properties of price bases.
Definition: economy_type.h:184
FioReadDword
uint32 FioReadDword()
Read a double word (32 bits) from the file (in low endian format).
Definition: fileio.cpp:176
IndustrySpec::num_table
byte num_table
Number of elements in the table.
Definition: industrytype.h:103
VE_DISABLE_EFFECT
Flag to disable visual effect.
Definition: vehicle_base.h:90
TE_MAIL
Cargo behaves mail-like.
Definition: cargotype.h:29
INVALID_ENGINE
static const EngineID INVALID_ENGINE
Constant denoting an invalid engine.
Definition: engine_type.h:174
GRFParameterInfo::first_bit
byte first_bit
First bit to use in the GRF parameter.
Definition: newgrf_config.h:134
BridgeSpec::material
StringID material
the string that contains the bridge description
Definition: bridge.h:51
HouseSpec
Definition: house.h:98
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:187
smallmap_gui.h
Smallmap GUI functions.
ObjectSpec::clear_cost_multiplier
uint8 clear_cost_multiplier
Clear cost multiplier per tile.
Definition: newgrf_object.h:69
ShipVehicleInfo::old_refittable
bool old_refittable
Is ship refittable; only used during initialisation. Later use EngineInfo::refit_mask.
Definition: engine_type.h:73
IndustryTileSpecialFlags
IndustryTileSpecialFlags
Flags for miscellaneous industry tile specialities.
Definition: industrytype.h:87
RailtypeInfo::introduction_date
Date introduction_date
Introduction date.
Definition: rail.h:244
RailtypeInfo::cost_multiplier
uint16 cost_multiplier
Cost multiplier for building this rail type.
Definition: rail.h:205
GetFileByGRFID
static GRFFile * GetFileByGRFID(uint32 grfid)
Obtain a NewGRF file by its grfID.
Definition: newgrf.cpp:392
DrawTileSprites::ground
PalSpriteID ground
Palette and sprite for the ground.
Definition: sprite.h:61
GetGRFConfig
GRFConfig * GetGRFConfig(uint32 grfid, uint32 mask)
Retrieve a NewGRF from the current config by its grfid.
Definition: newgrf_config.cpp:889
TileLayoutRegisters::child
uint8 child[2]
Registers for signed offsets for the position of child sprites.
Definition: newgrf_commons.h:102
CargoSpec::town_effect
TownEffect town_effect
The effect that delivering this cargo type has on towns. Also affects destination of subsidies...
Definition: cargotype.h:67
PALETTE_MODIFIER_COLOUR
this bit is set when a recolouring process is in action
Definition: sprites.h:1509
_generating_world
bool _generating_world
Whether we are generating the map or not.
Definition: genworld.cpp:61
HZ_ZONALL
1F This is just to englobe all above types at once
Definition: house.h:78
engine_base.h
Base class for engines.
SmallVector::FindIndex
int FindIndex(const T &item) const
Search for the first occurrence of an item.
Definition: smallvec_type.hpp:195
RoadVehicleInfo
Information about a road vehicle.
Definition: engine_type.h:112
newgrf_station.h
Header file for NewGRF stations.
WaterFeature::callback_mask
uint8 callback_mask
Bitmask of canal callbacks that have to be called.
Definition: newgrf_canal.h:27
RoadVehicleInfo::max_speed
uint16 max_speed
Maximum speed (1 unit = 1/3.2 mph = 0.5 km-ish/h)
Definition: engine_type.h:118
ClrBit
static T ClrBit(T &x, const uint8 y)
Clears a bit in a variable.
Definition: bitmath_func.hpp:153
PROP_SHIP_COST_FACTOR
Purchase cost.
Definition: newgrf_properties.h:44
AllowedSubtags::AllowedSubtags
AllowedSubtags(uint32 id, BranchHandler handler)
Create a branch node with a callback handler.
Definition: newgrf.cpp:7556
CIR_UNHANDLED
Variable was parsed but unread.
Definition: newgrf.cpp:989
NFO_UTF8_IDENTIFIER
static const WChar NFO_UTF8_IDENTIFIER
This character, the thorn (&#39;þ&#39;), indicates a unicode string to NFO.
Definition: newgrf_text.h:21
Engine::GetGRF
const GRFFile * GetGRF() const
Retrieve the NewGRF the engine is tied to.
Definition: engine_base.h:140
HouseSpec::extra_flags
HouseExtraFlags extra_flags
some more flags
Definition: house.h:118
GetGlobalVariable
bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
Reads a variable common to VarAction2 and Action7/9/D.
Definition: newgrf.cpp:5755
PROP_ROADVEH_COST_FACTOR
Purchase cost.
Definition: newgrf_properties.h:36
IndustrySpec::minimal_cargo
byte minimal_cargo
minimum amount of cargo transported to the stations.
Definition: industrytype.h:115
NamePart::prob
byte prob
The relative probability of the following name to appear in the bottom 7 bits.
Definition: newgrf_townname.h:21
IndustrySpec::cost_multiplier
uint8 cost_multiplier
Base construction cost multiplier.
Definition: industrytype.h:104
GRFParameterInfo
Information about one grf parameter.
Definition: newgrf_config.h:123
RAILTYPE_ELECTRIC
Electric rails.
Definition: rail_type.h:32
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:488
vehicle_base.h
Base class for all vehicles.
RAILVEH_SINGLEHEAD
indicates a "standalone" locomotive
Definition: engine_type.h:28
IndustrySpec::appear_creation
byte appear_creation[NUM_LANDSCAPE]
Probability of appearance during map creation.
Definition: industrytype.h:129
TextHandler
bool(* TextHandler)(byte, const char *str)
Type of callback function for text nodes.
Definition: newgrf.cpp:7510
OverrideManagerBase::ResetMapping
void ResetMapping()
Resets the mapping, which is used while initializing game.
Definition: newgrf_commons.cpp:84
BridgeSpec::max_length
uint16 max_length
the maximum length (not counting start and end tile)
Definition: bridge.h:46
NUM_AIRPORTS_PER_GRF
Maximal number of airports per NewGRF.
Definition: airport.h:42
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:71
GRFTempEngineData
Temporary engine data used when loading only.
Definition: newgrf.cpp:301
SpriteID
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:19
StrEmpty
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:59
ResetNewGRFData
void ResetNewGRFData()
Reset all NewGRF loaded data TODO.
Definition: newgrf.cpp:8073
fios.h
Declarations for savegames operations.
EngineID
uint16 EngineID
Unique identification number of an engine.
Definition: engine_type.h:22
CargoSpec::Get
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
Definition: cargotype.h:118
OrderSettings::gradual_loading
bool gradual_loading
load vehicles gradually
Definition: settings_type.h:439
PROP_AIRCRAFT_COST_FACTOR
Purchase cost.
Definition: newgrf_properties.h:50
VE_TYPE_COUNT
Number of bits used for the effect type.
Definition: vehicle_base.h:84
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:6035
ResetNewGRFErrors
static void ResetNewGRFErrors()
Clear all NewGRF errors.
Definition: newgrf.cpp:8059
RandomizedSpriteGroup::cmp_mode
RandomizedSpriteGroupCompareMode cmp_mode
Check for these triggers:
Definition: newgrf_spritegroup.h:202
IndustryTileSpec::animation
AnimationInfo animation
Information about the animation (is it looping, how many loops etc)
Definition: industrytype.h:161
PROP_SHIP_SPEED
Max. speed: 1 unit = 1/3.2 mph = 0.5 km-ish/h.
Definition: newgrf_properties.h:45
RailVehicleInfo::tractive_effort
byte tractive_effort
Tractive effort coefficient.
Definition: engine_type.h:60
newgrf_cargo.h
Cargo support for NewGRFs.
GRFConfig::palette
uint8 palette
GRFPalette, bitset.
Definition: newgrf_config.h:174
RoadVehicleChangeInfo
static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
Define properties for road vehicles.
Definition: newgrf.cpp:1340
PROP_AIRCRAFT_CARGO_AGE_PERIOD
Number of ticks before carried cargo is aged.
Definition: newgrf_properties.h:55
HouseSpec::minimum_life
byte minimum_life
The minimum number of years this house will survive before the town rebuilds it.
Definition: house.h:122
AirportSpec::name
StringID name
name of this airport
Definition: newgrf_airport.h:113
TranslateRefitMask
static uint32 TranslateRefitMask(uint32 refit_mask)
Translate the refit mask.
Definition: newgrf.cpp:948
CanalProperties
Canal properties local to the NewGRF.
Definition: newgrf.h:40
GRFFile::cargo_list
SmallVector< CargoLabel, 4 > cargo_list
Cargo translation table (local ID -> label)
Definition: newgrf.h:125
AircraftVehicleInfo
Information about a aircraft vehicle.
Definition: engine_type.h:98
PROP_ROADVEH_CARGO_CAPACITY
Capacity.
Definition: newgrf_properties.h:35
HouseSpec::remove_rating_decrease
uint16 remove_rating_decrease
rating decrease if removed
Definition: house.h:105
GRFLoadedFeatures::has_newindustries
bool has_newindustries
Set if there are any newindustries loaded.
Definition: newgrf.h:165
GCF_UNSAFE
GRF file is unsafe for static usage.
Definition: newgrf_config.h:25
RailtypeInfo::fallback_railtype
byte fallback_railtype
Original railtype number to use when drawing non-newgrf railtypes, or when drawing stations...
Definition: rail.h:190
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:28
GameSettings::order
OrderSettings order
settings related to orders
Definition: settings_type.h:551
AirportTileSpec::animation
AnimationInfo animation
Information about the animation.
Definition: newgrf_airporttiles.h:65
GRFLoadedFeatures
Definition: newgrf.h:161
VehicleSettings::wagon_speed_limits
bool wagon_speed_limits
enable wagon speed limits
Definition: settings_type.h:453
MapSpriteMappingRecolour
static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
Map the colour modifiers of TTDPatch to those that Open is using.
Definition: newgrf.cpp:711
InitNewGRFFile
static void InitNewGRFFile(const GRFConfig *config)
Prepare loading a NewGRF file with its config.
Definition: newgrf.cpp:8204
TLF_CHILD_X_OFFSET
Add signed offset to child sprite X positions from register TileLayoutRegisters::delta.child[0].
Definition: newgrf_commons.h:46
IndustrySpec::closure_text
StringID closure_text
Message appearing when the industry closes.
Definition: industrytype.h:124
VSG_SCOPE_PARENT
Related object of the resolved one.
Definition: newgrf_spritegroup.h:104
GRFTempEngineData::NONEMPTY
GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not av...
Definition: newgrf.cpp:306
FioSkipBytes
void FioSkipBytes(int n)
Skip n bytes ahead in the file.
Definition: fileio.cpp:150
EngineIDMapping::type
VehicleTypeByte type
The engine type.
Definition: engine_base.h:151
HouseSpec::min_year
Year min_year
introduction year of the house
Definition: house.h:100
RailtypeInfo::map_colour
byte map_colour
Colour on mini-map.
Definition: rail.h:235
PALETTE_MODIFIER_TRANSPARENT
when a sprite is to be displayed transparently, this bit needs to be set.
Definition: sprites.h:1508
error
void CDECL error(const char *s,...)
Error handling for fatal non-user errors.
Definition: openttd.cpp:110
Action5BlockType
Action5BlockType
The type of action 5 type.
Definition: newgrf.cpp:5613
DrawTileSeqStruct::delta_z
int8 delta_z
0x80 identifies child sprites
Definition: sprite.h:30
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:375
abs
static T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:83
AirportSpec::size_x
byte size_x
size of airport in x direction
Definition: newgrf_airport.h:107
RAILVEH_MULTIHEAD
indicates a combination of two locomotives
Definition: engine_type.h:29
RoadVehicleInfo::power
uint8 power
Power in 10hp units.
Definition: engine_type.h:121
InitializeSortedCargoSpecs
void InitializeSortedCargoSpecs()
Initialize the list of sorted cargo specifications.
Definition: cargotype.cpp:173
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
GRFTempEngineData::rv_max_speed
uint8 rv_max_speed
Temporary storage of RV prop 15, maximum speed in mph/0.8.
Definition: newgrf.cpp:315
InitRailTypes
void InitRailTypes()
Resolve sprites of custom rail types.
Definition: rail_cmd.cpp:138
MAX_BRIDGES
static const uint MAX_BRIDGES
Maximal number of available bridge specs.
Definition: bridge.h:36
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:34
AircraftVehicleInfo::max_range
uint16 max_range
Maximum range of this aircraft.
Definition: engine_type.h:108
AirportTileTable
Tile-offset / AirportTileID pair.
Definition: newgrf_airport.h:25
HandleNodes
static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
Handle the contents of a &#39;C&#39; choice of an Action14.
Definition: newgrf.cpp:7781
EngineInfo::string_id
StringID string_id
Default name of engine.
Definition: engine_type.h:145
GRFFile::canal_local_properties
CanalProperties canal_local_properties[CF_END]
Canal properties as set by this NewGRF.
Definition: newgrf.h:131
DataHandler
bool(* DataHandler)(size_t, ByteReader *)
Type of callback function for binary nodes.
Definition: newgrf.cpp:7509
FontSize
FontSize
Available font sizes.
Definition: gfx_type.h:203
SPR_AIRPORT_PREVIEW_BASE
static const SpriteID SPR_AIRPORT_PREVIEW_BASE
Airport preview sprites.
Definition: sprites.h:237
Slope
Slope
Enumeration for the slope-type.
Definition: slope_type.h:50
_gted
static GRFTempEngineData * _gted
Temporary engine data used during NewGRF loading.
Definition: newgrf.cpp:333
ResetPriceBaseMultipliers
void ResetPriceBaseMultipliers()
Reset changes to the price base multipliers.
Definition: economy.cpp:887
GRFConfig::filename
char * filename
Filename - either with or without full path.
Definition: newgrf_config.h:160
_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:8264
CargoLabel
uint32 CargoLabel
Globally unique label of a cargo type.
Definition: cargotype.h:22
NEW_HOUSE_OFFSET
static const HouseID NEW_HOUSE_OFFSET
Offset for new houses.
Definition: house.h:30
SHORE_REPLACE_ONLY_NEW
Only corner-shores were loaded by Action5 (openttd(w/d).grf only).
Definition: newgrf.h:158
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:25
GRFP_BLT_MASK
Bitmask to only get the blitter information.
Definition: newgrf_config.h:79
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:528
NEW_INDUSTRYOFFSET
static const IndustryType NEW_INDUSTRYOFFSET
original number of industry types
Definition: industry_type.h:27
SPR_OPENTTD_BASE
static const SpriteID SPR_OPENTTD_BASE
Extra graphic spritenumbers.
Definition: sprites.h:58
RailVehicleInfo::weight
uint16 weight
Weight of vehicle (tons); For multiheaded engines the weight of each single engine.
Definition: engine_type.h:50
StationSpec::cargo_threshold
uint16 cargo_threshold
Cargo threshold for choosing between little and lots of cargo.
Definition: newgrf_station.h:154
AllowedSubtags::type
byte type
The type of the node, must be one of &#39;C&#39;, &#39;B&#39; or &#39;T&#39;.
Definition: newgrf.cpp:7578
GRFLoadedFeatures::has_2CC
bool has_2CC
Set if any vehicle is loaded which uses 2cc (two company colours).
Definition: newgrf.h:162
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:77
NewGRFClass::Get
static NewGRFClass * Get(Tid cls_id)
Get a particular class.
Definition: newgrf_class_func.h:105
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:216
PROP_ROADVEH_CARGO_AGE_PERIOD
Number of ticks before carried cargo is aged.
Definition: newgrf_properties.h:41
_cargo_mask
uint32 _cargo_mask
Bitmask of cargo types available.
Definition: cargotype.cpp:31
RailtypeInfo::powered_railtypes
RailTypes powered_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype generates power ...
Definition: rail.h:177
landscape.h
Functions related to OTTD&#39;s landscape.
VE_DEFAULT
Default value to indicate that visual effect should be based on engine class.
Definition: vehicle_base.h:94
ResetRailTypes
void ResetRailTypes()
Reset all rail type information to its default values.
Definition: rail_cmd.cpp:65
GRFConfig::name
GRFTextWrapper * name
NOSAVE: GRF name (Action 0x08)
Definition: newgrf_config.h:161
ResetGenericCallbacks
void ResetGenericCallbacks()
Reset all generic feature callback sprite groups.
Definition: newgrf_generic.cpp:87
AllowedSubtags
Data structure to store the allowed id/type combinations for action 14.
Definition: newgrf.cpp:7520
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:152
CIR_INVALID_ID
Attempt to modify an invalid ID.
Definition: newgrf.cpp:991
AirportTileSpec
Defines the data structure of each individual tile of an airport.
Definition: newgrf_airporttiles.h:64
GRFTempEngineData::defaultcargo_grf
const GRFFile * defaultcargo_grf
GRF defining the cargo translation table to use if the default cargo is the &#39;first refittable&#39;...
Definition: newgrf.cpp:312
IndustryBehaviour
IndustryBehaviour
Various industry behaviours mostly to represent original TTD specialities.
Definition: industrytype.h:62
InitializeGRFSpecial
static void InitializeGRFSpecial()
Initialize the TTDPatch flags.
Definition: newgrf.cpp:7817
GRFP_GRF_DOS
The NewGRF says the DOS palette can be used.
Definition: newgrf_config.h:72
HouseSpec::animation
AnimationInfo animation
information about the animation.
Definition: house.h:120
ClearTemporaryNewGRFData
static void ClearTemporaryNewGRFData(GRFFile *gf)
Reset all NewGRFData that was used only while processing data.
Definition: newgrf.cpp:416
CargoSpec::Index
CargoID Index() const
Determines index of this cargospec.
Definition: cargotype.h:89
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:8531
GetGRFContainerVersion
byte GetGRFContainerVersion()
Get the container version of the currently opened GRF file.
Definition: newgrf.cpp:8837
AirportTileSpec::callback_mask
uint8 callback_mask
Bitmask telling which grf callback is set.
Definition: newgrf_airporttiles.h:67
IndustrySpec::conflicting
IndustryType conflicting[3]
Industries this industry cannot be close to.
Definition: industrytype.h:107
GetSnowLine
byte GetSnowLine()
Get the current snow line, either variable or static.
Definition: landscape.cpp:564
GRFFilePropsBase::local_id
uint16 local_id
id defined by the grf file for this entity
Definition: newgrf_commons.h:319
GRFConfig::min_loadable_version
uint32 min_loadable_version
NOSAVE: Minimum compatible version a NewGRF can define.
Definition: newgrf_config.h:167
IgnoreTownHouseProperty
static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
Ignore a house property.
Definition: newgrf.cpp:2248
SkipUnknownInfo
static bool SkipUnknownInfo(ByteReader *buf, byte type)
Try to skip the current node and all subnodes (if it&#39;s a branch node).
Definition: newgrf.cpp:7703
GRFLoadedFeatures::used_liveries
uint64 used_liveries
Bitmask of LiveryScheme used by the defined engines.
Definition: newgrf.h:163
RoadVehicleInfo::shorten_factor
byte shorten_factor
length on main map for this type is 8 - shorten_factor
Definition: engine_type.h:125
SPR_TRAMWAY_BASE
static const SpriteID SPR_TRAMWAY_BASE
Tramway sprites.
Definition: sprites.h:261
TE_FOOD
Cargo behaves food/fizzy-drinks-like.
Definition: cargotype.h:32
TLR_MAX_VAR10
static const uint TLR_MAX_VAR10
Maximum value for var 10.
Definition: newgrf_commons.h:108
PROP_AIRCRAFT_SPEED
Max. speed: 1 unit = 8 mph = 12.8 km-ish/h.
Definition: newgrf_properties.h:51
GameSettings::construction
ConstructionSettings construction
construction of things in-game
Definition: settings_type.h:545
SNOW_LINE_DAYS
static const uint SNOW_LINE_DAYS
Number of days in each month in the snow line table.
Definition: landscape.h:19
CIR_SUCCESS
Variable was parsed and read.
Definition: newgrf.cpp:987
IndustrySpec::accepts_cargo
CargoID accepts_cargo[3]
3 accepted cargoes.
Definition: industrytype.h:116
EC_STEAM
Steam rail engine.
Definition: engine_type.h:35
AllowedSubtags::data
DataHandler data
Callback function for a binary node, only valid if type == &#39;B&#39;.
Definition: newgrf.cpp:7580
MIN_YEAR
static const Year MIN_YEAR
The absolute minimum & maximum years in OTTD.
Definition: date_type.h:85
_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:342
MAX_SPRITEGROUP
static const uint MAX_SPRITEGROUP
Maximum GRF-local ID for a spritegroup.
Definition: newgrf.cpp:79
RoadVehicleInfo::air_drag
uint8 air_drag
Coefficient of air drag.
Definition: engine_type.h:123
GRFParameterInfo::min_value
uint32 min_value
The minimal value this parameter can have.
Definition: newgrf_config.h:130
GRFConfig::GetName
const char * GetName() const
Get the name of this grf.
Definition: newgrf_config.cpp:126
Date
int32 Date
The type to store our dates in.
Definition: date_type.h:16
GRFIdentifier::grfid
uint32 grfid
GRF ID (defined by Action 0x08)
Definition: newgrf_config.h:85
GRFError::data
char * data
Additional data for message and custom_message.
Definition: newgrf_config.h:109
PROP_ROADVEH_TRACTIVE_EFFORT
Tractive effort coefficient in 1/256.
Definition: newgrf_properties.h:40
GRFParameterInfo::name
struct GRFText * name
The name of this parameter.
Definition: newgrf_config.h:127
StationClassID
StationClassID
Definition: newgrf_station.h:82
RandomizedSpriteGroup::var_scope
VarSpriteGroupScope var_scope
Take this object:
Definition: newgrf_spritegroup.h:200
free
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:114
GRFTempEngineData::EMPTY
GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
Definition: newgrf.cpp:305
HouseSpec::grf_prop
GRFFileProps grf_prop
Properties related the the grf file.
Definition: house.h:114
PROP_VEHICLE_LOAD_AMOUNT
Loading speed.
Definition: newgrf_properties.h:21
RailtypeInfo::name
StringID name
Name of this rail type.
Definition: rail.h:165
GrfProcessingState::file_index
uint file_index
File index of currently processed GRF file.
Definition: newgrf.cpp:99
rev.h
declaration of OTTD revision dependent variables
GRFFilePropsBase::grffile
const struct GRFFile * grffile
grf file that introduced this entity
Definition: newgrf_commons.h:320
IndustrySpec::number_of_sounds
uint8 number_of_sounds
Number of sounds available in the sounds array.
Definition: industrytype.h:130
CargoSpec::bitnum
uint8 bitnum
Cargo bit number, is INVALID_CARGO for a non-used spec.
Definition: cargotype.h:57
AirportSpec::enabled
bool enabled
Entity still available (by default true). Newgrf can disable it, though.
Definition: newgrf_airport.h:119
IndustrySpec::station_name
StringID station_name
Default name for nearby station.
Definition: industrytype.h:127
GRFConfig::param
uint32 param[0x80]
GRF parameters.
Definition: newgrf_config.h:171
GCS_ACTIVATED
GRF file has been activated.
Definition: newgrf_config.h:40
HasBit
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Definition: bitmath_func.hpp:105
CargoSpec::units_volume
StringID units_volume
Name of a single unit of cargo of this type.
Definition: cargotype.h:73
CargoSpec::IsValid
bool IsValid() const
Tests for validity of this cargospec.
Definition: cargotype.h:99
IndustrySpec::production_up_text
StringID production_up_text
Message appearing when the industry&#39;s production is increasing.
Definition: industrytype.h:125
newgrf_sound.h
Functions related to NewGRF provided sounds.
StationSpec::callback_mask
byte callback_mask
Bitmask of station callbacks that have to be called.
Definition: newgrf_station.h:158
RandomizedSpriteGroup::num_groups
byte num_groups
must be power of 2
Definition: newgrf_spritegroup.h:207
_tags_root
AllowedSubtags _tags_root[]
Action14 root tags.
Definition: newgrf.cpp:7691
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:71
town.h
Base of the town class.
GetFileByFilename
static GRFFile * GetFileByFilename(const char *filename)
Obtain a NewGRF file by its filename.
Definition: newgrf.cpp:406
SmallVector::Get
const T * Get(uint index) const
Get the pointer to item "number" (const)
Definition: smallvec_type.hpp:313
NamePart::id
byte id
If probability bit 7 is set.
Definition: newgrf_townname.h:24
AllowedSubtags::branch
BranchHandler branch
Callback function for a branch node, only valid if type == &#39;C&#39; && call_handler.
Definition: newgrf.cpp:7584
_cur_parameter
static GRFParameterInfo * _cur_parameter
The parameter which info is currently changed by the newgrf.
Definition: newgrf.cpp:7426
ResetCustomStations
static void ResetCustomStations()
Reset and clear all NewGRF stations.
Definition: newgrf.cpp:7902
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition: settings_type.h:544
NEW_AIRPORTTILE_OFFSET
static const uint NEW_AIRPORTTILE_OFFSET
offset of first newgrf airport tile
Definition: airport.h:26
ChangeGRFParamType
static bool ChangeGRFParamType(size_t len, ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;PARAM&#39;->param_num->&#39;TYPE&#39; to set the typeof a parameter.
Definition: newgrf.cpp:7443
CargoID
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:22
CLEAN_TILELAYOUT
Free the dynamically allocated tile layout structure.
Definition: industrytype.h:25
EngineInfo::cargo_age_period
uint16 cargo_age_period
Number of ticks before carried cargo is aged.
Definition: engine_type.h:146
ValidateIndustryLayout
static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
Validate the industry layout; e.g.
Definition: newgrf.cpp:3303
IndustryTileSpec
Defines the data structure of each individual tile of an industry.
Definition: industrytype.h:148
GlobalVarChangeInfo
static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
Define properties for global variables.
Definition: newgrf.cpp:2584
INVALID_RAILTYPE
Flag for invalid railtype.
Definition: rail_type.h:36
GRFP_GRF_MASK
Bitmask to get only the NewGRF supplied information.
Definition: newgrf_config.h:75
PROP_TRAIN_WEIGHT
Weight in t (if dualheaded: for each single vehicle)
Definition: newgrf_properties.h:27
EngineInfo::base_life
Year base_life
Basic duration of engine availability (without random parts). 0xFF means infinite life...
Definition: engine_type.h:135
ConvertYMDToDate
Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
Definition: date.cpp:149
StationSpec::renderdata
NewGRFSpriteLayout * renderdata
Array of tile layouts.
Definition: newgrf_station.h:148
FioGetPos
size_t FioGetPos()
Get position in the current file.
Definition: fileio.cpp:68
DrawTileSeqStruct::delta_x
int8 delta_x
0x80 is sequence terminator
Definition: sprite.h:28
SoundEntry
Definition: sound_type.h:15
BSWAP32
static uint32 BSWAP32(uint32 x)
Perform a 32 bits endianness bitswap on x.
Definition: bitmath_func.hpp:380
SkipAct12
static void SkipAct12(ByteReader *buf)
Action 0x12 (SKIP)
Definition: newgrf.cpp:7232
SoundEffectChangeInfo
static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
Define properties for sound effects.
Definition: newgrf.cpp:3009
IndustryProductionSpriteGroup
Definition: newgrf_spritegroup.h:276
StationSpec::name
StringID name
Name of this station.
Definition: newgrf_station.h:126
MAX_CATCHMENT
Maximum catchment for airports with "modified catchment" enabled.
Definition: station_type.h:89
AirportSpec
Defines the data structure for an airport.
Definition: newgrf_airport.h:100
_loaded_newgrf_features
GRFLoadedFeatures _loaded_newgrf_features
Indicates which are the newgrf features currently loaded ingame.
Definition: newgrf.cpp:77
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:61
TranslateGRFStrings
static void TranslateGRFStrings(ByteReader *buf)
Action 0x13.
Definition: newgrf.cpp:7258
TownHouseChangeInfo
static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
Define properties for houses.
Definition: newgrf.cpp:2311
CargoSpec::multipliertowngrowth
uint16 multipliertowngrowth
Size of the effect.
Definition: cargotype.h:68
DeterministicSpriteGroupAdjust::parameter
byte parameter
Used for variables between 0x60 and 0x7F inclusive.
Definition: newgrf_spritegroup.h:154
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:55
GetRailTypeByLabel
RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels)
Get the rail type for a given label.
Definition: rail.cpp:285
PalSpriteID::sprite
SpriteID sprite
The &#39;real&#39; sprite.
Definition: gfx_type.h:25
TileLayoutRegisters::parent
uint8 parent[3]
Registers for signed offsets for the bounding box position of parent sprites.
Definition: newgrf_commons.h:101
GRFTempEngineData::ctt_exclude_mask
uint32 ctt_exclude_mask
Cargo types always excluded from the refit mask.
Definition: newgrf.cpp:317
StationSpec::disallowed_platforms
byte disallowed_platforms
Bitmask of number of platforms available for the station.
Definition: newgrf_station.h:132
bridge.h
Header file for bridges.
AnimationInfo::speed
uint8 speed
The speed, i.e. the amount of time between frames.
Definition: newgrf_animation_type.h:23
RailVehicleInfo::running_cost
byte running_cost
Running cost of engine; For multiheaded engines the sum of both running costs.
Definition: engine_type.h:51
ObjectSpec::cls_id
ObjectClassID cls_id
The class to which this spec belongs.
Definition: newgrf_object.h:63
StationSpec::cls_id
StationClassID cls_id
The class to which this spec belongs.
Definition: newgrf_station.h:125
TileLayoutRegisters::dodraw
uint8 dodraw
Register deciding whether the sprite shall be drawn at all. Non-zero means drawing.
Definition: newgrf_commons.h:95
LanguageMap::gender_map
SmallVector< Mapping, 1 > gender_map
Mapping of NewGRF and OpenTTD IDs for genders.
Definition: newgrf_text.h:60
TileLayoutSpriteGroup
Action 2 sprite layout for houses, industry tiles, objects and airport tiles.
Definition: newgrf_spritegroup.h:267
ChangeGRFParamDescription
static bool ChangeGRFParamDescription(byte langid, const char *str)
Callback function for &#39;INFO&#39;->&#39;PARAM&#39;->param_num->&#39;DESC&#39; to set the description of a parameter...
Definition: newgrf.cpp:7436
EngineInfo::climates
byte climates
Climates supported by the engine.
Definition: engine_type.h:138
SetUnicodeGlyph
static void SetUnicodeGlyph(FontSize size, WChar key, SpriteID sprite)
Map a SpriteID to the font size and key.
Definition: fontcache.h:155
_date
Date _date
Current date in days (day counter)
Definition: date.cpp:28
DrawTileSeqStruct
A tile child sprite and palette to draw for stations etc, with 3D bounding box.
Definition: sprite.h:27
IgnoreIndustryProperty
static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
Ignore an industry property.
Definition: newgrf.cpp:3218
CargoSpec::sprite
SpriteID sprite
Icon to display this cargo type, may be 0xFFF (which means to resolve an action123 chain)...
Definition: cargotype.h:77
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
WChar
uint32 WChar
Type for wide characters, i.e.
Definition: string_type.h:35
TTDPAirportType
TTDPAirportType
Allow incrementing of AirportClassID variables.
Definition: newgrf_airport.h:83
AirportSpec::max_year
Year max_year
last year the airport is available
Definition: newgrf_airport.h:112
ConvertDateToYMD
void ConvertDateToYMD(Date date, YearMonthDay *ymd)
Converts a Date to a Year, Month & Day.
Definition: date.cpp:94
SPRITE_MODIFIER_OPAQUE
Set when a sprite must not ever be displayed transparently.
Definition: sprites.h:1507
TLF_CUSTOM_PALETTE
Palette is from Action 1 (moved to SPRITE_MODIFIER_CUSTOM_SPRITE in palette during loading)...
Definition: newgrf_commons.h:41
ObjectSpec::climate
uint8 climate
In which climates is this object available?
Definition: newgrf_object.h:66
AirportTileSpec::grf_prop
GRFFileProps grf_prop
properties related the the grf file
Definition: newgrf_airporttiles.h:70
ShipVehicleInfo::canal_speed_frac
byte canal_speed_frac
Fraction of maximum speed for canal/river tiles.
Definition: engine_type.h:76
INDUSTRYTILE_NOANIM
static const IndustryGfx INDUSTRYTILE_NOANIM
flag to mark industry tiles as having no animation
Definition: industry_type.h:33
GrfProcessingState::AddSpriteSets
void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
Records new spritesets.
Definition: newgrf.cpp:132
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:62
AnimationInfo::frames
uint8 frames
The number of frames.
Definition: newgrf_animation_type.h:21
Action5Type::name
const char * name
Name for error messages.
Definition: newgrf.cpp:5624
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
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:262
GrfProcessingState::spritesets
std::map< uint, SpriteSet > spritesets[GSF_END]
Currently referenceable spritesets.
Definition: newgrf.cpp:91
GameCreationSettings::starting_year
Year starting_year
starting date
Definition: settings_type.h:277
ChangeGRFName
static bool ChangeGRFName(byte langid, const char *str)
Callback function for &#39;INFO&#39;->&#39;NAME&#39; to add a translation to the newgrf name.
Definition: newgrf.cpp:7313
AirportSpec::grf_prop
struct GRFFileProps grf_prop
Properties related to the grf file.
Definition: newgrf_airport.h:120
_object_mngr
ObjectOverrideManager _object_mngr
The override manager for our objects.
HZ_ZON5
center of town
Definition: house.h:77
A5BLOCK_FIXED
Only allow replacing a whole block of sprites. (TTDP compatible)
Definition: newgrf.cpp:5614
PROP_AIRCRAFT_RUNNING_COST_FACTOR
Yearly runningcost.
Definition: newgrf_properties.h:52
StationSpec::blocked
byte blocked
Bitmask of base tiles (0 - 7) which are blocked to trains.
Definition: newgrf_station.h:164
TileLayoutRegisters::palette
uint8 palette
Register specifying a signed offset for the palette.
Definition: newgrf_commons.h:97
NETWORK_MAX_GRF_COUNT
static const uint NETWORK_MAX_GRF_COUNT
Maximum number of GRFs that can be sent.
Definition: config.h:60
TileLayoutRegisters::flags
TileLayoutFlags flags
Flags defining which members are valid and to be used.
Definition: newgrf_commons.h:94
SPR_FLAGS_BASE
static const SpriteID SPR_FLAGS_BASE
Flags sprites (in same order as enum NetworkLanguage)
Definition: sprites.h:284
AircraftVehicleInfo::passenger_capacity
uint16 passenger_capacity
Passenger capacity (persons).
Definition: engine_type.h:107
AircraftVehicleInfo::mail_capacity
byte mail_capacity
Mail capacity (bags).
Definition: engine_type.h:106
Action5Type::min_sprites
uint16 min_sprites
If the Action5 contains less sprites, the whole block will be ignored.
Definition: newgrf.cpp:5622
Pool::CleanPool
virtual void CleanPool()
Virtual method that deletes all items in the pool.
MemSetT
static void MemSetT(T *ptr, byte value, size_t num=1)
Type-safe version of memset().
Definition: mem_func.hpp:51
EngineOverrideManager::ResetToDefaultMapping
void ResetToDefaultMapping()
Initializes the EngineOverrideManager with the default engines.
Definition: engine.cpp:488
RailVehicleInfo::visual_effect
byte visual_effect
Bitstuffed NewGRF visual effect data.
Definition: engine_type.h:58
PTYPE_END
Invalid parameter type.
Definition: newgrf_config.h:119
EC_ELECTRIC
Electric rail engine.
Definition: engine_type.h:37
GRFFile
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:104
HZ_SUBARTC_ABOVE
11 800 can appear in sub-arctic climate above the snow line
Definition: house.h:79
RailtypeInfo::maintenance_multiplier
uint16 maintenance_multiplier
Cost multiplier for maintenance of this rail type.
Definition: rail.h:210
VEH_TRAIN
Train vehicle type.
Definition: vehicle_type.h:24
Action5Type
Information about a single action 5 type.
Definition: newgrf.cpp:5619
StringIDMapping
Information for mapping static StringIDs.
Definition: newgrf.cpp:459
HandleParameterInfo
static bool HandleParameterInfo(ByteReader *buf)
Callback function for &#39;INFO&#39;->&#39;PARA&#39; to set extra information about the parameters.
Definition: newgrf.cpp:7648
GRFConfig::info
GRFTextWrapper * info
NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
Definition: newgrf_config.h:162
SetupCargoForClimate
void SetupCargoForClimate(LandscapeID l)
Set up the default cargo types for the given landscape type.
Definition: cargotype.cpp:42
TLF_VAR10_FLAGS
Flags which refer to using multiple action-1-2-3 chains.
Definition: newgrf_commons.h:61
PalSpriteID::pal
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:26
NewGRFClass::name
StringID name
Name of this class.
Definition: newgrf_class.h:41
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:104
BuildIndustriesLegend
void BuildIndustriesLegend()
Fills an array for the industries legends.
Definition: smallmap_gui.cpp:175