(svn r27763) -Update from Eints:
[openttd.git] / src / newgrf.cpp
blob14593b7e30f3b1a7dd60b4b358c5027fbfa72adb
1 /* $Id$ */
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 */
10 /** @file newgrf.cpp Base of all NewGRF support. */
12 #include "stdafx.h"
14 #include <stdarg.h>
16 #include "debug.h"
17 #include "fileio_func.h"
18 #include "engine_func.h"
19 #include "engine_base.h"
20 #include "bridge.h"
21 #include "town.h"
22 #include "newgrf_engine.h"
23 #include "newgrf_text.h"
24 #include "fontcache.h"
25 #include "currency.h"
26 #include "landscape.h"
27 #include "newgrf_cargo.h"
28 #include "newgrf_house.h"
29 #include "newgrf_sound.h"
30 #include "newgrf_station.h"
31 #include "industrytype.h"
32 #include "newgrf_canal.h"
33 #include "newgrf_townname.h"
34 #include "newgrf_industries.h"
35 #include "newgrf_airporttiles.h"
36 #include "newgrf_airport.h"
37 #include "newgrf_object.h"
38 #include "rev.h"
39 #include "fios.h"
40 #include "strings_func.h"
41 #include "date_func.h"
42 #include "string_func.h"
43 #include "network/network.h"
44 #include <map>
45 #include "smallmap_gui.h"
46 #include "genworld.h"
47 #include "error.h"
48 #include "vehicle_func.h"
49 #include "language.h"
50 #include "vehicle_base.h"
52 #include "table/strings.h"
53 #include "table/build_industry.h"
55 #include "safeguards.h"
57 /* TTDPatch extended GRF format codec
58 * (c) Petr Baudis 2004 (GPL'd)
59 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
61 * Contains portions of documentation by TTDPatch team.
62 * Thanks especially to Josef Drexler for the documentation as well as a lot
63 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
64 * served as subject to the initial testing of this codec. */
66 /** List of all loaded GRF files */
67 static SmallVector<GRFFile *, 16> _grf_files;
69 /** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
70 byte _misc_grf_features = 0;
72 /** 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
73 static uint32 _ttdpatch_flags[8];
75 /** Indicates which are the newgrf features currently loaded ingame */
76 GRFLoadedFeatures _loaded_newgrf_features;
78 static const uint MAX_SPRITEGROUP = UINT8_MAX; ///< Maximum GRF-local ID for a spritegroup.
80 /** Temporary data during loading of GRFs */
81 struct GrfProcessingState {
82 private:
83 /** Definition of a single Action1 spriteset */
84 struct SpriteSet {
85 SpriteID sprite; ///< SpriteID of the first sprite of the set.
86 uint num_sprites; ///< Number of sprites in the set.
89 /** Currently referenceable spritesets */
90 std::map<uint, SpriteSet> spritesets[GSF_END];
92 public:
93 /* Global state */
94 GrfLoadingStage stage; ///< Current loading stage
95 SpriteID spriteid; ///< First available SpriteID for loading realsprites.
97 /* Local state in the file */
98 uint file_index; ///< File index of currently processed GRF file.
99 GRFFile *grffile; ///< Currently processed GRF file.
100 GRFConfig *grfconfig; ///< Config of the currently processed GRF file.
101 uint32 nfo_line; ///< Currently processed pseudo sprite number in the GRF.
102 byte grf_container_ver; ///< Container format of the current GRF file.
104 /* Kind of return values when processing certain actions */
105 int skip_sprites; ///< Number of psuedo sprites to skip before processing the next one. (-1 to skip to end of file)
107 /* Currently referenceable spritegroups */
108 SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
110 /** Clear temporary data before processing the next file in the current loading stage */
111 void ClearDataForNextFile()
113 this->nfo_line = 0;
114 this->skip_sprites = 0;
116 for (uint i = 0; i < GSF_END; i++) {
117 this->spritesets[i].clear();
120 memset(this->spritegroups, 0, sizeof(this->spritegroups));
124 * Records new spritesets.
125 * @param feature GrfSpecFeature the set is defined for.
126 * @param first_sprite SpriteID of the first sprite in the set.
127 * @param first_set First spriteset to define.
128 * @param numsets Number of sets to define.
129 * @param numents Number of sprites per set to define.
131 void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
133 assert(feature < GSF_END);
134 for (uint i = 0; i < numsets; i++) {
135 SpriteSet &set = this->spritesets[feature][first_set + i];
136 set.sprite = first_sprite + i * numents;
137 set.num_sprites = numents;
142 * Check whether there are any valid spritesets for a feature.
143 * @param feature GrfSpecFeature to check.
144 * @return true if there are any valid sets.
145 * @note Spritesets with zero sprites are valid to allow callback-failures.
147 bool HasValidSpriteSets(byte feature) const
149 assert(feature < GSF_END);
150 return !this->spritesets[feature].empty();
154 * Check whether a specific set is defined.
155 * @param feature GrfSpecFeature to check.
156 * @param set Set to check.
157 * @return true if the set is valid.
158 * @note Spritesets with zero sprites are valid to allow callback-failures.
160 bool IsValidSpriteSet(byte feature, uint set) const
162 assert(feature < GSF_END);
163 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
167 * Returns the first sprite of a spriteset.
168 * @param feature GrfSpecFeature to query.
169 * @param set Set to query.
170 * @return First sprite of the set.
172 SpriteID GetSprite(byte feature, uint set) const
174 assert(IsValidSpriteSet(feature, set));
175 return this->spritesets[feature].find(set)->second.sprite;
179 * Returns the number of sprites in a spriteset
180 * @param feature GrfSpecFeature to query.
181 * @param set Set to query.
182 * @return Number of sprites in the set.
184 uint GetNumEnts(byte feature, uint set) const
186 assert(IsValidSpriteSet(feature, set));
187 return this->spritesets[feature].find(set)->second.num_sprites;
191 static GrfProcessingState _cur;
195 * Helper to check whether an image index is valid for a particular NewGRF vehicle.
196 * @param <T> The type of vehicle.
197 * @param image_index The image index to check.
198 * @return True iff the image index is valid, or 0xFD (use new graphics).
200 template <VehicleType T>
201 static inline bool IsValidNewGRFImageIndex(uint8 image_index)
203 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
206 class OTTDByteReaderSignal { };
208 /** Class to read from a NewGRF file */
209 class ByteReader {
210 protected:
211 byte *data;
212 byte *end;
214 public:
215 ByteReader(byte *data, byte *end) : data(data), end(end) { }
217 inline byte ReadByte()
219 if (data < end) return *(data)++;
220 throw OTTDByteReaderSignal();
223 uint16 ReadWord()
225 uint16 val = ReadByte();
226 return val | (ReadByte() << 8);
229 uint16 ReadExtendedByte()
231 uint16 val = ReadByte();
232 return val == 0xFF ? ReadWord() : val;
235 uint32 ReadDWord()
237 uint32 val = ReadWord();
238 return val | (ReadWord() << 16);
241 uint32 ReadVarSize(byte size)
243 switch (size) {
244 case 1: return ReadByte();
245 case 2: return ReadWord();
246 case 4: return ReadDWord();
247 default:
248 NOT_REACHED();
249 return 0;
253 const char *ReadString()
255 char *string = reinterpret_cast<char *>(data);
256 size_t string_length = ttd_strnlen(string, Remaining());
258 if (string_length == Remaining()) {
259 /* String was not NUL terminated, so make sure it is now. */
260 string[string_length - 1] = '\0';
261 grfmsg(7, "String was not terminated with a zero byte.");
262 } else {
263 /* Increase the string length to include the NUL byte. */
264 string_length++;
266 Skip(string_length);
268 return string;
271 inline size_t Remaining() const
273 return end - data;
276 inline bool HasData(size_t count = 1) const
278 return data + count <= end;
281 inline byte *Data()
283 return data;
286 inline void Skip(size_t len)
288 data += len;
289 /* It is valid to move the buffer to exactly the end of the data,
290 * as there may not be any more data read. */
291 if (data > end) throw OTTDByteReaderSignal();
295 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
297 static const uint NUM_STATIONS_PER_GRF = 255; ///< Number of StationSpecs per NewGRF; limited to 255 to allow extending Action3 with an extended byte later on.
299 /** Temporary engine data used when loading only */
300 struct GRFTempEngineData {
301 /** Summary state of refittability properties */
302 enum Refittability {
303 UNSET = 0, ///< No properties assigned. Default refit masks shall be activated.
304 EMPTY, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
305 NONEMPTY, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
308 uint16 cargo_allowed;
309 uint16 cargo_disallowed;
310 RailTypeLabel railtypelabel;
311 const GRFFile *defaultcargo_grf; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
312 Refittability refittability; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
313 bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)?
314 uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
315 uint32 ctt_include_mask; ///< Cargo types always included in the refit mask.
316 uint32 ctt_exclude_mask; ///< Cargo types always excluded from the refit mask.
319 * Update the summary refittability on setting a refittability property.
320 * @param non_empty true if the GRF sets the vehicle to be refittable.
322 void UpdateRefittability(bool non_empty)
324 if (non_empty) {
325 this->refittability = NONEMPTY;
326 } else if (this->refittability == UNSET) {
327 this->refittability = EMPTY;
332 static GRFTempEngineData *_gted; ///< Temporary engine data used during NewGRF loading
335 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
336 * GRM for vehicles is only used if dynamic engine allocation is disabled,
337 * so 256 is the number of original engines. */
338 static uint32 _grm_engines[256];
340 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
341 static uint32 _grm_cargoes[NUM_CARGO * 2];
343 struct GRFLocation {
344 uint32 grfid;
345 uint32 nfoline;
347 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
349 bool operator<(const GRFLocation &other) const
351 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
354 bool operator == (const GRFLocation &other) const
356 return this->grfid == other.grfid && this->nfoline == other.nfoline;
360 static std::map<GRFLocation, SpriteID> _grm_sprites;
361 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
362 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
365 * DEBUG() function dedicated to newGRF debugging messages
366 * Function is essentially the same as DEBUG(grf, severity, ...) with the
367 * addition of file:line information when parsing grf files.
368 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
369 * loading/parsing grf files, not for runtime debug messages as there
370 * is no file information available during that time.
371 * @param severity debugging severity level, see debug.h
372 * @param str message in printf() format
374 void CDECL grfmsg(int severity, const char *str, ...)
376 char buf[1024];
377 va_list va;
379 va_start(va, str);
380 vseprintf(buf, lastof(buf), str, va);
381 va_end(va);
383 DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
387 * Obtain a NewGRF file by its grfID
388 * @param grfid The grfID to obtain the file for
389 * @return The file.
391 static GRFFile *GetFileByGRFID(uint32 grfid)
393 const GRFFile * const *end = _grf_files.End();
394 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
395 if ((*file)->grfid == grfid) return *file;
397 return NULL;
401 * Obtain a NewGRF file by its filename
402 * @param filename The filename to obtain the file for.
403 * @return The file.
405 static GRFFile *GetFileByFilename(const char *filename)
407 const GRFFile * const *end = _grf_files.End();
408 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
409 if (strcmp((*file)->filename, filename) == 0) return *file;
411 return NULL;
414 /** Reset all NewGRFData that was used only while processing data */
415 static void ClearTemporaryNewGRFData(GRFFile *gf)
417 /* Clear the GOTO labels used for GRF processing */
418 for (GRFLabel *l = gf->label; l != NULL;) {
419 GRFLabel *l2 = l->next;
420 free(l);
421 l = l2;
423 gf->label = NULL;
427 * Disable a GRF
428 * @param message Error message or STR_NULL.
429 * @param config GRFConfig to disable, NULL for current.
430 * @return Error message of the GRF for further customisation.
432 static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = NULL)
434 GRFFile *file;
435 if (config != NULL) {
436 file = GetFileByGRFID(config->ident.grfid);
437 } else {
438 config = _cur.grfconfig;
439 file = _cur.grffile;
442 config->status = GCS_DISABLED;
443 if (file != NULL) ClearTemporaryNewGRFData(file);
444 if (config == _cur.grfconfig) _cur.skip_sprites = -1;
446 if (message != STR_NULL) {
447 delete config->error;
448 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
449 if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
452 return config->error;
456 * Information for mapping static StringIDs.
458 struct StringIDMapping {
459 uint32 grfid; ///< Source NewGRF.
460 StringID source; ///< Source StringID (GRF local).
461 StringID *target; ///< Destination for mapping result.
463 typedef SmallVector<StringIDMapping, 16> StringIDMappingVector;
464 static StringIDMappingVector _string_to_grf_mapping;
467 * Record a static StringID for getting translated later.
468 * @param source Source StringID (GRF local).
469 * @param target Destination for the mapping result.
471 static void AddStringForMapping(StringID source, StringID *target)
473 *target = STR_UNDEFINED;
474 StringIDMapping *item = _string_to_grf_mapping.Append();
475 item->grfid = _cur.grffile->grfid;
476 item->source = source;
477 item->target = target;
481 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
482 * string IDs, but only for the ones we are aware off; the rest
483 * like likely unused and will show a warning.
484 * @param str the string ID to convert
485 * @return the converted string ID
487 static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
489 /* StringID table for TextIDs 0x4E->0x6D */
490 static const StringID units_volume[] = {
491 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
492 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
493 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
494 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
495 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
496 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
497 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
498 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
501 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
502 assert(!IsInsideMM(str, 0xD000, 0xD7FF));
504 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
505 assert_compile(stringend - stringid == end - begin); \
506 if (str >= begin && str <= end) return str + (stringid - begin)
508 /* We have some changes in our cargo strings, resulting in some missing. */
509 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
510 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
511 if (str >= 0x004E && str <= 0x006D) return units_volume[str - 0x004E];
512 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
513 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
514 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
516 /* Map building names according to our lang file changes. There are several
517 * ranges of house ids, all of which need to be remapped to allow newgrfs
518 * to use original house names. */
519 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
520 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
521 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
523 /* Same thing for industries */
524 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
525 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
526 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
527 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
528 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
530 switch (str) {
531 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
532 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
533 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
535 #undef TEXTID_TO_STRINGID
537 if (str == STR_NULL) return STR_EMPTY;
539 DEBUG(grf, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
541 return STR_EMPTY;
545 * Used when setting an object's property to map to the GRF's strings
546 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
547 * @param grfid Id of the grf file.
548 * @param str StringID that we want to have the equivalent in OoenTTD.
549 * @return The properly adjusted StringID.
551 StringID MapGRFStringID(uint32 grfid, StringID str)
553 /* 0xD0 and 0xDC stand for all the TextIDs in the range
554 * of 0xD000 (misc graphics texts) and 0xDC00 (misc persistent texts).
555 * These strings are unique to each grf file, and thus require to be used with the
556 * grfid in which they are declared */
557 switch (GB(str, 8, 8)) {
558 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
559 case 0xDC:
560 return GetGRFStringID(grfid, str);
562 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
563 /* Strings embedded via 0x81 have 0x400 added to them (no real
564 * explanation why...) */
565 return GetGRFStringID(grfid, str - 0x400);
567 default: break;
570 return TTDPStringIDToOTTDStringIDMapping(str);
573 static std::map<uint32, uint32> _grf_id_overrides;
576 * Set the override for a NewGRF
577 * @param source_grfid The grfID which wants to override another NewGRF.
578 * @param target_grfid The grfID which is being overridden.
580 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
582 _grf_id_overrides[source_grfid] = target_grfid;
583 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
587 * Returns the engine associated to a certain internal_id, resp. allocates it.
588 * @param file NewGRF that wants to change the engine.
589 * @param type Vehicle type.
590 * @param internal_id Engine ID inside the NewGRF.
591 * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04).
592 * @return The requested engine.
594 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
596 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
597 * them use the same engine slots. */
598 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
599 if (_settings_game.vehicle.dynamic_engines) {
600 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
601 scope_grfid = file->grfid;
602 uint32 override = _grf_id_overrides[file->grfid];
603 if (override != 0) {
604 scope_grfid = override;
605 const GRFFile *grf_match = GetFileByGRFID(override);
606 if (grf_match == NULL) {
607 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
608 } else {
609 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
613 /* Check if the engine is registered in the override manager */
614 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
615 if (engine != INVALID_ENGINE) {
616 Engine *e = Engine::Get(engine);
617 if (e->grf_prop.grffile == NULL) e->grf_prop.grffile = file;
618 return e;
622 /* Check if there is an unreserved slot */
623 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
624 if (engine != INVALID_ENGINE) {
625 Engine *e = Engine::Get(engine);
627 if (e->grf_prop.grffile == NULL) {
628 e->grf_prop.grffile = file;
629 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
632 /* Reserve the engine slot */
633 if (!static_access) {
634 EngineIDMapping *eid = _engine_mngr.Get(engine);
635 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
638 return e;
641 if (static_access) return NULL;
643 if (!Engine::CanAllocateItem()) {
644 grfmsg(0, "Can't allocate any more engines");
645 return NULL;
648 size_t engine_pool_size = Engine::GetPoolSize();
650 /* ... it's not, so create a new one based off an existing engine */
651 Engine *e = new Engine(type, internal_id);
652 e->grf_prop.grffile = file;
654 /* Reserve the engine slot */
655 assert(_engine_mngr.Length() == e->index);
656 EngineIDMapping *eid = _engine_mngr.Append();
657 eid->type = type;
658 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
659 eid->internal_id = internal_id;
660 eid->substitute_id = min(internal_id, _engine_counts[type]); // substitute_id == _engine_counts[subtype] means "no substitute"
662 if (engine_pool_size != Engine::GetPoolSize()) {
663 /* Resize temporary engine data ... */
664 _gted = ReallocT(_gted, Engine::GetPoolSize());
666 /* and blank the new block. */
667 size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
668 memset(_gted + engine_pool_size, 0, len);
670 if (type == VEH_TRAIN) {
671 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
674 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
676 return e;
680 * Return the ID of a new engine
681 * @param file The NewGRF file providing the engine.
682 * @param type The Vehicle type.
683 * @param internal_id NewGRF-internal ID of the engine.
684 * @return The new EngineID.
685 * @note depending on the dynamic_engine setting and a possible override
686 * property the grfID may be unique or overwriting or partially re-defining
687 * properties of an existing engine.
689 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
691 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
692 if (_settings_game.vehicle.dynamic_engines) {
693 scope_grfid = file->grfid;
694 uint32 override = _grf_id_overrides[file->grfid];
695 if (override != 0) scope_grfid = override;
698 return _engine_mngr.GetID(type, internal_id, scope_grfid);
702 * Map the colour modifiers of TTDPatch to those that Open is using.
703 * @param grf_sprite Pointer to the structure been modified.
705 static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
707 if (HasBit(grf_sprite->pal, 14)) {
708 ClrBit(grf_sprite->pal, 14);
709 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_OPAQUE);
712 if (HasBit(grf_sprite->sprite, 14)) {
713 ClrBit(grf_sprite->sprite, 14);
714 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_TRANSPARENT);
717 if (HasBit(grf_sprite->sprite, 15)) {
718 ClrBit(grf_sprite->sprite, 15);
719 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOUR);
724 * Read a sprite and a palette from the GRF and convert them into a format
725 * suitable to OpenTTD.
726 * @param buf Input stream.
727 * @param read_flags Whether to read TileLayoutFlags.
728 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
729 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
730 * @param feature GrfSpecFeature to use spritesets from.
731 * @param [out] grf_sprite Read sprite and palette.
732 * @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
733 * @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
734 * @return Read TileLayoutFlags.
736 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)
738 grf_sprite->sprite = buf->ReadWord();
739 grf_sprite->pal = buf->ReadWord();
740 TileLayoutFlags flags = read_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
742 MapSpriteMappingRecolour(grf_sprite);
744 bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
745 ClrBit(grf_sprite->pal, 15);
746 if (custom_sprite) {
747 /* Use sprite from Action 1 */
748 uint index = GB(grf_sprite->sprite, 0, 14);
749 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
750 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
751 grf_sprite->sprite = SPR_IMG_QUERY;
752 grf_sprite->pal = PAL_NONE;
753 } else {
754 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
755 if (max_sprite_offset != NULL) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
756 SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
757 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
759 } else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
760 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
761 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
762 return flags;
765 if (flags & TLF_CUSTOM_PALETTE) {
766 /* Use palette from Action 1 */
767 uint index = GB(grf_sprite->pal, 0, 14);
768 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
769 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
770 grf_sprite->pal = PAL_NONE;
771 } else {
772 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
773 if (max_palette_offset != NULL) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
774 SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
775 SetBit(grf_sprite->pal, SPRITE_MODIFIER_CUSTOM_SPRITE);
777 } else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
778 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
779 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
780 return flags;
783 return flags;
787 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
788 * @param buf Input stream.
789 * @param flags TileLayoutFlags to process.
790 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
791 * @param dts Sprite layout to insert data into.
792 * @param index Sprite index to process; 0 for ground sprite.
794 static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bool is_parent, NewGRFSpriteLayout *dts, uint index)
796 if (!(flags & TLF_DRAWING_FLAGS)) return;
798 if (dts->registers == NULL) dts->AllocateRegisters();
799 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[index]);
800 regs.flags = flags & TLF_DRAWING_FLAGS;
802 if (flags & TLF_DODRAW) regs.dodraw = buf->ReadByte();
803 if (flags & TLF_SPRITE) regs.sprite = buf->ReadByte();
804 if (flags & TLF_PALETTE) regs.palette = buf->ReadByte();
806 if (is_parent) {
807 if (flags & TLF_BB_XY_OFFSET) {
808 regs.delta.parent[0] = buf->ReadByte();
809 regs.delta.parent[1] = buf->ReadByte();
811 if (flags & TLF_BB_Z_OFFSET) regs.delta.parent[2] = buf->ReadByte();
812 } else {
813 if (flags & TLF_CHILD_X_OFFSET) regs.delta.child[0] = buf->ReadByte();
814 if (flags & TLF_CHILD_Y_OFFSET) regs.delta.child[1] = buf->ReadByte();
817 if (flags & TLF_SPRITE_VAR10) {
818 regs.sprite_var10 = buf->ReadByte();
819 if (regs.sprite_var10 > TLR_MAX_VAR10) {
820 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
821 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
822 return;
826 if (flags & TLF_PALETTE_VAR10) {
827 regs.palette_var10 = buf->ReadByte();
828 if (regs.palette_var10 > TLR_MAX_VAR10) {
829 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
830 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
831 return;
837 * Read a spritelayout from the GRF.
838 * @param buf Input
839 * @param num_building_sprites Number of building sprites to read
840 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
841 * @param feature GrfSpecFeature to use spritesets from.
842 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
843 * @param no_z_position Whether bounding boxes have no Z offset
844 * @param dts Layout container to output into
845 * @return True on error (GRF was disabled).
847 static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
849 bool has_flags = HasBit(num_building_sprites, 6);
850 ClrBit(num_building_sprites, 6);
851 TileLayoutFlags valid_flags = TLF_KNOWN_FLAGS;
852 if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
853 dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags
855 uint16 *max_sprite_offset = AllocaM(uint16, num_building_sprites + 1);
856 uint16 *max_palette_offset = AllocaM(uint16, num_building_sprites + 1);
857 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
858 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
860 /* Groundsprite */
861 TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground, max_sprite_offset, max_palette_offset);
862 if (_cur.skip_sprites < 0) return true;
864 if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
865 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
866 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
867 return true;
870 ReadSpriteLayoutRegisters(buf, flags, false, dts, 0);
871 if (_cur.skip_sprites < 0) return true;
873 for (uint i = 0; i < num_building_sprites; i++) {
874 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&dts->seq[i]);
876 flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
877 if (_cur.skip_sprites < 0) return true;
879 if (flags & ~valid_flags) {
880 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
881 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
882 return true;
885 seq->delta_x = buf->ReadByte();
886 seq->delta_y = buf->ReadByte();
888 if (!no_z_position) seq->delta_z = buf->ReadByte();
890 if (seq->IsParentSprite()) {
891 seq->size_x = buf->ReadByte();
892 seq->size_y = buf->ReadByte();
893 seq->size_z = buf->ReadByte();
896 ReadSpriteLayoutRegisters(buf, flags, seq->IsParentSprite(), dts, i + 1);
897 if (_cur.skip_sprites < 0) return true;
900 /* Check if the number of sprites per spriteset is consistent */
901 bool is_consistent = true;
902 dts->consistent_max_offset = 0;
903 for (uint i = 0; i < num_building_sprites + 1; i++) {
904 if (max_sprite_offset[i] > 0) {
905 if (dts->consistent_max_offset == 0) {
906 dts->consistent_max_offset = max_sprite_offset[i];
907 } else if (dts->consistent_max_offset != max_sprite_offset[i]) {
908 is_consistent = false;
909 break;
912 if (max_palette_offset[i] > 0) {
913 if (dts->consistent_max_offset == 0) {
914 dts->consistent_max_offset = max_palette_offset[i];
915 } else if (dts->consistent_max_offset != max_palette_offset[i]) {
916 is_consistent = false;
917 break;
922 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
923 assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX)));
925 if (!is_consistent || dts->registers != NULL) {
926 dts->consistent_max_offset = 0;
927 if (dts->registers == NULL) dts->AllocateRegisters();
929 for (uint i = 0; i < num_building_sprites + 1; i++) {
930 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[i]);
931 regs.max_sprite_offset = max_sprite_offset[i];
932 regs.max_palette_offset = max_palette_offset[i];
936 return false;
940 * Translate the refit mask.
942 static uint32 TranslateRefitMask(uint32 refit_mask)
944 uint32 result = 0;
945 uint8 bit;
946 FOR_EACH_SET_BIT(bit, refit_mask) {
947 CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true);
948 if (cargo != CT_INVALID) SetBit(result, cargo);
950 return result;
954 * Converts TTD(P) Base Price pointers into the enum used by OTTD
955 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
956 * @param base_pointer TTD(P) Base Price Pointer
957 * @param error_location Function name for grf error messages
958 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
960 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
962 /* Special value for 'none' */
963 if (base_pointer == 0) {
964 *index = INVALID_PRICE;
965 return;
968 static const uint32 start = 0x4B34; ///< Position of first base price
969 static const uint32 size = 6; ///< Size of each base price record
971 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
972 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
973 return;
976 *index = (Price)((base_pointer - start) / size);
979 /** Possible return values for the FeatureChangeInfo functions */
980 enum ChangeInfoResult {
981 CIR_SUCCESS, ///< Variable was parsed and read
982 CIR_DISABLED, ///< GRF was disabled due to error
983 CIR_UNHANDLED, ///< Variable was parsed but unread
984 CIR_UNKNOWN, ///< Variable is unknown
985 CIR_INVALID_ID, ///< Attempt to modify an invalid ID
988 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
991 * Define properties common to all vehicles
992 * @param ei Engine info.
993 * @param prop The property to change.
994 * @param buf The property value.
995 * @return ChangeInfoResult.
997 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
999 switch (prop) {
1000 case 0x00: // Introduction date
1001 ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
1002 break;
1004 case 0x02: // Decay speed
1005 ei->decay_speed = buf->ReadByte();
1006 break;
1008 case 0x03: // Vehicle life
1009 ei->lifelength = buf->ReadByte();
1010 break;
1012 case 0x04: // Model life
1013 ei->base_life = buf->ReadByte();
1014 break;
1016 case 0x06: // Climates available
1017 ei->climates = buf->ReadByte();
1018 break;
1020 case PROP_VEHICLE_LOAD_AMOUNT: // 0x07 Loading speed
1021 /* Amount of cargo loaded during a vehicle's "loading tick" */
1022 ei->load_amount = buf->ReadByte();
1023 break;
1025 default:
1026 return CIR_UNKNOWN;
1029 return CIR_SUCCESS;
1033 * Define properties for rail vehicles
1034 * @param engine :ocal ID of the first vehicle.
1035 * @param numinfo Number of subsequent IDs to change the property for.
1036 * @param prop The property to change.
1037 * @param buf The property value.
1038 * @return ChangeInfoResult.
1040 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1042 ChangeInfoResult ret = CIR_SUCCESS;
1044 for (int i = 0; i < numinfo; i++) {
1045 Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i);
1046 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1048 EngineInfo *ei = &e->info;
1049 RailVehicleInfo *rvi = &e->u.rail;
1051 switch (prop) {
1052 case 0x05: { // Track type
1053 uint8 tracktype = buf->ReadByte();
1055 if (tracktype < _cur.grffile->railtype_list.Length()) {
1056 _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype];
1057 break;
1060 switch (tracktype) {
1061 case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
1062 case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
1063 case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
1064 default:
1065 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1066 break;
1068 break;
1071 case 0x08: // AI passenger service
1072 /* Tells the AI that this engine is designed for
1073 * passenger services and shouldn't be used for freight. */
1074 rvi->ai_passenger_only = buf->ReadByte();
1075 break;
1077 case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
1078 uint16 speed = buf->ReadWord();
1079 if (speed == 0xFFFF) speed = 0;
1081 rvi->max_speed = speed;
1082 break;
1085 case PROP_TRAIN_POWER: // 0x0B Power
1086 rvi->power = buf->ReadWord();
1088 /* Set engine / wagon state based on power */
1089 if (rvi->power != 0) {
1090 if (rvi->railveh_type == RAILVEH_WAGON) {
1091 rvi->railveh_type = RAILVEH_SINGLEHEAD;
1093 } else {
1094 rvi->railveh_type = RAILVEH_WAGON;
1096 break;
1098 case PROP_TRAIN_RUNNING_COST_FACTOR: // 0x0D Running cost factor
1099 rvi->running_cost = buf->ReadByte();
1100 break;
1102 case 0x0E: // Running cost base
1103 ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
1104 break;
1106 case 0x12: { // Sprite ID
1107 uint8 spriteid = buf->ReadByte();
1108 uint8 orig_spriteid = spriteid;
1110 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1111 * as an array index, so we need it to be half the original value. */
1112 if (spriteid < 0xFD) spriteid >>= 1;
1114 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1115 rvi->image_index = spriteid;
1116 } else {
1117 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1118 rvi->image_index = 0;
1120 break;
1123 case 0x13: { // Dual-headed
1124 uint8 dual = buf->ReadByte();
1126 if (dual != 0) {
1127 rvi->railveh_type = RAILVEH_MULTIHEAD;
1128 } else {
1129 rvi->railveh_type = rvi->power == 0 ?
1130 RAILVEH_WAGON : RAILVEH_SINGLEHEAD;
1132 break;
1135 case PROP_TRAIN_CARGO_CAPACITY: // 0x14 Cargo capacity
1136 rvi->capacity = buf->ReadByte();
1137 break;
1139 case 0x15: { // Cargo type
1140 _gted[e->index].defaultcargo_grf = _cur.grffile;
1141 uint8 ctype = buf->ReadByte();
1143 if (ctype == 0xFF) {
1144 /* 0xFF is specified as 'use first refittable' */
1145 ei->cargo_type = CT_INVALID;
1146 } else if (_cur.grffile->grf_version >= 8) {
1147 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1148 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1149 } else if (ctype < NUM_CARGO) {
1150 /* Use untranslated cargo. */
1151 ei->cargo_type = ctype;
1152 } else {
1153 ei->cargo_type = CT_INVALID;
1154 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1156 break;
1159 case PROP_TRAIN_WEIGHT: // 0x16 Weight
1160 SB(rvi->weight, 0, 8, buf->ReadByte());
1161 break;
1163 case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
1164 rvi->cost_factor = buf->ReadByte();
1165 break;
1167 case 0x18: // AI rank
1168 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1169 buf->ReadByte();
1170 break;
1172 case 0x19: { // Engine traction type
1173 /* What do the individual numbers mean?
1174 * 0x00 .. 0x07: Steam
1175 * 0x08 .. 0x27: Diesel
1176 * 0x28 .. 0x31: Electric
1177 * 0x32 .. 0x37: Monorail
1178 * 0x38 .. 0x41: Maglev
1180 uint8 traction = buf->ReadByte();
1181 EngineClass engclass;
1183 if (traction <= 0x07) {
1184 engclass = EC_STEAM;
1185 } else if (traction <= 0x27) {
1186 engclass = EC_DIESEL;
1187 } else if (traction <= 0x31) {
1188 engclass = EC_ELECTRIC;
1189 } else if (traction <= 0x37) {
1190 engclass = EC_MONORAIL;
1191 } else if (traction <= 0x41) {
1192 engclass = EC_MAGLEV;
1193 } else {
1194 break;
1197 if (_cur.grffile->railtype_list.Length() == 0) {
1198 /* Use traction type to select between normal and electrified
1199 * rail only when no translation list is in place. */
1200 if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1201 if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
1204 rvi->engclass = engclass;
1205 break;
1208 case 0x1A: // Alter purchase list sort order
1209 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1210 break;
1212 case 0x1B: // Powered wagons power bonus
1213 rvi->pow_wag_power = buf->ReadWord();
1214 break;
1216 case 0x1C: // Refit cost
1217 ei->refit_cost = buf->ReadByte();
1218 break;
1220 case 0x1D: { // Refit cargo
1221 uint32 mask = buf->ReadDWord();
1222 _gted[e->index].UpdateRefittability(mask != 0);
1223 ei->refit_mask = TranslateRefitMask(mask);
1224 _gted[e->index].defaultcargo_grf = _cur.grffile;
1225 break;
1228 case 0x1E: // Callback
1229 ei->callback_mask = buf->ReadByte();
1230 break;
1232 case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
1233 rvi->tractive_effort = buf->ReadByte();
1234 break;
1236 case 0x20: // Air drag
1237 rvi->air_drag = buf->ReadByte();
1238 break;
1240 case PROP_TRAIN_SHORTEN_FACTOR: // 0x21 Shorter vehicle
1241 rvi->shorten_factor = buf->ReadByte();
1242 break;
1244 case 0x22: // Visual effect
1245 rvi->visual_effect = buf->ReadByte();
1246 /* Avoid accidentally setting visual_effect to the default value
1247 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1248 if (rvi->visual_effect == VE_DEFAULT) {
1249 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1250 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1252 break;
1254 case 0x23: // Powered wagons weight bonus
1255 rvi->pow_wag_weight = buf->ReadByte();
1256 break;
1258 case 0x24: { // High byte of vehicle weight
1259 byte weight = buf->ReadByte();
1261 if (weight > 4) {
1262 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1263 } else {
1264 SB(rvi->weight, 8, 8, weight);
1266 break;
1269 case PROP_TRAIN_USER_DATA: // 0x25 User-defined bit mask to set when checking veh. var. 42
1270 rvi->user_def_data = buf->ReadByte();
1271 break;
1273 case 0x26: // Retire vehicle early
1274 ei->retire_early = buf->ReadByte();
1275 break;
1277 case 0x27: // Miscellaneous flags
1278 ei->misc_flags = buf->ReadByte();
1279 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1280 _gted[e->index].prop27_set = true;
1281 break;
1283 case 0x28: // Cargo classes allowed
1284 _gted[e->index].cargo_allowed = buf->ReadWord();
1285 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1286 _gted[e->index].defaultcargo_grf = _cur.grffile;
1287 break;
1289 case 0x29: // Cargo classes disallowed
1290 _gted[e->index].cargo_disallowed = buf->ReadWord();
1291 _gted[e->index].UpdateRefittability(false);
1292 break;
1294 case 0x2A: // Long format introduction date (days since year 0)
1295 ei->base_intro = buf->ReadDWord();
1296 break;
1298 case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
1299 ei->cargo_age_period = buf->ReadWord();
1300 break;
1302 case 0x2C: // CTT refit include list
1303 case 0x2D: { // CTT refit exclude list
1304 uint8 count = buf->ReadByte();
1305 _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
1306 if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile;
1307 uint32 &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1308 ctt = 0;
1309 while (count--) {
1310 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1311 if (ctype == CT_INVALID) continue;
1312 SetBit(ctt, ctype);
1314 break;
1317 default:
1318 ret = CommonVehicleChangeInfo(ei, prop, buf);
1319 break;
1323 return ret;
1327 * Define properties for road vehicles
1328 * @param engine Local ID of the first vehicle.
1329 * @param numinfo Number of subsequent IDs to change the property for.
1330 * @param prop The property to change.
1331 * @param buf The property value.
1332 * @return ChangeInfoResult.
1334 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1336 ChangeInfoResult ret = CIR_SUCCESS;
1338 for (int i = 0; i < numinfo; i++) {
1339 Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i);
1340 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1342 EngineInfo *ei = &e->info;
1343 RoadVehicleInfo *rvi = &e->u.road;
1345 switch (prop) {
1346 case 0x08: // Speed (1 unit is 0.5 kmh)
1347 rvi->max_speed = buf->ReadByte();
1348 break;
1350 case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1351 rvi->running_cost = buf->ReadByte();
1352 break;
1354 case 0x0A: // Running cost base
1355 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1356 break;
1358 case 0x0E: { // Sprite ID
1359 uint8 spriteid = buf->ReadByte();
1360 uint8 orig_spriteid = spriteid;
1362 /* cars have different custom id in the GRF file */
1363 if (spriteid == 0xFF) spriteid = 0xFD;
1365 if (spriteid < 0xFD) spriteid >>= 1;
1367 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1368 rvi->image_index = spriteid;
1369 } else {
1370 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1371 rvi->image_index = 0;
1373 break;
1376 case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1377 rvi->capacity = buf->ReadByte();
1378 break;
1380 case 0x10: { // Cargo type
1381 _gted[e->index].defaultcargo_grf = _cur.grffile;
1382 uint8 ctype = buf->ReadByte();
1384 if (ctype == 0xFF) {
1385 /* 0xFF is specified as 'use first refittable' */
1386 ei->cargo_type = CT_INVALID;
1387 } else if (_cur.grffile->grf_version >= 8) {
1388 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1389 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1390 } else if (ctype < NUM_CARGO) {
1391 /* Use untranslated cargo. */
1392 ei->cargo_type = ctype;
1393 } else {
1394 ei->cargo_type = CT_INVALID;
1395 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1397 break;
1400 case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1401 rvi->cost_factor = buf->ReadByte();
1402 break;
1404 case 0x12: // SFX
1405 rvi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1406 break;
1408 case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1409 rvi->power = buf->ReadByte();
1410 break;
1412 case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1413 rvi->weight = buf->ReadByte();
1414 break;
1416 case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1417 _gted[e->index].rv_max_speed = buf->ReadByte();
1418 break;
1420 case 0x16: { // Cargoes available for refitting
1421 uint32 mask = buf->ReadDWord();
1422 _gted[e->index].UpdateRefittability(mask != 0);
1423 ei->refit_mask = TranslateRefitMask(mask);
1424 _gted[e->index].defaultcargo_grf = _cur.grffile;
1425 break;
1428 case 0x17: // Callback mask
1429 ei->callback_mask = buf->ReadByte();
1430 break;
1432 case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1433 rvi->tractive_effort = buf->ReadByte();
1434 break;
1436 case 0x19: // Air drag
1437 rvi->air_drag = buf->ReadByte();
1438 break;
1440 case 0x1A: // Refit cost
1441 ei->refit_cost = buf->ReadByte();
1442 break;
1444 case 0x1B: // Retire vehicle early
1445 ei->retire_early = buf->ReadByte();
1446 break;
1448 case 0x1C: // Miscellaneous flags
1449 ei->misc_flags = buf->ReadByte();
1450 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1451 break;
1453 case 0x1D: // Cargo classes allowed
1454 _gted[e->index].cargo_allowed = buf->ReadWord();
1455 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1456 _gted[e->index].defaultcargo_grf = _cur.grffile;
1457 break;
1459 case 0x1E: // Cargo classes disallowed
1460 _gted[e->index].cargo_disallowed = buf->ReadWord();
1461 _gted[e->index].UpdateRefittability(false);
1462 break;
1464 case 0x1F: // Long format introduction date (days since year 0)
1465 ei->base_intro = buf->ReadDWord();
1466 break;
1468 case 0x20: // Alter purchase list sort order
1469 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1470 break;
1472 case 0x21: // Visual effect
1473 rvi->visual_effect = buf->ReadByte();
1474 /* Avoid accidentally setting visual_effect to the default value
1475 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1476 if (rvi->visual_effect == VE_DEFAULT) {
1477 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1478 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1480 break;
1482 case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1483 ei->cargo_age_period = buf->ReadWord();
1484 break;
1486 case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
1487 rvi->shorten_factor = buf->ReadByte();
1488 break;
1490 case 0x24: // CTT refit include list
1491 case 0x25: { // CTT refit exclude list
1492 uint8 count = buf->ReadByte();
1493 _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
1494 if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
1495 uint32 &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1496 ctt = 0;
1497 while (count--) {
1498 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1499 if (ctype == CT_INVALID) continue;
1500 SetBit(ctt, ctype);
1502 break;
1505 default:
1506 ret = CommonVehicleChangeInfo(ei, prop, buf);
1507 break;
1511 return ret;
1515 * Define properties for ships
1516 * @param engine Local ID of the first vehicle.
1517 * @param numinfo Number of subsequent IDs to change the property for.
1518 * @param prop The property to change.
1519 * @param buf The property value.
1520 * @return ChangeInfoResult.
1522 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1524 ChangeInfoResult ret = CIR_SUCCESS;
1526 for (int i = 0; i < numinfo; i++) {
1527 Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1528 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1530 EngineInfo *ei = &e->info;
1531 ShipVehicleInfo *svi = &e->u.ship;
1533 switch (prop) {
1534 case 0x08: { // Sprite ID
1535 uint8 spriteid = buf->ReadByte();
1536 uint8 orig_spriteid = spriteid;
1538 /* ships have different custom id in the GRF file */
1539 if (spriteid == 0xFF) spriteid = 0xFD;
1541 if (spriteid < 0xFD) spriteid >>= 1;
1543 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1544 svi->image_index = spriteid;
1545 } else {
1546 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1547 svi->image_index = 0;
1549 break;
1552 case 0x09: // Refittable
1553 svi->old_refittable = (buf->ReadByte() != 0);
1554 break;
1556 case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1557 svi->cost_factor = buf->ReadByte();
1558 break;
1560 case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1561 svi->max_speed = buf->ReadByte();
1562 break;
1564 case 0x0C: { // Cargo type
1565 _gted[e->index].defaultcargo_grf = _cur.grffile;
1566 uint8 ctype = buf->ReadByte();
1568 if (ctype == 0xFF) {
1569 /* 0xFF is specified as 'use first refittable' */
1570 ei->cargo_type = CT_INVALID;
1571 } else if (_cur.grffile->grf_version >= 8) {
1572 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1573 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1574 } else if (ctype < NUM_CARGO) {
1575 /* Use untranslated cargo. */
1576 ei->cargo_type = ctype;
1577 } else {
1578 ei->cargo_type = CT_INVALID;
1579 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1581 break;
1584 case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1585 svi->capacity = buf->ReadWord();
1586 break;
1588 case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1589 svi->running_cost = buf->ReadByte();
1590 break;
1592 case 0x10: // SFX
1593 svi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1594 break;
1596 case 0x11: { // Cargoes available for refitting
1597 uint32 mask = buf->ReadDWord();
1598 _gted[e->index].UpdateRefittability(mask != 0);
1599 ei->refit_mask = TranslateRefitMask(mask);
1600 _gted[e->index].defaultcargo_grf = _cur.grffile;
1601 break;
1604 case 0x12: // Callback mask
1605 ei->callback_mask = buf->ReadByte();
1606 break;
1608 case 0x13: // Refit cost
1609 ei->refit_cost = buf->ReadByte();
1610 break;
1612 case 0x14: // Ocean speed fraction
1613 svi->ocean_speed_frac = buf->ReadByte();
1614 break;
1616 case 0x15: // Canal speed fraction
1617 svi->canal_speed_frac = buf->ReadByte();
1618 break;
1620 case 0x16: // Retire vehicle early
1621 ei->retire_early = buf->ReadByte();
1622 break;
1624 case 0x17: // Miscellaneous flags
1625 ei->misc_flags = buf->ReadByte();
1626 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1627 break;
1629 case 0x18: // Cargo classes allowed
1630 _gted[e->index].cargo_allowed = buf->ReadWord();
1631 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1632 _gted[e->index].defaultcargo_grf = _cur.grffile;
1633 break;
1635 case 0x19: // Cargo classes disallowed
1636 _gted[e->index].cargo_disallowed = buf->ReadWord();
1637 _gted[e->index].UpdateRefittability(false);
1638 break;
1640 case 0x1A: // Long format introduction date (days since year 0)
1641 ei->base_intro = buf->ReadDWord();
1642 break;
1644 case 0x1B: // Alter purchase list sort order
1645 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1646 break;
1648 case 0x1C: // Visual effect
1649 svi->visual_effect = buf->ReadByte();
1650 /* Avoid accidentally setting visual_effect to the default value
1651 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1652 if (svi->visual_effect == VE_DEFAULT) {
1653 assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1654 SB(svi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1656 break;
1658 case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1659 ei->cargo_age_period = buf->ReadWord();
1660 break;
1662 case 0x1E: // CTT refit include list
1663 case 0x1F: { // CTT refit exclude list
1664 uint8 count = buf->ReadByte();
1665 _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
1666 if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
1667 uint32 &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1668 ctt = 0;
1669 while (count--) {
1670 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1671 if (ctype == CT_INVALID) continue;
1672 SetBit(ctt, ctype);
1674 break;
1677 default:
1678 ret = CommonVehicleChangeInfo(ei, prop, buf);
1679 break;
1683 return ret;
1687 * Define properties for aircraft
1688 * @param engine Local ID of the aircraft.
1689 * @param numinfo Number of subsequent IDs to change the property for.
1690 * @param prop The property to change.
1691 * @param buf The property value.
1692 * @return ChangeInfoResult.
1694 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1696 ChangeInfoResult ret = CIR_SUCCESS;
1698 for (int i = 0; i < numinfo; i++) {
1699 Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1700 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1702 EngineInfo *ei = &e->info;
1703 AircraftVehicleInfo *avi = &e->u.air;
1705 switch (prop) {
1706 case 0x08: { // Sprite ID
1707 uint8 spriteid = buf->ReadByte();
1708 uint8 orig_spriteid = spriteid;
1710 /* aircraft have different custom id in the GRF file */
1711 if (spriteid == 0xFF) spriteid = 0xFD;
1713 if (spriteid < 0xFD) spriteid >>= 1;
1715 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1716 avi->image_index = spriteid;
1717 } else {
1718 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1719 avi->image_index = 0;
1721 break;
1724 case 0x09: // Helicopter
1725 if (buf->ReadByte() == 0) {
1726 avi->subtype = AIR_HELI;
1727 } else {
1728 SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1730 break;
1732 case 0x0A: // Large
1733 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1734 break;
1736 case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1737 avi->cost_factor = buf->ReadByte();
1738 break;
1740 case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1741 avi->max_speed = (buf->ReadByte() * 128) / 10;
1742 break;
1744 case 0x0D: // Acceleration
1745 avi->acceleration = buf->ReadByte();
1746 break;
1748 case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1749 avi->running_cost = buf->ReadByte();
1750 break;
1752 case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1753 avi->passenger_capacity = buf->ReadWord();
1754 break;
1756 case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1757 avi->mail_capacity = buf->ReadByte();
1758 break;
1760 case 0x12: // SFX
1761 avi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1762 break;
1764 case 0x13: { // Cargoes available for refitting
1765 uint32 mask = buf->ReadDWord();
1766 _gted[e->index].UpdateRefittability(mask != 0);
1767 ei->refit_mask = TranslateRefitMask(mask);
1768 _gted[e->index].defaultcargo_grf = _cur.grffile;
1769 break;
1772 case 0x14: // Callback mask
1773 ei->callback_mask = buf->ReadByte();
1774 break;
1776 case 0x15: // Refit cost
1777 ei->refit_cost = buf->ReadByte();
1778 break;
1780 case 0x16: // Retire vehicle early
1781 ei->retire_early = buf->ReadByte();
1782 break;
1784 case 0x17: // Miscellaneous flags
1785 ei->misc_flags = buf->ReadByte();
1786 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1787 break;
1789 case 0x18: // Cargo classes allowed
1790 _gted[e->index].cargo_allowed = buf->ReadWord();
1791 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1792 _gted[e->index].defaultcargo_grf = _cur.grffile;
1793 break;
1795 case 0x19: // Cargo classes disallowed
1796 _gted[e->index].cargo_disallowed = buf->ReadWord();
1797 _gted[e->index].UpdateRefittability(false);
1798 break;
1800 case 0x1A: // Long format introduction date (days since year 0)
1801 ei->base_intro = buf->ReadDWord();
1802 break;
1804 case 0x1B: // Alter purchase list sort order
1805 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1806 break;
1808 case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1809 ei->cargo_age_period = buf->ReadWord();
1810 break;
1812 case 0x1D: // CTT refit include list
1813 case 0x1E: { // CTT refit exclude list
1814 uint8 count = buf->ReadByte();
1815 _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
1816 if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
1817 uint32 &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1818 ctt = 0;
1819 while (count--) {
1820 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1821 if (ctype == CT_INVALID) continue;
1822 SetBit(ctt, ctype);
1824 break;
1827 case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
1828 avi->max_range = buf->ReadWord();
1829 break;
1831 default:
1832 ret = CommonVehicleChangeInfo(ei, prop, buf);
1833 break;
1837 return ret;
1841 * Define properties for stations
1842 * @param stdid StationID of the first station tile.
1843 * @param numinfo Number of subsequent station tiles to change the property for.
1844 * @param prop The property to change.
1845 * @param buf The property value.
1846 * @return ChangeInfoResult.
1848 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
1850 ChangeInfoResult ret = CIR_SUCCESS;
1852 if (stid + numinfo > NUM_STATIONS_PER_GRF) {
1853 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
1854 return CIR_INVALID_ID;
1857 /* Allocate station specs if necessary */
1858 if (_cur.grffile->stations == NULL) _cur.grffile->stations = CallocT<StationSpec*>(NUM_STATIONS_PER_GRF);
1860 for (int i = 0; i < numinfo; i++) {
1861 StationSpec *statspec = _cur.grffile->stations[stid + i];
1863 /* Check that the station we are modifying is defined. */
1864 if (statspec == NULL && prop != 0x08) {
1865 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1866 return CIR_INVALID_ID;
1869 switch (prop) {
1870 case 0x08: { // Class ID
1871 StationSpec **spec = &_cur.grffile->stations[stid + i];
1873 /* Property 0x08 is special; it is where the station is allocated */
1874 if (*spec == NULL) *spec = CallocT<StationSpec>(1);
1876 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1877 uint32 classid = buf->ReadDWord();
1878 (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
1879 break;
1882 case 0x09: // Define sprite layout
1883 statspec->tiles = buf->ReadExtendedByte();
1884 delete[] statspec->renderdata; // delete earlier loaded stuff
1885 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1887 for (uint t = 0; t < statspec->tiles; t++) {
1888 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1889 dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
1891 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1892 buf->Skip(4);
1893 extern const DrawTileSprites _station_display_datas_rail[8];
1894 dts->Clone(&_station_display_datas_rail[t % 8]);
1895 continue;
1898 ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
1899 /* On error, bail out immediately. Temporary GRF data was already freed */
1900 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1902 static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
1903 tmp_layout.Clear();
1904 for (;;) {
1905 /* no relative bounding box support */
1906 DrawTileSeqStruct *dtss = tmp_layout.Append();
1907 MemSetT(dtss, 0);
1909 dtss->delta_x = buf->ReadByte();
1910 if (dtss->IsTerminator()) break;
1911 dtss->delta_y = buf->ReadByte();
1912 dtss->delta_z = buf->ReadByte();
1913 dtss->size_x = buf->ReadByte();
1914 dtss->size_y = buf->ReadByte();
1915 dtss->size_z = buf->ReadByte();
1917 ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss->image);
1918 /* On error, bail out immediately. Temporary GRF data was already freed */
1919 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1921 dts->Clone(tmp_layout.Begin());
1923 break;
1925 case 0x0A: { // Copy sprite layout
1926 byte srcid = buf->ReadByte();
1927 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1929 if (srcstatspec == NULL) {
1930 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1931 continue;
1934 delete[] statspec->renderdata; // delete earlier loaded stuff
1936 statspec->tiles = srcstatspec->tiles;
1937 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1938 for (uint t = 0; t < statspec->tiles; t++) {
1939 statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
1941 break;
1944 case 0x0B: // Callback mask
1945 statspec->callback_mask = buf->ReadByte();
1946 break;
1948 case 0x0C: // Disallowed number of platforms
1949 statspec->disallowed_platforms = buf->ReadByte();
1950 break;
1952 case 0x0D: // Disallowed platform lengths
1953 statspec->disallowed_lengths = buf->ReadByte();
1954 break;
1956 case 0x0E: // Define custom layout
1957 statspec->copied_layouts = false;
1959 while (buf->HasData()) {
1960 byte length = buf->ReadByte();
1961 byte number = buf->ReadByte();
1962 StationLayout layout;
1963 uint l, p;
1965 if (length == 0 || number == 0) break;
1967 if (length > statspec->lengths) {
1968 statspec->platforms = ReallocT(statspec->platforms, length);
1969 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
1971 statspec->layouts = ReallocT(statspec->layouts, length);
1972 memset(statspec->layouts + statspec->lengths, 0,
1973 (length - statspec->lengths) * sizeof(*statspec->layouts));
1975 statspec->lengths = length;
1977 l = length - 1; // index is zero-based
1979 if (number > statspec->platforms[l]) {
1980 statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
1981 /* We expect NULL being 0 here, but C99 guarantees that. */
1982 memset(statspec->layouts[l] + statspec->platforms[l], 0,
1983 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
1985 statspec->platforms[l] = number;
1988 p = 0;
1989 layout = MallocT<byte>(length * number);
1990 try {
1991 for (l = 0; l < length; l++) {
1992 for (p = 0; p < number; p++) {
1993 layout[l * number + p] = buf->ReadByte();
1996 } catch (...) {
1997 free(layout);
1998 throw;
2001 l--;
2002 p--;
2003 free(statspec->layouts[l][p]);
2004 statspec->layouts[l][p] = layout;
2006 break;
2008 case 0x0F: { // Copy custom layout
2009 byte srcid = buf->ReadByte();
2010 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
2012 if (srcstatspec == NULL) {
2013 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2014 continue;
2017 statspec->lengths = srcstatspec->lengths;
2018 statspec->platforms = srcstatspec->platforms;
2019 statspec->layouts = srcstatspec->layouts;
2020 statspec->copied_layouts = true;
2021 break;
2024 case 0x10: // Little/lots cargo threshold
2025 statspec->cargo_threshold = buf->ReadWord();
2026 break;
2028 case 0x11: // Pylon placement
2029 statspec->pylons = buf->ReadByte();
2030 break;
2032 case 0x12: // Cargo types for random triggers
2033 statspec->cargo_triggers = buf->ReadDWord();
2034 if (_cur.grffile->grf_version >= 7) {
2035 statspec->cargo_triggers = TranslateRefitMask(statspec->cargo_triggers);
2037 break;
2039 case 0x13: // General flags
2040 statspec->flags = buf->ReadByte();
2041 break;
2043 case 0x14: // Overhead wire placement
2044 statspec->wires = buf->ReadByte();
2045 break;
2047 case 0x15: // Blocked tiles
2048 statspec->blocked = buf->ReadByte();
2049 break;
2051 case 0x16: // Animation info
2052 statspec->animation.frames = buf->ReadByte();
2053 statspec->animation.status = buf->ReadByte();
2054 break;
2056 case 0x17: // Animation speed
2057 statspec->animation.speed = buf->ReadByte();
2058 break;
2060 case 0x18: // Animation triggers
2061 statspec->animation.triggers = buf->ReadWord();
2062 break;
2064 case 0x1A: // Advanced sprite layout
2065 statspec->tiles = buf->ReadExtendedByte();
2066 delete[] statspec->renderdata; // delete earlier loaded stuff
2067 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
2069 for (uint t = 0; t < statspec->tiles; t++) {
2070 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
2071 uint num_building_sprites = buf->ReadByte();
2072 /* On error, bail out immediately. Temporary GRF data was already freed */
2073 if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED;
2075 break;
2077 default:
2078 ret = CIR_UNKNOWN;
2079 break;
2083 return ret;
2087 * Define properties for water features
2088 * @param id Type of the first water feature.
2089 * @param numinfo Number of subsequent water feature ids to change the property for.
2090 * @param prop The property to change.
2091 * @param buf The property value.
2092 * @return ChangeInfoResult.
2094 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
2096 ChangeInfoResult ret = CIR_SUCCESS;
2098 if (id + numinfo > CF_END) {
2099 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id + numinfo, CF_END);
2100 return CIR_INVALID_ID;
2103 for (int i = 0; i < numinfo; i++) {
2104 CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
2106 switch (prop) {
2107 case 0x08:
2108 cp->callback_mask = buf->ReadByte();
2109 break;
2111 case 0x09:
2112 cp->flags = buf->ReadByte();
2113 break;
2115 default:
2116 ret = CIR_UNKNOWN;
2117 break;
2121 return ret;
2125 * Define properties for bridges
2126 * @param brid BridgeID of the bridge.
2127 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2128 * @param prop The property to change.
2129 * @param buf The property value.
2130 * @return ChangeInfoResult.
2132 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
2134 ChangeInfoResult ret = CIR_SUCCESS;
2136 if (brid + numinfo > MAX_BRIDGES) {
2137 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
2138 return CIR_INVALID_ID;
2141 for (int i = 0; i < numinfo; i++) {
2142 BridgeSpec *bridge = &_bridge[brid + i];
2144 switch (prop) {
2145 case 0x08: { // Year of availability
2146 /* We treat '0' as always available */
2147 byte year = buf->ReadByte();
2148 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
2149 break;
2152 case 0x09: // Minimum length
2153 bridge->min_length = buf->ReadByte();
2154 break;
2156 case 0x0A: // Maximum length
2157 bridge->max_length = buf->ReadByte();
2158 if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
2159 break;
2161 case 0x0B: // Cost factor
2162 bridge->price = buf->ReadByte();
2163 break;
2165 case 0x0C: // Maximum speed
2166 bridge->speed = buf->ReadWord();
2167 break;
2169 case 0x0D: { // Bridge sprite tables
2170 byte tableid = buf->ReadByte();
2171 byte numtables = buf->ReadByte();
2173 if (bridge->sprite_table == NULL) {
2174 /* Allocate memory for sprite table pointers and zero out */
2175 bridge->sprite_table = CallocT<PalSpriteID*>(7);
2178 for (; numtables-- != 0; tableid++) {
2179 if (tableid >= 7) { // skip invalid data
2180 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2181 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2182 continue;
2185 if (bridge->sprite_table[tableid] == NULL) {
2186 bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
2189 for (byte sprite = 0; sprite < 32; sprite++) {
2190 SpriteID image = buf->ReadWord();
2191 PaletteID pal = buf->ReadWord();
2193 bridge->sprite_table[tableid][sprite].sprite = image;
2194 bridge->sprite_table[tableid][sprite].pal = pal;
2196 MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
2199 break;
2202 case 0x0E: // Flags; bit 0 - disable far pillars
2203 bridge->flags = buf->ReadByte();
2204 break;
2206 case 0x0F: // Long format year of availability (year since year 0)
2207 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
2208 break;
2210 case 0x10: { // purchase string
2211 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2212 if (newone != STR_UNDEFINED) bridge->material = newone;
2213 break;
2216 case 0x11: // description of bridge with rails or roads
2217 case 0x12: {
2218 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2219 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
2220 break;
2223 case 0x13: // 16 bits cost multiplier
2224 bridge->price = buf->ReadWord();
2225 break;
2227 default:
2228 ret = CIR_UNKNOWN;
2229 break;
2233 return ret;
2237 * Ignore a house property
2238 * @param prop Property to read.
2239 * @param buf Property value.
2240 * @return ChangeInfoResult.
2242 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
2244 ChangeInfoResult ret = CIR_SUCCESS;
2246 switch (prop) {
2247 case 0x09:
2248 case 0x0B:
2249 case 0x0C:
2250 case 0x0D:
2251 case 0x0E:
2252 case 0x0F:
2253 case 0x11:
2254 case 0x14:
2255 case 0x15:
2256 case 0x16:
2257 case 0x18:
2258 case 0x19:
2259 case 0x1A:
2260 case 0x1B:
2261 case 0x1C:
2262 case 0x1D:
2263 case 0x1F:
2264 buf->ReadByte();
2265 break;
2267 case 0x0A:
2268 case 0x10:
2269 case 0x12:
2270 case 0x13:
2271 case 0x21:
2272 case 0x22:
2273 buf->ReadWord();
2274 break;
2276 case 0x1E:
2277 buf->ReadDWord();
2278 break;
2280 case 0x17:
2281 for (uint j = 0; j < 4; j++) buf->ReadByte();
2282 break;
2284 case 0x20: {
2285 byte count = buf->ReadByte();
2286 for (byte j = 0; j < count; j++) buf->ReadByte();
2287 break;
2290 default:
2291 ret = CIR_UNKNOWN;
2292 break;
2294 return ret;
2298 * Define properties for houses
2299 * @param hid HouseID of the house.
2300 * @param numinfo Number of subsequent houseIDs to change the property for.
2301 * @param prop The property to change.
2302 * @param buf The property value.
2303 * @return ChangeInfoResult.
2305 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2307 ChangeInfoResult ret = CIR_SUCCESS;
2309 if (hid + numinfo > NUM_HOUSES_PER_GRF) {
2310 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
2311 return CIR_INVALID_ID;
2314 /* Allocate house specs if they haven't been allocated already. */
2315 if (_cur.grffile->housespec == NULL) {
2316 _cur.grffile->housespec = CallocT<HouseSpec*>(NUM_HOUSES_PER_GRF);
2319 for (int i = 0; i < numinfo; i++) {
2320 HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2322 if (prop != 0x08 && housespec == NULL) {
2323 /* If the house property 08 is not yet set, ignore this property */
2324 ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2325 if (cir > ret) ret = cir;
2326 continue;
2329 switch (prop) {
2330 case 0x08: { // Substitute building type, and definition of a new house
2331 HouseSpec **house = &_cur.grffile->housespec[hid + i];
2332 byte subs_id = buf->ReadByte();
2334 if (subs_id == 0xFF) {
2335 /* Instead of defining a new house, a substitute house id
2336 * of 0xFF disables the old house with the current id. */
2337 HouseSpec::Get(hid + i)->enabled = false;
2338 continue;
2339 } else if (subs_id >= NEW_HOUSE_OFFSET) {
2340 /* The substitute id must be one of the original houses. */
2341 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2342 continue;
2345 /* Allocate space for this house. */
2346 if (*house == NULL) *house = CallocT<HouseSpec>(1);
2348 housespec = *house;
2350 MemCpyT(housespec, HouseSpec::Get(subs_id));
2352 housespec->enabled = true;
2353 housespec->grf_prop.local_id = hid + i;
2354 housespec->grf_prop.subst_id = subs_id;
2355 housespec->grf_prop.grffile = _cur.grffile;
2356 housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2357 housespec->random_colour[1] = 0x08; // for all new houses
2358 housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2359 housespec->random_colour[3] = 0x06;
2361 /* Make sure that the third cargo type is valid in this
2362 * climate. This can cause problems when copying the properties
2363 * of a house that accepts food, where the new house is valid
2364 * in the temperate climate. */
2365 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2366 housespec->cargo_acceptance[2] = 0;
2369 _loaded_newgrf_features.has_newhouses = true;
2370 break;
2373 case 0x09: // Building flags
2374 housespec->building_flags = (BuildingFlags)buf->ReadByte();
2375 break;
2377 case 0x0A: { // Availability years
2378 uint16 years = buf->ReadWord();
2379 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2380 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2381 break;
2384 case 0x0B: // Population
2385 housespec->population = buf->ReadByte();
2386 break;
2388 case 0x0C: // Mail generation multiplier
2389 housespec->mail_generation = buf->ReadByte();
2390 break;
2392 case 0x0D: // Passenger acceptance
2393 case 0x0E: // Mail acceptance
2394 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2395 break;
2397 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2398 int8 goods = buf->ReadByte();
2400 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2401 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2402 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2403 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2405 /* Make sure the cargo type is valid in this climate. */
2406 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2408 housespec->accepts_cargo[2] = cid;
2409 housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2410 break;
2413 case 0x10: // Local authority rating decrease on removal
2414 housespec->remove_rating_decrease = buf->ReadWord();
2415 break;
2417 case 0x11: // Removal cost multiplier
2418 housespec->removal_cost = buf->ReadByte();
2419 break;
2421 case 0x12: // Building name ID
2422 AddStringForMapping(buf->ReadWord(), &housespec->building_name);
2423 break;
2425 case 0x13: // Building availability mask
2426 housespec->building_availability = (HouseZones)buf->ReadWord();
2427 break;
2429 case 0x14: // House callback mask
2430 housespec->callback_mask |= buf->ReadByte();
2431 break;
2433 case 0x15: { // House override byte
2434 byte override = buf->ReadByte();
2436 /* The house being overridden must be an original house. */
2437 if (override >= NEW_HOUSE_OFFSET) {
2438 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2439 continue;
2442 _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2443 break;
2446 case 0x16: // Periodic refresh multiplier
2447 housespec->processing_time = min(buf->ReadByte(), 63);
2448 break;
2450 case 0x17: // Four random colours to use
2451 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2452 break;
2454 case 0x18: // Relative probability of appearing
2455 housespec->probability = buf->ReadByte();
2456 break;
2458 case 0x19: // Extra flags
2459 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2460 break;
2462 case 0x1A: // Animation frames
2463 housespec->animation.frames = buf->ReadByte();
2464 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2465 SB(housespec->animation.frames, 7, 1, 0);
2466 break;
2468 case 0x1B: // Animation speed
2469 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2470 break;
2472 case 0x1C: // Class of the building type
2473 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2474 break;
2476 case 0x1D: // Callback mask part 2
2477 housespec->callback_mask |= (buf->ReadByte() << 8);
2478 break;
2480 case 0x1E: { // Accepted cargo types
2481 uint32 cargotypes = buf->ReadDWord();
2483 /* Check if the cargo types should not be changed */
2484 if (cargotypes == 0xFFFFFFFF) break;
2486 for (uint j = 0; j < 3; j++) {
2487 /* Get the cargo number from the 'list' */
2488 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2489 CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2491 if (cargo == CT_INVALID) {
2492 /* Disable acceptance of invalid cargo type */
2493 housespec->cargo_acceptance[j] = 0;
2494 } else {
2495 housespec->accepts_cargo[j] = cargo;
2498 break;
2501 case 0x1F: // Minimum life span
2502 housespec->minimum_life = buf->ReadByte();
2503 break;
2505 case 0x20: { // Cargo acceptance watch list
2506 byte count = buf->ReadByte();
2507 for (byte j = 0; j < count; j++) {
2508 CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2509 if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
2511 break;
2514 case 0x21: // long introduction year
2515 housespec->min_year = buf->ReadWord();
2516 break;
2518 case 0x22: // long maximum year
2519 housespec->max_year = buf->ReadWord();
2520 break;
2522 default:
2523 ret = CIR_UNKNOWN;
2524 break;
2528 return ret;
2532 * Get the language map associated with a given NewGRF and language.
2533 * @param grfid The NewGRF to get the map for.
2534 * @param language_id The (NewGRF) language ID to get the map for.
2535 * @return The LanguageMap, or NULL if it couldn't be found.
2537 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2539 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2540 const GRFFile *grffile = GetFileByGRFID(grfid);
2541 return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
2545 * Load a cargo- or railtype-translation table.
2546 * @param gvid ID of the global variable. This is basically only checked for zerones.
2547 * @param numinfo Number of subsequent IDs to change the property for.
2548 * @param buf The property value.
2549 * @param [in,out] translation_table Storage location for the translation table.
2550 * @param name Name of the table for debug output.
2551 * @return ChangeInfoResult.
2553 template <typename T>
2554 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
2556 if (gvid != 0) {
2557 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
2558 return CIR_INVALID_ID;
2561 translation_table.Clear();
2562 for (int i = 0; i < numinfo; i++) {
2563 uint32 item = buf->ReadDWord();
2564 *translation_table.Append() = BSWAP32(item);
2567 return CIR_SUCCESS;
2571 * Define properties for global variables
2572 * @param gvid ID of the global variable.
2573 * @param numinfo Number of subsequent IDs to change the property for.
2574 * @param prop The property to change.
2575 * @param buf The property value.
2576 * @return ChangeInfoResult.
2578 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2580 /* Properties which are handled as a whole */
2581 switch (prop) {
2582 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2583 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2585 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2586 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2588 default:
2589 break;
2592 /* Properties which are handled per item */
2593 ChangeInfoResult ret = CIR_SUCCESS;
2594 for (int i = 0; i < numinfo; i++) {
2595 switch (prop) {
2596 case 0x08: { // Cost base factor
2597 int factor = buf->ReadByte();
2598 uint price = gvid + i;
2600 if (price < PR_END) {
2601 _cur.grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
2602 } else {
2603 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2605 break;
2608 case 0x0A: { // Currency display names
2609 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2610 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2612 if ((newone != STR_UNDEFINED) && (curidx < CURRENCY_END)) {
2613 _currency_specs[curidx].name = newone;
2615 break;
2618 case 0x0B: { // Currency multipliers
2619 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2620 uint32 rate = buf->ReadDWord();
2622 if (curidx < CURRENCY_END) {
2623 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2624 * which OTTD does not. For this reason, divide grf value by 1000,
2625 * to be compatible */
2626 _currency_specs[curidx].rate = rate / 1000;
2627 } else {
2628 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2630 break;
2633 case 0x0C: { // Currency options
2634 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2635 uint16 options = buf->ReadWord();
2637 if (curidx < CURRENCY_END) {
2638 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
2639 _currency_specs[curidx].separator[1] = '\0';
2640 /* By specifying only one bit, we prevent errors,
2641 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2642 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
2643 } else {
2644 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2646 break;
2649 case 0x0D: { // Currency prefix symbol
2650 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2651 uint32 tempfix = buf->ReadDWord();
2653 if (curidx < CURRENCY_END) {
2654 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
2655 _currency_specs[curidx].prefix[4] = 0;
2656 } else {
2657 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2659 break;
2662 case 0x0E: { // Currency suffix symbol
2663 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2664 uint32 tempfix = buf->ReadDWord();
2666 if (curidx < CURRENCY_END) {
2667 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
2668 _currency_specs[curidx].suffix[4] = 0;
2669 } else {
2670 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2672 break;
2675 case 0x0F: { // Euro introduction dates
2676 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2677 Year year_euro = buf->ReadWord();
2679 if (curidx < CURRENCY_END) {
2680 _currency_specs[curidx].to_euro = year_euro;
2681 } else {
2682 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2684 break;
2687 case 0x10: // Snow line height table
2688 if (numinfo > 1 || IsSnowLineSet()) {
2689 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2690 } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
2691 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2692 } else {
2693 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2695 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2696 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2697 table[i][j] = buf->ReadByte();
2698 if (_cur.grffile->grf_version >= 8) {
2699 if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 256;
2700 } else {
2701 if (table[i][j] >= 128) {
2702 /* no snow */
2703 table[i][j] = 0xFF;
2704 } else {
2705 table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 128;
2710 SetSnowLine(table);
2712 break;
2714 case 0x11: // GRF match for engine allocation
2715 /* This is loaded during the reservation stage, so just skip it here. */
2716 /* Each entry is 8 bytes. */
2717 buf->Skip(8);
2718 break;
2720 case 0x13: // Gender translation table
2721 case 0x14: // Case translation table
2722 case 0x15: { // Plural form translation
2723 uint curidx = gvid + i; // The current index, i.e. language.
2724 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL;
2725 if (lang == NULL) {
2726 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2727 /* Skip over the data. */
2728 if (prop == 0x15) {
2729 buf->ReadByte();
2730 } else {
2731 while (buf->ReadByte() != 0) {
2732 buf->ReadString();
2735 break;
2738 if (_cur.grffile->language_map == NULL) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2740 if (prop == 0x15) {
2741 uint plural_form = buf->ReadByte();
2742 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2743 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2744 } else {
2745 _cur.grffile->language_map[curidx].plural_form = plural_form;
2747 break;
2750 byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2751 while (newgrf_id != 0) {
2752 const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2754 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2755 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2756 * is just a subset of UTF8, or they need the bigger UTF8 characters
2757 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2758 WChar c;
2759 size_t len = Utf8Decode(&c, name);
2760 if (c == NFO_UTF8_IDENTIFIER) name += len;
2762 LanguageMap::Mapping map;
2763 map.newgrf_id = newgrf_id;
2764 if (prop == 0x13) {
2765 map.openttd_id = lang->GetGenderIndex(name);
2766 if (map.openttd_id >= MAX_NUM_GENDERS) {
2767 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2768 } else {
2769 *_cur.grffile->language_map[curidx].gender_map.Append() = map;
2771 } else {
2772 map.openttd_id = lang->GetCaseIndex(name);
2773 if (map.openttd_id >= MAX_NUM_CASES) {
2774 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2775 } else {
2776 *_cur.grffile->language_map[curidx].case_map.Append() = map;
2779 newgrf_id = buf->ReadByte();
2781 break;
2784 default:
2785 ret = CIR_UNKNOWN;
2786 break;
2790 return ret;
2793 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2795 /* Properties which are handled as a whole */
2796 switch (prop) {
2797 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2798 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2800 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2801 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2803 default:
2804 break;
2807 /* Properties which are handled per item */
2808 ChangeInfoResult ret = CIR_SUCCESS;
2809 for (int i = 0; i < numinfo; i++) {
2810 switch (prop) {
2811 case 0x08: // Cost base factor
2812 case 0x15: // Plural form translation
2813 buf->ReadByte();
2814 break;
2816 case 0x0A: // Currency display names
2817 case 0x0C: // Currency options
2818 case 0x0F: // Euro introduction dates
2819 buf->ReadWord();
2820 break;
2822 case 0x0B: // Currency multipliers
2823 case 0x0D: // Currency prefix symbol
2824 case 0x0E: // Currency suffix symbol
2825 buf->ReadDWord();
2826 break;
2828 case 0x10: // Snow line height table
2829 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
2830 break;
2832 case 0x11: { // GRF match for engine allocation
2833 uint32 s = buf->ReadDWord();
2834 uint32 t = buf->ReadDWord();
2835 SetNewGRFOverride(s, t);
2836 break;
2839 case 0x13: // Gender translation table
2840 case 0x14: // Case translation table
2841 while (buf->ReadByte() != 0) {
2842 buf->ReadString();
2844 break;
2846 default:
2847 ret = CIR_UNKNOWN;
2848 break;
2852 return ret;
2857 * Define properties for cargoes
2858 * @param cid Local ID of the cargo.
2859 * @param numinfo Number of subsequent IDs to change the property for.
2860 * @param prop The property to change.
2861 * @param buf The property value.
2862 * @return ChangeInfoResult.
2864 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
2866 ChangeInfoResult ret = CIR_SUCCESS;
2868 if (cid + numinfo > NUM_CARGO) {
2869 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
2870 return CIR_INVALID_ID;
2873 for (int i = 0; i < numinfo; i++) {
2874 CargoSpec *cs = CargoSpec::Get(cid + i);
2876 switch (prop) {
2877 case 0x08: // Bit number of cargo
2878 cs->bitnum = buf->ReadByte();
2879 if (cs->IsValid()) {
2880 cs->grffile = _cur.grffile;
2881 SetBit(_cargo_mask, cid + i);
2882 } else {
2883 ClrBit(_cargo_mask, cid + i);
2885 break;
2887 case 0x09: // String ID for cargo type name
2888 AddStringForMapping(buf->ReadWord(), &cs->name);
2889 break;
2891 case 0x0A: // String for 1 unit of cargo
2892 AddStringForMapping(buf->ReadWord(), &cs->name_single);
2893 break;
2895 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2896 case 0x1B: // String for cargo units
2897 /* String for units of cargo. This is different in OpenTTD
2898 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2899 * Property 1B is used to set OpenTTD's behaviour. */
2900 AddStringForMapping(buf->ReadWord(), &cs->units_volume);
2901 break;
2903 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2904 case 0x1C: // String for any amount of cargo
2905 /* Strings for an amount of cargo. This is different in OpenTTD
2906 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2907 * Property 1C is used to set OpenTTD's behaviour. */
2908 AddStringForMapping(buf->ReadWord(), &cs->quantifier);
2909 break;
2911 case 0x0D: // String for two letter cargo abbreviation
2912 AddStringForMapping(buf->ReadWord(), &cs->abbrev);
2913 break;
2915 case 0x0E: // Sprite ID for cargo icon
2916 cs->sprite = buf->ReadWord();
2917 break;
2919 case 0x0F: // Weight of one unit of cargo
2920 cs->weight = buf->ReadByte();
2921 break;
2923 case 0x10: // Used for payment calculation
2924 cs->transit_days[0] = buf->ReadByte();
2925 break;
2927 case 0x11: // Used for payment calculation
2928 cs->transit_days[1] = buf->ReadByte();
2929 break;
2931 case 0x12: // Base cargo price
2932 cs->initial_payment = buf->ReadDWord();
2933 break;
2935 case 0x13: // Colour for station rating bars
2936 cs->rating_colour = buf->ReadByte();
2937 break;
2939 case 0x14: // Colour for cargo graph
2940 cs->legend_colour = buf->ReadByte();
2941 break;
2943 case 0x15: // Freight status
2944 cs->is_freight = (buf->ReadByte() != 0);
2945 break;
2947 case 0x16: // Cargo classes
2948 cs->classes = buf->ReadWord();
2949 break;
2951 case 0x17: // Cargo label
2952 cs->label = buf->ReadDWord();
2953 cs->label = BSWAP32(cs->label);
2954 break;
2956 case 0x18: { // Town growth substitute type
2957 uint8 substitute_type = buf->ReadByte();
2959 switch (substitute_type) {
2960 case 0x00: cs->town_effect = TE_PASSENGERS; break;
2961 case 0x02: cs->town_effect = TE_MAIL; break;
2962 case 0x05: cs->town_effect = TE_GOODS; break;
2963 case 0x09: cs->town_effect = TE_WATER; break;
2964 case 0x0B: cs->town_effect = TE_FOOD; break;
2965 default:
2966 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
2967 /* FALL THROUGH */
2968 case 0xFF: cs->town_effect = TE_NONE; break;
2970 break;
2973 case 0x19: // Town growth coefficient
2974 cs->multipliertowngrowth = buf->ReadWord();
2975 break;
2977 case 0x1A: // Bitmask of callbacks to use
2978 cs->callback_mask = buf->ReadByte();
2979 break;
2981 case 0x1D: // Vehicle capacity muliplier
2982 cs->multiplier = max<uint16>(1u, buf->ReadWord());
2983 break;
2985 default:
2986 ret = CIR_UNKNOWN;
2987 break;
2991 return ret;
2996 * Define properties for sound effects
2997 * @param sid Local ID of the sound.
2998 * @param numinfo Number of subsequent IDs to change the property for.
2999 * @param prop The property to change.
3000 * @param buf The property value.
3001 * @return ChangeInfoResult.
3003 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
3005 ChangeInfoResult ret = CIR_SUCCESS;
3007 if (_cur.grffile->sound_offset == 0) {
3008 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3009 return CIR_INVALID_ID;
3012 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
3013 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
3014 return CIR_INVALID_ID;
3017 for (int i = 0; i < numinfo; i++) {
3018 SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
3020 switch (prop) {
3021 case 0x08: // Relative volume
3022 sound->volume = buf->ReadByte();
3023 break;
3025 case 0x09: // Priority
3026 sound->priority = buf->ReadByte();
3027 break;
3029 case 0x0A: { // Override old sound
3030 SoundID orig_sound = buf->ReadByte();
3032 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
3033 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
3034 } else {
3035 SoundEntry *old_sound = GetSound(orig_sound);
3037 /* Literally copy the data of the new sound over the original */
3038 *old_sound = *sound;
3040 break;
3043 default:
3044 ret = CIR_UNKNOWN;
3045 break;
3049 return ret;
3053 * Ignore an industry tile property
3054 * @param prop The property to ignore.
3055 * @param buf The property value.
3056 * @return ChangeInfoResult.
3058 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
3060 ChangeInfoResult ret = CIR_SUCCESS;
3062 switch (prop) {
3063 case 0x09:
3064 case 0x0D:
3065 case 0x0E:
3066 case 0x10:
3067 case 0x11:
3068 case 0x12:
3069 buf->ReadByte();
3070 break;
3072 case 0x0A:
3073 case 0x0B:
3074 case 0x0C:
3075 case 0x0F:
3076 buf->ReadWord();
3077 break;
3079 default:
3080 ret = CIR_UNKNOWN;
3081 break;
3083 return ret;
3087 * Define properties for industry tiles
3088 * @param indtid Local ID of the industry tile.
3089 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3090 * @param prop The property to change.
3091 * @param buf The property value.
3092 * @return ChangeInfoResult.
3094 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
3096 ChangeInfoResult ret = CIR_SUCCESS;
3098 if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
3099 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
3100 return CIR_INVALID_ID;
3103 /* Allocate industry tile specs if they haven't been allocated already. */
3104 if (_cur.grffile->indtspec == NULL) {
3105 _cur.grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES_PER_GRF);
3108 for (int i = 0; i < numinfo; i++) {
3109 IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
3111 if (prop != 0x08 && tsp == NULL) {
3112 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
3113 if (cir > ret) ret = cir;
3114 continue;
3117 switch (prop) {
3118 case 0x08: { // Substitute industry tile type
3119 IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i];
3120 byte subs_id = buf->ReadByte();
3122 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
3123 /* The substitute id must be one of the original industry tile. */
3124 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3125 continue;
3128 /* Allocate space for this industry. */
3129 if (*tilespec == NULL) {
3130 *tilespec = CallocT<IndustryTileSpec>(1);
3131 tsp = *tilespec;
3133 memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
3134 tsp->enabled = true;
3136 /* A copied tile should not have the animation infos copied too.
3137 * The anim_state should be left untouched, though
3138 * It is up to the author to animate them himself */
3139 tsp->anim_production = INDUSTRYTILE_NOANIM;
3140 tsp->anim_next = INDUSTRYTILE_NOANIM;
3142 tsp->grf_prop.local_id = indtid + i;
3143 tsp->grf_prop.subst_id = subs_id;
3144 tsp->grf_prop.grffile = _cur.grffile;
3145 _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3147 break;
3150 case 0x09: { // Industry tile override
3151 byte ovrid = buf->ReadByte();
3153 /* The industry being overridden must be an original industry. */
3154 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
3155 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3156 continue;
3159 _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
3160 break;
3163 case 0x0A: // Tile acceptance
3164 case 0x0B:
3165 case 0x0C: {
3166 uint16 acctp = buf->ReadWord();
3167 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
3168 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
3169 break;
3172 case 0x0D: // Land shape flags
3173 tsp->slopes_refused = (Slope)buf->ReadByte();
3174 break;
3176 case 0x0E: // Callback mask
3177 tsp->callback_mask = buf->ReadByte();
3178 break;
3180 case 0x0F: // Animation information
3181 tsp->animation.frames = buf->ReadByte();
3182 tsp->animation.status = buf->ReadByte();
3183 break;
3185 case 0x10: // Animation speed
3186 tsp->animation.speed = buf->ReadByte();
3187 break;
3189 case 0x11: // Triggers for callback 25
3190 tsp->animation.triggers = buf->ReadByte();
3191 break;
3193 case 0x12: // Special flags
3194 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
3195 break;
3197 default:
3198 ret = CIR_UNKNOWN;
3199 break;
3203 return ret;
3207 * Ignore an industry property
3208 * @param prop The property to ignore.
3209 * @param buf The property value.
3210 * @return ChangeInfoResult.
3212 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
3214 ChangeInfoResult ret = CIR_SUCCESS;
3216 switch (prop) {
3217 case 0x09:
3218 case 0x0B:
3219 case 0x0F:
3220 case 0x12:
3221 case 0x13:
3222 case 0x14:
3223 case 0x17:
3224 case 0x18:
3225 case 0x19:
3226 case 0x21:
3227 case 0x22:
3228 buf->ReadByte();
3229 break;
3231 case 0x0C:
3232 case 0x0D:
3233 case 0x0E:
3234 case 0x10:
3235 case 0x1B:
3236 case 0x1F:
3237 case 0x24:
3238 buf->ReadWord();
3239 break;
3241 case 0x11:
3242 case 0x1A:
3243 case 0x1C:
3244 case 0x1D:
3245 case 0x1E:
3246 case 0x20:
3247 case 0x23:
3248 buf->ReadDWord();
3249 break;
3251 case 0x0A: {
3252 byte num_table = buf->ReadByte();
3253 for (byte j = 0; j < num_table; j++) {
3254 for (uint k = 0;; k++) {
3255 byte x = buf->ReadByte();
3256 if (x == 0xFE && k == 0) {
3257 buf->ReadByte();
3258 buf->ReadByte();
3259 break;
3262 byte y = buf->ReadByte();
3263 if (x == 0 && y == 0x80) break;
3265 byte gfx = buf->ReadByte();
3266 if (gfx == 0xFE) buf->ReadWord();
3269 break;
3272 case 0x16:
3273 for (byte j = 0; j < 3; j++) buf->ReadByte();
3274 break;
3276 case 0x15: {
3277 byte number_of_sounds = buf->ReadByte();
3278 for (uint8 j = 0; j < number_of_sounds; j++) {
3279 buf->ReadByte();
3281 break;
3284 default:
3285 ret = CIR_UNKNOWN;
3286 break;
3288 return ret;
3292 * Validate the industry layout; e.g. to prevent duplicate tiles.
3293 * @param layout The layout to check.
3294 * @param size The size of the layout.
3295 * @return True if the layout is deemed valid.
3297 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
3299 for (int i = 0; i < size - 1; i++) {
3300 for (int j = i + 1; j < size; j++) {
3301 if (layout[i].ti.x == layout[j].ti.x &&
3302 layout[i].ti.y == layout[j].ti.y) {
3303 return false;
3307 return true;
3310 /** Clean the tile table of the IndustrySpec if it's needed. */
3311 static void CleanIndustryTileTable(IndustrySpec *ind)
3313 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
3314 for (int j = 0; j < ind->num_table; j++) {
3315 /* remove the individual layouts */
3316 free(ind->table[j]);
3318 /* remove the layouts pointers */
3319 free(ind->table);
3320 ind->table = NULL;
3325 * Define properties for industries
3326 * @param indid Local ID of the industry.
3327 * @param numinfo Number of subsequent industry IDs to change the property for.
3328 * @param prop The property to change.
3329 * @param buf The property value.
3330 * @return ChangeInfoResult.
3332 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3334 ChangeInfoResult ret = CIR_SUCCESS;
3336 if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
3337 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
3338 return CIR_INVALID_ID;
3341 /* Allocate industry specs if they haven't been allocated already. */
3342 if (_cur.grffile->industryspec == NULL) {
3343 _cur.grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES_PER_GRF);
3346 for (int i = 0; i < numinfo; i++) {
3347 IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3349 if (prop != 0x08 && indsp == NULL) {
3350 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3351 if (cir > ret) ret = cir;
3352 continue;
3355 switch (prop) {
3356 case 0x08: { // Substitute industry type
3357 IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i];
3358 byte subs_id = buf->ReadByte();
3360 if (subs_id == 0xFF) {
3361 /* Instead of defining a new industry, a substitute industry id
3362 * of 0xFF disables the old industry with the current id. */
3363 _industry_specs[indid + i].enabled = false;
3364 continue;
3365 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3366 /* The substitute id must be one of the original industry. */
3367 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3368 continue;
3371 /* Allocate space for this industry.
3372 * Only need to do it once. If ever it is called again, it should not
3373 * do anything */
3374 if (*indspec == NULL) {
3375 *indspec = CallocT<IndustrySpec>(1);
3376 indsp = *indspec;
3378 memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
3379 indsp->enabled = true;
3380 indsp->grf_prop.local_id = indid + i;
3381 indsp->grf_prop.subst_id = subs_id;
3382 indsp->grf_prop.grffile = _cur.grffile;
3383 /* If the grf industry needs to check its surounding upon creation, it should
3384 * rely on callbacks, not on the original placement functions */
3385 indsp->check_proc = CHECK_NOTHING;
3387 break;
3390 case 0x09: { // Industry type override
3391 byte ovrid = buf->ReadByte();
3393 /* The industry being overridden must be an original industry. */
3394 if (ovrid >= NEW_INDUSTRYOFFSET) {
3395 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3396 continue;
3398 indsp->grf_prop.override = ovrid;
3399 _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3400 break;
3403 case 0x0A: { // Set industry layout(s)
3404 byte new_num_layouts = buf->ReadByte(); // Number of layaouts
3405 /* We read the total size in bytes, but we can't rely on the
3406 * newgrf to provide a sane value. First assume the value is
3407 * sane but later on we make sure we enlarge the array if the
3408 * newgrf contains more data. Each tile uses either 3 or 5
3409 * bytes, so to play it safe we assume 3. */
3410 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
3411 IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(new_num_layouts); // Table with tiles to compose an industry
3412 IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles); // Temporary array to read the tile layouts from the GRF
3413 uint size;
3414 const IndustryTileTable *copy_from;
3416 try {
3417 for (byte j = 0; j < new_num_layouts; j++) {
3418 for (uint k = 0;; k++) {
3419 if (k >= def_num_tiles) {
3420 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3421 /* Size reported by newgrf was not big enough so enlarge the array. */
3422 def_num_tiles *= 2;
3423 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
3426 itt[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3428 if (itt[k].ti.x == 0xFE && k == 0) {
3429 /* This means we have to borrow the layout from an old industry */
3430 IndustryType type = buf->ReadByte(); // industry holding required layout
3431 byte laynbr = buf->ReadByte(); // layout number to borrow
3433 copy_from = _origin_industry_specs[type].table[laynbr];
3434 for (size = 1;; size++) {
3435 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
3437 break;
3440 itt[k].ti.y = buf->ReadByte(); // Or table definition finalisation
3442 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
3443 /* Not the same terminator. The one we are using is rather
3444 x = -80, y = x . So, adjust it. */
3445 itt[k].ti.x = -0x80;
3446 itt[k].ti.y = 0;
3447 itt[k].gfx = 0;
3449 size = k + 1;
3450 copy_from = itt;
3451 break;
3454 itt[k].gfx = buf->ReadByte();
3456 if (itt[k].gfx == 0xFE) {
3457 /* Use a new tile from this GRF */
3458 int local_tile_id = buf->ReadWord();
3460 /* Read the ID from the _industile_mngr. */
3461 int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3463 if (tempid == INVALID_INDUSTRYTILE) {
3464 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3465 } else {
3466 /* Declared as been valid, can be used */
3467 itt[k].gfx = tempid;
3468 size = k + 1;
3469 copy_from = itt;
3471 } else if (itt[k].gfx == 0xFF) {
3472 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
3473 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
3475 /* When there were only 256x256 maps, TileIndex was a uint16 and
3476 * itt[k].ti was just a TileIndexDiff that was added to it.
3477 * As such negative "x" values were shifted into the "y" position.
3478 * x = -1, y = 1 -> x = 255, y = 0
3479 * Since GRF version 8 the position is interpreted as pair of independent int8.
3480 * For GRF version < 8 we need to emulate the old shifting behaviour.
3482 if (_cur.grffile->grf_version < 8 && itt[k].ti.x < 0) itt[k].ti.y += 1;
3486 if (!ValidateIndustryLayout(copy_from, size)) {
3487 /* The industry layout was not valid, so skip this one. */
3488 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3489 new_num_layouts--;
3490 j--;
3491 } else {
3492 tile_table[j] = CallocT<IndustryTileTable>(size);
3493 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3496 } catch (...) {
3497 for (int i = 0; i < new_num_layouts; i++) {
3498 free(tile_table[i]);
3500 free(tile_table);
3501 free(itt);
3502 throw;
3505 /* Clean the tile table if it was already set by a previous prop A. */
3506 CleanIndustryTileTable(indsp);
3507 /* Install final layout construction in the industry spec */
3508 indsp->num_table = new_num_layouts;
3509 indsp->table = tile_table;
3510 SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
3511 free(itt);
3512 break;
3515 case 0x0B: // Industry production flags
3516 indsp->life_type = (IndustryLifeType)buf->ReadByte();
3517 break;
3519 case 0x0C: // Industry closure message
3520 AddStringForMapping(buf->ReadWord(), &indsp->closure_text);
3521 break;
3523 case 0x0D: // Production increase message
3524 AddStringForMapping(buf->ReadWord(), &indsp->production_up_text);
3525 break;
3527 case 0x0E: // Production decrease message
3528 AddStringForMapping(buf->ReadWord(), &indsp->production_down_text);
3529 break;
3531 case 0x0F: // Fund cost multiplier
3532 indsp->cost_multiplier = buf->ReadByte();
3533 break;
3535 case 0x10: // Production cargo types
3536 for (byte j = 0; j < 2; j++) {
3537 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3539 break;
3541 case 0x11: // Acceptance cargo types
3542 for (byte j = 0; j < 3; j++) {
3543 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3545 buf->ReadByte(); // Unnused, eat it up
3546 break;
3548 case 0x12: // Production multipliers
3549 case 0x13:
3550 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3551 break;
3553 case 0x14: // Minimal amount of cargo distributed
3554 indsp->minimal_cargo = buf->ReadByte();
3555 break;
3557 case 0x15: { // Random sound effects
3558 indsp->number_of_sounds = buf->ReadByte();
3559 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
3561 try {
3562 for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
3563 sounds[j] = buf->ReadByte();
3565 } catch (...) {
3566 free(sounds);
3567 throw;
3570 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3571 free(indsp->random_sounds);
3573 indsp->random_sounds = sounds;
3574 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
3575 break;
3578 case 0x16: // Conflicting industry types
3579 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3580 break;
3582 case 0x17: // Probability in random game
3583 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3584 break;
3586 case 0x18: // Probability during gameplay
3587 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3588 break;
3590 case 0x19: // Map colour
3591 indsp->map_colour = buf->ReadByte();
3592 break;
3594 case 0x1A: // Special industry flags to define special behavior
3595 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3596 break;
3598 case 0x1B: // New industry text ID
3599 AddStringForMapping(buf->ReadWord(), &indsp->new_industry_text);
3600 break;
3602 case 0x1C: // Input cargo multipliers for the three input cargo types
3603 case 0x1D:
3604 case 0x1E: {
3605 uint32 multiples = buf->ReadDWord();
3606 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3607 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3608 break;
3611 case 0x1F: // Industry name
3612 AddStringForMapping(buf->ReadWord(), &indsp->name);
3613 break;
3615 case 0x20: // Prospecting success chance
3616 indsp->prospecting_chance = buf->ReadDWord();
3617 break;
3619 case 0x21: // Callback mask
3620 case 0x22: { // Callback additional mask
3621 byte aflag = buf->ReadByte();
3622 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3623 break;
3626 case 0x23: // removal cost multiplier
3627 indsp->removal_cost_multiplier = buf->ReadDWord();
3628 break;
3630 case 0x24: { // name for nearby station
3631 uint16 str = buf->ReadWord();
3632 if (str == 0) {
3633 indsp->station_name = STR_NULL;
3634 } else {
3635 AddStringForMapping(str, &indsp->station_name);
3637 break;
3640 default:
3641 ret = CIR_UNKNOWN;
3642 break;
3646 return ret;
3650 * Create a copy of the tile table so it can be freed later
3651 * without problems.
3652 * @param as The AirportSpec to copy the arrays of.
3654 static void DuplicateTileTable(AirportSpec *as)
3656 AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
3657 for (int i = 0; i < as->num_table; i++) {
3658 uint num_tiles = 1;
3659 const AirportTileTable *it = as->table[0];
3660 do {
3661 num_tiles++;
3662 } while ((++it)->ti.x != -0x80);
3663 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3664 MemCpyT(table_list[i], as->table[i], num_tiles);
3666 as->table = table_list;
3667 HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
3668 MemCpyT(depot_table, as->depot_table, as->nof_depots);
3669 as->depot_table = depot_table;
3673 * Define properties for airports
3674 * @param airport Local ID of the airport.
3675 * @param numinfo Number of subsequent airport IDs to change the property for.
3676 * @param prop The property to change.
3677 * @param buf The property value.
3678 * @return ChangeInfoResult.
3680 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3682 ChangeInfoResult ret = CIR_SUCCESS;
3684 if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
3685 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
3686 return CIR_INVALID_ID;
3689 /* Allocate industry specs if they haven't been allocated already. */
3690 if (_cur.grffile->airportspec == NULL) {
3691 _cur.grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS_PER_GRF);
3694 for (int i = 0; i < numinfo; i++) {
3695 AirportSpec *as = _cur.grffile->airportspec[airport + i];
3697 if (as == NULL && prop != 0x08 && prop != 0x09) {
3698 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3699 return CIR_INVALID_ID;
3702 switch (prop) {
3703 case 0x08: { // Modify original airport
3704 byte subs_id = buf->ReadByte();
3706 if (subs_id == 0xFF) {
3707 /* Instead of defining a new airport, an airport id
3708 * of 0xFF disables the old airport with the current id. */
3709 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3710 continue;
3711 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3712 /* The substitute id must be one of the original airports. */
3713 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3714 continue;
3717 AirportSpec **spec = &_cur.grffile->airportspec[airport + i];
3718 /* Allocate space for this airport.
3719 * Only need to do it once. If ever it is called again, it should not
3720 * do anything */
3721 if (*spec == NULL) {
3722 *spec = MallocT<AirportSpec>(1);
3723 as = *spec;
3725 memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
3726 as->enabled = true;
3727 as->grf_prop.local_id = airport + i;
3728 as->grf_prop.subst_id = subs_id;
3729 as->grf_prop.grffile = _cur.grffile;
3730 /* override the default airport */
3731 _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3732 /* Create a copy of the original tiletable so it can be freed later. */
3733 DuplicateTileTable(as);
3735 break;
3738 case 0x0A: { // Set airport layout
3739 as->num_table = buf->ReadByte(); // Number of layaouts
3740 as->rotation = MallocT<Direction>(as->num_table);
3741 uint32 defsize = buf->ReadDWord(); // Total size of the definition
3742 AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3743 AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
3744 int size;
3745 const AirportTileTable *copy_from;
3746 try {
3747 for (byte j = 0; j < as->num_table; j++) {
3748 as->rotation[j] = (Direction)buf->ReadByte();
3749 for (int k = 0;; k++) {
3750 att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3751 att[k].ti.y = buf->ReadByte();
3753 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3754 /* Not the same terminator. The one we are using is rather
3755 * x = -80, y = 0 . So, adjust it. */
3756 att[k].ti.x = -0x80;
3757 att[k].ti.y = 0;
3758 att[k].gfx = 0;
3760 size = k + 1;
3761 copy_from = att;
3762 break;
3765 att[k].gfx = buf->ReadByte();
3767 if (att[k].gfx == 0xFE) {
3768 /* Use a new tile from this GRF */
3769 int local_tile_id = buf->ReadWord();
3771 /* Read the ID from the _airporttile_mngr. */
3772 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3774 if (tempid == INVALID_AIRPORTTILE) {
3775 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3776 } else {
3777 /* Declared as been valid, can be used */
3778 att[k].gfx = tempid;
3779 size = k + 1;
3780 copy_from = att;
3782 } else if (att[k].gfx == 0xFF) {
3783 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3784 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3787 if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
3788 as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
3789 as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
3790 } else {
3791 as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
3792 as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
3795 tile_table[j] = CallocT<AirportTileTable>(size);
3796 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3798 /* Install final layout construction in the airport spec */
3799 as->table = tile_table;
3800 free(att);
3801 } catch (...) {
3802 for (int i = 0; i < as->num_table; i++) {
3803 free(tile_table[i]);
3805 free(tile_table);
3806 free(att);
3807 throw;
3809 break;
3812 case 0x0C:
3813 as->min_year = buf->ReadWord();
3814 as->max_year = buf->ReadWord();
3815 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3816 break;
3818 case 0x0D:
3819 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3820 break;
3822 case 0x0E:
3823 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3824 break;
3826 case 0x0F:
3827 as->noise_level = buf->ReadByte();
3828 break;
3830 case 0x10:
3831 AddStringForMapping(buf->ReadWord(), &as->name);
3832 break;
3834 case 0x11: // Maintenance cost factor
3835 as->maintenance_cost = buf->ReadWord();
3836 break;
3838 default:
3839 ret = CIR_UNKNOWN;
3840 break;
3844 return ret;
3848 * Ignore properties for objects
3849 * @param prop The property to ignore.
3850 * @param buf The property value.
3851 * @return ChangeInfoResult.
3853 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
3855 ChangeInfoResult ret = CIR_SUCCESS;
3857 switch (prop) {
3858 case 0x0B:
3859 case 0x0C:
3860 case 0x0D:
3861 case 0x12:
3862 case 0x14:
3863 case 0x16:
3864 case 0x17:
3865 buf->ReadByte();
3866 break;
3868 case 0x09:
3869 case 0x0A:
3870 case 0x10:
3871 case 0x11:
3872 case 0x13:
3873 case 0x15:
3874 buf->ReadWord();
3875 break;
3877 case 0x08:
3878 case 0x0E:
3879 case 0x0F:
3880 buf->ReadDWord();
3881 break;
3883 default:
3884 ret = CIR_UNKNOWN;
3885 break;
3888 return ret;
3892 * Define properties for objects
3893 * @param id Local ID of the object.
3894 * @param numinfo Number of subsequent objectIDs to change the property for.
3895 * @param prop The property to change.
3896 * @param buf The property value.
3897 * @return ChangeInfoResult.
3899 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
3901 ChangeInfoResult ret = CIR_SUCCESS;
3903 if (id + numinfo > NUM_OBJECTS_PER_GRF) {
3904 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
3905 return CIR_INVALID_ID;
3908 /* Allocate object specs if they haven't been allocated already. */
3909 if (_cur.grffile->objectspec == NULL) {
3910 _cur.grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS_PER_GRF);
3913 for (int i = 0; i < numinfo; i++) {
3914 ObjectSpec *spec = _cur.grffile->objectspec[id + i];
3916 if (prop != 0x08 && spec == NULL) {
3917 /* If the object property 08 is not yet set, ignore this property */
3918 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
3919 if (cir > ret) ret = cir;
3920 continue;
3923 switch (prop) {
3924 case 0x08: { // Class ID
3925 ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
3927 /* Allocate space for this object. */
3928 if (*ospec == NULL) {
3929 *ospec = CallocT<ObjectSpec>(1);
3930 (*ospec)->views = 1; // Default for NewGRFs that don't set it.
3933 /* Swap classid because we read it in BE. */
3934 uint32 classid = buf->ReadDWord();
3935 (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
3936 (*ospec)->enabled = true;
3937 break;
3940 case 0x09: { // Class name
3941 ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
3942 AddStringForMapping(buf->ReadWord(), &objclass->name);
3943 break;
3946 case 0x0A: // Object name
3947 AddStringForMapping(buf->ReadWord(), &spec->name);
3948 break;
3950 case 0x0B: // Climate mask
3951 spec->climate = buf->ReadByte();
3952 break;
3954 case 0x0C: // Size
3955 spec->size = buf->ReadByte();
3956 break;
3958 case 0x0D: // Build cost multipler
3959 spec->build_cost_multiplier = buf->ReadByte();
3960 spec->clear_cost_multiplier = spec->build_cost_multiplier;
3961 break;
3963 case 0x0E: // Introduction date
3964 spec->introduction_date = buf->ReadDWord();
3965 break;
3967 case 0x0F: // End of life
3968 spec->end_of_life_date = buf->ReadDWord();
3969 break;
3971 case 0x10: // Flags
3972 spec->flags = (ObjectFlags)buf->ReadWord();
3973 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
3974 break;
3976 case 0x11: // Animation info
3977 spec->animation.frames = buf->ReadByte();
3978 spec->animation.status = buf->ReadByte();
3979 break;
3981 case 0x12: // Animation speed
3982 spec->animation.speed = buf->ReadByte();
3983 break;
3985 case 0x13: // Animation triggers
3986 spec->animation.triggers = buf->ReadWord();
3987 break;
3989 case 0x14: // Removal cost multiplier
3990 spec->clear_cost_multiplier = buf->ReadByte();
3991 break;
3993 case 0x15: // Callback mask
3994 spec->callback_mask = buf->ReadWord();
3995 break;
3997 case 0x16: // Building height
3998 spec->height = buf->ReadByte();
3999 break;
4001 case 0x17: // Views
4002 spec->views = buf->ReadByte();
4003 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
4004 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
4005 spec->views = 1;
4007 break;
4009 case 0x18: // Amount placed on 256^2 map on map creation
4010 spec->generate_amount = buf->ReadByte();
4011 break;
4013 default:
4014 ret = CIR_UNKNOWN;
4015 break;
4019 return ret;
4023 * Define properties for railtypes
4024 * @param id ID of the railtype.
4025 * @param numinfo Number of subsequent IDs to change the property for.
4026 * @param prop The property to change.
4027 * @param buf The property value.
4028 * @return ChangeInfoResult.
4030 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4032 ChangeInfoResult ret = CIR_SUCCESS;
4034 extern RailtypeInfo _railtypes[RAILTYPE_END];
4036 if (id + numinfo > RAILTYPE_END) {
4037 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4038 return CIR_INVALID_ID;
4041 for (int i = 0; i < numinfo; i++) {
4042 RailType rt = _cur.grffile->railtype_map[id + i];
4043 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
4045 RailtypeInfo *rti = &_railtypes[rt];
4047 switch (prop) {
4048 case 0x08: // Label of rail type
4049 /* Skipped here as this is loaded during reservation stage. */
4050 buf->ReadDWord();
4051 break;
4053 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4054 uint16 str = buf->ReadWord();
4055 AddStringForMapping(str, &rti->strings.toolbar_caption);
4056 if (_cur.grffile->grf_version < 8) {
4057 AddStringForMapping(str, &rti->strings.name);
4059 break;
4062 case 0x0A: // Menu text of railtype
4063 AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4064 break;
4066 case 0x0B: // Build window caption
4067 AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4068 break;
4070 case 0x0C: // Autoreplace text
4071 AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4072 break;
4074 case 0x0D: // New locomotive text
4075 AddStringForMapping(buf->ReadWord(), &rti->strings.new_loco);
4076 break;
4078 case 0x0E: // Compatible railtype list
4079 case 0x0F: // Powered railtype list
4080 case 0x18: // Railtype list required for date introduction
4081 case 0x19: // Introduced railtype list
4083 /* Rail type compatibility bits are added to the existing bits
4084 * to allow multiple GRFs to modify compatibility with the
4085 * default rail types. */
4086 int n = buf->ReadByte();
4087 for (int j = 0; j != n; j++) {
4088 RailTypeLabel label = buf->ReadDWord();
4089 RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
4090 if (rt != INVALID_RAILTYPE) {
4091 switch (prop) {
4092 case 0x0F: SetBit(rti->powered_railtypes, rt); // Powered implies compatible.
4093 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
4094 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
4095 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
4099 break;
4102 case 0x10: // Rail Type flags
4103 rti->flags = (RailTypeFlags)buf->ReadByte();
4104 break;
4106 case 0x11: // Curve speed advantage
4107 rti->curve_speed = buf->ReadByte();
4108 break;
4110 case 0x12: // Station graphic
4111 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
4112 break;
4114 case 0x13: // Construction cost factor
4115 rti->cost_multiplier = buf->ReadWord();
4116 break;
4118 case 0x14: // Speed limit
4119 rti->max_speed = buf->ReadWord();
4120 break;
4122 case 0x15: // Acceleration model
4123 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
4124 break;
4126 case 0x16: // Map colour
4127 rti->map_colour = buf->ReadByte();
4128 break;
4130 case 0x17: // Introduction date
4131 rti->introduction_date = buf->ReadDWord();
4132 break;
4134 case 0x1A: // Sort order
4135 rti->sorting_order = buf->ReadByte();
4136 break;
4138 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4139 AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4140 break;
4142 case 0x1C: // Maintenance cost factor
4143 rti->maintenance_multiplier = buf->ReadWord();
4144 break;
4146 case 0x1D: // Alternate rail type label list
4147 /* Skipped here as this is loaded during reservation stage. */
4148 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4149 break;
4151 default:
4152 ret = CIR_UNKNOWN;
4153 break;
4157 return ret;
4160 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4162 ChangeInfoResult ret = CIR_SUCCESS;
4164 extern RailtypeInfo _railtypes[RAILTYPE_END];
4166 if (id + numinfo > RAILTYPE_END) {
4167 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4168 return CIR_INVALID_ID;
4171 for (int i = 0; i < numinfo; i++) {
4172 switch (prop) {
4173 case 0x08: // Label of rail type
4175 RailTypeLabel rtl = buf->ReadDWord();
4176 rtl = BSWAP32(rtl);
4178 RailType rt = GetRailTypeByLabel(rtl, false);
4179 if (rt == INVALID_RAILTYPE) {
4180 /* Set up new rail type */
4181 rt = AllocateRailType(rtl);
4184 _cur.grffile->railtype_map[id + i] = rt;
4185 break;
4188 case 0x09: // Toolbar caption of railtype
4189 case 0x0A: // Menu text
4190 case 0x0B: // Build window caption
4191 case 0x0C: // Autoreplace text
4192 case 0x0D: // New loco
4193 case 0x13: // Construction cost
4194 case 0x14: // Speed limit
4195 case 0x1B: // Name of railtype
4196 case 0x1C: // Maintenance cost factor
4197 buf->ReadWord();
4198 break;
4200 case 0x1D: // Alternate rail type label list
4201 if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
4202 int n = buf->ReadByte();
4203 for (int j = 0; j != n; j++) {
4204 *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord());
4206 break;
4208 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
4209 /* FALL THROUGH */
4211 case 0x0E: // Compatible railtype list
4212 case 0x0F: // Powered railtype list
4213 case 0x18: // Railtype list required for date introduction
4214 case 0x19: // Introduced railtype list
4215 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4216 break;
4218 case 0x10: // Rail Type flags
4219 case 0x11: // Curve speed advantage
4220 case 0x12: // Station graphic
4221 case 0x15: // Acceleration model
4222 case 0x16: // Map colour
4223 case 0x1A: // Sort order
4224 buf->ReadByte();
4225 break;
4227 case 0x17: // Introduction date
4228 buf->ReadDWord();
4229 break;
4231 default:
4232 ret = CIR_UNKNOWN;
4233 break;
4237 return ret;
4240 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
4242 ChangeInfoResult ret = CIR_SUCCESS;
4244 if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
4245 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
4246 return CIR_INVALID_ID;
4249 /* Allocate airport tile specs if they haven't been allocated already. */
4250 if (_cur.grffile->airtspec == NULL) {
4251 _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES_PER_GRF);
4254 for (int i = 0; i < numinfo; i++) {
4255 AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
4257 if (prop != 0x08 && tsp == NULL) {
4258 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4259 return CIR_INVALID_ID;
4262 switch (prop) {
4263 case 0x08: { // Substitute airport tile type
4264 AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
4265 byte subs_id = buf->ReadByte();
4267 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
4268 /* The substitute id must be one of the original airport tiles. */
4269 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4270 continue;
4273 /* Allocate space for this airport tile. */
4274 if (*tilespec == NULL) {
4275 *tilespec = CallocT<AirportTileSpec>(1);
4276 tsp = *tilespec;
4278 memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
4279 tsp->enabled = true;
4281 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
4283 tsp->grf_prop.local_id = airtid + i;
4284 tsp->grf_prop.subst_id = subs_id;
4285 tsp->grf_prop.grffile = _cur.grffile;
4286 _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
4288 break;
4291 case 0x09: { // Airport tile override
4292 byte override = buf->ReadByte();
4294 /* The airport tile being overridden must be an original airport tile. */
4295 if (override >= NEW_AIRPORTTILE_OFFSET) {
4296 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
4297 continue;
4300 _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
4301 break;
4304 case 0x0E: // Callback mask
4305 tsp->callback_mask = buf->ReadByte();
4306 break;
4308 case 0x0F: // Animation information
4309 tsp->animation.frames = buf->ReadByte();
4310 tsp->animation.status = buf->ReadByte();
4311 break;
4313 case 0x10: // Animation speed
4314 tsp->animation.speed = buf->ReadByte();
4315 break;
4317 case 0x11: // Animation triggers
4318 tsp->animation.triggers = buf->ReadByte();
4319 break;
4321 default:
4322 ret = CIR_UNKNOWN;
4323 break;
4327 return ret;
4330 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4332 switch (cir) {
4333 default: NOT_REACHED();
4335 case CIR_DISABLED:
4336 /* Error has already been printed; just stop parsing */
4337 return true;
4339 case CIR_SUCCESS:
4340 return false;
4342 case CIR_UNHANDLED:
4343 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4344 return false;
4346 case CIR_UNKNOWN:
4347 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4348 /* FALL THROUGH */
4350 case CIR_INVALID_ID: {
4351 /* No debug message for an invalid ID, as it has already been output */
4352 GRFError *error = DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4353 if (cir != CIR_INVALID_ID) error->param_value[1] = property;
4354 return true;
4359 /* Action 0x00 */
4360 static void FeatureChangeInfo(ByteReader *buf)
4362 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4364 * B feature
4365 * B num-props how many properties to change per vehicle/station
4366 * B num-info how many vehicles/stations to change
4367 * E id ID of first vehicle/station to change, if num-info is
4368 * greater than one, this one and the following
4369 * vehicles/stations will be changed
4370 * B property what property to change, depends on the feature
4371 * V new-info new bytes of info (variable size; depends on properties) */
4373 static const VCI_Handler handler[] = {
4374 /* GSF_TRAINS */ RailVehicleChangeInfo,
4375 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4376 /* GSF_SHIPS */ ShipVehicleChangeInfo,
4377 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4378 /* GSF_STATIONS */ StationChangeInfo,
4379 /* GSF_CANALS */ CanalChangeInfo,
4380 /* GSF_BRIDGES */ BridgeChangeInfo,
4381 /* GSF_HOUSES */ TownHouseChangeInfo,
4382 /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4383 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4384 /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4385 /* GSF_CARGOES */ NULL, // Cargo is handled during reservation
4386 /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4387 /* GSF_AIRPORTS */ AirportChangeInfo,
4388 /* GSF_SIGNALS */ NULL,
4389 /* GSF_OBJECTS */ ObjectChangeInfo,
4390 /* GSF_RAILTYPES */ RailTypeChangeInfo,
4391 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4394 uint8 feature = buf->ReadByte();
4395 uint8 numprops = buf->ReadByte();
4396 uint numinfo = buf->ReadByte();
4397 uint engine = buf->ReadExtendedByte();
4399 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4400 feature, numprops, engine, numinfo);
4402 if (feature >= lengthof(handler) || handler[feature] == NULL) {
4403 if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
4404 return;
4407 /* Mark the feature as used by the grf */
4408 SetBit(_cur.grffile->grf_features, feature);
4410 while (numprops-- && buf->HasData()) {
4411 uint8 prop = buf->ReadByte();
4413 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4414 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
4418 /* Action 0x00 (GLS_SAFETYSCAN) */
4419 static void SafeChangeInfo(ByteReader *buf)
4421 uint8 feature = buf->ReadByte();
4422 uint8 numprops = buf->ReadByte();
4423 uint numinfo = buf->ReadByte();
4424 buf->ReadExtendedByte(); // id
4426 if (feature == GSF_BRIDGES && numprops == 1) {
4427 uint8 prop = buf->ReadByte();
4428 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4429 * is considered safe. */
4430 if (prop == 0x0D) return;
4431 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4432 uint8 prop = buf->ReadByte();
4433 /* Engine ID Mappings are safe, if the source is static */
4434 if (prop == 0x11) {
4435 bool is_safe = true;
4436 for (uint i = 0; i < numinfo; i++) {
4437 uint32 s = buf->ReadDWord();
4438 buf->ReadDWord(); // dest
4439 const GRFConfig *grfconfig = GetGRFConfig(s);
4440 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
4441 is_safe = false;
4442 break;
4445 if (is_safe) return;
4449 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4451 /* Skip remainder of GRF */
4452 _cur.skip_sprites = -1;
4455 /* Action 0x00 (GLS_RESERVE) */
4456 static void ReserveChangeInfo(ByteReader *buf)
4458 uint8 feature = buf->ReadByte();
4460 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
4462 uint8 numprops = buf->ReadByte();
4463 uint8 numinfo = buf->ReadByte();
4464 uint8 index = buf->ReadExtendedByte();
4466 while (numprops-- && buf->HasData()) {
4467 uint8 prop = buf->ReadByte();
4468 ChangeInfoResult cir = CIR_SUCCESS;
4470 switch (feature) {
4471 default: NOT_REACHED();
4472 case GSF_CARGOES:
4473 cir = CargoChangeInfo(index, numinfo, prop, buf);
4474 break;
4476 case GSF_GLOBALVAR:
4477 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4478 break;
4480 case GSF_RAILTYPES:
4481 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4482 break;
4485 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
4489 /* Action 0x01 */
4490 static void NewSpriteSet(ByteReader *buf)
4492 /* Basic format: <01> <feature> <num-sets> <num-ent>
4493 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4495 * B feature feature to define sprites for
4496 * 0, 1, 2, 3: veh-type, 4: train stations
4497 * E first-set first sprite set to define
4498 * B num-sets number of sprite sets (extended byte in extended format)
4499 * E num-ent how many entries per sprite set
4500 * For vehicles, this is the number of different
4501 * vehicle directions in each sprite set
4502 * Set num-dirs=8, unless your sprites are symmetric.
4503 * In that case, use num-dirs=4.
4506 uint8 feature = buf->ReadByte();
4507 uint16 num_sets = buf->ReadByte();
4508 uint16 first_set = 0;
4510 if (num_sets == 0 && buf->HasData(3)) {
4511 /* Extended Action1 format.
4512 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4513 first_set = buf->ReadExtendedByte();
4514 num_sets = buf->ReadExtendedByte();
4516 uint16 num_ents = buf->ReadExtendedByte();
4518 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4520 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4521 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4524 for (int i = 0; i < num_sets * num_ents; i++) {
4525 _cur.nfo_line++;
4526 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
4530 /* Action 0x01 (SKIP) */
4531 static void SkipAct1(ByteReader *buf)
4533 buf->ReadByte();
4534 uint16 num_sets = buf->ReadByte();
4536 if (num_sets == 0 && buf->HasData(3)) {
4537 /* Extended Action1 format.
4538 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4539 buf->ReadExtendedByte(); // first_set
4540 num_sets = buf->ReadExtendedByte();
4542 uint16 num_ents = buf->ReadExtendedByte();
4544 _cur.skip_sprites = num_sets * num_ents;
4546 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
4549 /* Helper function to either create a callback or link to a previously
4550 * defined spritegroup. */
4551 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4553 if (HasBit(groupid, 15)) {
4554 assert(CallbackResultSpriteGroup::CanAllocateItem());
4555 return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
4558 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4559 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4560 return NULL;
4563 return _cur.spritegroups[groupid];
4567 * Helper function to either create a callback or a result sprite group.
4568 * @param feature GrfSpecFeature to define spritegroup for.
4569 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4570 * @param type Type of the currently being parsed Action2. (only for debug output)
4571 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4572 * @return Created spritegroup.
4574 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4576 if (HasBit(spriteid, 15)) {
4577 assert(CallbackResultSpriteGroup::CanAllocateItem());
4578 return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
4581 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4582 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4583 return NULL;
4586 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4587 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4589 /* Ensure that the sprites are loeded */
4590 assert(spriteset_start + num_sprites <= _cur.spriteid);
4592 assert(ResultSpriteGroup::CanAllocateItem());
4593 return new ResultSpriteGroup(spriteset_start, num_sprites);
4596 /* Action 0x02 */
4597 static void NewSpriteGroup(ByteReader *buf)
4599 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4601 * B feature see action 1
4602 * B set-id ID of this particular definition
4603 * B type/num-entries
4604 * if 80 or greater, this is a randomized or variational
4605 * list definition, see below
4606 * otherwise it specifies a number of entries, the exact
4607 * meaning depends on the feature
4608 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4609 SpriteGroup *act_group = NULL;
4611 uint8 feature = buf->ReadByte();
4612 uint8 setid = buf->ReadByte();
4613 uint8 type = buf->ReadByte();
4615 /* Sprite Groups are created here but they are allocated from a pool, so
4616 * we do not need to delete anything if there is an exception from the
4617 * ByteReader. */
4619 switch (type) {
4620 /* Deterministic Sprite Group */
4621 case 0x81: // Self scope, byte
4622 case 0x82: // Parent scope, byte
4623 case 0x85: // Self scope, word
4624 case 0x86: // Parent scope, word
4625 case 0x89: // Self scope, dword
4626 case 0x8A: // Parent scope, dword
4628 byte varadjust;
4629 byte varsize;
4631 assert(DeterministicSpriteGroup::CanAllocateItem());
4632 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
4633 act_group = group;
4634 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4636 switch (GB(type, 2, 2)) {
4637 default: NOT_REACHED();
4638 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
4639 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
4640 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
4643 static SmallVector<DeterministicSpriteGroupAdjust, 16> adjusts;
4644 adjusts.Clear();
4646 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4647 * from the outset, so we shall have to keep reallocing. */
4648 do {
4649 DeterministicSpriteGroupAdjust *adjust = adjusts.Append();
4651 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4652 adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
4653 adjust->variable = buf->ReadByte();
4654 if (adjust->variable == 0x7E) {
4655 /* Link subroutine group */
4656 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
4657 } else {
4658 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
4661 varadjust = buf->ReadByte();
4662 adjust->shift_num = GB(varadjust, 0, 5);
4663 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
4664 adjust->and_mask = buf->ReadVarSize(varsize);
4666 if (adjust->type != DSGA_TYPE_NONE) {
4667 adjust->add_val = buf->ReadVarSize(varsize);
4668 adjust->divmod_val = buf->ReadVarSize(varsize);
4669 } else {
4670 adjust->add_val = 0;
4671 adjust->divmod_val = 0;
4674 /* Continue reading var adjusts while bit 5 is set. */
4675 } while (HasBit(varadjust, 5));
4677 group->num_adjusts = adjusts.Length();
4678 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
4679 MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts);
4681 group->num_ranges = buf->ReadByte();
4682 if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
4684 for (uint i = 0; i < group->num_ranges; i++) {
4685 group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4686 group->ranges[i].low = buf->ReadVarSize(varsize);
4687 group->ranges[i].high = buf->ReadVarSize(varsize);
4690 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4691 break;
4694 /* Randomized Sprite Group */
4695 case 0x80: // Self scope
4696 case 0x83: // Parent scope
4697 case 0x84: // Relative scope
4699 assert(RandomizedSpriteGroup::CanAllocateItem());
4700 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
4701 act_group = group;
4702 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4704 if (HasBit(type, 2)) {
4705 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
4706 group->count = buf->ReadByte();
4709 uint8 triggers = buf->ReadByte();
4710 group->triggers = GB(triggers, 0, 7);
4711 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
4712 group->lowest_randbit = buf->ReadByte();
4713 group->num_groups = buf->ReadByte();
4714 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
4716 for (uint i = 0; i < group->num_groups; i++) {
4717 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
4720 break;
4723 /* Neither a variable or randomized sprite group... must be a real group */
4724 default:
4726 switch (feature) {
4727 case GSF_TRAINS:
4728 case GSF_ROADVEHICLES:
4729 case GSF_SHIPS:
4730 case GSF_AIRCRAFT:
4731 case GSF_STATIONS:
4732 case GSF_CANALS:
4733 case GSF_CARGOES:
4734 case GSF_AIRPORTS:
4735 case GSF_RAILTYPES:
4737 byte num_loaded = type;
4738 byte num_loading = buf->ReadByte();
4740 if (!_cur.HasValidSpriteSets(feature)) {
4741 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4742 return;
4745 assert(RealSpriteGroup::CanAllocateItem());
4746 RealSpriteGroup *group = new RealSpriteGroup();
4747 act_group = group;
4749 group->num_loaded = num_loaded;
4750 group->num_loading = num_loading;
4751 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
4752 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
4754 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4755 setid, num_loaded, num_loading);
4757 for (uint i = 0; i < num_loaded; i++) {
4758 uint16 spriteid = buf->ReadWord();
4759 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4760 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
4763 for (uint i = 0; i < num_loading; i++) {
4764 uint16 spriteid = buf->ReadWord();
4765 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4766 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
4769 break;
4772 case GSF_HOUSES:
4773 case GSF_AIRPORTTILES:
4774 case GSF_OBJECTS:
4775 case GSF_INDUSTRYTILES: {
4776 byte num_building_sprites = max((uint8)1, type);
4778 assert(TileLayoutSpriteGroup::CanAllocateItem());
4779 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
4780 act_group = group;
4782 /* On error, bail out immediately. Temporary GRF data was already freed */
4783 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
4784 break;
4787 case GSF_INDUSTRIES: {
4788 if (type > 1) {
4789 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
4790 break;
4793 assert(IndustryProductionSpriteGroup::CanAllocateItem());
4794 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
4795 act_group = group;
4796 group->version = type;
4797 if (type == 0) {
4798 for (uint i = 0; i < 3; i++) {
4799 group->subtract_input[i] = (int16)buf->ReadWord(); // signed
4801 for (uint i = 0; i < 2; i++) {
4802 group->add_output[i] = buf->ReadWord(); // unsigned
4804 group->again = buf->ReadByte();
4805 } else {
4806 for (uint i = 0; i < 3; i++) {
4807 group->subtract_input[i] = buf->ReadByte();
4809 for (uint i = 0; i < 2; i++) {
4810 group->add_output[i] = buf->ReadByte();
4812 group->again = buf->ReadByte();
4814 break;
4817 /* Loading of Tile Layout and Production Callback groups would happen here */
4818 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
4823 _cur.spritegroups[setid] = act_group;
4826 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
4828 if (feature == GSF_OBJECTS) {
4829 switch (ctype) {
4830 case 0: return 0;
4831 case 0xFF: return CT_PURCHASE_OBJECT;
4832 default:
4833 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
4834 return CT_INVALID;
4837 /* Special cargo types for purchase list and stations */
4838 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
4839 if (ctype == 0xFF) return CT_PURCHASE;
4841 if (_cur.grffile->cargo_list.Length() == 0) {
4842 /* No cargo table, so use bitnum values */
4843 if (ctype >= 32) {
4844 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
4845 return CT_INVALID;
4848 const CargoSpec *cs;
4849 FOR_ALL_CARGOSPECS(cs) {
4850 if (cs->bitnum == ctype) {
4851 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
4852 return cs->Index();
4856 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
4857 return CT_INVALID;
4860 /* Check if the cargo type is out of bounds of the cargo translation table */
4861 if (ctype >= _cur.grffile->cargo_list.Length()) {
4862 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1);
4863 return CT_INVALID;
4866 /* Look up the cargo label from the translation table */
4867 CargoLabel cl = _cur.grffile->cargo_list[ctype];
4868 if (cl == 0) {
4869 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
4870 return CT_INVALID;
4873 ctype = GetCargoIDByLabel(cl);
4874 if (ctype == CT_INVALID) {
4875 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));
4876 return CT_INVALID;
4879 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);
4880 return ctype;
4884 static bool IsValidGroupID(uint16 groupid, const char *function)
4886 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4887 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
4888 return false;
4891 return true;
4894 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
4896 static EngineID *last_engines;
4897 static uint last_engines_count;
4898 bool wagover = false;
4900 /* Test for 'wagon override' flag */
4901 if (HasBit(idcount, 7)) {
4902 wagover = true;
4903 /* Strip off the flag */
4904 idcount = GB(idcount, 0, 7);
4906 if (last_engines_count == 0) {
4907 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4908 return;
4911 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4912 last_engines_count, idcount);
4913 } else {
4914 if (last_engines_count != idcount) {
4915 last_engines = ReallocT(last_engines, idcount);
4916 last_engines_count = idcount;
4920 EngineID *engines = AllocaM(EngineID, idcount);
4921 for (uint i = 0; i < idcount; i++) {
4922 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
4923 if (e == NULL) {
4924 /* No engine could be allocated?!? Deal with it. Okay,
4925 * this might look bad. Also make sure this NewGRF
4926 * gets disabled, as a half loaded one is bad. */
4927 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
4928 return;
4931 engines[i] = e->index;
4932 if (!wagover) last_engines[i] = engines[i];
4935 uint8 cidcount = buf->ReadByte();
4936 for (uint c = 0; c < cidcount; c++) {
4937 uint8 ctype = buf->ReadByte();
4938 uint16 groupid = buf->ReadWord();
4939 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
4941 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
4943 ctype = TranslateCargo(feature, ctype);
4944 if (ctype == CT_INVALID) continue;
4946 for (uint i = 0; i < idcount; i++) {
4947 EngineID engine = engines[i];
4949 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
4951 if (wagover) {
4952 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
4953 } else {
4954 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
4959 uint16 groupid = buf->ReadWord();
4960 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
4962 grfmsg(8, "-- Default group id 0x%04X", groupid);
4964 for (uint i = 0; i < idcount; i++) {
4965 EngineID engine = engines[i];
4967 if (wagover) {
4968 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
4969 } else {
4970 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
4971 SetEngineGRF(engine, _cur.grffile);
4977 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
4979 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
4980 for (uint i = 0; i < idcount; i++) {
4981 cfs[i] = (CanalFeature)buf->ReadByte();
4984 uint8 cidcount = buf->ReadByte();
4985 buf->Skip(cidcount * 3);
4987 uint16 groupid = buf->ReadWord();
4988 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
4990 for (uint i = 0; i < idcount; i++) {
4991 CanalFeature cf = cfs[i];
4993 if (cf >= CF_END) {
4994 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
4995 continue;
4998 _water_feature[cf].grffile = _cur.grffile;
4999 _water_feature[cf].group = _cur.spritegroups[groupid];
5004 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
5006 uint8 *stations = AllocaM(uint8, idcount);
5007 for (uint i = 0; i < idcount; i++) {
5008 stations[i] = buf->ReadByte();
5011 uint8 cidcount = buf->ReadByte();
5012 for (uint c = 0; c < cidcount; c++) {
5013 uint8 ctype = buf->ReadByte();
5014 uint16 groupid = buf->ReadWord();
5015 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
5017 ctype = TranslateCargo(GSF_STATIONS, ctype);
5018 if (ctype == CT_INVALID) continue;
5020 for (uint i = 0; i < idcount; i++) {
5021 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5023 if (statspec == NULL) {
5024 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5025 continue;
5028 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5032 uint16 groupid = buf->ReadWord();
5033 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
5035 for (uint i = 0; i < idcount; i++) {
5036 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5038 if (statspec == NULL) {
5039 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5040 continue;
5043 if (statspec->grf_prop.grffile != NULL) {
5044 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5045 continue;
5048 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
5049 statspec->grf_prop.grffile = _cur.grffile;
5050 statspec->grf_prop.local_id = stations[i];
5051 StationClass::Assign(statspec);
5056 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
5058 uint8 *houses = AllocaM(uint8, idcount);
5059 for (uint i = 0; i < idcount; i++) {
5060 houses[i] = buf->ReadByte();
5063 /* Skip the cargo type section, we only care about the default group */
5064 uint8 cidcount = buf->ReadByte();
5065 buf->Skip(cidcount * 3);
5067 uint16 groupid = buf->ReadWord();
5068 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
5070 if (_cur.grffile->housespec == NULL) {
5071 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5072 return;
5075 for (uint i = 0; i < idcount; i++) {
5076 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
5078 if (hs == NULL) {
5079 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5080 continue;
5083 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5087 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5089 uint8 *industries = AllocaM(uint8, idcount);
5090 for (uint i = 0; i < idcount; i++) {
5091 industries[i] = buf->ReadByte();
5094 /* Skip the cargo type section, we only care about the default group */
5095 uint8 cidcount = buf->ReadByte();
5096 buf->Skip(cidcount * 3);
5098 uint16 groupid = buf->ReadWord();
5099 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5101 if (_cur.grffile->industryspec == NULL) {
5102 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5103 return;
5106 for (uint i = 0; i < idcount; i++) {
5107 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5109 if (indsp == NULL) {
5110 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5111 continue;
5114 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5118 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5120 uint8 *indtiles = AllocaM(uint8, idcount);
5121 for (uint i = 0; i < idcount; i++) {
5122 indtiles[i] = buf->ReadByte();
5125 /* Skip the cargo type section, we only care about the default group */
5126 uint8 cidcount = buf->ReadByte();
5127 buf->Skip(cidcount * 3);
5129 uint16 groupid = buf->ReadWord();
5130 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5132 if (_cur.grffile->indtspec == NULL) {
5133 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5134 return;
5137 for (uint i = 0; i < idcount; i++) {
5138 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5140 if (indtsp == NULL) {
5141 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5142 continue;
5145 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5149 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5151 CargoID *cargoes = AllocaM(CargoID, idcount);
5152 for (uint i = 0; i < idcount; i++) {
5153 cargoes[i] = buf->ReadByte();
5156 /* Skip the cargo type section, we only care about the default group */
5157 uint8 cidcount = buf->ReadByte();
5158 buf->Skip(cidcount * 3);
5160 uint16 groupid = buf->ReadWord();
5161 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5163 for (uint i = 0; i < idcount; i++) {
5164 CargoID cid = cargoes[i];
5166 if (cid >= NUM_CARGO) {
5167 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5168 continue;
5171 CargoSpec *cs = CargoSpec::Get(cid);
5172 cs->grffile = _cur.grffile;
5173 cs->group = _cur.spritegroups[groupid];
5177 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5179 if (_cur.grffile->objectspec == NULL) {
5180 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5181 return;
5184 uint8 *objects = AllocaM(uint8, idcount);
5185 for (uint i = 0; i < idcount; i++) {
5186 objects[i] = buf->ReadByte();
5189 uint8 cidcount = buf->ReadByte();
5190 for (uint c = 0; c < cidcount; c++) {
5191 uint8 ctype = buf->ReadByte();
5192 uint16 groupid = buf->ReadWord();
5193 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5195 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5196 if (ctype == CT_INVALID) continue;
5198 for (uint i = 0; i < idcount; i++) {
5199 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5201 if (spec == NULL) {
5202 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5203 continue;
5206 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5210 uint16 groupid = buf->ReadWord();
5211 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5213 for (uint i = 0; i < idcount; i++) {
5214 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5216 if (spec == NULL) {
5217 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5218 continue;
5221 if (spec->grf_prop.grffile != NULL) {
5222 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5223 continue;
5226 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5227 spec->grf_prop.grffile = _cur.grffile;
5228 spec->grf_prop.local_id = objects[i];
5232 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5234 uint8 *railtypes = AllocaM(uint8, idcount);
5235 for (uint i = 0; i < idcount; i++) {
5236 railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
5239 uint8 cidcount = buf->ReadByte();
5240 for (uint c = 0; c < cidcount; c++) {
5241 uint8 ctype = buf->ReadByte();
5242 uint16 groupid = buf->ReadWord();
5243 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5245 if (ctype >= RTSG_END) continue;
5247 extern RailtypeInfo _railtypes[RAILTYPE_END];
5248 for (uint i = 0; i < idcount; i++) {
5249 if (railtypes[i] != INVALID_RAILTYPE) {
5250 RailtypeInfo *rti = &_railtypes[railtypes[i]];
5252 rti->grffile[ctype] = _cur.grffile;
5253 rti->group[ctype] = _cur.spritegroups[groupid];
5258 /* Railtypes do not use the default group. */
5259 buf->ReadWord();
5262 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5264 uint8 *airports = AllocaM(uint8, idcount);
5265 for (uint i = 0; i < idcount; i++) {
5266 airports[i] = buf->ReadByte();
5269 /* Skip the cargo type section, we only care about the default group */
5270 uint8 cidcount = buf->ReadByte();
5271 buf->Skip(cidcount * 3);
5273 uint16 groupid = buf->ReadWord();
5274 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5276 if (_cur.grffile->airportspec == NULL) {
5277 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5278 return;
5281 for (uint i = 0; i < idcount; i++) {
5282 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5284 if (as == NULL) {
5285 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5286 continue;
5289 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5293 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5295 uint8 *airptiles = AllocaM(uint8, idcount);
5296 for (uint i = 0; i < idcount; i++) {
5297 airptiles[i] = buf->ReadByte();
5300 /* Skip the cargo type section, we only care about the default group */
5301 uint8 cidcount = buf->ReadByte();
5302 buf->Skip(cidcount * 3);
5304 uint16 groupid = buf->ReadWord();
5305 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5307 if (_cur.grffile->airtspec == NULL) {
5308 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5309 return;
5312 for (uint i = 0; i < idcount; i++) {
5313 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5315 if (airtsp == NULL) {
5316 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5317 continue;
5320 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5325 /* Action 0x03 */
5326 static void FeatureMapSpriteGroup(ByteReader *buf)
5328 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5329 * id-list := [<id>] [id-list]
5330 * cargo-list := <cargo-type> <cid> [cargo-list]
5332 * B feature see action 0
5333 * B n-id bits 0-6: how many IDs this definition applies to
5334 * bit 7: if set, this is a wagon override definition (see below)
5335 * B ids the IDs for which this definition applies
5336 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5337 * can be zero, in that case the def-cid is used always
5338 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5339 * W cid cargo ID (sprite group ID) for this type of cargo
5340 * W def-cid default cargo ID (sprite group ID) */
5342 uint8 feature = buf->ReadByte();
5343 uint8 idcount = buf->ReadByte();
5345 /* If idcount is zero, this is a feature callback */
5346 if (idcount == 0) {
5347 /* Skip number of cargo ids? */
5348 buf->ReadByte();
5349 uint16 groupid = buf->ReadWord();
5350 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
5352 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
5354 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5355 return;
5358 /* Mark the feature as used by the grf (generic callbacks do not count) */
5359 SetBit(_cur.grffile->grf_features, feature);
5361 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
5363 switch (feature) {
5364 case GSF_TRAINS:
5365 case GSF_ROADVEHICLES:
5366 case GSF_SHIPS:
5367 case GSF_AIRCRAFT:
5368 VehicleMapSpriteGroup(buf, feature, idcount);
5369 return;
5371 case GSF_CANALS:
5372 CanalMapSpriteGroup(buf, idcount);
5373 return;
5375 case GSF_STATIONS:
5376 StationMapSpriteGroup(buf, idcount);
5377 return;
5379 case GSF_HOUSES:
5380 TownHouseMapSpriteGroup(buf, idcount);
5381 return;
5383 case GSF_INDUSTRIES:
5384 IndustryMapSpriteGroup(buf, idcount);
5385 return;
5387 case GSF_INDUSTRYTILES:
5388 IndustrytileMapSpriteGroup(buf, idcount);
5389 return;
5391 case GSF_CARGOES:
5392 CargoMapSpriteGroup(buf, idcount);
5393 return;
5395 case GSF_AIRPORTS:
5396 AirportMapSpriteGroup(buf, idcount);
5397 return;
5399 case GSF_OBJECTS:
5400 ObjectMapSpriteGroup(buf, idcount);
5401 break;
5403 case GSF_RAILTYPES:
5404 RailTypeMapSpriteGroup(buf, idcount);
5405 break;
5407 case GSF_AIRPORTTILES:
5408 AirportTileMapSpriteGroup(buf, idcount);
5409 return;
5411 default:
5412 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
5413 return;
5417 /* Action 0x04 */
5418 static void FeatureNewName(ByteReader *buf)
5420 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5422 * B veh-type see action 0 (as 00..07, + 0A
5423 * But IF veh-type = 48, then generic text
5424 * B language-id If bit 6 is set, This is the extended language scheme,
5425 * with up to 64 language.
5426 * Otherwise, it is a mapping where set bits have meaning
5427 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5428 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5429 * B num-veh number of vehicles which are getting a new name
5430 * B/W offset number of the first vehicle that gets a new name
5431 * Byte : ID of vehicle to change
5432 * Word : ID of string to change/add
5433 * S data new texts, each of them zero-terminated, after
5434 * which the next name begins. */
5436 bool new_scheme = _cur.grffile->grf_version >= 7;
5438 uint8 feature = buf->ReadByte();
5439 uint8 lang = buf->ReadByte();
5440 uint8 num = buf->ReadByte();
5441 bool generic = HasBit(lang, 7);
5442 uint16 id;
5443 if (generic) {
5444 id = buf->ReadWord();
5445 } else if (feature <= GSF_AIRCRAFT) {
5446 id = buf->ReadExtendedByte();
5447 } else {
5448 id = buf->ReadByte();
5451 ClrBit(lang, 7);
5453 uint16 endid = id + num;
5455 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5456 id, endid, feature, lang);
5458 for (; id < endid && buf->HasData(); id++) {
5459 const char *name = buf->ReadString();
5460 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5462 switch (feature) {
5463 case GSF_TRAINS:
5464 case GSF_ROADVEHICLES:
5465 case GSF_SHIPS:
5466 case GSF_AIRCRAFT:
5467 if (!generic) {
5468 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
5469 if (e == NULL) break;
5470 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
5471 e->info.string_id = string;
5472 } else {
5473 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5475 break;
5477 case GSF_INDUSTRIES: {
5478 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5479 break;
5482 case GSF_HOUSES:
5483 default:
5484 switch (GB(id, 8, 8)) {
5485 case 0xC4: // Station class name
5486 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5487 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5488 } else {
5489 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
5490 StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5492 break;
5494 case 0xC5: // Station name
5495 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5496 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5497 } else {
5498 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5500 break;
5502 case 0xC7: // Airporttile name
5503 if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
5504 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
5505 } else {
5506 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5508 break;
5510 case 0xC9: // House name
5511 if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
5512 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
5513 } else {
5514 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5516 break;
5518 case 0xD0:
5519 case 0xD1:
5520 case 0xD2:
5521 case 0xD3:
5522 case 0xDC:
5523 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5524 break;
5526 default:
5527 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
5528 break;
5530 break;
5536 * Sanitize incoming sprite offsets for Action 5 graphics replacements.
5537 * @param num The number of sprites to load.
5538 * @param offset Offset from the base.
5539 * @param max_sprites The maximum number of sprites that can be loaded in this action 5.
5540 * @param name Used for error warnings.
5541 * @return The number of sprites that is going to be skipped.
5543 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
5546 if (offset >= max_sprites) {
5547 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
5548 uint orig_num = num;
5549 num = 0;
5550 return orig_num;
5553 if (offset + num > max_sprites) {
5554 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
5555 uint orig_num = num;
5556 num = max(max_sprites - offset, 0);
5557 return orig_num - num;
5560 return 0;
5564 /** The type of action 5 type. */
5565 enum Action5BlockType {
5566 A5BLOCK_FIXED, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5567 A5BLOCK_ALLOW_OFFSET, ///< Allow replacing any subset by specifiing an offset.
5568 A5BLOCK_INVALID, ///< unknown/not-implemented type
5570 /** Information about a single action 5 type. */
5571 struct Action5Type {
5572 Action5BlockType block_type; ///< How is this Action5 type processed?
5573 SpriteID sprite_base; ///< Load the sprites starting from this sprite.
5574 uint16 min_sprites; ///< If the Action5 contains less sprites, the whole block will be ignored.
5575 uint16 max_sprites; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5576 const char *name; ///< Name for error messages.
5579 /** The information about action 5 types. */
5580 static const Action5Type _action5_types[] = {
5581 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5582 /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
5583 /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
5584 /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
5585 /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
5586 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
5587 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Rail catenary graphics" },
5588 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
5589 /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5590 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
5591 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
5592 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
5593 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
5594 /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5595 /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
5596 /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5597 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
5598 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
5599 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
5600 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
5601 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
5602 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
5603 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
5604 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
5605 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
5606 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET, SPR_PALETTE_BASE, 1, PALETTE_SPRITE_COUNT, "Palette" },
5609 /* Action 0x05 */
5610 static void GraphicsNew(ByteReader *buf)
5612 /* <05> <graphics-type> <num-sprites> <other data...>
5614 * B graphics-type What set of graphics the sprites define.
5615 * E num-sprites How many sprites are in this set?
5616 * V other data Graphics type specific data. Currently unused. */
5617 /* TODO */
5619 uint8 type = buf->ReadByte();
5620 uint16 num = buf->ReadExtendedByte();
5621 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
5622 ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
5624 if ((type == 0x0D) && (num == 10) && HasBit(_cur.grfconfig->flags, GCF_SYSTEM)) {
5625 /* Special not-TTDP-compatible case used in openttd.grf
5626 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5627 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5628 LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_S
5629 LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_W
5630 LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_WSE
5631 LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_N
5632 LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NWS
5633 LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_ENW
5634 LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_SEN
5635 LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_E
5636 LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_EW
5637 LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NS
5638 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
5639 return;
5642 /* Supported type? */
5643 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
5644 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
5645 _cur.skip_sprites = num;
5646 return;
5649 const Action5Type *action5_type = &_action5_types[type];
5651 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5652 * except for the long version of the shore type:
5653 * Ignore offset if not allowed */
5654 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
5655 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
5656 offset = 0;
5659 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5660 * This does not make sense, if <offset> is allowed */
5661 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
5662 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);
5663 _cur.skip_sprites = num;
5664 return;
5667 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5668 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
5669 SpriteID replace = action5_type->sprite_base + offset;
5671 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5672 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);
5674 for (; num > 0; num--) {
5675 _cur.nfo_line++;
5676 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
5679 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
5681 _cur.skip_sprites = skip_num;
5684 /* Action 0x05 (SKIP) */
5685 static void SkipAct5(ByteReader *buf)
5687 /* Ignore type byte */
5688 buf->ReadByte();
5690 /* Skip the sprites of this action */
5691 _cur.skip_sprites = buf->ReadExtendedByte();
5693 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
5697 * Reads a variable common to VarAction2 and Action7/9/D.
5699 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5700 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5702 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5703 * @param value returns the value of the variable.
5704 * @param grffile NewGRF querying the variable
5705 * @return true iff the variable is known and the value is returned in 'value'.
5707 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
5709 switch (param) {
5710 case 0x00: // current date
5711 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
5712 return true;
5714 case 0x01: // current year
5715 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
5716 return true;
5718 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)
5719 YearMonthDay ymd;
5720 ConvertDateToYMD(_date, &ymd);
5721 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
5722 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
5723 return true;
5726 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5727 *value = _settings_game.game_creation.landscape;
5728 return true;
5730 case 0x06: // road traffic side, bit 4 clear=left, set=right
5731 *value = _settings_game.vehicle.road_side << 4;
5732 return true;
5734 case 0x09: // date fraction
5735 *value = _date_fract * 885;
5736 return true;
5738 case 0x0A: // animation counter
5739 *value = _tick_counter;
5740 return true;
5742 case 0x0B: { // TTDPatch version
5743 uint major = 2;
5744 uint minor = 6;
5745 uint revision = 1; // special case: 2.0.1 is 2.0.10
5746 uint build = 1382;
5747 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
5748 return true;
5751 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5752 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
5753 return true;
5755 case 0x0E: // Y-offset for train sprites
5756 *value = _cur.grffile->traininfo_vehicle_pitch;
5757 return true;
5759 case 0x0F: // Rail track type cost factors
5760 *value = 0;
5761 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
5762 if (_settings_game.vehicle.disable_elrails) {
5763 /* skip elrail multiplier - disabled */
5764 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
5765 } else {
5766 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
5767 /* Skip monorail multiplier - no space in result */
5769 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
5770 return true;
5772 case 0x11: // current rail tool type
5773 *value = 0; // constant fake value to avoid desync
5774 return true;
5776 case 0x12: // Game mode
5777 *value = _game_mode;
5778 return true;
5780 /* case 0x13: // Tile refresh offset to left not implemented */
5781 /* case 0x14: // Tile refresh offset to right not implemented */
5782 /* case 0x15: // Tile refresh offset upwards not implemented */
5783 /* case 0x16: // Tile refresh offset downwards not implemented */
5784 /* case 0x17: // temperate snow line not implemented */
5786 case 0x1A: // Always -1
5787 *value = UINT_MAX;
5788 return true;
5790 case 0x1B: // Display options
5791 *value = 0x3F; // constant fake value to avoid desync
5792 return true;
5794 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5795 *value = 1;
5796 return true;
5798 case 0x1E: // Miscellaneous GRF features
5799 *value = _misc_grf_features;
5801 /* Add the local flags */
5802 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
5803 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
5804 return true;
5806 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5808 case 0x20: { // snow line height
5809 byte snowline = GetSnowLine();
5810 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= _settings_game.construction.max_heightlevel) {
5811 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
5812 } else {
5813 /* No snow */
5814 *value = 0xFF;
5816 return true;
5819 case 0x21: // OpenTTD version
5820 *value = _openttd_newgrf_version;
5821 return true;
5823 case 0x22: // difficulty level
5824 *value = SP_CUSTOM;
5825 return true;
5827 case 0x23: // long format date
5828 *value = _date;
5829 return true;
5831 case 0x24: // long format year
5832 *value = _cur_year;
5833 return true;
5835 default: return false;
5839 static uint32 GetParamVal(byte param, uint32 *cond_val)
5841 /* First handle variable common with VarAction2 */
5842 uint32 value;
5843 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
5845 /* Non-common variable */
5846 switch (param) {
5847 case 0x84: { // GRF loading stage
5848 uint32 res = 0;
5850 if (_cur.stage > GLS_INIT) SetBit(res, 0);
5851 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
5852 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
5853 return res;
5856 case 0x85: // TTDPatch flags, only for bit tests
5857 if (cond_val == NULL) {
5858 /* Supported in Action 0x07 and 0x09, not 0x0D */
5859 return 0;
5860 } else {
5861 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
5862 *cond_val %= 0x20;
5863 return param_val;
5866 case 0x88: // GRF ID check
5867 return 0;
5869 /* case 0x99: Global ID offset not implemented */
5871 default:
5872 /* GRF Parameter */
5873 if (param < 0x80) return _cur.grffile->GetParam(param);
5875 /* In-game variable. */
5876 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
5877 return UINT_MAX;
5881 /* Action 0x06 */
5882 static void CfgApply(ByteReader *buf)
5884 /* <06> <param-num> <param-size> <offset> ... <FF>
5886 * B param-num Number of parameter to substitute (First = "zero")
5887 * Ignored if that parameter was not specified in newgrf.cfg
5888 * B param-size How many bytes to replace. If larger than 4, the
5889 * bytes of the following parameter are used. In that
5890 * case, nothing is applied unless *all* parameters
5891 * were specified.
5892 * B offset Offset into data from beginning of next sprite
5893 * to place where parameter is to be stored. */
5895 /* Preload the next sprite */
5896 size_t pos = FioGetPos();
5897 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
5898 uint8 type = FioReadByte();
5899 byte *preload_sprite = NULL;
5901 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5902 if (type == 0xFF) {
5903 preload_sprite = MallocT<byte>(num);
5904 FioReadBlock(preload_sprite, num);
5907 /* Reset the file position to the start of the next sprite */
5908 FioSeekTo(pos, SEEK_SET);
5910 if (type != 0xFF) {
5911 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5912 free(preload_sprite);
5913 return;
5916 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
5917 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
5918 if (it != _grf_line_to_action6_sprite_override.end()) {
5919 free(preload_sprite);
5920 preload_sprite = _grf_line_to_action6_sprite_override[location];
5921 } else {
5922 _grf_line_to_action6_sprite_override[location] = preload_sprite;
5925 /* Now perform the Action 0x06 on our data. */
5927 for (;;) {
5928 uint i;
5929 uint param_num;
5930 uint param_size;
5931 uint offset;
5932 bool add_value;
5934 /* Read the parameter to apply. 0xFF indicates no more data to change. */
5935 param_num = buf->ReadByte();
5936 if (param_num == 0xFF) break;
5938 /* Get the size of the parameter to use. If the size covers multiple
5939 * double words, sequential parameter values are used. */
5940 param_size = buf->ReadByte();
5942 /* Bit 7 of param_size indicates we should add to the original value
5943 * instead of replacing it. */
5944 add_value = HasBit(param_size, 7);
5945 param_size = GB(param_size, 0, 7);
5947 /* Where to apply the data to within the pseudo sprite data. */
5948 offset = buf->ReadExtendedByte();
5950 /* If the parameter is a GRF parameter (not an internal variable) check
5951 * if it (and all further sequential parameters) has been defined. */
5952 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
5953 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
5954 break;
5957 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
5959 bool carry = false;
5960 for (i = 0; i < param_size && offset + i < num; i++) {
5961 uint32 value = GetParamVal(param_num + i / 4, NULL);
5962 /* Reset carry flag for each iteration of the variable (only really
5963 * matters if param_size is greater than 4) */
5964 if (i % 4 == 0) carry = false;
5966 if (add_value) {
5967 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
5968 preload_sprite[offset + i] = GB(new_value, 0, 8);
5969 /* Check if the addition overflowed */
5970 carry = new_value >= 256;
5971 } else {
5972 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
5979 * Disable a static NewGRF when it is influencing another (non-static)
5980 * NewGRF as this could cause desyncs.
5982 * We could just tell the NewGRF querying that the file doesn't exist,
5983 * but that might give unwanted results. Disabling the NewGRF gives the
5984 * best result as no NewGRF author can complain about that.
5985 * @param c The NewGRF to disable.
5987 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
5989 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
5990 error->data = stredup(_cur.grfconfig->GetName());
5993 /* Action 0x07
5994 * Action 0x09 */
5995 static void SkipIf(ByteReader *buf)
5997 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
5999 * B param-num
6000 * B param-size
6001 * B condition-type
6002 * V value
6003 * B num-sprites */
6004 /* TODO: More params. More condition types. */
6005 uint32 cond_val = 0;
6006 uint32 mask = 0;
6007 bool result;
6009 uint8 param = buf->ReadByte();
6010 uint8 paramsize = buf->ReadByte();
6011 uint8 condtype = buf->ReadByte();
6013 if (condtype < 2) {
6014 /* Always 1 for bit tests, the given value should be ignored. */
6015 paramsize = 1;
6018 switch (paramsize) {
6019 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6020 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6021 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6022 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6023 default: break;
6026 if (param < 0x80 && _cur.grffile->param_end <= param) {
6027 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6028 return;
6031 uint32 param_val = GetParamVal(param, &cond_val);
6033 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
6036 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6037 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6038 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6039 * So, when the condition type is one of those, the specific variable
6040 * 0x88 code is skipped, so the "general" code for the cargo
6041 * availability conditions kicks in.
6043 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
6044 /* GRF ID checks */
6046 GRFConfig *c = GetGRFConfig(cond_val, mask);
6048 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6049 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6050 c = NULL;
6053 if (condtype != 10 && c == NULL) {
6054 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6055 return;
6058 switch (condtype) {
6059 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6060 case 0x06: // Is GRFID active?
6061 result = c->status == GCS_ACTIVATED;
6062 break;
6064 case 0x07: // Is GRFID non-active?
6065 result = c->status != GCS_ACTIVATED;
6066 break;
6068 case 0x08: // GRFID is not but will be active?
6069 result = c->status == GCS_INITIALISED;
6070 break;
6072 case 0x09: // GRFID is or will be active?
6073 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6074 break;
6076 case 0x0A: // GRFID is not nor will be active
6077 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6078 result = c == NULL || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6079 break;
6081 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
6083 } else {
6084 /* Parameter or variable tests */
6085 switch (condtype) {
6086 case 0x00: result = !!(param_val & (1 << cond_val));
6087 break;
6088 case 0x01: result = !(param_val & (1 << cond_val));
6089 break;
6090 case 0x02: result = (param_val & mask) == cond_val;
6091 break;
6092 case 0x03: result = (param_val & mask) != cond_val;
6093 break;
6094 case 0x04: result = (param_val & mask) < cond_val;
6095 break;
6096 case 0x05: result = (param_val & mask) > cond_val;
6097 break;
6098 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6099 break;
6100 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6101 break;
6102 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6103 break;
6104 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6105 break;
6107 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
6111 if (!result) {
6112 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6113 return;
6116 uint8 numsprites = buf->ReadByte();
6118 /* numsprites can be a GOTO label if it has been defined in the GRF
6119 * file. The jump will always be the first matching label that follows
6120 * the current nfo_line. If no matching label is found, the first matching
6121 * label in the file is used. */
6122 GRFLabel *choice = NULL;
6123 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
6124 if (label->label != numsprites) continue;
6126 /* Remember a goto before the current line */
6127 if (choice == NULL) choice = label;
6128 /* If we find a label here, this is definitely good */
6129 if (label->nfo_line > _cur.nfo_line) {
6130 choice = label;
6131 break;
6135 if (choice != NULL) {
6136 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6137 FioSeekTo(choice->pos, SEEK_SET);
6138 _cur.nfo_line = choice->nfo_line;
6139 return;
6142 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6143 _cur.skip_sprites = numsprites;
6144 if (_cur.skip_sprites == 0) {
6145 /* Zero means there are no sprites to skip, so
6146 * we use -1 to indicate that all further
6147 * sprites should be skipped. */
6148 _cur.skip_sprites = -1;
6150 /* If an action 8 hasn't been encountered yet, disable the grf. */
6151 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6152 DisableGrf();
6158 /* Action 0x08 (GLS_FILESCAN) */
6159 static void ScanInfo(ByteReader *buf)
6161 uint8 grf_version = buf->ReadByte();
6162 uint32 grfid = buf->ReadDWord();
6163 const char *name = buf->ReadString();
6165 _cur.grfconfig->ident.grfid = grfid;
6167 if (grf_version < 2 || grf_version > 8) {
6168 SetBit(_cur.grfconfig->flags, GCF_INVALID);
6169 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);
6172 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6173 if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6175 AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
6177 if (buf->HasData()) {
6178 const char *info = buf->ReadString();
6179 AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
6182 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6183 _cur.skip_sprites = -1;
6186 /* Action 0x08 */
6187 static void GRFInfo(ByteReader *buf)
6189 /* <08> <version> <grf-id> <name> <info>
6191 * B version newgrf version, currently 06
6192 * 4*B grf-id globally unique ID of this .grf file
6193 * S name name of this .grf set
6194 * S info string describing the set, and e.g. author and copyright */
6196 uint8 version = buf->ReadByte();
6197 uint32 grfid = buf->ReadDWord();
6198 const char *name = buf->ReadString();
6200 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6201 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6202 return;
6205 if (_cur.grffile->grfid != grfid) {
6206 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));
6207 _cur.grffile->grfid = grfid;
6210 _cur.grffile->grf_version = version;
6211 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6213 /* Do swap the GRFID for displaying purposes since people expect that */
6214 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);
6217 /* Action 0x0A */
6218 static void SpriteReplace(ByteReader *buf)
6220 /* <0A> <num-sets> <set1> [<set2> ...]
6221 * <set>: <num-sprites> <first-sprite>
6223 * B num-sets How many sets of sprites to replace.
6224 * Each set:
6225 * B num-sprites How many sprites are in this set
6226 * W first-sprite First sprite number to replace */
6228 uint8 num_sets = buf->ReadByte();
6230 for (uint i = 0; i < num_sets; i++) {
6231 uint8 num_sprites = buf->ReadByte();
6232 uint16 first_sprite = buf->ReadWord();
6234 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6235 i, num_sprites, first_sprite
6238 for (uint j = 0; j < num_sprites; j++) {
6239 int load_index = first_sprite + j;
6240 _cur.nfo_line++;
6241 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6243 /* Shore sprites now located at different addresses.
6244 * So detect when the old ones get replaced. */
6245 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6246 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
6252 /* Action 0x0A (SKIP) */
6253 static void SkipActA(ByteReader *buf)
6255 uint8 num_sets = buf->ReadByte();
6257 for (uint i = 0; i < num_sets; i++) {
6258 /* Skip the sprites this replaces */
6259 _cur.skip_sprites += buf->ReadByte();
6260 /* But ignore where they go */
6261 buf->ReadWord();
6264 grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
6267 /* Action 0x0B */
6268 static void GRFLoadError(ByteReader *buf)
6270 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6272 * B severity 00: notice, contine loading grf file
6273 * 01: warning, continue loading grf file
6274 * 02: error, but continue loading grf file, and attempt
6275 * loading grf again when loading or starting next game
6276 * 03: error, abort loading and prevent loading again in
6277 * the future (only when restarting the patch)
6278 * B language-id see action 4, use 1F for built-in error messages
6279 * B message-id message to show, see below
6280 * S message for custom messages (message-id FF), text of the message
6281 * not present for built-in messages.
6282 * V data additional data for built-in (or custom) messages
6283 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6285 static const StringID msgstr[] = {
6286 STR_NEWGRF_ERROR_VERSION_NUMBER,
6287 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6288 STR_NEWGRF_ERROR_UNSET_SWITCH,
6289 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6290 STR_NEWGRF_ERROR_LOAD_BEFORE,
6291 STR_NEWGRF_ERROR_LOAD_AFTER,
6292 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6295 static const StringID sevstr[] = {
6296 STR_NEWGRF_ERROR_MSG_INFO,
6297 STR_NEWGRF_ERROR_MSG_WARNING,
6298 STR_NEWGRF_ERROR_MSG_ERROR,
6299 STR_NEWGRF_ERROR_MSG_FATAL
6302 byte severity = buf->ReadByte();
6303 byte lang = buf->ReadByte();
6304 byte message_id = buf->ReadByte();
6306 /* Skip the error if it isn't valid for the current language. */
6307 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
6309 /* Skip the error until the activation stage unless bit 7 of the severity
6310 * is set. */
6311 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6312 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6313 return;
6315 ClrBit(severity, 7);
6317 if (severity >= lengthof(sevstr)) {
6318 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6319 severity = 2;
6320 } else if (severity == 3) {
6321 /* This is a fatal error, so make sure the GRF is deactivated and no
6322 * more of it gets loaded. */
6323 DisableGrf();
6325 /* Make sure we show fatal errors, instead of silly infos from before */
6326 delete _cur.grfconfig->error;
6327 _cur.grfconfig->error = NULL;
6330 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6331 grfmsg(7, "GRFLoadError: Invalid message id.");
6332 return;
6335 if (buf->Remaining() <= 1) {
6336 grfmsg(7, "GRFLoadError: No message data supplied.");
6337 return;
6340 /* For now we can only show one message per newgrf file. */
6341 if (_cur.grfconfig->error != NULL) return;
6343 GRFError *error = new GRFError(sevstr[severity]);
6345 if (message_id == 0xFF) {
6346 /* This is a custom error message. */
6347 if (buf->HasData()) {
6348 const char *message = buf->ReadString();
6350 error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, NULL, SCC_RAW_STRING_POINTER);
6351 } else {
6352 grfmsg(7, "GRFLoadError: No custom message supplied.");
6353 error->custom_message = stredup("");
6355 } else {
6356 error->message = msgstr[message_id];
6359 if (buf->HasData()) {
6360 const char *data = buf->ReadString();
6362 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6363 } else {
6364 grfmsg(7, "GRFLoadError: No message data supplied.");
6365 error->data = stredup("");
6368 /* Only two parameter numbers can be used in the string. */
6369 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6370 uint param_number = buf->ReadByte();
6371 error->param_value[i] = _cur.grffile->GetParam(param_number);
6374 _cur.grfconfig->error = error;
6377 /* Action 0x0C */
6378 static void GRFComment(ByteReader *buf)
6380 /* <0C> [<ignored...>]
6382 * V ignored Anything following the 0C is ignored */
6384 if (!buf->HasData()) return;
6386 const char *text = buf->ReadString();
6387 grfmsg(2, "GRFComment: %s", text);
6390 /* Action 0x0D (GLS_SAFETYSCAN) */
6391 static void SafeParamSet(ByteReader *buf)
6393 uint8 target = buf->ReadByte();
6395 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6396 if (target < 0x80 || target == 0x9E) return;
6398 /* GRM could be unsafe, but as here it can only happen after other GRFs
6399 * are loaded, it should be okay. If the GRF tried to use the slots it
6400 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6401 * sprites is considered safe. */
6403 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6405 /* Skip remainder of GRF */
6406 _cur.skip_sprites = -1;
6410 static uint32 GetPatchVariable(uint8 param)
6412 switch (param) {
6413 /* start year - 1920 */
6414 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
6416 /* freight trains weight factor */
6417 case 0x0E: return _settings_game.vehicle.freight_trains;
6419 /* empty wagon speed increase */
6420 case 0x0F: return 0;
6422 /* plane speed factor; our patch option is reversed from TTDPatch's,
6423 * the following is good for 1x, 2x and 4x (most common?) and...
6424 * well not really for 3x. */
6425 case 0x10:
6426 switch (_settings_game.vehicle.plane_speed) {
6427 default:
6428 case 4: return 1;
6429 case 3: return 2;
6430 case 2: return 2;
6431 case 1: return 4;
6435 /* 2CC colourmap base sprite */
6436 case 0x11: return SPR_2CCMAP_BASE;
6438 /* map size: format = -MABXYSS
6439 * M : the type of map
6440 * bit 0 : set : squared map. Bit 1 is now not relevant
6441 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6442 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6443 * clear : X is the bigger edge.
6444 * A : minimum edge(log2) of the map
6445 * B : maximum edge(log2) of the map
6446 * XY : edges(log2) of each side of the map.
6447 * SS : combination of both X and Y, thus giving the size(log2) of the map
6449 case 0x13: {
6450 byte map_bits = 0;
6451 byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6452 byte log_Y = MapLogY() - 6;
6453 byte max_edge = max(log_X, log_Y);
6455 if (log_X == log_Y) { // we have a squared map, since both edges are identical
6456 SetBit(map_bits, 0);
6457 } else {
6458 if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
6461 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
6462 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
6465 /* The maximum height of the map. */
6466 case 0x14:
6467 return _settings_game.construction.max_heightlevel;
6469 /* Extra foundations base sprite */
6470 case 0x15:
6471 return SPR_SLOPES_BASE;
6473 /* Shore base sprite */
6474 case 0x16:
6475 return SPR_SHORE_BASE;
6477 default:
6478 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
6479 return 0;
6484 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
6486 uint start = 0;
6487 uint size = 0;
6489 if (op == 6) {
6490 /* Return GRFID of set that reserved ID */
6491 return grm[_cur.grffile->GetParam(target)];
6494 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6495 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
6497 for (uint i = start; i < num_ids; i++) {
6498 if (grm[i] == 0) {
6499 size++;
6500 } else {
6501 if (op == 2 || op == 3) break;
6502 start = i + 1;
6503 size = 0;
6506 if (size == count) break;
6509 if (size == count) {
6510 /* Got the slot... */
6511 if (op == 0 || op == 3) {
6512 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
6513 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
6515 return start;
6518 /* Unable to allocate */
6519 if (op != 4 && op != 5) {
6520 /* Deactivate GRF */
6521 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
6522 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6523 return UINT_MAX;
6526 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
6527 return UINT_MAX;
6531 /** Action 0x0D: Set parameter */
6532 static void ParamSet(ByteReader *buf)
6534 /* <0D> <target> <operation> <source1> <source2> [<data>]
6536 * B target parameter number where result is stored
6537 * B operation operation to perform, see below
6538 * B source1 first source operand
6539 * B source2 second source operand
6540 * D data data to use in the calculation, not necessary
6541 * if both source1 and source2 refer to actual parameters
6543 * Operations
6544 * 00 Set parameter equal to source1
6545 * 01 Addition, source1 + source2
6546 * 02 Subtraction, source1 - source2
6547 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6548 * 04 Signed multiplication, source1 * source2 (both signed)
6549 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6550 * signed quantity; left shift if positive and right shift if
6551 * negative, source1 is unsigned)
6552 * 06 Signed bit shift, source1 by source2
6553 * (source2 like in 05, and source1 as well)
6556 uint8 target = buf->ReadByte();
6557 uint8 oper = buf->ReadByte();
6558 uint32 src1 = buf->ReadByte();
6559 uint32 src2 = buf->ReadByte();
6561 uint32 data = 0;
6562 if (buf->Remaining() >= 4) data = buf->ReadDWord();
6564 /* You can add 80 to the operation to make it apply only if the target
6565 * is not defined yet. In this respect, a parameter is taken to be
6566 * defined if any of the following applies:
6567 * - it has been set to any value in the newgrf(w).cfg parameter list
6568 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6569 * an earlier action D */
6570 if (HasBit(oper, 7)) {
6571 if (target < 0x80 && target < _cur.grffile->param_end) {
6572 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
6573 return;
6576 oper = GB(oper, 0, 7);
6579 if (src2 == 0xFE) {
6580 if (GB(data, 0, 8) == 0xFF) {
6581 if (data == 0x0000FFFF) {
6582 /* Patch variables */
6583 src1 = GetPatchVariable(src1);
6584 } else {
6585 /* GRF Resource Management */
6586 uint8 op = src1;
6587 uint8 feature = GB(data, 8, 8);
6588 uint16 count = GB(data, 16, 16);
6590 if (_cur.stage == GLS_RESERVE) {
6591 if (feature == 0x08) {
6592 /* General sprites */
6593 if (op == 0) {
6594 /* Check if the allocated sprites will fit below the original sprite limit */
6595 if (_cur.spriteid + count >= 16384) {
6596 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
6597 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6598 return;
6601 /* Reserve space at the current sprite ID */
6602 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
6603 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
6604 _cur.spriteid += count;
6607 /* Ignore GRM result during reservation */
6608 src1 = 0;
6609 } else if (_cur.stage == GLS_ACTIVATION) {
6610 switch (feature) {
6611 case 0x00: // Trains
6612 case 0x01: // Road Vehicles
6613 case 0x02: // Ships
6614 case 0x03: // Aircraft
6615 if (!_settings_game.vehicle.dynamic_engines) {
6616 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
6617 if (_cur.skip_sprites == -1) return;
6618 } else {
6619 /* GRM does not apply for dynamic engine allocation. */
6620 switch (op) {
6621 case 2:
6622 case 3:
6623 src1 = _cur.grffile->GetParam(target);
6624 break;
6626 default:
6627 src1 = 0;
6628 break;
6631 break;
6633 case 0x08: // General sprites
6634 switch (op) {
6635 case 0:
6636 /* Return space reserved during reservation stage */
6637 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
6638 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
6639 break;
6641 case 1:
6642 src1 = _cur.spriteid;
6643 break;
6645 default:
6646 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
6647 return;
6649 break;
6651 case 0x0B: // Cargo
6652 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6653 src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
6654 if (_cur.skip_sprites == -1) return;
6655 break;
6657 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
6659 } else {
6660 /* Ignore GRM during initialization */
6661 src1 = 0;
6664 } else {
6665 /* Read another GRF File's parameter */
6666 const GRFFile *file = GetFileByGRFID(data);
6667 GRFConfig *c = GetGRFConfig(data);
6668 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6669 /* Disable the read GRF if it is a static NewGRF. */
6670 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6671 src1 = 0;
6672 } else if (file == NULL || c == NULL || c->status == GCS_DISABLED) {
6673 src1 = 0;
6674 } else if (src1 == 0xFE) {
6675 src1 = c->version;
6676 } else {
6677 src1 = file->GetParam(src1);
6680 } else {
6681 /* The source1 and source2 operands refer to the grf parameter number
6682 * like in action 6 and 7. In addition, they can refer to the special
6683 * variables available in action 7, or they can be FF to use the value
6684 * of <data>. If referring to parameters that are undefined, a value
6685 * of 0 is used instead. */
6686 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
6687 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
6690 /* TODO: You can access the parameters of another GRF file by using
6691 * source2=FE, source1=the other GRF's parameter number and data=GRF
6692 * ID. This is only valid with operation 00 (set). If the GRF ID
6693 * cannot be found, a value of 0 is used for the parameter value
6694 * instead. */
6696 uint32 res;
6697 switch (oper) {
6698 case 0x00:
6699 res = src1;
6700 break;
6702 case 0x01:
6703 res = src1 + src2;
6704 break;
6706 case 0x02:
6707 res = src1 - src2;
6708 break;
6710 case 0x03:
6711 res = src1 * src2;
6712 break;
6714 case 0x04:
6715 res = (int32)src1 * (int32)src2;
6716 break;
6718 case 0x05:
6719 if ((int32)src2 < 0) {
6720 res = src1 >> -(int32)src2;
6721 } else {
6722 res = src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6724 break;
6726 case 0x06:
6727 if ((int32)src2 < 0) {
6728 res = (int32)src1 >> -(int32)src2;
6729 } else {
6730 res = (int32)src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6732 break;
6734 case 0x07: // Bitwise AND
6735 res = src1 & src2;
6736 break;
6738 case 0x08: // Bitwise OR
6739 res = src1 | src2;
6740 break;
6742 case 0x09: // Unsigned division
6743 if (src2 == 0) {
6744 res = src1;
6745 } else {
6746 res = src1 / src2;
6748 break;
6750 case 0x0A: // Signed divison
6751 if (src2 == 0) {
6752 res = src1;
6753 } else {
6754 res = (int32)src1 / (int32)src2;
6756 break;
6758 case 0x0B: // Unsigned modulo
6759 if (src2 == 0) {
6760 res = src1;
6761 } else {
6762 res = src1 % src2;
6764 break;
6766 case 0x0C: // Signed modulo
6767 if (src2 == 0) {
6768 res = src1;
6769 } else {
6770 res = (int32)src1 % (int32)src2;
6772 break;
6774 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
6777 switch (target) {
6778 case 0x8E: // Y-Offset for train sprites
6779 _cur.grffile->traininfo_vehicle_pitch = res;
6780 break;
6782 case 0x8F: { // Rail track type cost factors
6783 extern RailtypeInfo _railtypes[RAILTYPE_END];
6784 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
6785 if (_settings_game.vehicle.disable_elrails) {
6786 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
6787 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
6788 } else {
6789 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
6790 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
6792 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
6793 break;
6796 /* @todo implement */
6797 case 0x93: // Tile refresh offset to left
6798 case 0x94: // Tile refresh offset to right
6799 case 0x95: // Tile refresh offset upwards
6800 case 0x96: // Tile refresh offset downwards
6801 case 0x97: // Snow line height
6802 case 0x99: // Global ID offset
6803 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6804 break;
6806 case 0x9E: // Miscellaneous GRF features
6807 /* Set train list engine width */
6808 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
6809 /* Remove the local flags from the global flags */
6810 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
6812 /* Only copy safe bits for static grfs */
6813 if (HasBit(_cur.grfconfig->flags, GCF_STATIC)) {
6814 uint32 safe_bits = 0;
6815 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
6817 _misc_grf_features = (_misc_grf_features & ~safe_bits) | (res & safe_bits);
6818 } else {
6819 _misc_grf_features = res;
6821 break;
6823 case 0x9F: // locale-dependent settings
6824 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6825 break;
6827 default:
6828 if (target < 0x80) {
6829 _cur.grffile->param[target] = res;
6830 /* param is zeroed by default */
6831 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
6832 } else {
6833 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
6835 break;
6839 /* Action 0x0E (GLS_SAFETYSCAN) */
6840 static void SafeGRFInhibit(ByteReader *buf)
6842 /* <0E> <num> <grfids...>
6844 * B num Number of GRFIDs that follow
6845 * D grfids GRFIDs of the files to deactivate */
6847 uint8 num = buf->ReadByte();
6849 for (uint i = 0; i < num; i++) {
6850 uint32 grfid = buf->ReadDWord();
6852 /* GRF is unsafe it if tries to deactivate other GRFs */
6853 if (grfid != _cur.grfconfig->ident.grfid) {
6854 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6856 /* Skip remainder of GRF */
6857 _cur.skip_sprites = -1;
6859 return;
6864 /* Action 0x0E */
6865 static void GRFInhibit(ByteReader *buf)
6867 /* <0E> <num> <grfids...>
6869 * B num Number of GRFIDs that follow
6870 * D grfids GRFIDs of the files to deactivate */
6872 uint8 num = buf->ReadByte();
6874 for (uint i = 0; i < num; i++) {
6875 uint32 grfid = buf->ReadDWord();
6876 GRFConfig *file = GetGRFConfig(grfid);
6878 /* Unset activation flag */
6879 if (file != NULL && file != _cur.grfconfig) {
6880 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
6881 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
6882 error->data = stredup(_cur.grfconfig->GetName());
6887 /** Action 0x0F - Define Town names */
6888 static void FeatureTownName(ByteReader *buf)
6890 /* <0F> <id> <style-name> <num-parts> <parts>
6892 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6893 * V style-name Name of the style (only for final definition)
6894 * B num-parts Number of parts in this definition
6895 * V parts The parts */
6897 uint32 grfid = _cur.grffile->grfid;
6899 GRFTownName *townname = AddGRFTownName(grfid);
6901 byte id = buf->ReadByte();
6902 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
6904 if (HasBit(id, 7)) {
6905 /* Final definition */
6906 ClrBit(id, 7);
6907 bool new_scheme = _cur.grffile->grf_version >= 7;
6909 byte lang = buf->ReadByte();
6911 byte nb_gen = townname->nb_gen;
6912 do {
6913 ClrBit(lang, 7);
6915 const char *name = buf->ReadString();
6917 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
6918 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
6919 free(lang_name);
6921 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6923 lang = buf->ReadByte();
6924 } while (lang != 0);
6925 townname->id[nb_gen] = id;
6926 townname->nb_gen++;
6929 byte nb = buf->ReadByte();
6930 grfmsg(6, "FeatureTownName: %u parts", nb);
6932 townname->nbparts[id] = nb;
6933 townname->partlist[id] = CallocT<NamePartList>(nb);
6935 for (int i = 0; i < nb; i++) {
6936 byte nbtext = buf->ReadByte();
6937 townname->partlist[id][i].bitstart = buf->ReadByte();
6938 townname->partlist[id][i].bitcount = buf->ReadByte();
6939 townname->partlist[id][i].maxprob = 0;
6940 townname->partlist[id][i].partcount = nbtext;
6941 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
6942 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);
6944 for (int j = 0; j < nbtext; j++) {
6945 byte prob = buf->ReadByte();
6947 if (HasBit(prob, 7)) {
6948 byte ref_id = buf->ReadByte();
6950 if (townname->nbparts[ref_id] == 0) {
6951 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
6952 DelGRFTownName(grfid);
6953 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
6954 return;
6957 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
6958 townname->partlist[id][i].parts[j].data.id = ref_id;
6959 } else {
6960 const char *text = buf->ReadString();
6961 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
6962 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
6964 townname->partlist[id][i].parts[j].prob = prob;
6965 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
6967 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
6971 /** Action 0x10 - Define goto label */
6972 static void DefineGotoLabel(ByteReader *buf)
6974 /* <10> <label> [<comment>]
6976 * B label The label to define
6977 * V comment Optional comment - ignored */
6979 byte nfo_label = buf->ReadByte();
6981 GRFLabel *label = MallocT<GRFLabel>(1);
6982 label->label = nfo_label;
6983 label->nfo_line = _cur.nfo_line;
6984 label->pos = FioGetPos();
6985 label->next = NULL;
6987 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
6988 if (_cur.grffile->label == NULL) {
6989 _cur.grffile->label = label;
6990 } else {
6991 /* Attach the label to the end of the list */
6992 GRFLabel *l;
6993 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
6994 l->next = label;
6997 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7001 * Process a sound import from another GRF file.
7002 * @param sound Destination for sound.
7004 static void ImportGRFSound(SoundEntry *sound)
7006 const GRFFile *file;
7007 uint32 grfid = FioReadDword();
7008 SoundID sound_id = FioReadWord();
7010 file = GetFileByGRFID(grfid);
7011 if (file == NULL || file->sound_offset == 0) {
7012 grfmsg(1, "ImportGRFSound: Source file not available");
7013 return;
7016 if (sound_id >= file->num_sounds) {
7017 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
7018 return;
7021 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7023 *sound = *GetSound(file->sound_offset + sound_id);
7025 /* Reset volume and priority, which TTDPatch doesn't copy */
7026 sound->volume = 128;
7027 sound->priority = 0;
7031 * Load a sound from a file.
7032 * @param offs File offset to read sound from.
7033 * @param sound Destination for sound.
7035 static void LoadGRFSound(size_t offs, SoundEntry *sound)
7037 /* Set default volume and priority */
7038 sound->volume = 0x80;
7039 sound->priority = 0;
7041 if (offs != SIZE_MAX) {
7042 /* Sound is present in the NewGRF. */
7043 sound->file_slot = _cur.file_index;
7044 sound->file_offset = offs;
7045 sound->grf_container_ver = _cur.grf_container_ver;
7049 /* Action 0x11 */
7050 static void GRFSound(ByteReader *buf)
7052 /* <11> <num>
7054 * W num Number of sound files that follow */
7056 uint16 num = buf->ReadWord();
7057 if (num == 0) return;
7059 SoundEntry *sound;
7060 if (_cur.grffile->sound_offset == 0) {
7061 _cur.grffile->sound_offset = GetNumSounds();
7062 _cur.grffile->num_sounds = num;
7063 sound = AllocateSound(num);
7064 } else {
7065 sound = GetSound(_cur.grffile->sound_offset);
7068 for (int i = 0; i < num; i++) {
7069 _cur.nfo_line++;
7071 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7072 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7073 bool invalid = i >= _cur.grffile->num_sounds;
7075 size_t offs = FioGetPos();
7077 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7078 byte type = FioReadByte();
7080 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7081 /* Reference to sprite section. */
7082 if (invalid) {
7083 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7084 FioSkipBytes(len);
7085 } else if (len != 4) {
7086 grfmsg(1, "GRFSound: Invalid sprite section import");
7087 FioSkipBytes(len);
7088 } else {
7089 uint32 id = FioReadDword();
7090 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7092 continue;
7095 if (type != 0xFF) {
7096 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7097 FioSkipBytes(7);
7098 SkipSpriteData(type, len - 8);
7099 continue;
7102 if (invalid) {
7103 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7104 FioSkipBytes(len);
7107 byte action = FioReadByte();
7108 switch (action) {
7109 case 0xFF:
7110 /* Allocate sound only in init stage. */
7111 if (_cur.stage == GLS_INIT) {
7112 if (_cur.grf_container_ver >= 2) {
7113 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7114 } else {
7115 LoadGRFSound(offs, sound + i);
7118 FioSkipBytes(len - 1); // already read <action>
7119 break;
7121 case 0xFE:
7122 if (_cur.stage == GLS_ACTIVATION) {
7123 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7124 * importing sounds, so this is probably all wrong... */
7125 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7126 ImportGRFSound(sound + i);
7127 } else {
7128 FioSkipBytes(len - 1); // already read <action>
7130 break;
7132 default:
7133 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7134 FioSkipBytes(len - 1); // already read <action>
7135 break;
7140 /* Action 0x11 (SKIP) */
7141 static void SkipAct11(ByteReader *buf)
7143 /* <11> <num>
7145 * W num Number of sound files that follow */
7147 _cur.skip_sprites = buf->ReadWord();
7149 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
7152 /** Action 0x12 */
7153 static void LoadFontGlyph(ByteReader *buf)
7155 /* <12> <num_def> <font_size> <num_char> <base_char>
7157 * B num_def Number of definitions
7158 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7159 * B num_char Number of consecutive glyphs
7160 * W base_char First character index */
7162 uint8 num_def = buf->ReadByte();
7164 for (uint i = 0; i < num_def; i++) {
7165 FontSize size = (FontSize)buf->ReadByte();
7166 uint8 num_char = buf->ReadByte();
7167 uint16 base_char = buf->ReadWord();
7169 if (size >= FS_END) {
7170 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7173 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7175 for (uint c = 0; c < num_char; c++) {
7176 if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
7177 _cur.nfo_line++;
7178 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7183 /** Action 0x12 (SKIP) */
7184 static void SkipAct12(ByteReader *buf)
7186 /* <12> <num_def> <font_size> <num_char> <base_char>
7188 * B num_def Number of definitions
7189 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7190 * B num_char Number of consecutive glyphs
7191 * W base_char First character index */
7193 uint8 num_def = buf->ReadByte();
7195 for (uint i = 0; i < num_def; i++) {
7196 /* Ignore 'size' byte */
7197 buf->ReadByte();
7199 /* Sum up number of characters */
7200 _cur.skip_sprites += buf->ReadByte();
7202 /* Ignore 'base_char' word */
7203 buf->ReadWord();
7206 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
7209 /** Action 0x13 */
7210 static void TranslateGRFStrings(ByteReader *buf)
7212 /* <13> <grfid> <num-ent> <offset> <text...>
7214 * 4*B grfid The GRFID of the file whose texts are to be translated
7215 * B num-ent Number of strings
7216 * W offset First text ID
7217 * S text... Zero-terminated strings */
7219 uint32 grfid = buf->ReadDWord();
7220 const GRFConfig *c = GetGRFConfig(grfid);
7221 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7222 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7223 return;
7226 if (c->status == GCS_INITIALISED) {
7227 /* If the file is not active but will be activated later, give an error
7228 * and disable this file. */
7229 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
7231 char tmp[256];
7232 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
7233 error->data = stredup(tmp);
7235 return;
7238 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7239 * to be added as a generic string, thus the language id of 0x7F. For this to work
7240 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7241 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7242 * not change anything if a string has been provided specifically for this language. */
7243 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7244 byte num_strings = buf->ReadByte();
7245 uint16 first_id = buf->ReadWord();
7247 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
7248 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7249 return;
7252 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7253 const char *string = buf->ReadString();
7255 if (StrEmpty(string)) {
7256 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7257 continue;
7260 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7264 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7265 static bool ChangeGRFName(byte langid, const char *str)
7267 AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
7268 return true;
7271 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7272 static bool ChangeGRFDescription(byte langid, const char *str)
7274 AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
7275 return true;
7278 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7279 static bool ChangeGRFURL(byte langid, const char *str)
7281 AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str);
7282 return true;
7285 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7286 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7288 if (len != 1) {
7289 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7290 buf->Skip(len);
7291 } else {
7292 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7294 return true;
7297 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7298 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7300 if (len != 1) {
7301 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7302 buf->Skip(len);
7303 } else {
7304 char data = buf->ReadByte();
7305 GRFPalette pal = GRFP_GRF_UNSET;
7306 switch (data) {
7307 case '*':
7308 case 'A': pal = GRFP_GRF_ANY; break;
7309 case 'W': pal = GRFP_GRF_WINDOWS; break;
7310 case 'D': pal = GRFP_GRF_DOS; break;
7311 default:
7312 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7313 break;
7315 if (pal != GRFP_GRF_UNSET) {
7316 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7317 _cur.grfconfig->palette |= pal;
7320 return true;
7323 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7324 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7326 if (len != 1) {
7327 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7328 buf->Skip(len);
7329 } else {
7330 char data = buf->ReadByte();
7331 GRFPalette pal = GRFP_BLT_UNSET;
7332 switch (data) {
7333 case '8': pal = GRFP_BLT_UNSET; break;
7334 case '3': pal = GRFP_BLT_32BPP; break;
7335 default:
7336 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7337 return true;
7339 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7340 _cur.grfconfig->palette |= pal;
7342 return true;
7345 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7346 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7348 if (len != 4) {
7349 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7350 buf->Skip(len);
7351 } else {
7352 /* Set min_loadable_version as well (default to minimal compatibility) */
7353 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7355 return true;
7358 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7359 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7361 if (len != 4) {
7362 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7363 buf->Skip(len);
7364 } else {
7365 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7366 if (_cur.grfconfig->version == 0) {
7367 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7368 _cur.grfconfig->min_loadable_version = 0;
7370 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7371 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7372 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
7375 return true;
7378 static GRFParameterInfo *_cur_parameter; ///< The parameter which info is currently changed by the newgrf.
7380 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7381 static bool ChangeGRFParamName(byte langid, const char *str)
7383 AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
7384 return true;
7387 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7388 static bool ChangeGRFParamDescription(byte langid, const char *str)
7390 AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
7391 return true;
7394 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7395 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7397 if (len != 1) {
7398 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7399 buf->Skip(len);
7400 } else {
7401 GRFParameterType type = (GRFParameterType)buf->ReadByte();
7402 if (type < PTYPE_END) {
7403 _cur_parameter->type = type;
7404 } else {
7405 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7408 return true;
7411 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7412 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7414 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7415 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7416 buf->Skip(len);
7417 } else if (len != 8) {
7418 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7419 buf->Skip(len);
7420 } else {
7421 _cur_parameter->min_value = buf->ReadDWord();
7422 _cur_parameter->max_value = buf->ReadDWord();
7424 return true;
7427 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7428 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7430 if (len < 1 || len > 3) {
7431 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7432 buf->Skip(len);
7433 } else {
7434 byte param_nr = buf->ReadByte();
7435 if (param_nr >= lengthof(_cur.grfconfig->param)) {
7436 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7437 buf->Skip(len - 1);
7438 } else {
7439 _cur_parameter->param_nr = param_nr;
7440 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
7441 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7445 return true;
7448 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7449 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7451 if (len != 4) {
7452 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7453 buf->Skip(len);
7454 } else {
7455 _cur_parameter->def_value = buf->ReadDWord();
7457 _cur.grfconfig->has_param_defaults = true;
7458 return true;
7461 typedef bool (*DataHandler)(size_t, ByteReader *); ///< Type of callback function for binary nodes
7462 typedef bool (*TextHandler)(byte, const char *str); ///< Type of callback function for text nodes
7463 typedef bool (*BranchHandler)(ByteReader *); ///< Type of callback function for branch nodes
7466 * Data structure to store the allowed id/type combinations for action 14. The
7467 * data can be represented as a tree with 3 types of nodes:
7468 * 1. Branch nodes (identified by 'C' for choice).
7469 * 2. Binary leaf nodes (identified by 'B').
7470 * 3. Text leaf nodes (identified by 'T').
7472 struct AllowedSubtags {
7473 /** Create empty subtags object used to identify the end of a list. */
7474 AllowedSubtags() :
7475 id(0),
7476 type(0)
7480 * Create a binary leaf node.
7481 * @param id The id for this node.
7482 * @param handler The callback function to call.
7484 AllowedSubtags(uint32 id, DataHandler handler) :
7485 id(id),
7486 type('B')
7488 this->handler.data = handler;
7492 * Create a text leaf node.
7493 * @param id The id for this node.
7494 * @param handler The callback function to call.
7496 AllowedSubtags(uint32 id, TextHandler handler) :
7497 id(id),
7498 type('T')
7500 this->handler.text = handler;
7504 * Create a branch node with a callback handler
7505 * @param id The id for this node.
7506 * @param handler The callback function to call.
7508 AllowedSubtags(uint32 id, BranchHandler handler) :
7509 id(id),
7510 type('C')
7512 this->handler.call_handler = true;
7513 this->handler.u.branch = handler;
7517 * Create a branch node with a list of sub-nodes.
7518 * @param id The id for this node.
7519 * @param subtags Array with all valid subtags.
7521 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
7522 id(id),
7523 type('C')
7525 this->handler.call_handler = false;
7526 this->handler.u.subtags = subtags;
7529 uint32 id; ///< The identifier for this node
7530 byte type; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7531 union {
7532 DataHandler data; ///< Callback function for a binary node, only valid if type == 'B'.
7533 TextHandler text; ///< Callback function for a text node, only valid if type == 'T'.
7534 struct {
7535 union {
7536 BranchHandler branch; ///< Callback function for a branch node, only valid if type == 'C' && call_handler.
7537 AllowedSubtags *subtags; ///< Pointer to a list of subtags, only valid if type == 'C' && !call_handler.
7538 } u;
7539 bool call_handler; ///< True if there is a callback function for this node, false if there is a list of subnodes.
7541 } handler;
7544 static bool SkipUnknownInfo(ByteReader *buf, byte type);
7545 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
7548 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7549 * of some parameter values (type uint/enum) or the names of some bits
7550 * (type bitmask). In both cases the format is the same:
7551 * Each subnode should be a text node with the value/bit number as id.
7553 static bool ChangeGRFParamValueNames(ByteReader *buf)
7555 byte type = buf->ReadByte();
7556 while (type != 0) {
7557 uint32 id = buf->ReadDWord();
7558 if (type != 'T' || id > _cur_parameter->max_value) {
7559 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7560 if (!SkipUnknownInfo(buf, type)) return false;
7561 type = buf->ReadByte();
7562 continue;
7565 byte langid = buf->ReadByte();
7566 const char *name_string = buf->ReadString();
7568 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
7569 if (val_name != _cur_parameter->value_names.End()) {
7570 AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
7571 } else {
7572 GRFText *list = NULL;
7573 AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
7574 _cur_parameter->value_names.Insert(id, list);
7577 type = buf->ReadByte();
7579 return true;
7582 /** Action14 parameter tags */
7583 AllowedSubtags _tags_parameters[] = {
7584 AllowedSubtags('NAME', ChangeGRFParamName),
7585 AllowedSubtags('DESC', ChangeGRFParamDescription),
7586 AllowedSubtags('TYPE', ChangeGRFParamType),
7587 AllowedSubtags('LIMI', ChangeGRFParamLimits),
7588 AllowedSubtags('MASK', ChangeGRFParamMask),
7589 AllowedSubtags('VALU', ChangeGRFParamValueNames),
7590 AllowedSubtags('DFLT', ChangeGRFParamDefault),
7591 AllowedSubtags()
7595 * Callback function for 'INFO'->'PARA' to set extra information about the
7596 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7597 * the parameter number as id. The first parameter has id 0. The maximum
7598 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7600 static bool HandleParameterInfo(ByteReader *buf)
7602 byte type = buf->ReadByte();
7603 while (type != 0) {
7604 uint32 id = buf->ReadDWord();
7605 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
7606 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7607 if (!SkipUnknownInfo(buf, type)) return false;
7608 type = buf->ReadByte();
7609 continue;
7612 if (id >= _cur.grfconfig->param_info.Length()) {
7613 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
7614 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
7615 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
7617 if (_cur.grfconfig->param_info[id] == NULL) {
7618 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
7620 _cur_parameter = _cur.grfconfig->param_info[id];
7621 /* Read all parameter-data and process each node. */
7622 if (!HandleNodes(buf, _tags_parameters)) return false;
7623 type = buf->ReadByte();
7625 return true;
7628 /** Action14 tags for the INFO node */
7629 AllowedSubtags _tags_info[] = {
7630 AllowedSubtags('NAME', ChangeGRFName),
7631 AllowedSubtags('DESC', ChangeGRFDescription),
7632 AllowedSubtags('URL_', ChangeGRFURL),
7633 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
7634 AllowedSubtags('PALS', ChangeGRFPalette),
7635 AllowedSubtags('BLTR', ChangeGRFBlitter),
7636 AllowedSubtags('VRSN', ChangeGRFVersion),
7637 AllowedSubtags('MINV', ChangeGRFMinVersion),
7638 AllowedSubtags('PARA', HandleParameterInfo),
7639 AllowedSubtags()
7642 /** Action14 root tags */
7643 AllowedSubtags _tags_root[] = {
7644 AllowedSubtags('INFO', _tags_info),
7645 AllowedSubtags()
7650 * Try to skip the current node and all subnodes (if it's a branch node).
7651 * @param buf Buffer.
7652 * @param type The node type to skip.
7653 * @return True if we could skip the node, false if an error occurred.
7655 static bool SkipUnknownInfo(ByteReader *buf, byte type)
7657 /* type and id are already read */
7658 switch (type) {
7659 case 'C': {
7660 byte new_type = buf->ReadByte();
7661 while (new_type != 0) {
7662 buf->ReadDWord(); // skip the id
7663 if (!SkipUnknownInfo(buf, new_type)) return false;
7664 new_type = buf->ReadByte();
7666 break;
7669 case 'T':
7670 buf->ReadByte(); // lang
7671 buf->ReadString(); // actual text
7672 break;
7674 case 'B': {
7675 uint16 size = buf->ReadWord();
7676 buf->Skip(size);
7677 break;
7680 default:
7681 return false;
7684 return true;
7688 * Handle the nodes of an Action14
7689 * @param type Type of node.
7690 * @param id ID.
7691 * @param buf Buffer.
7692 * @param subtags Allowed subtags.
7693 * @return Whether all tags could be handled.
7695 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
7697 uint i = 0;
7698 AllowedSubtags *tag;
7699 while ((tag = &subtags[i++])->type != 0) {
7700 if (tag->id != BSWAP32(id) || tag->type != type) continue;
7701 switch (type) {
7702 default: NOT_REACHED();
7704 case 'T': {
7705 byte langid = buf->ReadByte();
7706 return tag->handler.text(langid, buf->ReadString());
7709 case 'B': {
7710 size_t len = buf->ReadWord();
7711 if (buf->Remaining() < len) return false;
7712 return tag->handler.data(len, buf);
7715 case 'C': {
7716 if (tag->handler.call_handler) {
7717 return tag->handler.u.branch(buf);
7719 return HandleNodes(buf, tag->handler.u.subtags);
7723 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
7724 return SkipUnknownInfo(buf, type);
7728 * Handle the contents of a 'C' choice of an Action14
7729 * @param buf Buffer.
7730 * @param subtags List of subtags.
7731 * @return Whether the nodes could all be handled.
7733 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
7735 byte type = buf->ReadByte();
7736 while (type != 0) {
7737 uint32 id = buf->ReadDWord();
7738 if (!HandleNode(type, id, buf, subtags)) return false;
7739 type = buf->ReadByte();
7741 return true;
7745 * Handle Action 0x14
7746 * @param buf Buffer.
7748 static void StaticGRFInfo(ByteReader *buf)
7750 /* <14> <type> <id> <text/data...> */
7751 HandleNodes(buf, _tags_root);
7755 * Set the current NewGRF as unsafe for static use
7756 * @param buf Unused.
7757 * @note Used during safety scan on unsafe actions.
7759 static void GRFUnsafe(ByteReader *buf)
7761 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7763 /* Skip remainder of GRF */
7764 _cur.skip_sprites = -1;
7768 /** Initialize the TTDPatch flags */
7769 static void InitializeGRFSpecial()
7771 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
7772 | (1 << 0x0D) // newairports
7773 | (1 << 0x0E) // largestations
7774 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
7775 | (0 << 0x10) // loadtime
7776 | (1 << 0x12) // presignals
7777 | (1 << 0x13) // extpresignals
7778 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
7779 | (1 << 0x1B) // multihead
7780 | (1 << 0x1D) // lowmemory
7781 | (1 << 0x1E); // generalfixes
7783 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
7784 | (1 << 0x08) // mammothtrains
7785 | (1 << 0x09) // trainrefit
7786 | (0 << 0x0B) // subsidiaries
7787 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
7788 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7789 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7790 | (1 << 0x14) // bridgespeedlimits
7791 | (1 << 0x16) // eternalgame
7792 | (1 << 0x17) // newtrains
7793 | (1 << 0x18) // newrvs
7794 | (1 << 0x19) // newships
7795 | (1 << 0x1A) // newplanes
7796 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7797 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
7799 _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
7800 | (1 << 0x03) // semaphores
7801 | (1 << 0x0A) // newobjects
7802 | (0 << 0x0B) // enhancedgui
7803 | (0 << 0x0C) // newagerating
7804 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
7805 | (1 << 0x0E) // fullloadany
7806 | (1 << 0x0F) // planespeed
7807 | (0 << 0x10) // moreindustriesperclimate - obsolete
7808 | (0 << 0x11) // moretoylandfeatures
7809 | (1 << 0x12) // newstations
7810 | (1 << 0x13) // tracktypecostdiff
7811 | (1 << 0x14) // manualconvert
7812 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
7813 | (1 << 0x16) // canals
7814 | (1 << 0x17) // newstartyear
7815 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
7816 | (1 << 0x19) // newhouses
7817 | (1 << 0x1A) // newbridges
7818 | (1 << 0x1B) // newtownnames
7819 | (1 << 0x1C) // moreanimation
7820 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
7821 | (1 << 0x1E) // newshistory
7822 | (0 << 0x1F); // custombridgeheads
7824 _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
7825 | (1 << 0x01) // windowsnap
7826 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
7827 | (1 << 0x03) // pathbasedsignalling
7828 | (0 << 0x04) // aichoosechance
7829 | (1 << 0x05) // resolutionwidth
7830 | (1 << 0x06) // resolutionheight
7831 | (1 << 0x07) // newindustries
7832 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
7833 | (0 << 0x09) // townroadbranchprob
7834 | (0 << 0x0A) // tempsnowline
7835 | (1 << 0x0B) // newcargo
7836 | (1 << 0x0C) // enhancemultiplayer
7837 | (1 << 0x0D) // onewayroads
7838 | (1 << 0x0E) // irregularstations
7839 | (1 << 0x0F) // statistics
7840 | (1 << 0x10) // newsounds
7841 | (1 << 0x11) // autoreplace
7842 | (1 << 0x12) // autoslope
7843 | (0 << 0x13) // followvehicle
7844 | (1 << 0x14) // trams
7845 | (0 << 0x15) // enhancetunnels
7846 | (1 << 0x16) // shortrvs
7847 | (1 << 0x17) // articulatedrvs
7848 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
7849 | (1 << 0x1E) // variablerunningcosts
7850 | (1 << 0x1F); // any switch is on
7853 /** Reset and clear all NewGRF stations */
7854 static void ResetCustomStations()
7856 const GRFFile * const *end = _grf_files.End();
7857 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7858 StationSpec **&stations = (*file)->stations;
7859 if (stations == NULL) continue;
7860 for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
7861 if (stations[i] == NULL) continue;
7862 StationSpec *statspec = stations[i];
7864 delete[] statspec->renderdata;
7866 /* Release platforms and layouts */
7867 if (!statspec->copied_layouts) {
7868 for (uint l = 0; l < statspec->lengths; l++) {
7869 for (uint p = 0; p < statspec->platforms[l]; p++) {
7870 free(statspec->layouts[l][p]);
7872 free(statspec->layouts[l]);
7874 free(statspec->layouts);
7875 free(statspec->platforms);
7878 /* Release this station */
7879 free(statspec);
7882 /* Free and reset the station data */
7883 free(stations);
7884 stations = NULL;
7888 /** Reset and clear all NewGRF houses */
7889 static void ResetCustomHouses()
7891 const GRFFile * const *end = _grf_files.End();
7892 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7893 HouseSpec **&housespec = (*file)->housespec;
7894 if (housespec == NULL) continue;
7895 for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
7896 free(housespec[i]);
7899 free(housespec);
7900 housespec = NULL;
7904 /** Reset and clear all NewGRF airports */
7905 static void ResetCustomAirports()
7907 const GRFFile * const *end = _grf_files.End();
7908 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7909 AirportSpec **aslist = (*file)->airportspec;
7910 if (aslist != NULL) {
7911 for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
7912 AirportSpec *as = aslist[i];
7914 if (as != NULL) {
7915 /* We need to remove the tiles layouts */
7916 for (int j = 0; j < as->num_table; j++) {
7917 /* remove the individual layouts */
7918 free(as->table[j]);
7920 free(as->table);
7921 free(as->depot_table);
7923 free(as);
7926 free(aslist);
7927 (*file)->airportspec = NULL;
7930 AirportTileSpec **&airporttilespec = (*file)->airtspec;
7931 if (airporttilespec != NULL) {
7932 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
7933 free(airporttilespec[i]);
7935 free(airporttilespec);
7936 airporttilespec = NULL;
7941 /** Reset and clear all NewGRF industries */
7942 static void ResetCustomIndustries()
7944 const GRFFile * const *end = _grf_files.End();
7945 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7946 IndustrySpec **&industryspec = (*file)->industryspec;
7947 IndustryTileSpec **&indtspec = (*file)->indtspec;
7949 /* We are verifiying both tiles and industries specs loaded from the grf file
7950 * First, let's deal with industryspec */
7951 if (industryspec != NULL) {
7952 for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
7953 IndustrySpec *ind = industryspec[i];
7954 if (ind == NULL) continue;
7956 /* We need to remove the sounds array */
7957 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
7958 free(ind->random_sounds);
7961 /* We need to remove the tiles layouts */
7962 CleanIndustryTileTable(ind);
7964 free(ind);
7967 free(industryspec);
7968 industryspec = NULL;
7971 if (indtspec == NULL) continue;
7972 for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
7973 free(indtspec[i]);
7976 free(indtspec);
7977 indtspec = NULL;
7981 /** Reset and clear all NewObjects */
7982 static void ResetCustomObjects()
7984 const GRFFile * const *end = _grf_files.End();
7985 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7986 ObjectSpec **&objectspec = (*file)->objectspec;
7987 if (objectspec == NULL) continue;
7988 for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
7989 free(objectspec[i]);
7992 free(objectspec);
7993 objectspec = NULL;
7997 /** Reset and clear all NewGRFs */
7998 static void ResetNewGRF()
8000 const GRFFile * const *end = _grf_files.End();
8001 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8002 delete *file;
8005 _grf_files.Clear();
8006 _cur.grffile = NULL;
8009 /** Clear all NewGRF errors */
8010 static void ResetNewGRFErrors()
8012 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
8013 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
8014 delete c->error;
8015 c->error = NULL;
8021 * Reset all NewGRF loaded data
8022 * TODO
8024 void ResetNewGRFData()
8026 CleanUpStrings();
8027 CleanUpGRFTownNames();
8029 /* Copy/reset original engine info data */
8030 SetupEngines();
8032 /* Copy/reset original bridge info data */
8033 ResetBridges();
8035 /* Reset rail type information */
8036 ResetRailTypes();
8038 /* Allocate temporary refit/cargo class data */
8039 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
8041 /* Fill rail type label temporary data for default trains */
8042 Engine *e;
8043 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
8044 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
8047 /* Reset GRM reservations */
8048 memset(&_grm_engines, 0, sizeof(_grm_engines));
8049 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
8051 /* Reset generic feature callback lists */
8052 ResetGenericCallbacks();
8054 /* Reset price base data */
8055 ResetPriceBaseMultipliers();
8057 /* Reset the curencies array */
8058 ResetCurrencies();
8060 /* Reset the house array */
8061 ResetCustomHouses();
8062 ResetHouses();
8064 /* Reset the industries structures*/
8065 ResetCustomIndustries();
8066 ResetIndustries();
8068 /* Reset the objects. */
8069 ObjectClass::Reset();
8070 ResetCustomObjects();
8071 ResetObjects();
8073 /* Reset station classes */
8074 StationClass::Reset();
8075 ResetCustomStations();
8077 /* Reset airport-related structures */
8078 AirportClass::Reset();
8079 ResetCustomAirports();
8080 AirportSpec::ResetAirports();
8081 AirportTileSpec::ResetAirportTiles();
8083 /* Reset canal sprite groups and flags */
8084 memset(_water_feature, 0, sizeof(_water_feature));
8086 /* Reset the snowline table. */
8087 ClearSnowLine();
8089 /* Reset NewGRF files */
8090 ResetNewGRF();
8092 /* Reset NewGRF errors. */
8093 ResetNewGRFErrors();
8095 /* Set up the default cargo types */
8096 SetupCargoForClimate(_settings_game.game_creation.landscape);
8098 /* Reset misc GRF features and train list display variables */
8099 _misc_grf_features = 0;
8101 _loaded_newgrf_features.has_2CC = false;
8102 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8103 _loaded_newgrf_features.has_newhouses = false;
8104 _loaded_newgrf_features.has_newindustries = false;
8105 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
8107 /* Clear all GRF overrides */
8108 _grf_id_overrides.clear();
8110 InitializeSoundPool();
8111 _spritegroup_pool.CleanPool();
8115 * Reset NewGRF data which is stored persistently in savegames.
8117 void ResetPersistentNewGRFData()
8119 /* Reset override managers */
8120 _engine_mngr.ResetToDefaultMapping();
8121 _house_mngr.ResetMapping();
8122 _industry_mngr.ResetMapping();
8123 _industile_mngr.ResetMapping();
8124 _airport_mngr.ResetMapping();
8125 _airporttile_mngr.ResetMapping();
8129 * Construct the Cargo Mapping
8130 * @note This is the reverse of a cargo translation table
8132 static void BuildCargoTranslationMap()
8134 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8136 for (CargoID c = 0; c < NUM_CARGO; c++) {
8137 const CargoSpec *cs = CargoSpec::Get(c);
8138 if (!cs->IsValid()) continue;
8140 if (_cur.grffile->cargo_list.Length() == 0) {
8141 /* Default translation table, so just a straight mapping to bitnum */
8142 _cur.grffile->cargo_map[c] = cs->bitnum;
8143 } else {
8144 /* Check the translation table for this cargo's label */
8145 int index = _cur.grffile->cargo_list.FindIndex(cs->label);
8146 if (index >= 0) _cur.grffile->cargo_map[c] = index;
8152 * Prepare loading a NewGRF file with its config
8153 * @param config The NewGRF configuration struct with name, id, parameters and alike.
8155 static void InitNewGRFFile(const GRFConfig *config)
8157 GRFFile *newfile = GetFileByFilename(config->filename);
8158 if (newfile != NULL) {
8159 /* We already loaded it once. */
8160 _cur.grffile = newfile;
8161 return;
8164 newfile = new GRFFile(config);
8165 *_grf_files.Append() = _cur.grffile = newfile;
8169 * Constructor for GRFFile
8170 * @param config GRFConfig to copy name, grfid and parameters from.
8172 GRFFile::GRFFile(const GRFConfig *config)
8174 this->filename = stredup(config->filename);
8175 this->grfid = config->ident.grfid;
8177 /* Initialise local settings to defaults */
8178 this->traininfo_vehicle_pitch = 0;
8179 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8181 /* Mark price_base_multipliers as 'not set' */
8182 for (Price i = PR_BEGIN; i < PR_END; i++) {
8183 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8186 /* Initialise rail type map with default rail types */
8187 memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
8188 this->railtype_map[0] = RAILTYPE_RAIL;
8189 this->railtype_map[1] = RAILTYPE_ELECTRIC;
8190 this->railtype_map[2] = RAILTYPE_MONO;
8191 this->railtype_map[3] = RAILTYPE_MAGLEV;
8193 /* Copy the initial parameter list
8194 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8195 assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8197 assert(config->num_params <= lengthof(config->param));
8198 this->param_end = config->num_params;
8199 if (this->param_end > 0) {
8200 MemCpyT(this->param, config->param, this->param_end);
8204 GRFFile::~GRFFile()
8206 free(this->filename);
8207 delete[] this->language_map;
8212 * List of what cargo labels are refittable for the given the vehicle-type.
8213 * Only currently active labels are applied.
8215 static const CargoLabel _default_refitmasks_rail[] = {
8216 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8217 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8218 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8219 'PLST', 'FZDR',
8220 0 };
8222 static const CargoLabel _default_refitmasks_road[] = {
8223 0 };
8225 static const CargoLabel _default_refitmasks_ships[] = {
8226 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8227 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8228 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8229 'PLST', 'FZDR',
8230 0 };
8232 static const CargoLabel _default_refitmasks_aircraft[] = {
8233 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8234 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8235 0 };
8237 static const CargoLabel * const _default_refitmasks[] = {
8238 _default_refitmasks_rail,
8239 _default_refitmasks_road,
8240 _default_refitmasks_ships,
8241 _default_refitmasks_aircraft,
8246 * Precalculate refit masks from cargo classes for all vehicles.
8248 static void CalculateRefitMasks()
8250 Engine *e;
8252 FOR_ALL_ENGINES(e) {
8253 EngineID engine = e->index;
8254 EngineInfo *ei = &e->info;
8255 bool only_defaultcargo; ///< Set if the vehicle shall carry only the default cargo
8257 /* Did the newgrf specify any refitting? If not, use defaults. */
8258 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8259 uint32 mask = 0;
8260 uint32 not_mask = 0;
8261 uint32 xor_mask = ei->refit_mask;
8263 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8264 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8265 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8267 if (_gted[engine].cargo_allowed != 0) {
8268 /* Build up the list of cargo types from the set cargo classes. */
8269 const CargoSpec *cs;
8270 FOR_ALL_CARGOSPECS(cs) {
8271 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8272 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8276 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8278 /* Apply explicit refit includes/excludes. */
8279 ei->refit_mask |= _gted[engine].ctt_include_mask;
8280 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8281 } else {
8282 uint32 xor_mask = 0;
8284 /* Don't apply default refit mask to wagons nor engines with no capacity */
8285 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8286 const CargoLabel *cl = _default_refitmasks[e->type];
8287 for (uint i = 0;; i++) {
8288 if (cl[i] == 0) break;
8290 CargoID cargo = GetCargoIDByLabel(cl[i]);
8291 if (cargo == CT_INVALID) continue;
8293 SetBit(xor_mask, cargo);
8297 ei->refit_mask = xor_mask & _cargo_mask;
8299 /* If the mask is zero, the vehicle shall only carry the default cargo */
8300 only_defaultcargo = (ei->refit_mask == 0);
8303 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8304 if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8306 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8307 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8308 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8309 ei->cargo_type = CT_INVALID;
8312 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8313 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8314 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8315 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8316 const uint8 *cargo_map_for_first_refittable = NULL;
8318 const GRFFile *file = _gted[engine].defaultcargo_grf;
8319 if (file == NULL) file = e->GetGRF();
8320 if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
8321 cargo_map_for_first_refittable = file->cargo_map;
8325 if (cargo_map_for_first_refittable != NULL) {
8326 /* Use first refittable cargo from cargo translation table */
8327 byte best_local_slot = 0xFF;
8328 CargoID cargo_type;
8329 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8330 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8331 if (local_slot < best_local_slot) {
8332 best_local_slot = local_slot;
8333 ei->cargo_type = cargo_type;
8338 if (ei->cargo_type == CT_INVALID) {
8339 /* Use first refittable cargo slot */
8340 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8343 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8345 /* Clear refit_mask for not refittable ships */
8346 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8347 ei->refit_mask = 0;
8352 /** Set to use the correct action0 properties for each canal feature */
8353 static void FinaliseCanals()
8355 for (uint i = 0; i < CF_END; i++) {
8356 if (_water_feature[i].grffile != NULL) {
8357 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
8358 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
8363 /** Check for invalid engines */
8364 static void FinaliseEngineArray()
8366 Engine *e;
8368 FOR_ALL_ENGINES(e) {
8369 if (e->GetGRF() == NULL) {
8370 const EngineIDMapping &eid = _engine_mngr[e->index];
8371 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8372 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8376 /* When the train does not set property 27 (misc flags), but it
8377 * is overridden by a NewGRF graphically we want to disable the
8378 * flipping possibility. */
8379 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
8380 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8383 /* Skip wagons, there livery is defined via the engine */
8384 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8385 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
8386 SetBit(_loaded_newgrf_features.used_liveries, ls);
8387 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8389 if (e->type == VEH_TRAIN) {
8390 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8391 switch (ls) {
8392 case LS_STEAM:
8393 case LS_DIESEL:
8394 case LS_ELECTRIC:
8395 case LS_MONORAIL:
8396 case LS_MAGLEV:
8397 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8398 break;
8400 case LS_DMU:
8401 case LS_EMU:
8402 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8403 break;
8405 default: NOT_REACHED();
8412 /** Check for invalid cargoes */
8413 static void FinaliseCargoArray()
8415 for (CargoID c = 0; c < NUM_CARGO; c++) {
8416 CargoSpec *cs = CargoSpec::Get(c);
8417 if (!cs->IsValid()) {
8418 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8419 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8420 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8426 * Check if a given housespec is valid and disable it if it's not.
8427 * The housespecs that follow it are used to check the validity of
8428 * multitile houses.
8429 * @param hs The housespec to check.
8430 * @param next1 The housespec that follows \c hs.
8431 * @param next2 The housespec that follows \c next1.
8432 * @param next3 The housespec that follows \c next2.
8433 * @param filename The filename of the newgrf this house was defined in.
8434 * @return Whether the given housespec is valid.
8436 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8438 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8439 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8440 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8441 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8442 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8443 hs->enabled = false;
8444 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);
8445 return false;
8448 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8449 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8450 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8451 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8452 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8453 hs->enabled = false;
8454 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);
8455 return false;
8458 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8459 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8460 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8461 hs->enabled = false;
8462 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);
8463 return false;
8466 /* Make sure that additional parts of multitile houses are not available. */
8467 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
8468 hs->enabled = false;
8469 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);
8470 return false;
8473 return true;
8477 * Make sure there is at least one house available in the year 0 for the given
8478 * climate / housezone combination.
8479 * @param bitmask The climate and housezone to check for. Exactly one climate
8480 * bit and one housezone bit should be set.
8482 static void EnsureEarlyHouse(HouseZones bitmask)
8484 Year min_year = MAX_YEAR;
8486 for (int i = 0; i < NUM_HOUSES; i++) {
8487 HouseSpec *hs = HouseSpec::Get(i);
8488 if (hs == NULL || !hs->enabled) continue;
8489 if ((hs->building_availability & bitmask) != bitmask) continue;
8490 if (hs->min_year < min_year) min_year = hs->min_year;
8493 if (min_year == 0) return;
8495 for (int i = 0; i < NUM_HOUSES; i++) {
8496 HouseSpec *hs = HouseSpec::Get(i);
8497 if (hs == NULL || !hs->enabled) continue;
8498 if ((hs->building_availability & bitmask) != bitmask) continue;
8499 if (hs->min_year == min_year) hs->min_year = 0;
8504 * Add all new houses to the house array. House properties can be set at any
8505 * time in the GRF file, so we can only add a house spec to the house array
8506 * after the file has finished loading. We also need to check the dates, due to
8507 * the TTDPatch behaviour described below that we need to emulate.
8509 static void FinaliseHouseArray()
8511 /* If there are no houses with start dates before 1930, then all houses
8512 * with start dates of 1930 have them reset to 0. This is in order to be
8513 * compatible with TTDPatch, where if no houses have start dates before
8514 * 1930 and the date is before 1930, the game pretends that this is 1930.
8515 * If there have been any houses defined with start dates before 1930 then
8516 * the dates are left alone.
8517 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8518 * minimum introduction date to 0.
8520 const GRFFile * const *end = _grf_files.End();
8521 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8522 HouseSpec **&housespec = (*file)->housespec;
8523 if (housespec == NULL) continue;
8525 for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8526 HouseSpec *hs = housespec[i];
8528 if (hs == NULL) continue;
8530 const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : NULL);
8531 const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : NULL);
8532 const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : NULL);
8534 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
8536 _house_mngr.SetEntitySpec(hs);
8540 for (int i = 0; i < NUM_HOUSES; i++) {
8541 HouseSpec *hs = HouseSpec::Get(i);
8542 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : NULL);
8543 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : NULL);
8544 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : NULL);
8546 /* We need to check all houses again to we are sure that multitile houses
8547 * did get consecutive IDs and none of the parts are missing. */
8548 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
8549 /* GetHouseNorthPart checks 3 houses that are directly before
8550 * it in the house pool. If any of those houses have multi-tile
8551 * flags set it assumes it's part of a multitile house. Since
8552 * we can have invalid houses in the pool marked as disabled, we
8553 * don't want to have them influencing valid tiles. As such set
8554 * building_flags to zero here to make sure any house following
8555 * this one in the pool is properly handled as 1x1 house. */
8556 hs->building_flags = TILE_NO_FLAG;
8560 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
8561 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
8562 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
8563 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
8564 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
8565 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
8567 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
8568 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
8569 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
8570 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
8571 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
8572 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
8577 * Add all new industries to the industry array. Industry properties can be set at any
8578 * time in the GRF file, so we can only add a industry spec to the industry array
8579 * after the file has finished loading.
8581 static void FinaliseIndustriesArray()
8583 const GRFFile * const *end = _grf_files.End();
8584 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8585 IndustrySpec **&industryspec = (*file)->industryspec;
8586 IndustryTileSpec **&indtspec = (*file)->indtspec;
8587 if (industryspec != NULL) {
8588 for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8589 IndustrySpec *indsp = industryspec[i];
8591 if (indsp != NULL && indsp->enabled) {
8592 StringID strid;
8593 /* process the conversion of text at the end, so to be sure everything will be fine
8594 * and available. Check if it does not return undefind marker, which is a very good sign of a
8595 * substitute industry who has not changed the string been examined, thus using it as such */
8596 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
8597 if (strid != STR_UNDEFINED) indsp->name = strid;
8599 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
8600 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
8602 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
8603 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
8605 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
8606 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
8608 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
8609 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
8611 if (indsp->station_name != STR_NULL) {
8612 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8613 * station's name. Don't want to lose the value, therefore, do not process. */
8614 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
8615 if (strid != STR_UNDEFINED) indsp->station_name = strid;
8618 _industry_mngr.SetEntitySpec(indsp);
8619 _loaded_newgrf_features.has_newindustries = true;
8624 if (indtspec != NULL) {
8625 for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8626 IndustryTileSpec *indtsp = indtspec[i];
8627 if (indtsp != NULL) {
8628 _industile_mngr.SetEntitySpec(indtsp);
8634 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
8635 IndustrySpec *indsp = &_industry_specs[j];
8636 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
8637 for (uint i = 0; i < 3; i++) {
8638 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
8641 if (!indsp->enabled) {
8642 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
8648 * Add all new objects to the object array. Object properties can be set at any
8649 * time in the GRF file, so we can only add an object spec to the object array
8650 * after the file has finished loading.
8652 static void FinaliseObjectsArray()
8654 const GRFFile * const *end = _grf_files.End();
8655 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8656 ObjectSpec **&objectspec = (*file)->objectspec;
8657 if (objectspec != NULL) {
8658 for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8659 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
8660 _object_mngr.SetEntitySpec(objectspec[i]);
8668 * Add all new airports to the airport array. Airport properties can be set at any
8669 * time in the GRF file, so we can only add a airport spec to the airport array
8670 * after the file has finished loading.
8672 static void FinaliseAirportsArray()
8674 const GRFFile * const *end = _grf_files.End();
8675 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8676 AirportSpec **&airportspec = (*file)->airportspec;
8677 if (airportspec != NULL) {
8678 for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8679 if (airportspec[i] != NULL && airportspec[i]->enabled) {
8680 _airport_mngr.SetEntitySpec(airportspec[i]);
8685 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8686 if (airporttilespec != NULL) {
8687 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8688 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
8689 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
8696 /* Here we perform initial decoding of some special sprites (as are they
8697 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8698 * partial implementation yet).
8699 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8700 * a crafted invalid GRF file. We should tell that to the user somehow, or
8701 * better make this more robust in the future. */
8702 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
8704 /* XXX: There is a difference between staged loading in TTDPatch and
8705 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8706 * during stage 1, whilst action 3 is carried out during stage 2 (to
8707 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8708 * IDs are valid only within a given set (action 1) block, and may be
8709 * overwritten after action 3 associates them. But overwriting happens
8710 * in an earlier stage than associating, so... We just process actions
8711 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8712 * --pasky
8713 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8714 * is not in memory and scanning the file every time would be too expensive.
8715 * In other stages we skip action 0x10 since it's already dealt with. */
8716 static const SpecialSpriteHandler handlers[][GLS_END] = {
8717 /* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
8718 /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
8719 /* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
8720 /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
8721 /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
8722 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
8723 /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
8724 /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
8725 /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
8726 /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
8727 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
8728 /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
8729 /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
8730 /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
8731 /* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
8732 /* 0x0F */ { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
8733 /* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
8734 /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
8735 /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
8736 /* 0x13 */ { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
8737 /* 0x14 */ { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
8740 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
8742 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
8743 if (it == _grf_line_to_action6_sprite_override.end()) {
8744 /* No preloaded sprite to work with; read the
8745 * pseudo sprite content. */
8746 FioReadBlock(buf, num);
8747 } else {
8748 /* Use the preloaded sprite data. */
8749 buf = _grf_line_to_action6_sprite_override[location];
8750 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8752 /* Skip the real (original) content of this action. */
8753 FioSeekTo(num, SEEK_CUR);
8756 ByteReader br(buf, buf + num);
8757 ByteReader *bufp = &br;
8759 try {
8760 byte action = bufp->ReadByte();
8762 if (action == 0xFF) {
8763 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8764 } else if (action == 0xFE) {
8765 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8766 } else if (action >= lengthof(handlers)) {
8767 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
8768 } else if (handlers[action][stage] == NULL) {
8769 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
8770 } else {
8771 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
8772 handlers[action][stage](bufp);
8774 } catch (...) {
8775 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8776 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
8781 /** Signature of a container version 2 GRF. */
8782 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8785 * Get the container version of the currently opened GRF file.
8786 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
8788 byte GetGRFContainerVersion()
8790 size_t pos = FioGetPos();
8792 if (FioReadWord() == 0) {
8793 /* Check for GRF container version 2, which is identified by the bytes
8794 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8795 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
8796 if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
8799 return 2;
8802 /* Container version 1 has no header, rewind to start. */
8803 FioSeekTo(pos, SEEK_SET);
8804 return 1;
8808 * Load a particular NewGRF.
8809 * @param config The configuration of the to be loaded NewGRF.
8810 * @param file_index The Fio index of the first NewGRF to load.
8811 * @param stage The loading stage of the NewGRF.
8812 * @param subdir The sub directory to find the NewGRF in.
8814 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
8816 const char *filename = config->filename;
8818 /* A .grf file is activated only if it was active when the game was
8819 * started. If a game is loaded, only its active .grfs will be
8820 * reactivated, unless "loadallgraphics on" is used. A .grf file is
8821 * considered active if its action 8 has been processed, i.e. its
8822 * action 8 hasn't been skipped using an action 7.
8824 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
8825 * carried out. All others are ignored, because they only need to be
8826 * processed once at initialization. */
8827 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
8828 _cur.grffile = GetFileByFilename(filename);
8829 if (_cur.grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
8830 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
8831 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
8834 if (file_index >= MAX_FILE_SLOTS) {
8835 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of file slots has been reached", filename);
8836 config->status = GCS_DISABLED;
8837 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
8838 return;
8841 FioOpenFile(file_index, filename, subdir);
8842 _cur.file_index = file_index; // XXX
8843 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
8845 _cur.grfconfig = config;
8847 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
8849 _cur.grf_container_ver = GetGRFContainerVersion();
8850 if (_cur.grf_container_ver == 0) {
8851 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8852 return;
8855 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
8856 /* We need the sprite offsets in the init stage for NewGRF sounds
8857 * and in the activation stage for real sprites. */
8858 ReadGRFSpriteOffsets(_cur.grf_container_ver);
8859 } else {
8860 /* Skip sprite section offset if present. */
8861 if (_cur.grf_container_ver >= 2) FioReadDword();
8864 if (_cur.grf_container_ver >= 2) {
8865 /* Read compression value. */
8866 byte compression = FioReadByte();
8867 if (compression != 0) {
8868 DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
8869 return;
8873 /* Skip the first sprite; we don't care about how many sprites this
8874 * does contain; newest TTDPatches and George's longvehicles don't
8875 * neither, apparently. */
8876 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
8877 if (num == 4 && FioReadByte() == 0xFF) {
8878 FioReadDword();
8879 } else {
8880 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8881 return;
8884 _cur.ClearDataForNextFile();
8886 ReusableBuffer<byte> buf;
8888 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
8889 byte type = FioReadByte();
8890 _cur.nfo_line++;
8892 if (type == 0xFF) {
8893 if (_cur.skip_sprites == 0) {
8894 DecodeSpecialSprite(buf.Allocate(num), num, stage);
8896 /* Stop all processing if we are to skip the remaining sprites */
8897 if (_cur.skip_sprites == -1) break;
8899 continue;
8900 } else {
8901 FioSkipBytes(num);
8903 } else {
8904 if (_cur.skip_sprites == 0) {
8905 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8906 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
8907 break;
8910 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
8911 /* Reference to data section. Container version >= 2 only. */
8912 FioSkipBytes(num);
8913 } else {
8914 FioSkipBytes(7);
8915 SkipSpriteData(type, num - 8);
8919 if (_cur.skip_sprites > 0) _cur.skip_sprites--;
8924 * Relocates the old shore sprites at new positions.
8926 * 1. If shore sprites are neither loaded by Action5 nor ActionA, the extra sprites from openttd(w/d).grf are used. (SHORE_REPLACE_ONLY_NEW)
8927 * 2. If a newgrf replaces some shore sprites by ActionA. The (maybe also replaced) grass tiles are used for corner shores. (SHORE_REPLACE_ACTION_A)
8928 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
8930 static void ActivateOldShore()
8932 /* Use default graphics, if no shore sprites were loaded.
8933 * Should not happen, as the base set's extra grf should include some. */
8934 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
8936 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
8937 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
8938 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
8939 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
8940 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
8941 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
8942 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
8943 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
8944 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
8947 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
8948 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
8949 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
8950 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
8951 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
8952 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
8953 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
8954 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
8955 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
8957 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
8958 * If they would be used somewhen, then these grass tiles will most like not look as needed */
8959 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
8960 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
8965 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
8967 static void FinalisePriceBaseMultipliers()
8969 extern const PriceBaseSpec _price_base_specs[];
8970 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
8971 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
8973 /* Evaluate grf overrides */
8974 int num_grfs = _grf_files.Length();
8975 int *grf_overrides = AllocaM(int, num_grfs);
8976 for (int i = 0; i < num_grfs; i++) {
8977 grf_overrides[i] = -1;
8979 GRFFile *source = _grf_files[i];
8980 uint32 override = _grf_id_overrides[source->grfid];
8981 if (override == 0) continue;
8983 GRFFile *dest = GetFileByGRFID(override);
8984 if (dest == NULL) continue;
8986 grf_overrides[i] = _grf_files.FindIndex(dest);
8987 assert(grf_overrides[i] >= 0);
8990 /* Override features and price base multipliers of earlier loaded grfs */
8991 for (int i = 0; i < num_grfs; i++) {
8992 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
8993 GRFFile *source = _grf_files[i];
8994 GRFFile *dest = _grf_files[grf_overrides[i]];
8996 uint32 features = (source->grf_features | dest->grf_features) & override_features;
8997 source->grf_features |= features;
8998 dest->grf_features |= features;
9000 for (Price p = PR_BEGIN; p < PR_END; p++) {
9001 /* No price defined -> nothing to do */
9002 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
9003 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9004 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9008 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9009 for (int i = num_grfs - 1; i >= 0; i--) {
9010 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
9011 GRFFile *source = _grf_files[i];
9012 GRFFile *dest = _grf_files[grf_overrides[i]];
9014 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9015 source->grf_features |= features;
9016 dest->grf_features |= features;
9018 for (Price p = PR_BEGIN; p < PR_END; p++) {
9019 /* Already a price defined -> nothing to do */
9020 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
9021 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9022 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9026 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9027 for (int i = 0; i < num_grfs; i++) {
9028 if (grf_overrides[i] < 0) continue;
9029 GRFFile *source = _grf_files[i];
9030 GRFFile *dest = _grf_files[grf_overrides[i]];
9032 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9033 source->grf_features |= features;
9034 dest->grf_features |= features;
9036 for (Price p = PR_BEGIN; p < PR_END; p++) {
9037 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
9038 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
9039 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9041 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
9045 /* Apply fallback prices for grf version < 8 */
9046 const GRFFile * const *end = _grf_files.End();
9047 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9048 if ((*file)->grf_version >= 8) continue;
9049 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9050 for (Price p = PR_BEGIN; p < PR_END; p++) {
9051 Price fallback_price = _price_base_specs[p].fallback_price;
9052 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9053 /* No price multiplier has been set.
9054 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9055 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9060 /* Decide local/global scope of price base multipliers */
9061 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9062 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9063 for (Price p = PR_BEGIN; p < PR_END; p++) {
9064 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9065 /* No multiplier was set; set it to a neutral value */
9066 price_base_multipliers[p] = 0;
9067 } else {
9068 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
9069 /* The grf does not define any objects of the feature,
9070 * so it must be a difficulty setting. Apply it globally */
9071 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
9072 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9073 price_base_multipliers[p] = 0;
9074 } else {
9075 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
9082 extern void InitGRFTownGeneratorNames();
9084 /** Finish loading NewGRFs and execute needed post-processing */
9085 static void AfterLoadGRFs()
9087 for (StringIDMapping *it = _string_to_grf_mapping.Begin(); it != _string_to_grf_mapping.End(); it++) {
9088 *it->target = MapGRFStringID(it->grfid, it->source);
9090 _string_to_grf_mapping.Clear();
9092 /* Free the action 6 override sprites. */
9093 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9094 free((*it).second);
9096 _grf_line_to_action6_sprite_override.clear();
9098 /* Polish cargoes */
9099 FinaliseCargoArray();
9101 /* Pre-calculate all refit masks after loading GRF files. */
9102 CalculateRefitMasks();
9104 /* Polish engines */
9105 FinaliseEngineArray();
9107 /* Set the actually used Canal properties */
9108 FinaliseCanals();
9110 /* Add all new houses to the house array. */
9111 FinaliseHouseArray();
9113 /* Add all new industries to the industry array. */
9114 FinaliseIndustriesArray();
9116 /* Add all new objects to the object array. */
9117 FinaliseObjectsArray();
9119 InitializeSortedCargoSpecs();
9121 /* Sort the list of industry types. */
9122 SortIndustryTypes();
9124 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9125 BuildIndustriesLegend();
9127 /* Build the routemap legend, based on the available cargos */
9128 BuildLinkStatsLegend();
9130 /* Add all new airports to the airports array. */
9131 FinaliseAirportsArray();
9132 BindAirportSpecs();
9134 /* Update the townname generators list */
9135 InitGRFTownGeneratorNames();
9137 /* Run all queued vehicle list order changes */
9138 CommitVehicleListOrderChanges();
9140 /* Load old shore sprites in new position, if they were replaced by ActionA */
9141 ActivateOldShore();
9143 /* Set up custom rail types */
9144 InitRailTypes();
9146 Engine *e;
9147 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
9148 if (_gted[e->index].rv_max_speed != 0) {
9149 /* Set RV maximum speed from the mph/0.8 unit value */
9150 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9154 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
9155 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9156 if (railtype == INVALID_RAILTYPE) {
9157 /* Rail type is not available, so disable this engine */
9158 e->info.climates = 0;
9159 } else {
9160 e->u.rail.railtype = railtype;
9164 SetYearEngineAgingStops();
9166 FinalisePriceBaseMultipliers();
9168 /* Deallocate temporary loading data */
9169 free(_gted);
9170 _grm_sprites.clear();
9174 * Load all the NewGRFs.
9175 * @param load_index The offset for the first sprite to add.
9176 * @param file_index The Fio index of the first NewGRF to load.
9177 * @param num_baseset Number of NewGRFs at the front of the list to look up in the baseset dir instead of the newgrf dir.
9179 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9181 /* In case of networking we need to "sync" the start values
9182 * so all NewGRFs are loaded equally. For this we use the
9183 * start date of the game and we set the counters, etc. to
9184 * 0 so they're the same too. */
9185 Date date = _date;
9186 Year year = _cur_year;
9187 DateFract date_fract = _date_fract;
9188 uint16 tick_counter = _tick_counter;
9189 byte display_opt = _display_opt;
9191 if (_networking) {
9192 _cur_year = _settings_game.game_creation.starting_year;
9193 _date = ConvertYMDToDate(_cur_year, 0, 1);
9194 _date_fract = 0;
9195 _tick_counter = 0;
9196 _display_opt = 0;
9199 InitializeGRFSpecial();
9201 ResetNewGRFData();
9204 * Reset the status of all files, so we can 'retry' to load them.
9205 * This is needed when one for example rearranges the NewGRFs in-game
9206 * and a previously disabled NewGRF becomes useable. If it would not
9207 * be reset, the NewGRF would remain disabled even though it should
9208 * have been enabled.
9210 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9211 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9214 _cur.spriteid = load_index;
9216 /* Load newgrf sprites
9217 * in each loading stage, (try to) open each file specified in the config
9218 * and load information from it. */
9219 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9220 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9221 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9222 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9223 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9226 if (stage == GLS_RESERVE) {
9227 static const uint32 overrides[][2] = {
9228 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9229 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9230 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9232 for (size_t i = 0; i < lengthof(overrides); i++) {
9233 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9237 uint slot = file_index;
9238 uint num_non_static = 0;
9240 _cur.stage = stage;
9241 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9242 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9243 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9245 Subdirectory subdir = slot < file_index + num_baseset ? BASESET_DIR : NEWGRF_DIR;
9246 if (!FioCheckFileExists(c->filename, subdir)) {
9247 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9248 c->status = GCS_NOT_FOUND;
9249 continue;
9252 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
9254 if (!HasBit(c->flags, GCF_STATIC) && !HasBit(c->flags, GCF_SYSTEM)) {
9255 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
9256 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
9257 c->status = GCS_DISABLED;
9258 c->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9259 continue;
9261 num_non_static++;
9263 LoadNewGRFFile(c, slot++, stage, subdir);
9264 if (stage == GLS_RESERVE) {
9265 SetBit(c->flags, GCF_RESERVED);
9266 } else if (stage == GLS_ACTIVATION) {
9267 ClrBit(c->flags, GCF_RESERVED);
9268 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9269 ClearTemporaryNewGRFData(_cur.grffile);
9270 BuildCargoTranslationMap();
9271 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9272 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9273 /* We're not going to activate this, so free whatever data we allocated */
9274 ClearTemporaryNewGRFData(_cur.grffile);
9279 /* Pseudo sprite processing is finished; free temporary stuff */
9280 _cur.ClearDataForNextFile();
9282 /* Call any functions that should be run after GRFs have been loaded. */
9283 AfterLoadGRFs();
9285 /* Now revert back to the original situation */
9286 _cur_year = year;
9287 _date = date;
9288 _date_fract = date_fract;
9289 _tick_counter = tick_counter;
9290 _display_opt = display_opt;