Inline InitNewGRFFile
[openttd/fttd.git] / src / newgrf.cpp
blobb39c34e23a2fb913aca42be123c50c9e280b8d86
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 "font.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.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"
51 #include "rail.h"
52 #include "core/pointer.h"
54 #include "table/strings.h"
55 #include "table/build_industry.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 /* Currently referenceable spritegroups */
105 SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
107 /** Clear temporary data before processing the next file in the current loading stage */
108 void ClearDataForNextFile()
110 this->nfo_line = 0;
112 for (uint i = 0; i < GSF_END; i++) {
113 this->spritesets[i].clear();
116 memset(this->spritegroups, 0, sizeof(this->spritegroups));
120 * Records new spritesets.
121 * @param feature GrfSpecFeature the set is defined for.
122 * @param first_sprite SpriteID of the first sprite in the set.
123 * @param first_set First spriteset to define.
124 * @param numsets Number of sets to define.
125 * @param numents Number of sprites per set to define.
127 void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
129 assert(feature < GSF_END);
130 for (uint i = 0; i < numsets; i++) {
131 SpriteSet &set = this->spritesets[feature][first_set + i];
132 set.sprite = first_sprite + i * numents;
133 set.num_sprites = numents;
138 * Check whether there are any valid spritesets for a feature.
139 * @param feature GrfSpecFeature to check.
140 * @return true if there are any valid sets.
141 * @note Spritesets with zero sprites are valid to allow callback-failures.
143 bool HasValidSpriteSets(byte feature) const
145 assert(feature < GSF_END);
146 return !this->spritesets[feature].empty();
150 * Check whether a specific set is defined.
151 * @param feature GrfSpecFeature to check.
152 * @param set Set to check.
153 * @return true if the set is valid.
154 * @note Spritesets with zero sprites are valid to allow callback-failures.
156 bool IsValidSpriteSet(byte feature, uint set) const
158 assert(feature < GSF_END);
159 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
163 * Returns the first sprite of a spriteset.
164 * @param feature GrfSpecFeature to query.
165 * @param set Set to query.
166 * @return First sprite of the set.
168 SpriteID GetSprite(byte feature, uint set) const
170 assert(IsValidSpriteSet(feature, set));
171 return this->spritesets[feature].find(set)->second.sprite;
175 * Returns the number of sprites in a spriteset
176 * @param feature GrfSpecFeature to query.
177 * @param set Set to query.
178 * @return Number of sprites in the set.
180 uint GetNumEnts(byte feature, uint set) const
182 assert(IsValidSpriteSet(feature, set));
183 return this->spritesets[feature].find(set)->second.num_sprites;
187 static GrfProcessingState _cur;
191 * Helper to check whether an image index is valid for a particular NewGRF vehicle.
192 * @param <T> The type of vehicle.
193 * @param image_index The image index to check.
194 * @return True iff the image index is valid, or 0xFD (use new graphics).
196 template <VehicleType T>
197 static inline bool IsValidNewGRFImageIndex(uint8 image_index)
199 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
202 /** Class to read from a NewGRF file */
203 class ByteReader {
204 protected:
205 byte *data;
206 byte *end;
208 public:
209 ByteReader(byte *data, byte *end) : data(data), end(end) { }
211 class out_of_data { };
213 inline byte ReadByte()
215 if (data < end) return *(data)++;
216 throw out_of_data();
219 uint16 ReadWord()
221 uint16 val = ReadByte();
222 return val | (ReadByte() << 8);
225 uint16 ReadExtendedByte()
227 uint16 val = ReadByte();
228 return val == 0xFF ? ReadWord() : val;
231 uint32 ReadDWord()
233 uint32 val = ReadWord();
234 return val | (ReadWord() << 16);
237 uint32 ReadVarSize(byte size)
239 switch (size) {
240 case 1: return ReadByte();
241 case 2: return ReadWord();
242 case 4: return ReadDWord();
243 default:
244 NOT_REACHED();
245 return 0;
249 const char *ReadString (void);
251 inline size_t Remaining() const
253 return end - data;
256 inline bool HasData(size_t count = 1) const
258 return Remaining() >= count;
261 uint32 PeekDWord() const
263 if (!HasData (4)) throw out_of_data();
264 return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
267 inline void Skip(size_t len)
269 data += len;
270 /* It is valid to move the buffer to exactly the end of the data,
271 * as there may not be any more data read. */
272 if (data > end) throw out_of_data();
275 byte *Dup (size_t len)
277 if (!HasData (len)) throw out_of_data();
279 byte *p = xmemdupt (data, len);
280 data += len;
281 return p;
285 const char *ByteReader::ReadString (void)
287 const char *string = reinterpret_cast<char *>(data);
289 size_t remaining = Remaining();
290 size_t string_length = ttd_strnlen (string, remaining);
292 if (string_length == remaining) {
293 /* String was not NUL terminated, so make sure it is now. */
294 grfmsg(7, "String was not terminated with a zero byte.");
295 data = end;
296 data[-1] = 0;
297 } else {
298 /* Increase the string length to include the NUL byte. */
299 string_length++;
300 data += string_length;
303 return string;
306 typedef int (*SpecialSpriteHandler) (ByteReader *buf);
308 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.
310 /** Temporary engine data used when loading only */
311 struct GRFTempEngineData {
312 /** Summary state of refittability properties */
313 enum Refittability {
314 UNSET = 0, ///< No properties assigned. Default refit masks shall be activated.
315 EMPTY, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
316 NONEMPTY, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
319 uint16 cargo_allowed;
320 uint16 cargo_disallowed;
321 RailTypeLabel railtypelabel;
322 const GRFFile *defaultcargo_grf; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
323 Refittability refittability; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
324 bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)?
325 uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
326 uint32 ctt_include_mask; ///< Cargo types always included in the refit mask.
327 uint32 ctt_exclude_mask; ///< Cargo types always excluded from the refit mask.
330 * Update the summary refittability on setting a refittability property.
331 * @param non_empty true if the GRF sets the vehicle to be refittable.
333 void UpdateRefittability(bool non_empty)
335 if (non_empty) {
336 this->refittability = NONEMPTY;
337 } else if (this->refittability == UNSET) {
338 this->refittability = EMPTY;
343 static GRFTempEngineData *_gted; ///< Temporary engine data used during NewGRF loading
346 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
347 * GRM for vehicles is only used if dynamic engine allocation is disabled,
348 * so 256 is the number of original engines. */
349 static uint32 _grm_engines[256];
351 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
352 static uint32 _grm_cargoes[NUM_CARGO * 2];
354 struct GRFLocation {
355 uint32 grfid;
356 uint32 nfoline;
358 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
360 bool operator<(const GRFLocation &other) const
362 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
365 bool operator == (const GRFLocation &other) const
367 return this->grfid == other.grfid && this->nfoline == other.nfoline;
371 static std::map<GRFLocation, SpriteID> _grm_sprites;
372 typedef std::map <GRFLocation, ttd_unique_free_ptr <byte> > GRFLineToSpriteOverride;
373 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
376 * DEBUG() function dedicated to newGRF debugging messages
377 * Function is essentially the same as DEBUG(grf, severity, ...) with the
378 * addition of file:line information when parsing grf files.
379 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
380 * loading/parsing grf files, not for runtime debug messages as there
381 * is no file information available during that time.
382 * @param severity debugging severity level, see debug.h
383 * @param str message in printf() format
385 void CDECL grfmsg(int severity, const char *str, ...)
387 char buf[1024];
388 va_list va;
390 va_start(va, str);
391 bstrvfmt (buf, str, va);
392 va_end(va);
394 DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
398 * Obtain a NewGRF file by its grfID
399 * @param grfid The grfID to obtain the file for
400 * @return The file.
402 static GRFFile *GetFileByGRFID(uint32 grfid)
404 const GRFFile * const *end = _grf_files.End();
405 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
406 if ((*file)->grfid == grfid) return *file;
408 return NULL;
412 * Obtain a NewGRF file by its filename
413 * @param filename The filename to obtain the file for.
414 * @return The file.
416 static GRFFile *GetFileByFilename(const char *filename)
418 const GRFFile * const *end = _grf_files.End();
419 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
420 if (strcmp((*file)->filename, filename) == 0) return *file;
422 return NULL;
425 /** Reset all NewGRFData that was used only while processing data */
426 static void ClearTemporaryNewGRFData(GRFFile *gf)
428 /* Clear the GOTO labels used for GRF processing */
429 for (GRFLabel *l = gf->label; l != NULL;) {
430 GRFLabel *l2 = l->next;
431 free(l);
432 l = l2;
434 gf->label = NULL;
438 * Disable the GRF being loaded
439 * @param message Error message or STR_NULL.
440 * @return Error message of the GRF for further customisation.
442 static GRFError *DisableCur (StringID message = STR_NULL)
444 GRFConfig *config = _cur.grfconfig;
446 config->status = GCS_DISABLED;
447 if (_cur.grffile != NULL) ClearTemporaryNewGRFData (_cur.grffile);
449 if (message != STR_NULL) {
450 delete config->error;
451 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
452 if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
455 return config->error;
459 * Disable a GRF
460 * @param message Error message.
461 * @param config GRFConfig to disable.
463 static void DisableGrf (StringID message, GRFConfig *config)
465 assert (config != NULL);
466 assert (config != _cur.grfconfig);
468 config->status = GCS_DISABLED;
470 GRFFile *file = GetFileByGRFID (config->ident.grfid);
471 if (file != NULL) ClearTemporaryNewGRFData(file);
473 delete config->error;
474 config->error = new GRFError (STR_NEWGRF_ERROR_MSG_FATAL, message);
475 config->error->data = xstrdup (_cur.grfconfig->GetName());
479 * Information for mapping static StringIDs.
481 struct StringIDMapping {
482 uint32 grfid; ///< Source NewGRF.
483 StringID source; ///< Source StringID (GRF local).
484 StringID *target; ///< Destination for mapping result.
486 typedef SmallVector<StringIDMapping, 16> StringIDMappingVector;
487 static StringIDMappingVector _string_to_grf_mapping;
490 * Record a static StringID for getting translated later.
491 * @param source Source StringID (GRF local).
492 * @param target Destination for the mapping result.
494 static void AddStringForMapping(StringID source, StringID *target)
496 *target = STR_UNDEFINED;
497 StringIDMapping *item = _string_to_grf_mapping.Append();
498 item->grfid = _cur.grffile->grfid;
499 item->source = source;
500 item->target = target;
504 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
505 * string IDs, but only for the ones we are aware off; the rest
506 * like likely unused and will show a warning.
507 * @param str the string ID to convert
508 * @return the converted string ID
510 static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
512 /* StringID table for TextIDs 0x4E->0x6D */
513 static const StringID units_volume[] = {
514 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
515 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
516 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
517 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
518 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
519 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
520 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
521 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
524 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
525 assert(!IsInsideMM(str, 0xD000, 0xD7FF));
527 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
528 assert_compile(stringend - stringid == end - begin); \
529 if (str >= begin && str <= end) return str + (stringid - begin)
531 /* We have some changes in our cargo strings, resulting in some missing. */
532 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
533 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
534 if (str >= 0x004E && str <= 0x006D) return units_volume[str - 0x004E];
535 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
536 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
537 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
539 /* Map building names according to our lang file changes. There are several
540 * ranges of house ids, all of which need to be remapped to allow newgrfs
541 * to use original house names. */
542 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
543 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
544 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
546 /* Same thing for industries */
547 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
548 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
549 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
550 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
551 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
553 switch (str) {
554 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
555 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
556 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
558 #undef TEXTID_TO_STRINGID
560 if (str == STR_NULL) return STR_EMPTY;
562 DEBUG(grf, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
564 return STR_EMPTY;
568 * Used when setting an object's property to map to the GRF's strings
569 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
570 * @param grfid Id of the grf file.
571 * @param str StringID that we want to have the equivalent in OoenTTD.
572 * @return The properly adjusted StringID.
574 StringID MapGRFStringID(uint32 grfid, StringID str)
576 /* 0xD0 and 0xDC stand for all the TextIDs in the range
577 * of 0xD000 (misc graphics texts) and 0xDC00 (misc persistent texts).
578 * These strings are unique to each grf file, and thus require to be used with the
579 * grfid in which they are declared */
580 switch (GB(str, 8, 8)) {
581 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
582 case 0xDC:
583 return GetGRFStringID(grfid, str);
585 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
586 /* Strings embedded via 0x81 have 0x400 added to them (no real
587 * explanation why...) */
588 return GetGRFStringID(grfid, str - 0x400);
590 default: break;
593 return TTDPStringIDToOTTDStringIDMapping(str);
596 static std::map<uint32, uint32> _grf_id_overrides;
599 * Set the override for a NewGRF
600 * @param source_grfid The grfID which wants to override another NewGRF.
601 * @param target_grfid The grfID which is being overridden.
603 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
605 _grf_id_overrides[source_grfid] = target_grfid;
606 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
610 * Returns the engine associated to a certain internal_id, resp. allocates it.
611 * @param file NewGRF that wants to change the engine.
612 * @param type Vehicle type.
613 * @param internal_id Engine ID inside the NewGRF.
614 * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04).
615 * @return The requested engine.
617 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
619 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
620 * them use the same engine slots. */
621 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
622 if (_settings_game.vehicle.dynamic_engines) {
623 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
624 scope_grfid = file->grfid;
625 uint32 override = _grf_id_overrides[file->grfid];
626 if (override != 0) {
627 scope_grfid = override;
628 const GRFFile *grf_match = GetFileByGRFID(override);
629 if (grf_match == NULL) {
630 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
631 } else {
632 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
636 /* Check if the engine is registered in the override manager */
637 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
638 if (engine != INVALID_ENGINE) {
639 Engine *e = Engine::Get(engine);
640 if (e->grf_prop.grffile == NULL) e->grf_prop.grffile = file;
641 return e;
645 /* Check if there is an unreserved slot */
646 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
647 if (engine != INVALID_ENGINE) {
648 Engine *e = Engine::Get(engine);
650 if (e->grf_prop.grffile == NULL) {
651 e->grf_prop.grffile = file;
652 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
655 /* Reserve the engine slot */
656 if (!static_access) {
657 EngineIDMapping *eid = _engine_mngr.Get(engine);
658 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
661 return e;
664 if (static_access) return NULL;
666 if (!Engine::CanAllocateItem()) {
667 grfmsg(0, "Can't allocate any more engines");
668 return NULL;
671 size_t engine_pool_size = Engine::GetPoolSize();
673 /* ... it's not, so create a new one based off an existing engine */
674 Engine *e = new Engine(type, internal_id);
675 e->grf_prop.grffile = file;
677 /* Reserve the engine slot */
678 assert(_engine_mngr.Length() == e->index);
679 EngineIDMapping *eid = _engine_mngr.Append();
680 eid->type = type;
681 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
682 eid->internal_id = internal_id;
683 eid->substitute_id = min(internal_id, _engine_counts[type]); // substitute_id == _engine_counts[subtype] means "no substitute"
685 if (engine_pool_size != Engine::GetPoolSize()) {
686 /* Resize temporary engine data ... */
687 _gted = xrealloct (_gted, Engine::GetPoolSize());
689 /* and blank the new block. */
690 size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
691 memset(_gted + engine_pool_size, 0, len);
693 if (type == VEH_TRAIN) {
694 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
697 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
699 return e;
703 * Return the ID of a new engine
704 * @param file The NewGRF file providing the engine.
705 * @param type The Vehicle type.
706 * @param internal_id NewGRF-internal ID of the engine.
707 * @return The new EngineID.
708 * @note depending on the dynamic_engine setting and a possible override
709 * property the grfID may be unique or overwriting or partially re-defining
710 * properties of an existing engine.
712 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
714 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
715 if (_settings_game.vehicle.dynamic_engines) {
716 scope_grfid = file->grfid;
717 uint32 override = _grf_id_overrides[file->grfid];
718 if (override != 0) scope_grfid = override;
721 return _engine_mngr.GetID(type, internal_id, scope_grfid);
725 * Read a sprite and paletteD from the GRF and map the colour modifiers
726 * of TTDPatch to those that Open is using.
727 * @param buf Input stream.
728 * @param grf_sprite Pointer to the structure to read.
730 static void ReadPalSprite (ByteReader *buf, PalSpriteID *grf_sprite)
732 SpriteID sprite = buf->ReadWord();
733 PaletteID pal = buf->ReadWord();
735 if (HasBit(pal, 14)) {
736 ClrBit(pal, 14);
737 SetBit(sprite, SPRITE_MODIFIER_OPAQUE);
740 if (HasBit(sprite, 14)) {
741 ClrBit(sprite, 14);
742 SetBit(sprite, PALETTE_MODIFIER_TRANSPARENT);
745 if (HasBit(sprite, 15)) {
746 ClrBit(sprite, 15);
747 SetBit(sprite, PALETTE_MODIFIER_COLOUR);
750 grf_sprite->sprite = sprite;
751 grf_sprite->pal = pal;
755 * Read a sprite and a palette from the GRF and convert them into a format
756 * suitable to OpenTTD.
757 * @param buf Input stream.
758 * @param read_flags Whether to read TileLayoutFlags.
759 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
760 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
761 * @param feature GrfSpecFeature to use spritesets from.
762 * @param [out] grf_sprite Read sprite and palette.
763 * @param [out] pflags Read TileLayoutFlags.
764 * @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
765 * @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
766 * @return Whether reading succeeded.
768 static bool ReadSpriteLayoutSprite (ByteReader *buf, bool read_flags,
769 bool invert_action1_flag, bool use_cur_spritesets, int feature,
770 PalSpriteID *grf_sprite, TileLayoutFlags *pflags = NULL,
771 uint16 *max_sprite_offset = NULL, uint16 *max_palette_offset = NULL)
773 ReadPalSprite (buf, grf_sprite);
775 TileLayoutFlags flags = read_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
776 if (pflags != NULL) *pflags = flags;
778 bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
779 ClrBit(grf_sprite->pal, 15);
780 if (custom_sprite) {
781 /* Use sprite from Action 1 */
782 uint index = GB(grf_sprite->sprite, 0, 14);
783 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
784 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
785 grf_sprite->sprite = SPR_IMG_QUERY;
786 grf_sprite->pal = PAL_NONE;
787 } else {
788 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
789 if (max_sprite_offset != NULL) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
790 SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
791 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
793 } else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
794 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
795 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
796 return false;
799 if (flags & TLF_CUSTOM_PALETTE) {
800 /* Use palette from Action 1 */
801 uint index = GB(grf_sprite->pal, 0, 14);
802 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
803 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
804 grf_sprite->pal = PAL_NONE;
805 } else {
806 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
807 if (max_palette_offset != NULL) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
808 SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
809 SetBit(grf_sprite->pal, SPRITE_MODIFIER_CUSTOM_SPRITE);
811 } else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
812 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
813 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
814 return false;
817 return true;
821 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
822 * @param buf Input stream.
823 * @param flags TileLayoutFlags to process.
824 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
825 * @param dts Sprite layout to insert data into.
826 * @param index Sprite index to process; 0 for ground sprite.
827 * @return Whether reading succeeded.
829 static bool ReadSpriteLayoutRegisters (ByteReader *buf, TileLayoutFlags flags,
830 bool is_parent, NewGRFSpriteLayout *dts, uint index)
832 if (!(flags & TLF_DRAWING_FLAGS)) return true;
834 if (dts->registers == NULL) dts->AllocateRegisters();
835 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[index]);
836 regs.flags = flags & TLF_DRAWING_FLAGS;
838 if (flags & TLF_DODRAW) regs.dodraw = buf->ReadByte();
839 if (flags & TLF_SPRITE) regs.sprite = buf->ReadByte();
840 if (flags & TLF_PALETTE) regs.palette = buf->ReadByte();
842 if (is_parent) {
843 if (flags & TLF_BB_XY_OFFSET) {
844 regs.delta.parent[0] = buf->ReadByte();
845 regs.delta.parent[1] = buf->ReadByte();
847 if (flags & TLF_BB_Z_OFFSET) regs.delta.parent[2] = buf->ReadByte();
848 } else {
849 if (flags & TLF_CHILD_X_OFFSET) regs.delta.child[0] = buf->ReadByte();
850 if (flags & TLF_CHILD_Y_OFFSET) regs.delta.child[1] = buf->ReadByte();
853 if (flags & TLF_SPRITE_VAR10) {
854 regs.sprite_var10 = buf->ReadByte();
855 if (regs.sprite_var10 > TLR_MAX_VAR10) {
856 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
857 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
858 return false;
862 if (flags & TLF_PALETTE_VAR10) {
863 regs.palette_var10 = buf->ReadByte();
864 if (regs.palette_var10 > TLR_MAX_VAR10) {
865 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
866 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
867 return false;
871 return true;
875 * Read a spritelayout from the GRF.
876 * @param buf Input
877 * @param num_building_sprites Number of building sprites to read
878 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
879 * @param feature GrfSpecFeature to use spritesets from.
880 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
881 * @param no_z_position Whether bounding boxes have no Z offset
882 * @param dts Layout container to output into
883 * @return True on error (GRF was disabled).
885 static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
887 bool has_flags = HasBit(num_building_sprites, 6);
888 ClrBit(num_building_sprites, 6);
889 TileLayoutFlags valid_flags = TLF_KNOWN_FLAGS;
890 if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
891 dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags
893 uint16 *max_sprite_offset = AllocaM(uint16, num_building_sprites + 1);
894 uint16 *max_palette_offset = AllocaM(uint16, num_building_sprites + 1);
895 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
896 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
898 /* Groundsprite */
899 TileLayoutFlags flags;
900 if (!ReadSpriteLayoutSprite (buf, has_flags, false,
901 use_cur_spritesets, feature, &dts->ground, &flags,
902 max_sprite_offset, max_palette_offset)) {
903 return true;
906 if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
907 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
908 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
909 return true;
912 if (!ReadSpriteLayoutRegisters (buf, flags, false, dts, 0)) {
913 return true;
916 for (uint i = 0; i < num_building_sprites; i++) {
917 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&dts->seq[i]);
919 if (!ReadSpriteLayoutSprite (buf, has_flags, false,
920 use_cur_spritesets, feature, &seq->image, &flags,
921 max_sprite_offset + i + 1, max_palette_offset + i + 1)) {
922 return true;
925 if (flags & ~valid_flags) {
926 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
927 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
928 return true;
931 seq->delta_x = buf->ReadByte();
932 seq->delta_y = buf->ReadByte();
934 if (!no_z_position) seq->delta_z = buf->ReadByte();
936 if (seq->IsParentSprite()) {
937 seq->size_x = buf->ReadByte();
938 seq->size_y = buf->ReadByte();
939 seq->size_z = buf->ReadByte();
942 if (!ReadSpriteLayoutRegisters (buf, flags, seq->IsParentSprite(), dts, i + 1)) {
943 return true;
947 /* Check if the number of sprites per spriteset is consistent */
948 bool is_consistent = true;
949 dts->consistent_max_offset = 0;
950 for (uint i = 0; i < num_building_sprites + 1; i++) {
951 if (max_sprite_offset[i] > 0) {
952 if (dts->consistent_max_offset == 0) {
953 dts->consistent_max_offset = max_sprite_offset[i];
954 } else if (dts->consistent_max_offset != max_sprite_offset[i]) {
955 is_consistent = false;
956 break;
959 if (max_palette_offset[i] > 0) {
960 if (dts->consistent_max_offset == 0) {
961 dts->consistent_max_offset = max_palette_offset[i];
962 } else if (dts->consistent_max_offset != max_palette_offset[i]) {
963 is_consistent = false;
964 break;
969 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
970 assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX)));
972 if (!is_consistent || dts->registers != NULL) {
973 dts->consistent_max_offset = 0;
974 if (dts->registers == NULL) dts->AllocateRegisters();
976 for (uint i = 0; i < num_building_sprites + 1; i++) {
977 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[i]);
978 regs.max_sprite_offset = max_sprite_offset[i];
979 regs.max_palette_offset = max_palette_offset[i];
983 return false;
987 * Translate the refit mask.
989 static uint32 TranslateRefitMask(uint32 refit_mask)
991 uint32 result = 0;
992 uint8 bit;
993 FOR_EACH_SET_BIT(bit, refit_mask) {
994 CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true);
995 if (cargo != CT_INVALID) SetBit(result, cargo);
997 return result;
1001 * Converts TTD(P) Base Price pointers into the enum used by OTTD
1002 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
1003 * @param base_pointer TTD(P) Base Price Pointer
1004 * @param error_location Function name for grf error messages
1005 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
1007 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
1009 /* Special value for 'none' */
1010 if (base_pointer == 0) {
1011 *index = INVALID_PRICE;
1012 return;
1015 static const uint32 start = 0x4B34; ///< Position of first base price
1016 static const uint32 size = 6; ///< Size of each base price record
1018 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
1019 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
1020 return;
1023 *index = (Price)((base_pointer - start) / size);
1026 /** Possible return values for the FeatureChangeInfo functions */
1027 enum ChangeInfoResult {
1028 CIR_SUCCESS, ///< Variable was parsed and read
1029 CIR_DISABLED, ///< GRF was disabled due to error
1030 CIR_UNHANDLED, ///< Variable was parsed but unread
1031 CIR_UNKNOWN, ///< Variable is unknown
1032 CIR_INVALID_ID, ///< Attempt to modify an invalid ID
1035 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
1038 * Define properties common to all vehicles
1039 * @param ei Engine info.
1040 * @param prop The property to change.
1041 * @param buf The property value.
1042 * @return ChangeInfoResult.
1044 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
1046 switch (prop) {
1047 case 0x00: // Introduction date
1048 ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
1049 break;
1051 case 0x02: // Decay speed
1052 ei->decay_speed = buf->ReadByte();
1053 break;
1055 case 0x03: // Vehicle life
1056 ei->lifelength = buf->ReadByte();
1057 break;
1059 case 0x04: // Model life
1060 ei->base_life = buf->ReadByte();
1061 break;
1063 case 0x06: // Climates available
1064 ei->climates = buf->ReadByte();
1065 break;
1067 case PROP_VEHICLE_LOAD_AMOUNT: // 0x07 Loading speed
1068 /* Amount of cargo loaded during a vehicle's "loading tick" */
1069 ei->load_amount = buf->ReadByte();
1070 break;
1072 default:
1073 return CIR_UNKNOWN;
1076 return CIR_SUCCESS;
1080 * Define properties for rail vehicles
1081 * @param engine :ocal ID of the first vehicle.
1082 * @param numinfo Number of subsequent IDs to change the property for.
1083 * @param prop The property to change.
1084 * @param buf The property value.
1085 * @return ChangeInfoResult.
1087 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1089 ChangeInfoResult ret = CIR_SUCCESS;
1091 for (int i = 0; i < numinfo; i++) {
1092 Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i);
1093 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1095 EngineInfo *ei = &e->info;
1096 RailVehicleInfo *rvi = &e->u.rail;
1098 switch (prop) {
1099 case 0x05: { // Track type
1100 uint8 tracktype = buf->ReadByte();
1102 if (tracktype < _cur.grffile->railtype_list.Length()) {
1103 _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype];
1104 break;
1107 switch (tracktype) {
1108 case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
1109 case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
1110 case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
1111 default:
1112 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1113 break;
1115 break;
1118 case 0x08: // AI passenger service
1119 /* Tells the AI that this engine is designed for
1120 * passenger services and shouldn't be used for freight. */
1121 rvi->ai_passenger_only = buf->ReadByte();
1122 break;
1124 case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
1125 uint16 speed = buf->ReadWord();
1126 if (speed == 0xFFFF) speed = 0;
1128 rvi->max_speed = speed;
1129 break;
1132 case PROP_TRAIN_POWER: // 0x0B Power
1133 rvi->power = buf->ReadWord();
1135 /* Set engine / wagon state based on power */
1136 if (rvi->power != 0) {
1137 if (rvi->railveh_type == RAILVEH_WAGON) {
1138 rvi->railveh_type = RAILVEH_SINGLEHEAD;
1140 } else {
1141 rvi->railveh_type = RAILVEH_WAGON;
1143 break;
1145 case PROP_TRAIN_RUNNING_COST_FACTOR: // 0x0D Running cost factor
1146 rvi->running_cost = buf->ReadByte();
1147 break;
1149 case 0x0E: // Running cost base
1150 ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
1151 break;
1153 case 0x12: { // Sprite ID
1154 uint8 spriteid = buf->ReadByte();
1155 uint8 orig_spriteid = spriteid;
1157 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1158 * as an array index, so we need it to be half the original value. */
1159 if (spriteid < 0xFD) spriteid >>= 1;
1161 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1162 rvi->image_index = spriteid;
1163 } else {
1164 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1165 rvi->image_index = 0;
1167 break;
1170 case 0x13: { // Dual-headed
1171 uint8 dual = buf->ReadByte();
1173 if (dual != 0) {
1174 rvi->railveh_type = RAILVEH_MULTIHEAD;
1175 } else {
1176 rvi->railveh_type = rvi->power == 0 ?
1177 RAILVEH_WAGON : RAILVEH_SINGLEHEAD;
1179 break;
1182 case PROP_TRAIN_CARGO_CAPACITY: // 0x14 Cargo capacity
1183 rvi->capacity = buf->ReadByte();
1184 break;
1186 case 0x15: { // Cargo type
1187 _gted[e->index].defaultcargo_grf = _cur.grffile;
1188 uint8 ctype = buf->ReadByte();
1190 if (ctype == 0xFF) {
1191 /* 0xFF is specified as 'use first refittable' */
1192 ei->cargo_type = CT_INVALID;
1193 } else if (_cur.grffile->grf_version >= 8) {
1194 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1195 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1196 } else if (ctype < NUM_CARGO) {
1197 /* Use untranslated cargo. */
1198 ei->cargo_type = ctype;
1199 } else {
1200 ei->cargo_type = CT_INVALID;
1201 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1203 break;
1206 case PROP_TRAIN_WEIGHT: // 0x16 Weight
1207 SB(rvi->weight, 0, 8, buf->ReadByte());
1208 break;
1210 case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
1211 rvi->cost_factor = buf->ReadByte();
1212 break;
1214 case 0x18: // AI rank
1215 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1216 buf->ReadByte();
1217 break;
1219 case 0x19: { // Engine traction type
1220 /* What do the individual numbers mean?
1221 * 0x00 .. 0x07: Steam
1222 * 0x08 .. 0x27: Diesel
1223 * 0x28 .. 0x31: Electric
1224 * 0x32 .. 0x37: Monorail
1225 * 0x38 .. 0x41: Maglev
1227 uint8 traction = buf->ReadByte();
1228 EngineClass engclass;
1230 if (traction <= 0x07) {
1231 engclass = EC_STEAM;
1232 } else if (traction <= 0x27) {
1233 engclass = EC_DIESEL;
1234 } else if (traction <= 0x31) {
1235 engclass = EC_ELECTRIC;
1236 } else if (traction <= 0x37) {
1237 engclass = EC_MONORAIL;
1238 } else if (traction <= 0x41) {
1239 engclass = EC_MAGLEV;
1240 } else {
1241 break;
1244 if (_cur.grffile->railtype_list.Length() == 0) {
1245 /* Use traction type to select between normal and electrified
1246 * rail only when no translation list is in place. */
1247 if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1248 if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
1251 rvi->engclass = engclass;
1252 break;
1255 case 0x1A: // Alter purchase list sort order
1256 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1257 break;
1259 case 0x1B: // Powered wagons power bonus
1260 rvi->pow_wag_power = buf->ReadWord();
1261 break;
1263 case 0x1C: // Refit cost
1264 ei->refit_cost = buf->ReadByte();
1265 break;
1267 case 0x1D: { // Refit cargo
1268 uint32 mask = buf->ReadDWord();
1269 _gted[e->index].UpdateRefittability(mask != 0);
1270 ei->refit_mask = TranslateRefitMask(mask);
1271 _gted[e->index].defaultcargo_grf = _cur.grffile;
1272 break;
1275 case 0x1E: // Callback
1276 ei->callback_mask = buf->ReadByte();
1277 break;
1279 case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
1280 rvi->tractive_effort = buf->ReadByte();
1281 break;
1283 case 0x20: // Air drag
1284 rvi->air_drag = buf->ReadByte();
1285 break;
1287 case PROP_TRAIN_SHORTEN_FACTOR: // 0x21 Shorter vehicle
1288 rvi->shorten_factor = buf->ReadByte();
1289 break;
1291 case 0x22: // Visual effect
1292 rvi->visual_effect = buf->ReadByte();
1293 /* Avoid accidentally setting visual_effect to the default value
1294 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1295 if (rvi->visual_effect == VE_DEFAULT) {
1296 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1297 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1299 break;
1301 case 0x23: // Powered wagons weight bonus
1302 rvi->pow_wag_weight = buf->ReadByte();
1303 break;
1305 case 0x24: { // High byte of vehicle weight
1306 byte weight = buf->ReadByte();
1308 if (weight > 4) {
1309 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1310 } else {
1311 SB(rvi->weight, 8, 8, weight);
1313 break;
1316 case PROP_TRAIN_USER_DATA: // 0x25 User-defined bit mask to set when checking veh. var. 42
1317 rvi->user_def_data = buf->ReadByte();
1318 break;
1320 case 0x26: // Retire vehicle early
1321 ei->retire_early = buf->ReadByte();
1322 break;
1324 case 0x27: // Miscellaneous flags
1325 ei->misc_flags = buf->ReadByte();
1326 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1327 _gted[e->index].prop27_set = true;
1328 break;
1330 case 0x28: // Cargo classes allowed
1331 _gted[e->index].cargo_allowed = buf->ReadWord();
1332 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1333 _gted[e->index].defaultcargo_grf = _cur.grffile;
1334 break;
1336 case 0x29: // Cargo classes disallowed
1337 _gted[e->index].cargo_disallowed = buf->ReadWord();
1338 _gted[e->index].UpdateRefittability(false);
1339 break;
1341 case 0x2A: // Long format introduction date (days since year 0)
1342 ei->base_intro = buf->ReadDWord();
1343 break;
1345 case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
1346 ei->cargo_age_period = buf->ReadWord();
1347 break;
1349 case 0x2C: // CTT refit include list
1350 case 0x2D: { // CTT refit exclude list
1351 uint8 count = buf->ReadByte();
1352 _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
1353 if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile;
1354 uint32 &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1355 ctt = 0;
1356 while (count--) {
1357 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1358 if (ctype == CT_INVALID) continue;
1359 SetBit(ctt, ctype);
1361 break;
1364 default:
1365 ret = CommonVehicleChangeInfo(ei, prop, buf);
1366 break;
1370 return ret;
1374 * Define properties for road vehicles
1375 * @param engine Local ID of the first vehicle.
1376 * @param numinfo Number of subsequent IDs to change the property for.
1377 * @param prop The property to change.
1378 * @param buf The property value.
1379 * @return ChangeInfoResult.
1381 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1383 ChangeInfoResult ret = CIR_SUCCESS;
1385 for (int i = 0; i < numinfo; i++) {
1386 Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i);
1387 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1389 EngineInfo *ei = &e->info;
1390 RoadVehicleInfo *rvi = &e->u.road;
1392 switch (prop) {
1393 case 0x08: // Speed (1 unit is 0.5 kmh)
1394 rvi->max_speed = buf->ReadByte();
1395 break;
1397 case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1398 rvi->running_cost = buf->ReadByte();
1399 break;
1401 case 0x0A: // Running cost base
1402 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1403 break;
1405 case 0x0E: { // Sprite ID
1406 uint8 spriteid = buf->ReadByte();
1407 uint8 orig_spriteid = spriteid;
1409 /* cars have different custom id in the GRF file */
1410 if (spriteid == 0xFF) spriteid = 0xFD;
1412 if (spriteid < 0xFD) spriteid >>= 1;
1414 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1415 rvi->image_index = spriteid;
1416 } else {
1417 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1418 rvi->image_index = 0;
1420 break;
1423 case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1424 rvi->capacity = buf->ReadByte();
1425 break;
1427 case 0x10: { // Cargo type
1428 _gted[e->index].defaultcargo_grf = _cur.grffile;
1429 uint8 ctype = buf->ReadByte();
1431 if (ctype == 0xFF) {
1432 /* 0xFF is specified as 'use first refittable' */
1433 ei->cargo_type = CT_INVALID;
1434 } else if (_cur.grffile->grf_version >= 8) {
1435 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1436 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1437 } else if (ctype < NUM_CARGO) {
1438 /* Use untranslated cargo. */
1439 ei->cargo_type = ctype;
1440 } else {
1441 ei->cargo_type = CT_INVALID;
1442 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1444 break;
1447 case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1448 rvi->cost_factor = buf->ReadByte();
1449 break;
1451 case 0x12: // SFX
1452 rvi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1453 break;
1455 case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1456 rvi->power = buf->ReadByte();
1457 break;
1459 case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1460 rvi->weight = buf->ReadByte();
1461 break;
1463 case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1464 _gted[e->index].rv_max_speed = buf->ReadByte();
1465 break;
1467 case 0x16: { // Cargoes available for refitting
1468 uint32 mask = buf->ReadDWord();
1469 _gted[e->index].UpdateRefittability(mask != 0);
1470 ei->refit_mask = TranslateRefitMask(mask);
1471 _gted[e->index].defaultcargo_grf = _cur.grffile;
1472 break;
1475 case 0x17: // Callback mask
1476 ei->callback_mask = buf->ReadByte();
1477 break;
1479 case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1480 rvi->tractive_effort = buf->ReadByte();
1481 break;
1483 case 0x19: // Air drag
1484 rvi->air_drag = buf->ReadByte();
1485 break;
1487 case 0x1A: // Refit cost
1488 ei->refit_cost = buf->ReadByte();
1489 break;
1491 case 0x1B: // Retire vehicle early
1492 ei->retire_early = buf->ReadByte();
1493 break;
1495 case 0x1C: // Miscellaneous flags
1496 ei->misc_flags = buf->ReadByte();
1497 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1498 break;
1500 case 0x1D: // Cargo classes allowed
1501 _gted[e->index].cargo_allowed = buf->ReadWord();
1502 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1503 _gted[e->index].defaultcargo_grf = _cur.grffile;
1504 break;
1506 case 0x1E: // Cargo classes disallowed
1507 _gted[e->index].cargo_disallowed = buf->ReadWord();
1508 _gted[e->index].UpdateRefittability(false);
1509 break;
1511 case 0x1F: // Long format introduction date (days since year 0)
1512 ei->base_intro = buf->ReadDWord();
1513 break;
1515 case 0x20: // Alter purchase list sort order
1516 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1517 break;
1519 case 0x21: // Visual effect
1520 rvi->visual_effect = buf->ReadByte();
1521 /* Avoid accidentally setting visual_effect to the default value
1522 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1523 if (rvi->visual_effect == VE_DEFAULT) {
1524 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1525 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1527 break;
1529 case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1530 ei->cargo_age_period = buf->ReadWord();
1531 break;
1533 case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
1534 rvi->shorten_factor = buf->ReadByte();
1535 break;
1537 case 0x24: // CTT refit include list
1538 case 0x25: { // CTT refit exclude list
1539 uint8 count = buf->ReadByte();
1540 _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
1541 if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
1542 uint32 &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1543 ctt = 0;
1544 while (count--) {
1545 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1546 if (ctype == CT_INVALID) continue;
1547 SetBit(ctt, ctype);
1549 break;
1552 default:
1553 ret = CommonVehicleChangeInfo(ei, prop, buf);
1554 break;
1558 return ret;
1562 * Define properties for ships
1563 * @param engine Local ID of the first vehicle.
1564 * @param numinfo Number of subsequent IDs to change the property for.
1565 * @param prop The property to change.
1566 * @param buf The property value.
1567 * @return ChangeInfoResult.
1569 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1571 ChangeInfoResult ret = CIR_SUCCESS;
1573 for (int i = 0; i < numinfo; i++) {
1574 Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1575 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1577 EngineInfo *ei = &e->info;
1578 ShipVehicleInfo *svi = &e->u.ship;
1580 switch (prop) {
1581 case 0x08: { // Sprite ID
1582 uint8 spriteid = buf->ReadByte();
1583 uint8 orig_spriteid = spriteid;
1585 /* ships have different custom id in the GRF file */
1586 if (spriteid == 0xFF) spriteid = 0xFD;
1588 if (spriteid < 0xFD) spriteid >>= 1;
1590 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1591 svi->image_index = spriteid;
1592 } else {
1593 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1594 svi->image_index = 0;
1596 break;
1599 case 0x09: // Refittable
1600 svi->old_refittable = (buf->ReadByte() != 0);
1601 break;
1603 case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1604 svi->cost_factor = buf->ReadByte();
1605 break;
1607 case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1608 svi->max_speed = buf->ReadByte();
1609 break;
1611 case 0x0C: { // Cargo type
1612 _gted[e->index].defaultcargo_grf = _cur.grffile;
1613 uint8 ctype = buf->ReadByte();
1615 if (ctype == 0xFF) {
1616 /* 0xFF is specified as 'use first refittable' */
1617 ei->cargo_type = CT_INVALID;
1618 } else if (_cur.grffile->grf_version >= 8) {
1619 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1620 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1621 } else if (ctype < NUM_CARGO) {
1622 /* Use untranslated cargo. */
1623 ei->cargo_type = ctype;
1624 } else {
1625 ei->cargo_type = CT_INVALID;
1626 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1628 break;
1631 case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1632 svi->capacity = buf->ReadWord();
1633 break;
1635 case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1636 svi->running_cost = buf->ReadByte();
1637 break;
1639 case 0x10: // SFX
1640 svi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1641 break;
1643 case 0x11: { // Cargoes available for refitting
1644 uint32 mask = buf->ReadDWord();
1645 _gted[e->index].UpdateRefittability(mask != 0);
1646 ei->refit_mask = TranslateRefitMask(mask);
1647 _gted[e->index].defaultcargo_grf = _cur.grffile;
1648 break;
1651 case 0x12: // Callback mask
1652 ei->callback_mask = buf->ReadByte();
1653 break;
1655 case 0x13: // Refit cost
1656 ei->refit_cost = buf->ReadByte();
1657 break;
1659 case 0x14: // Ocean speed fraction
1660 svi->ocean_speed_frac = buf->ReadByte();
1661 break;
1663 case 0x15: // Canal speed fraction
1664 svi->canal_speed_frac = buf->ReadByte();
1665 break;
1667 case 0x16: // Retire vehicle early
1668 ei->retire_early = buf->ReadByte();
1669 break;
1671 case 0x17: // Miscellaneous flags
1672 ei->misc_flags = buf->ReadByte();
1673 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1674 break;
1676 case 0x18: // Cargo classes allowed
1677 _gted[e->index].cargo_allowed = buf->ReadWord();
1678 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1679 _gted[e->index].defaultcargo_grf = _cur.grffile;
1680 break;
1682 case 0x19: // Cargo classes disallowed
1683 _gted[e->index].cargo_disallowed = buf->ReadWord();
1684 _gted[e->index].UpdateRefittability(false);
1685 break;
1687 case 0x1A: // Long format introduction date (days since year 0)
1688 ei->base_intro = buf->ReadDWord();
1689 break;
1691 case 0x1B: // Alter purchase list sort order
1692 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1693 break;
1695 case 0x1C: // Visual effect
1696 svi->visual_effect = buf->ReadByte();
1697 /* Avoid accidentally setting visual_effect to the default value
1698 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1699 if (svi->visual_effect == VE_DEFAULT) {
1700 assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1701 SB(svi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1703 break;
1705 case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1706 ei->cargo_age_period = buf->ReadWord();
1707 break;
1709 case 0x1E: // CTT refit include list
1710 case 0x1F: { // CTT refit exclude list
1711 uint8 count = buf->ReadByte();
1712 _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
1713 if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
1714 uint32 &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1715 ctt = 0;
1716 while (count--) {
1717 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1718 if (ctype == CT_INVALID) continue;
1719 SetBit(ctt, ctype);
1721 break;
1724 default:
1725 ret = CommonVehicleChangeInfo(ei, prop, buf);
1726 break;
1730 return ret;
1734 * Define properties for aircraft
1735 * @param engine Local ID of the aircraft.
1736 * @param numinfo Number of subsequent IDs to change the property for.
1737 * @param prop The property to change.
1738 * @param buf The property value.
1739 * @return ChangeInfoResult.
1741 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1743 ChangeInfoResult ret = CIR_SUCCESS;
1745 for (int i = 0; i < numinfo; i++) {
1746 Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1747 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1749 EngineInfo *ei = &e->info;
1750 AircraftVehicleInfo *avi = &e->u.air;
1752 switch (prop) {
1753 case 0x08: { // Sprite ID
1754 uint8 spriteid = buf->ReadByte();
1755 uint8 orig_spriteid = spriteid;
1757 /* aircraft have different custom id in the GRF file */
1758 if (spriteid == 0xFF) spriteid = 0xFD;
1760 if (spriteid < 0xFD) spriteid >>= 1;
1762 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1763 avi->image_index = spriteid;
1764 } else {
1765 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1766 avi->image_index = 0;
1768 break;
1771 case 0x09: // Helicopter
1772 if (buf->ReadByte() == 0) {
1773 avi->subtype = AIR_HELI;
1774 } else {
1775 SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1777 break;
1779 case 0x0A: // Large
1780 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1781 break;
1783 case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1784 avi->cost_factor = buf->ReadByte();
1785 break;
1787 case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1788 avi->max_speed = (buf->ReadByte() * 128) / 10;
1789 break;
1791 case 0x0D: // Acceleration
1792 avi->acceleration = buf->ReadByte();
1793 break;
1795 case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1796 avi->running_cost = buf->ReadByte();
1797 break;
1799 case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1800 avi->passenger_capacity = buf->ReadWord();
1801 break;
1803 case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1804 avi->mail_capacity = buf->ReadByte();
1805 break;
1807 case 0x12: // SFX
1808 avi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1809 break;
1811 case 0x13: { // Cargoes available for refitting
1812 uint32 mask = buf->ReadDWord();
1813 _gted[e->index].UpdateRefittability(mask != 0);
1814 ei->refit_mask = TranslateRefitMask(mask);
1815 _gted[e->index].defaultcargo_grf = _cur.grffile;
1816 break;
1819 case 0x14: // Callback mask
1820 ei->callback_mask = buf->ReadByte();
1821 break;
1823 case 0x15: // Refit cost
1824 ei->refit_cost = buf->ReadByte();
1825 break;
1827 case 0x16: // Retire vehicle early
1828 ei->retire_early = buf->ReadByte();
1829 break;
1831 case 0x17: // Miscellaneous flags
1832 ei->misc_flags = buf->ReadByte();
1833 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1834 break;
1836 case 0x18: // Cargo classes allowed
1837 _gted[e->index].cargo_allowed = buf->ReadWord();
1838 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1839 _gted[e->index].defaultcargo_grf = _cur.grffile;
1840 break;
1842 case 0x19: // Cargo classes disallowed
1843 _gted[e->index].cargo_disallowed = buf->ReadWord();
1844 _gted[e->index].UpdateRefittability(false);
1845 break;
1847 case 0x1A: // Long format introduction date (days since year 0)
1848 ei->base_intro = buf->ReadDWord();
1849 break;
1851 case 0x1B: // Alter purchase list sort order
1852 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1853 break;
1855 case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1856 ei->cargo_age_period = buf->ReadWord();
1857 break;
1859 case 0x1D: // CTT refit include list
1860 case 0x1E: { // CTT refit exclude list
1861 uint8 count = buf->ReadByte();
1862 _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
1863 if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
1864 uint32 &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1865 ctt = 0;
1866 while (count--) {
1867 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1868 if (ctype == CT_INVALID) continue;
1869 SetBit(ctt, ctype);
1871 break;
1874 case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
1875 avi->max_range = buf->ReadWord();
1876 break;
1878 default:
1879 ret = CommonVehicleChangeInfo(ei, prop, buf);
1880 break;
1884 return ret;
1888 * Define properties for stations
1889 * @param stdid StationID of the first station tile.
1890 * @param numinfo Number of subsequent station tiles to change the property for.
1891 * @param prop The property to change.
1892 * @param buf The property value.
1893 * @return ChangeInfoResult.
1895 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
1897 ChangeInfoResult ret = CIR_SUCCESS;
1899 if (stid + numinfo > NUM_STATIONS_PER_GRF) {
1900 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
1901 return CIR_INVALID_ID;
1904 /* Allocate station specs if necessary */
1905 if (_cur.grffile->stations == NULL) _cur.grffile->stations = xcalloct<StationSpec*>(NUM_STATIONS_PER_GRF);
1907 for (int i = 0; i < numinfo; i++) {
1908 StationSpec *statspec = _cur.grffile->stations[stid + i];
1910 /* Check that the station we are modifying is defined. */
1911 if (statspec == NULL && prop != 0x08) {
1912 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1913 return CIR_INVALID_ID;
1916 switch (prop) {
1917 case 0x08: { // Class ID
1918 StationSpec **spec = &_cur.grffile->stations[stid + i];
1920 /* Property 0x08 is special; it is where the station is allocated */
1921 if (*spec == NULL) *spec = xcalloct<StationSpec>();
1923 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1924 uint32 classid = buf->ReadDWord();
1925 (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
1926 break;
1929 case 0x09: // Define sprite layout
1930 statspec->tiles = buf->ReadExtendedByte();
1931 delete[] statspec->renderdata; // delete earlier loaded stuff
1932 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1934 for (uint t = 0; t < statspec->tiles; t++) {
1935 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1936 dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
1938 if (buf->HasData(4) && buf->PeekDWord() == 0) {
1939 buf->Skip(4);
1940 extern const DrawTileSprites _station_display_datas_rail[8];
1941 dts->Clone(&_station_display_datas_rail[t % 8]);
1942 continue;
1945 /* On error, bail out immediately. Temporary GRF data was already freed */
1946 if (!ReadSpriteLayoutSprite (buf, false, false, false, GSF_STATIONS, &dts->ground)) {
1947 return CIR_DISABLED;
1950 static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
1951 tmp_layout.Clear();
1952 for (;;) {
1953 /* no relative bounding box support */
1954 DrawTileSeqStruct *dtss = tmp_layout.Append();
1955 MemSetT(dtss, 0);
1957 dtss->delta_x = buf->ReadByte();
1958 if (dtss->IsTerminator()) break;
1959 dtss->delta_y = buf->ReadByte();
1960 dtss->delta_z = buf->ReadByte();
1961 dtss->size_x = buf->ReadByte();
1962 dtss->size_y = buf->ReadByte();
1963 dtss->size_z = buf->ReadByte();
1965 /* On error, bail out immediately. Temporary GRF data was already freed */
1966 if (!ReadSpriteLayoutSprite (buf, false, true, false, GSF_STATIONS, &dtss->image)) {
1967 return CIR_DISABLED;
1970 dts->Clone(tmp_layout.Begin());
1972 break;
1974 case 0x0A: { // Copy sprite layout
1975 byte srcid = buf->ReadByte();
1976 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1978 if (srcstatspec == NULL) {
1979 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1980 continue;
1983 delete[] statspec->renderdata; // delete earlier loaded stuff
1985 statspec->tiles = srcstatspec->tiles;
1986 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1987 for (uint t = 0; t < statspec->tiles; t++) {
1988 statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
1990 break;
1993 case 0x0B: // Callback mask
1994 statspec->callback_mask = buf->ReadByte();
1995 break;
1997 case 0x0C: // Disallowed number of platforms
1998 statspec->disallowed_platforms = buf->ReadByte();
1999 break;
2001 case 0x0D: // Disallowed platform lengths
2002 statspec->disallowed_lengths = buf->ReadByte();
2003 break;
2005 case 0x0E: // Define custom layout
2006 statspec->copied_layouts = false;
2008 while (buf->HasData()) {
2009 byte length = buf->ReadByte();
2010 byte number = buf->ReadByte();
2012 if (length == 0 || number == 0) break;
2014 if (length > statspec->lengths) {
2015 statspec->platforms = xrealloct (statspec->platforms, length);
2016 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
2018 statspec->layouts = xrealloct (statspec->layouts, length);
2019 memset(statspec->layouts + statspec->lengths, 0,
2020 (length - statspec->lengths) * sizeof(*statspec->layouts));
2022 statspec->lengths = length;
2025 uint l = length - 1; // index is zero-based
2027 if (number > statspec->platforms[l]) {
2028 statspec->layouts[l] = xrealloct (statspec->layouts[l], number);
2029 /* We expect NULL being 0 here, but C99 guarantees that. */
2030 memset(statspec->layouts[l] + statspec->platforms[l], 0,
2031 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
2033 statspec->platforms[l] = number;
2036 StationLayout layout = buf->Dup (length * number);
2038 StationLayout *p = &statspec->layouts[l][number - 1];
2039 free (*p);
2040 *p = layout;
2042 break;
2044 case 0x0F: { // Copy custom layout
2045 byte srcid = buf->ReadByte();
2046 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
2048 if (srcstatspec == NULL) {
2049 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2050 continue;
2053 statspec->lengths = srcstatspec->lengths;
2054 statspec->platforms = srcstatspec->platforms;
2055 statspec->layouts = srcstatspec->layouts;
2056 statspec->copied_layouts = true;
2057 break;
2060 case 0x10: // Little/lots cargo threshold
2061 statspec->cargo_threshold = buf->ReadWord();
2062 break;
2064 case 0x11: // Pylon placement
2065 statspec->pylons = buf->ReadByte();
2066 break;
2068 case 0x12: // Cargo types for random triggers
2069 statspec->cargo_triggers = buf->ReadDWord();
2070 if (_cur.grffile->grf_version >= 7) {
2071 statspec->cargo_triggers = TranslateRefitMask(statspec->cargo_triggers);
2073 break;
2075 case 0x13: // General flags
2076 statspec->flags = buf->ReadByte();
2077 break;
2079 case 0x14: // Overhead wire placement
2080 statspec->wires = buf->ReadByte();
2081 break;
2083 case 0x15: // Blocked tiles
2084 statspec->blocked = buf->ReadByte();
2085 break;
2087 case 0x16: // Animation info
2088 statspec->animation.frames = buf->ReadByte();
2089 statspec->animation.status = buf->ReadByte();
2090 break;
2092 case 0x17: // Animation speed
2093 statspec->animation.speed = buf->ReadByte();
2094 break;
2096 case 0x18: // Animation triggers
2097 statspec->animation.triggers = buf->ReadWord();
2098 break;
2100 case 0x1A: // Advanced sprite layout
2101 statspec->tiles = buf->ReadExtendedByte();
2102 delete[] statspec->renderdata; // delete earlier loaded stuff
2103 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
2105 for (uint t = 0; t < statspec->tiles; t++) {
2106 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
2107 uint num_building_sprites = buf->ReadByte();
2108 /* On error, bail out immediately. Temporary GRF data was already freed */
2109 if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) {
2110 return CIR_DISABLED;
2113 break;
2115 default:
2116 ret = CIR_UNKNOWN;
2117 break;
2121 return ret;
2125 * Define properties for water features
2126 * @param id Type of the first water feature.
2127 * @param numinfo Number of subsequent water feature ids to change the property for.
2128 * @param prop The property to change.
2129 * @param buf The property value.
2130 * @return ChangeInfoResult.
2132 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
2134 ChangeInfoResult ret = CIR_SUCCESS;
2136 if (id + numinfo > CF_END) {
2137 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id + numinfo, CF_END);
2138 return CIR_INVALID_ID;
2141 for (int i = 0; i < numinfo; i++) {
2142 CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
2144 switch (prop) {
2145 case 0x08:
2146 cp->callback_mask = buf->ReadByte();
2147 break;
2149 case 0x09:
2150 cp->flags = buf->ReadByte();
2151 break;
2153 default:
2154 ret = CIR_UNKNOWN;
2155 break;
2159 return ret;
2163 * Define properties for bridges
2164 * @param brid BridgeID of the bridge.
2165 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2166 * @param prop The property to change.
2167 * @param buf The property value.
2168 * @return ChangeInfoResult.
2170 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
2172 ChangeInfoResult ret = CIR_SUCCESS;
2174 if (brid + numinfo > MAX_BRIDGES) {
2175 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
2176 return CIR_INVALID_ID;
2179 for (int i = 0; i < numinfo; i++) {
2180 BridgeSpec *bridge = &_bridge[brid + i];
2182 switch (prop) {
2183 case 0x08: { // Year of availability
2184 /* We treat '0' as always available */
2185 byte year = buf->ReadByte();
2186 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
2187 break;
2190 case 0x09: // Minimum length
2191 bridge->min_length = buf->ReadByte();
2192 break;
2194 case 0x0A: // Maximum length
2195 bridge->max_length = buf->ReadByte();
2196 if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
2197 break;
2199 case 0x0B: // Cost factor
2200 bridge->price = buf->ReadByte();
2201 break;
2203 case 0x0C: // Maximum speed
2204 bridge->speed = buf->ReadWord();
2205 break;
2207 case 0x0D: { // Bridge sprite tables
2208 byte tableid = buf->ReadByte();
2209 byte numtables = buf->ReadByte();
2211 if (bridge->sprite_table == NULL) {
2212 /* Allocate memory for sprite table pointers and zero out */
2213 bridge->sprite_table = xcalloct<PalSpriteID*>(7);
2216 for (; numtables-- != 0; tableid++) {
2217 if (tableid >= 7) { // skip invalid data
2218 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2219 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2220 continue;
2223 if (bridge->sprite_table[tableid] == NULL) {
2224 bridge->sprite_table[tableid] = xmalloct<PalSpriteID>(32);
2227 for (byte sprite = 0; sprite < 32; sprite++) {
2228 ReadPalSprite (buf, &bridge->sprite_table[tableid][sprite]);
2231 break;
2234 case 0x0E: // Flags; bit 0 - disable far pillars
2235 bridge->flags = buf->ReadByte();
2236 break;
2238 case 0x0F: // Long format year of availability (year since year 0)
2239 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
2240 break;
2242 case 0x10: { // purchase string
2243 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2244 if (newone != STR_UNDEFINED) bridge->material = newone;
2245 break;
2248 case 0x11: // description of bridge with rails or roads
2249 case 0x12: {
2250 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2251 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
2252 break;
2255 case 0x13: // 16 bits cost multiplier
2256 bridge->price = buf->ReadWord();
2257 break;
2259 case 0x14: // purchase sprite
2260 bridge->sprite = buf->ReadWord();
2261 bridge->pal = buf->ReadWord();
2262 break;
2264 default:
2265 ret = CIR_UNKNOWN;
2266 break;
2270 return ret;
2274 * Ignore a house property
2275 * @param prop Property to read.
2276 * @param buf Property value.
2277 * @return ChangeInfoResult.
2279 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
2281 ChangeInfoResult ret = CIR_SUCCESS;
2283 switch (prop) {
2284 case 0x09:
2285 case 0x0B:
2286 case 0x0C:
2287 case 0x0D:
2288 case 0x0E:
2289 case 0x0F:
2290 case 0x11:
2291 case 0x14:
2292 case 0x15:
2293 case 0x16:
2294 case 0x18:
2295 case 0x19:
2296 case 0x1A:
2297 case 0x1B:
2298 case 0x1C:
2299 case 0x1D:
2300 case 0x1F:
2301 buf->ReadByte();
2302 break;
2304 case 0x0A:
2305 case 0x10:
2306 case 0x12:
2307 case 0x13:
2308 case 0x21:
2309 case 0x22:
2310 buf->ReadWord();
2311 break;
2313 case 0x1E:
2314 buf->ReadDWord();
2315 break;
2317 case 0x17:
2318 for (uint j = 0; j < 4; j++) buf->ReadByte();
2319 break;
2321 case 0x20: {
2322 byte count = buf->ReadByte();
2323 for (byte j = 0; j < count; j++) buf->ReadByte();
2324 break;
2327 default:
2328 ret = CIR_UNKNOWN;
2329 break;
2331 return ret;
2335 * Define properties for houses
2336 * @param hid HouseID of the house.
2337 * @param numinfo Number of subsequent houseIDs to change the property for.
2338 * @param prop The property to change.
2339 * @param buf The property value.
2340 * @return ChangeInfoResult.
2342 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2344 ChangeInfoResult ret = CIR_SUCCESS;
2346 if (hid + numinfo > NUM_HOUSES_PER_GRF) {
2347 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
2348 return CIR_INVALID_ID;
2351 /* Allocate house specs if they haven't been allocated already. */
2352 if (_cur.grffile->housespec == NULL) {
2353 _cur.grffile->housespec = xcalloct<HouseSpec*>(NUM_HOUSES_PER_GRF);
2356 for (int i = 0; i < numinfo; i++) {
2357 HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2359 if (prop != 0x08 && housespec == NULL) {
2360 /* If the house property 08 is not yet set, ignore this property */
2361 ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2362 if (cir > ret) ret = cir;
2363 continue;
2366 switch (prop) {
2367 case 0x08: { // Substitute building type, and definition of a new house
2368 HouseSpec **house = &_cur.grffile->housespec[hid + i];
2369 byte subs_id = buf->ReadByte();
2371 if (subs_id == 0xFF) {
2372 /* Instead of defining a new house, a substitute house id
2373 * of 0xFF disables the old house with the current id. */
2374 HouseSpec::Get(hid + i)->enabled = false;
2375 continue;
2376 } else if (subs_id >= NEW_HOUSE_OFFSET) {
2377 /* The substitute id must be one of the original houses. */
2378 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2379 continue;
2382 /* Allocate space for this house. */
2383 if (*house == NULL) *house = xcalloct<HouseSpec>();
2385 housespec = *house;
2387 MemCpyT(housespec, HouseSpec::Get(subs_id));
2389 housespec->enabled = true;
2390 housespec->grf_prop.local_id = hid + i;
2391 housespec->grf_prop.subst_id = subs_id;
2392 housespec->grf_prop.grffile = _cur.grffile;
2393 housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2394 housespec->random_colour[1] = 0x08; // for all new houses
2395 housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2396 housespec->random_colour[3] = 0x06;
2398 /* Make sure that the third cargo type is valid in this
2399 * climate. This can cause problems when copying the properties
2400 * of a house that accepts food, where the new house is valid
2401 * in the temperate climate. */
2402 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2403 housespec->cargo_acceptance[2] = 0;
2406 _loaded_newgrf_features.has_newhouses = true;
2407 break;
2410 case 0x09: // Building flags
2411 housespec->building_flags = (BuildingFlags)buf->ReadByte();
2412 break;
2414 case 0x0A: { // Availability years
2415 uint16 years = buf->ReadWord();
2416 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2417 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2418 break;
2421 case 0x0B: // Population
2422 housespec->population = buf->ReadByte();
2423 break;
2425 case 0x0C: // Mail generation multiplier
2426 housespec->mail_generation = buf->ReadByte();
2427 break;
2429 case 0x0D: // Passenger acceptance
2430 case 0x0E: // Mail acceptance
2431 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2432 break;
2434 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2435 int8 goods = buf->ReadByte();
2437 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2438 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2439 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2440 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2442 /* Make sure the cargo type is valid in this climate. */
2443 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2445 housespec->accepts_cargo[2] = cid;
2446 housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2447 break;
2450 case 0x10: // Local authority rating decrease on removal
2451 housespec->remove_rating_decrease = buf->ReadWord();
2452 break;
2454 case 0x11: // Removal cost multiplier
2455 housespec->removal_cost = buf->ReadByte();
2456 break;
2458 case 0x12: // Building name ID
2459 AddStringForMapping(buf->ReadWord(), &housespec->building_name);
2460 break;
2462 case 0x13: // Building availability mask
2463 housespec->building_availability = (HouseZones)buf->ReadWord();
2464 break;
2466 case 0x14: // House callback mask
2467 housespec->callback_mask |= buf->ReadByte();
2468 break;
2470 case 0x15: { // House override byte
2471 byte override = buf->ReadByte();
2473 /* The house being overridden must be an original house. */
2474 if (override >= NEW_HOUSE_OFFSET) {
2475 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2476 continue;
2479 _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2480 break;
2483 case 0x16: // Periodic refresh multiplier
2484 housespec->processing_time = min(buf->ReadByte(), 63);
2485 break;
2487 case 0x17: // Four random colours to use
2488 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2489 break;
2491 case 0x18: // Relative probability of appearing
2492 housespec->probability = buf->ReadByte();
2493 break;
2495 case 0x19: // Extra flags
2496 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2497 break;
2499 case 0x1A: // Animation frames
2500 housespec->animation.frames = buf->ReadByte();
2501 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2502 SB(housespec->animation.frames, 7, 1, 0);
2503 break;
2505 case 0x1B: // Animation speed
2506 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2507 break;
2509 case 0x1C: // Class of the building type
2510 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2511 break;
2513 case 0x1D: // Callback mask part 2
2514 housespec->callback_mask |= (buf->ReadByte() << 8);
2515 break;
2517 case 0x1E: { // Accepted cargo types
2518 uint32 cargotypes = buf->ReadDWord();
2520 /* Check if the cargo types should not be changed */
2521 if (cargotypes == 0xFFFFFFFF) break;
2523 for (uint j = 0; j < 3; j++) {
2524 /* Get the cargo number from the 'list' */
2525 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2526 CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2528 if (cargo == CT_INVALID) {
2529 /* Disable acceptance of invalid cargo type */
2530 housespec->cargo_acceptance[j] = 0;
2531 } else {
2532 housespec->accepts_cargo[j] = cargo;
2535 break;
2538 case 0x1F: // Minimum life span
2539 housespec->minimum_life = buf->ReadByte();
2540 break;
2542 case 0x20: { // Cargo acceptance watch list
2543 byte count = buf->ReadByte();
2544 for (byte j = 0; j < count; j++) {
2545 CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2546 if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
2548 break;
2551 case 0x21: // long introduction year
2552 housespec->min_year = buf->ReadWord();
2553 break;
2555 case 0x22: // long maximum year
2556 housespec->max_year = buf->ReadWord();
2557 break;
2559 default:
2560 ret = CIR_UNKNOWN;
2561 break;
2565 return ret;
2569 * Get the language map associated with a given NewGRF and language.
2570 * @param grfid The NewGRF to get the map for.
2571 * @param language_id The (NewGRF) language ID to get the map for.
2572 * @return The LanguageMap, or NULL if it couldn't be found.
2574 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2576 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2577 const GRFFile *grffile = GetFileByGRFID(grfid);
2578 return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
2582 * Load a cargo- or railtype-translation table.
2583 * @param gvid ID of the global variable. This is basically only checked for zerones.
2584 * @param numinfo Number of subsequent IDs to change the property for.
2585 * @param buf The property value.
2586 * @param [in,out] translation_table Storage location for the translation table.
2587 * @param name Name of the table for debug output.
2588 * @return ChangeInfoResult.
2590 template <typename T>
2591 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
2593 if (gvid != 0) {
2594 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
2595 return CIR_INVALID_ID;
2598 translation_table.Clear();
2599 for (int i = 0; i < numinfo; i++) {
2600 uint32 item = buf->ReadDWord();
2601 *translation_table.Append() = BSWAP32(item);
2604 return CIR_SUCCESS;
2608 * Define properties for global variables
2609 * @param gvid ID of the global variable.
2610 * @param numinfo Number of subsequent IDs to change the property for.
2611 * @param prop The property to change.
2612 * @param buf The property value.
2613 * @return ChangeInfoResult.
2615 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2617 /* Properties which are handled as a whole */
2618 switch (prop) {
2619 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2620 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2622 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2623 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2625 default:
2626 break;
2629 /* Properties which are handled per item */
2630 ChangeInfoResult ret = CIR_SUCCESS;
2631 for (int i = 0; i < numinfo; i++) {
2632 switch (prop) {
2633 case 0x08: { // Cost base factor
2634 int factor = buf->ReadByte();
2635 uint price = gvid + i;
2637 if (price < PR_END) {
2638 _cur.grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
2639 } else {
2640 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2642 break;
2645 case 0x0A: { // Currency display names
2646 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2647 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2649 if ((newone != STR_UNDEFINED) && (curidx < CURRENCY_END)) {
2650 _currency_specs[curidx].name = newone;
2652 break;
2655 case 0x0B: { // Currency multipliers
2656 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2657 uint32 rate = buf->ReadDWord();
2659 if (curidx < CURRENCY_END) {
2660 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2661 * which OTTD does not. For this reason, divide grf value by 1000,
2662 * to be compatible */
2663 _currency_specs[curidx].rate = rate / 1000;
2664 } else {
2665 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2667 break;
2670 case 0x0C: { // Currency options
2671 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2672 uint16 options = buf->ReadWord();
2674 if (curidx < CURRENCY_END) {
2675 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
2676 _currency_specs[curidx].separator[1] = '\0';
2677 /* By specifying only one bit, we prevent errors,
2678 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2679 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
2680 } else {
2681 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2683 break;
2686 case 0x0D: { // Currency prefix symbol
2687 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2688 uint32 tempfix = buf->ReadDWord();
2690 if (curidx < CURRENCY_END) {
2691 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
2692 _currency_specs[curidx].prefix[4] = 0;
2693 } else {
2694 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2696 break;
2699 case 0x0E: { // Currency suffix symbol
2700 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2701 uint32 tempfix = buf->ReadDWord();
2703 if (curidx < CURRENCY_END) {
2704 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
2705 _currency_specs[curidx].suffix[4] = 0;
2706 } else {
2707 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2709 break;
2712 case 0x0F: { // Euro introduction dates
2713 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2714 Year year_euro = buf->ReadWord();
2716 if (curidx < CURRENCY_END) {
2717 _currency_specs[curidx].to_euro = year_euro;
2718 } else {
2719 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2721 break;
2724 case 0x10: // Snow line height table
2725 if (numinfo > 1 || IsSnowLineSet()) {
2726 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2727 } else if (!buf->HasData (SNOW_LINE_MONTHS * SNOW_LINE_DAYS)) {
2728 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2729 } else {
2730 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2732 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2733 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2734 table[i][j] = buf->ReadByte();
2735 if (_cur.grffile->grf_version >= 8) {
2736 if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 256;
2737 } else {
2738 if (table[i][j] >= 128) {
2739 /* no snow */
2740 table[i][j] = 0xFF;
2741 } else {
2742 table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 128;
2747 SetSnowLine(table);
2749 break;
2751 case 0x11: // GRF match for engine allocation
2752 /* This is loaded during the reservation stage, so just skip it here. */
2753 /* Each entry is 8 bytes. */
2754 buf->Skip(8);
2755 break;
2757 case 0x13: // Gender translation table
2758 case 0x14: // Case translation table
2759 case 0x15: { // Plural form translation
2760 uint curidx = gvid + i; // The current index, i.e. language.
2761 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL;
2762 if (lang == NULL) {
2763 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2764 /* Skip over the data. */
2765 if (prop == 0x15) {
2766 buf->ReadByte();
2767 } else {
2768 while (buf->ReadByte() != 0) {
2769 buf->ReadString();
2772 break;
2775 if (_cur.grffile->language_map == NULL) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2777 if (prop == 0x15) {
2778 uint plural_form = buf->ReadByte();
2779 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2780 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2781 } else {
2782 _cur.grffile->language_map[curidx].plural_form = plural_form;
2784 break;
2787 for (;;) {
2788 byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2789 if (newgrf_id == 0) break;
2791 const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2793 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2794 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2795 * is just a subset of UTF8, or they need the bigger UTF8 characters
2796 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2797 WChar c;
2798 size_t len = Utf8Decode(&c, name);
2799 if (c == NFO_UTF8_IDENTIFIER) name += len;
2801 LanguageMap::Mapping map;
2802 map.newgrf_id = newgrf_id;
2803 if (prop == 0x13) {
2804 map.openttd_id = lang->GetGenderIndex(name);
2805 if (map.openttd_id >= MAX_NUM_GENDERS) {
2806 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2807 } else {
2808 *_cur.grffile->language_map[curidx].gender_map.Append() = map;
2810 } else {
2811 map.openttd_id = lang->GetCaseIndex(name);
2812 if (map.openttd_id >= MAX_NUM_CASES) {
2813 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2814 } else {
2815 *_cur.grffile->language_map[curidx].case_map.Append() = map;
2819 break;
2822 default:
2823 ret = CIR_UNKNOWN;
2824 break;
2828 return ret;
2831 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2833 /* Properties which are handled as a whole */
2834 switch (prop) {
2835 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2836 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2838 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2839 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2841 default:
2842 break;
2845 /* Properties which are handled per item */
2846 ChangeInfoResult ret = CIR_SUCCESS;
2847 for (int i = 0; i < numinfo; i++) {
2848 switch (prop) {
2849 case 0x08: // Cost base factor
2850 case 0x15: // Plural form translation
2851 buf->ReadByte();
2852 break;
2854 case 0x0A: // Currency display names
2855 case 0x0C: // Currency options
2856 case 0x0F: // Euro introduction dates
2857 buf->ReadWord();
2858 break;
2860 case 0x0B: // Currency multipliers
2861 case 0x0D: // Currency prefix symbol
2862 case 0x0E: // Currency suffix symbol
2863 buf->ReadDWord();
2864 break;
2866 case 0x10: // Snow line height table
2867 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
2868 break;
2870 case 0x11: { // GRF match for engine allocation
2871 uint32 s = buf->ReadDWord();
2872 uint32 t = buf->ReadDWord();
2873 SetNewGRFOverride(s, t);
2874 break;
2877 case 0x13: // Gender translation table
2878 case 0x14: // Case translation table
2879 while (buf->ReadByte() != 0) {
2880 buf->ReadString();
2882 break;
2884 default:
2885 ret = CIR_UNKNOWN;
2886 break;
2890 return ret;
2895 * Define properties for cargoes
2896 * @param cid Local ID of the cargo.
2897 * @param numinfo Number of subsequent IDs to change the property for.
2898 * @param prop The property to change.
2899 * @param buf The property value.
2900 * @return ChangeInfoResult.
2902 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
2904 ChangeInfoResult ret = CIR_SUCCESS;
2906 if (cid + numinfo > NUM_CARGO) {
2907 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
2908 return CIR_INVALID_ID;
2911 for (int i = 0; i < numinfo; i++) {
2912 CargoSpec *cs = CargoSpec::Get(cid + i);
2914 switch (prop) {
2915 case 0x08: // Bit number of cargo
2916 cs->bitnum = buf->ReadByte();
2917 if (cs->IsValid()) {
2918 cs->grffile = _cur.grffile;
2919 SetBit(_cargo_mask, cid + i);
2920 } else {
2921 ClrBit(_cargo_mask, cid + i);
2923 break;
2925 case 0x09: // String ID for cargo type name
2926 AddStringForMapping(buf->ReadWord(), &cs->name);
2927 break;
2929 case 0x0A: // String for 1 unit of cargo
2930 AddStringForMapping(buf->ReadWord(), &cs->name_single);
2931 break;
2933 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2934 case 0x1B: // String for cargo units
2935 /* String for units of cargo. This is different in OpenTTD
2936 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2937 * Property 1B is used to set OpenTTD's behaviour. */
2938 AddStringForMapping(buf->ReadWord(), &cs->units_volume);
2939 break;
2941 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2942 case 0x1C: // String for any amount of cargo
2943 /* Strings for an amount of cargo. This is different in OpenTTD
2944 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2945 * Property 1C is used to set OpenTTD's behaviour. */
2946 AddStringForMapping(buf->ReadWord(), &cs->quantifier);
2947 break;
2949 case 0x0D: // String for two letter cargo abbreviation
2950 AddStringForMapping(buf->ReadWord(), &cs->abbrev);
2951 break;
2953 case 0x0E: // Sprite ID for cargo icon
2954 cs->sprite = buf->ReadWord();
2955 break;
2957 case 0x0F: // Weight of one unit of cargo
2958 cs->weight = buf->ReadByte();
2959 break;
2961 case 0x10: // Used for payment calculation
2962 cs->transit_days[0] = buf->ReadByte();
2963 break;
2965 case 0x11: // Used for payment calculation
2966 cs->transit_days[1] = buf->ReadByte();
2967 break;
2969 case 0x12: // Base cargo price
2970 cs->initial_payment = buf->ReadDWord();
2971 break;
2973 case 0x13: // Colour for station rating bars
2974 cs->rating_colour = buf->ReadByte();
2975 break;
2977 case 0x14: // Colour for cargo graph
2978 cs->legend_colour = buf->ReadByte();
2979 break;
2981 case 0x15: // Freight status
2982 cs->is_freight = (buf->ReadByte() != 0);
2983 break;
2985 case 0x16: // Cargo classes
2986 cs->classes = buf->ReadWord();
2987 break;
2989 case 0x17: // Cargo label
2990 cs->label = buf->ReadDWord();
2991 cs->label = BSWAP32(cs->label);
2992 break;
2994 case 0x18: { // Town growth substitute type
2995 uint8 substitute_type = buf->ReadByte();
2997 switch (substitute_type) {
2998 case 0x00: cs->town_effect = TE_PASSENGERS; break;
2999 case 0x02: cs->town_effect = TE_MAIL; break;
3000 case 0x05: cs->town_effect = TE_GOODS; break;
3001 case 0x09: cs->town_effect = TE_WATER; break;
3002 case 0x0B: cs->town_effect = TE_FOOD; break;
3003 default:
3004 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
3005 /* FALL THROUGH */
3006 case 0xFF: cs->town_effect = TE_NONE; break;
3008 break;
3011 case 0x19: // Town growth coefficient
3012 cs->multipliertowngrowth = buf->ReadWord();
3013 break;
3015 case 0x1A: // Bitmask of callbacks to use
3016 cs->callback_mask = buf->ReadByte();
3017 break;
3019 case 0x1D: // Vehicle capacity muliplier
3020 cs->multiplier = max<uint16>(1u, buf->ReadWord());
3021 break;
3023 default:
3024 ret = CIR_UNKNOWN;
3025 break;
3029 return ret;
3034 * Define properties for sound effects
3035 * @param sid Local ID of the sound.
3036 * @param numinfo Number of subsequent IDs to change the property for.
3037 * @param prop The property to change.
3038 * @param buf The property value.
3039 * @return ChangeInfoResult.
3041 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
3043 ChangeInfoResult ret = CIR_SUCCESS;
3045 if (_cur.grffile->sound_offset == 0) {
3046 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3047 return CIR_INVALID_ID;
3050 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
3051 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
3052 return CIR_INVALID_ID;
3055 for (int i = 0; i < numinfo; i++) {
3056 SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
3058 switch (prop) {
3059 case 0x08: // Relative volume
3060 sound->volume = buf->ReadByte();
3061 break;
3063 case 0x09: // Priority
3064 sound->priority = buf->ReadByte();
3065 break;
3067 case 0x0A: { // Override old sound
3068 SoundID orig_sound = buf->ReadByte();
3070 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
3071 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
3072 } else {
3073 SoundEntry *old_sound = GetSound(orig_sound);
3075 /* Literally copy the data of the new sound over the original */
3076 *old_sound = *sound;
3078 break;
3081 default:
3082 ret = CIR_UNKNOWN;
3083 break;
3087 return ret;
3091 * Ignore an industry tile property
3092 * @param prop The property to ignore.
3093 * @param buf The property value.
3094 * @return ChangeInfoResult.
3096 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
3098 ChangeInfoResult ret = CIR_SUCCESS;
3100 switch (prop) {
3101 case 0x09:
3102 case 0x0D:
3103 case 0x0E:
3104 case 0x10:
3105 case 0x11:
3106 case 0x12:
3107 buf->ReadByte();
3108 break;
3110 case 0x0A:
3111 case 0x0B:
3112 case 0x0C:
3113 case 0x0F:
3114 buf->ReadWord();
3115 break;
3117 default:
3118 ret = CIR_UNKNOWN;
3119 break;
3121 return ret;
3125 * Define properties for industry tiles
3126 * @param indtid Local ID of the industry tile.
3127 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3128 * @param prop The property to change.
3129 * @param buf The property value.
3130 * @return ChangeInfoResult.
3132 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
3134 ChangeInfoResult ret = CIR_SUCCESS;
3136 if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
3137 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
3138 return CIR_INVALID_ID;
3141 /* Allocate industry tile specs if they haven't been allocated already. */
3142 if (_cur.grffile->indtspec == NULL) {
3143 _cur.grffile->indtspec = xcalloct<IndustryTileSpec*>(NUM_INDUSTRYTILES_PER_GRF);
3146 for (int i = 0; i < numinfo; i++) {
3147 IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
3149 if (prop != 0x08 && tsp == NULL) {
3150 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
3151 if (cir > ret) ret = cir;
3152 continue;
3155 switch (prop) {
3156 case 0x08: { // Substitute industry tile type
3157 byte subs_id = buf->ReadByte();
3159 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
3160 /* The substitute id must be one of the original industry tile. */
3161 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3162 continue;
3165 /* Allocate space for this industry. */
3166 if (tsp == NULL) {
3167 tsp = xmemdupt (&_industry_tile_specs[subs_id]);
3168 _cur.grffile->indtspec[indtid + i] = tsp;
3170 tsp->enabled = true;
3172 /* A copied tile should not have the animation infos copied too.
3173 * The anim_state should be left untouched, though
3174 * It is up to the author to animate them himself */
3175 tsp->anim_production = INDUSTRYTILE_NOANIM;
3176 tsp->anim_next = INDUSTRYTILE_NOANIM;
3178 tsp->grf_prop.local_id = indtid + i;
3179 tsp->grf_prop.subst_id = subs_id;
3180 tsp->grf_prop.grffile = _cur.grffile;
3181 _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3183 break;
3186 case 0x09: { // Industry tile override
3187 byte ovrid = buf->ReadByte();
3189 /* The industry being overridden must be an original industry. */
3190 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
3191 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3192 continue;
3195 _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
3196 break;
3199 case 0x0A: // Tile acceptance
3200 case 0x0B:
3201 case 0x0C: {
3202 uint16 acctp = buf->ReadWord();
3203 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
3204 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
3205 break;
3208 case 0x0D: // Land shape flags
3209 tsp->slopes_refused = (Slope)buf->ReadByte();
3210 break;
3212 case 0x0E: // Callback mask
3213 tsp->callback_mask = buf->ReadByte();
3214 break;
3216 case 0x0F: // Animation information
3217 tsp->animation.frames = buf->ReadByte();
3218 tsp->animation.status = buf->ReadByte();
3219 break;
3221 case 0x10: // Animation speed
3222 tsp->animation.speed = buf->ReadByte();
3223 break;
3225 case 0x11: // Triggers for callback 25
3226 tsp->animation.triggers = buf->ReadByte();
3227 break;
3229 case 0x12: // Special flags
3230 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
3231 break;
3233 default:
3234 ret = CIR_UNKNOWN;
3235 break;
3239 return ret;
3243 * Ignore an industry property
3244 * @param prop The property to ignore.
3245 * @param buf The property value.
3246 * @return ChangeInfoResult.
3248 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
3250 ChangeInfoResult ret = CIR_SUCCESS;
3252 switch (prop) {
3253 case 0x09:
3254 case 0x0B:
3255 case 0x0F:
3256 case 0x12:
3257 case 0x13:
3258 case 0x14:
3259 case 0x17:
3260 case 0x18:
3261 case 0x19:
3262 case 0x21:
3263 case 0x22:
3264 buf->ReadByte();
3265 break;
3267 case 0x0C:
3268 case 0x0D:
3269 case 0x0E:
3270 case 0x10:
3271 case 0x1B:
3272 case 0x1F:
3273 case 0x24:
3274 buf->ReadWord();
3275 break;
3277 case 0x11:
3278 case 0x1A:
3279 case 0x1C:
3280 case 0x1D:
3281 case 0x1E:
3282 case 0x20:
3283 case 0x23:
3284 buf->ReadDWord();
3285 break;
3287 case 0x0A: {
3288 byte num_table = buf->ReadByte();
3289 for (byte j = 0; j < num_table; j++) {
3290 for (uint k = 0;; k++) {
3291 byte x = buf->ReadByte();
3292 if (x == 0xFE && k == 0) {
3293 buf->ReadByte();
3294 buf->ReadByte();
3295 break;
3298 byte y = buf->ReadByte();
3299 if (x == 0 && y == 0x80) break;
3301 byte gfx = buf->ReadByte();
3302 if (gfx == 0xFE) buf->ReadWord();
3305 break;
3308 case 0x16:
3309 for (byte j = 0; j < 3; j++) buf->ReadByte();
3310 break;
3312 case 0x15: {
3313 byte number_of_sounds = buf->ReadByte();
3314 for (uint8 j = 0; j < number_of_sounds; j++) {
3315 buf->ReadByte();
3317 break;
3320 default:
3321 ret = CIR_UNKNOWN;
3322 break;
3324 return ret;
3328 * Validate the industry layout; e.g. to prevent duplicate tiles.
3329 * @param layout The layout to check.
3330 * @param size The size of the layout.
3331 * @return True if the layout is deemed valid.
3333 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
3335 for (int i = 0; i < size - 1; i++) {
3336 for (int j = i + 1; j < size; j++) {
3337 if (layout[i].ti.x == layout[j].ti.x &&
3338 layout[i].ti.y == layout[j].ti.y) {
3339 return false;
3343 return true;
3346 /** Clean the tile table of the IndustrySpec if it's needed. */
3347 static void CleanIndustryTileTable(IndustrySpec *ind)
3349 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
3350 for (int j = 0; j < ind->num_table; j++) {
3351 /* remove the individual layouts */
3352 free(ind->table[j]);
3354 /* remove the layouts pointers */
3355 free(ind->table);
3356 ind->table = NULL;
3361 * Define properties for industries
3362 * @param indid Local ID of the industry.
3363 * @param numinfo Number of subsequent industry IDs to change the property for.
3364 * @param prop The property to change.
3365 * @param buf The property value.
3366 * @return ChangeInfoResult.
3368 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3370 ChangeInfoResult ret = CIR_SUCCESS;
3372 if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
3373 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
3374 return CIR_INVALID_ID;
3377 /* Allocate industry specs if they haven't been allocated already. */
3378 if (_cur.grffile->industryspec == NULL) {
3379 _cur.grffile->industryspec = xcalloct<IndustrySpec*>(NUM_INDUSTRYTYPES_PER_GRF);
3382 for (int i = 0; i < numinfo; i++) {
3383 IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3385 if (prop != 0x08 && indsp == NULL) {
3386 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3387 if (cir > ret) ret = cir;
3388 continue;
3391 switch (prop) {
3392 case 0x08: { // Substitute industry type
3393 byte subs_id = buf->ReadByte();
3395 if (subs_id == 0xFF) {
3396 /* Instead of defining a new industry, a substitute industry id
3397 * of 0xFF disables the old industry with the current id. */
3398 _industry_specs[indid + i].enabled = false;
3399 continue;
3400 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3401 /* The substitute id must be one of the original industry. */
3402 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3403 continue;
3406 /* Allocate space for this industry.
3407 * Only need to do it once. If ever it is called again, it should not
3408 * do anything */
3409 if (indsp == NULL) {
3410 indsp = xmemdupt (&_origin_industry_specs[subs_id]);
3411 _cur.grffile->industryspec[indid + i] = indsp;
3413 indsp->enabled = true;
3414 indsp->grf_prop.local_id = indid + i;
3415 indsp->grf_prop.subst_id = subs_id;
3416 indsp->grf_prop.grffile = _cur.grffile;
3417 /* If the grf industry needs to check its surounding upon creation, it should
3418 * rely on callbacks, not on the original placement functions */
3419 indsp->check_proc = CHECK_NOTHING;
3421 break;
3424 case 0x09: { // Industry type override
3425 byte ovrid = buf->ReadByte();
3427 /* The industry being overridden must be an original industry. */
3428 if (ovrid >= NEW_INDUSTRYOFFSET) {
3429 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3430 continue;
3432 indsp->grf_prop.override = ovrid;
3433 _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3434 break;
3437 case 0x0A: { // Set industry layout(s)
3438 byte new_num_layouts = buf->ReadByte(); // Number of layaouts
3439 /* We read the total size in bytes, but we can't rely on the
3440 * newgrf to provide a sane value. First assume the value is
3441 * sane but later on we make sure we enlarge the array if the
3442 * newgrf contains more data. Each tile uses either 3 or 5
3443 * bytes, so to play it safe we assume 3. */
3444 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
3445 IndustryTileTable **tile_table = xcalloct<IndustryTileTable*>(new_num_layouts); // Table with tiles to compose an industry
3446 IndustryTileTable *itt = xcalloct<IndustryTileTable>(def_num_tiles); // Temporary array to read the tile layouts from the GRF
3447 uint size;
3448 const IndustryTileTable *copy_from;
3450 try {
3451 for (byte j = 0; j < new_num_layouts; j++) {
3452 for (uint k = 0;; k++) {
3453 if (k >= def_num_tiles) {
3454 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3455 /* Size reported by newgrf was not big enough so enlarge the array. */
3456 def_num_tiles *= 2;
3457 itt = xrealloct<IndustryTileTable>(itt, def_num_tiles);
3460 itt[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3462 if (itt[k].ti.x == 0xFE && k == 0) {
3463 /* This means we have to borrow the layout from an old industry */
3464 IndustryType type = buf->ReadByte(); // industry holding required layout
3465 byte laynbr = buf->ReadByte(); // layout number to borrow
3467 copy_from = _origin_industry_specs[type].table[laynbr];
3468 for (size = 1;; size++) {
3469 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
3471 break;
3474 itt[k].ti.y = buf->ReadByte(); // Or table definition finalisation
3476 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
3477 /* Not the same terminator. The one we are using is rather
3478 x = -80, y = x . So, adjust it. */
3479 itt[k].ti.x = -0x80;
3480 itt[k].ti.y = 0;
3481 itt[k].gfx = 0;
3483 size = k + 1;
3484 copy_from = itt;
3485 break;
3488 itt[k].gfx = buf->ReadByte();
3490 if (itt[k].gfx == 0xFE) {
3491 /* Use a new tile from this GRF */
3492 int local_tile_id = buf->ReadWord();
3494 /* Read the ID from the _industile_mngr. */
3495 int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3497 if (tempid == INVALID_INDUSTRYTILE) {
3498 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3499 } else {
3500 /* Declared as been valid, can be used */
3501 itt[k].gfx = tempid;
3502 size = k + 1;
3503 copy_from = itt;
3505 } else if (itt[k].gfx == 0xFF) {
3506 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
3507 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
3509 /* When there were only 256x256 maps, TileIndex was a uint16 and
3510 * itt[k].ti was just a TileIndexDiff that was added to it.
3511 * As such negative "x" values were shifted into the "y" position.
3512 * x = -1, y = 1 -> x = 255, y = 0
3513 * Since GRF version 8 the position is interpreted as pair of independent int8.
3514 * For GRF version < 8 we need to emulate the old shifting behaviour.
3516 if (_cur.grffile->grf_version < 8 && itt[k].ti.x < 0) itt[k].ti.y += 1;
3520 if (!ValidateIndustryLayout(copy_from, size)) {
3521 /* The industry layout was not valid, so skip this one. */
3522 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3523 new_num_layouts--;
3524 j--;
3525 } else {
3526 tile_table[j] = xmemdupt (copy_from, size);
3529 } catch (...) {
3530 for (int i = 0; i < new_num_layouts; i++) {
3531 free(tile_table[i]);
3533 free(tile_table);
3534 free(itt);
3535 throw;
3538 /* Clean the tile table if it was already set by a previous prop A. */
3539 CleanIndustryTileTable(indsp);
3540 /* Install final layout construction in the industry spec */
3541 indsp->num_table = new_num_layouts;
3542 indsp->table = tile_table;
3543 SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
3544 free(itt);
3545 break;
3548 case 0x0B: // Industry production flags
3549 indsp->life_type = (IndustryLifeType)buf->ReadByte();
3550 break;
3552 case 0x0C: // Industry closure message
3553 AddStringForMapping(buf->ReadWord(), &indsp->closure_text);
3554 break;
3556 case 0x0D: // Production increase message
3557 AddStringForMapping(buf->ReadWord(), &indsp->production_up_text);
3558 break;
3560 case 0x0E: // Production decrease message
3561 AddStringForMapping(buf->ReadWord(), &indsp->production_down_text);
3562 break;
3564 case 0x0F: // Fund cost multiplier
3565 indsp->cost_multiplier = buf->ReadByte();
3566 break;
3568 case 0x10: // Production cargo types
3569 for (byte j = 0; j < 2; j++) {
3570 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3572 break;
3574 case 0x11: // Acceptance cargo types
3575 for (byte j = 0; j < 3; j++) {
3576 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3578 buf->ReadByte(); // Unnused, eat it up
3579 break;
3581 case 0x12: // Production multipliers
3582 case 0x13:
3583 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3584 break;
3586 case 0x14: // Minimal amount of cargo distributed
3587 indsp->minimal_cargo = buf->ReadByte();
3588 break;
3590 case 0x15: { // Random sound effects
3591 indsp->number_of_sounds = buf->ReadByte();
3592 uint8 *sounds = buf->Dup (indsp->number_of_sounds);
3594 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3595 free(indsp->random_sounds);
3597 indsp->random_sounds = sounds;
3598 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
3599 break;
3602 case 0x16: // Conflicting industry types
3603 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3604 break;
3606 case 0x17: // Probability in random game
3607 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3608 break;
3610 case 0x18: // Probability during gameplay
3611 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3612 break;
3614 case 0x19: // Map colour
3615 indsp->map_colour = buf->ReadByte();
3616 break;
3618 case 0x1A: // Special industry flags to define special behavior
3619 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3620 break;
3622 case 0x1B: // New industry text ID
3623 AddStringForMapping(buf->ReadWord(), &indsp->new_industry_text);
3624 break;
3626 case 0x1C: // Input cargo multipliers for the three input cargo types
3627 case 0x1D:
3628 case 0x1E: {
3629 uint32 multiples = buf->ReadDWord();
3630 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3631 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3632 break;
3635 case 0x1F: // Industry name
3636 AddStringForMapping(buf->ReadWord(), &indsp->name);
3637 break;
3639 case 0x20: // Prospecting success chance
3640 indsp->prospecting_chance = buf->ReadDWord();
3641 break;
3643 case 0x21: // Callback mask
3644 case 0x22: { // Callback additional mask
3645 byte aflag = buf->ReadByte();
3646 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3647 break;
3650 case 0x23: // removal cost multiplier
3651 indsp->removal_cost_multiplier = buf->ReadDWord();
3652 break;
3654 case 0x24: { // name for nearby station
3655 uint16 str = buf->ReadWord();
3656 if (str == 0) {
3657 indsp->station_name = STR_NULL;
3658 } else {
3659 AddStringForMapping(str, &indsp->station_name);
3661 break;
3664 default:
3665 ret = CIR_UNKNOWN;
3666 break;
3670 return ret;
3674 * Clone an AirportSpec.
3675 * @param src The AirportSpec to clone.
3676 * @return A fresh copy of the AirportSpec
3678 static AirportSpec *CloneAirportSpec (const AirportSpec *src)
3680 AirportSpec *as = xmemdupt (src);
3682 AirportTileTable **table_list = xmalloct<AirportTileTable*> (src->num_table);
3683 for (uint i = 0; i < src->num_table; i++) {
3684 uint num_tiles = 1;
3685 const AirportTileTable *it = src->table[i];
3686 do {
3687 num_tiles++;
3688 } while ((++it)->ti.x != -0x80);
3689 table_list[i] = xmemdupt (src->table[i], num_tiles);
3691 as->table = table_list;
3693 as->depot_table = xmemdupt (src->depot_table, src->nof_depots);
3695 return as;
3699 * Define properties for airports
3700 * @param airport Local ID of the airport.
3701 * @param numinfo Number of subsequent airport IDs to change the property for.
3702 * @param prop The property to change.
3703 * @param buf The property value.
3704 * @return ChangeInfoResult.
3706 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3708 ChangeInfoResult ret = CIR_SUCCESS;
3710 if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
3711 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
3712 return CIR_INVALID_ID;
3715 /* Allocate industry specs if they haven't been allocated already. */
3716 if (_cur.grffile->airportspec == NULL) {
3717 _cur.grffile->airportspec = xcalloct<AirportSpec*>(NUM_AIRPORTS_PER_GRF);
3720 for (int i = 0; i < numinfo; i++) {
3721 AirportSpec *as = _cur.grffile->airportspec[airport + i];
3723 if (as == NULL && prop != 0x08 && prop != 0x09) {
3724 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3725 return CIR_INVALID_ID;
3728 switch (prop) {
3729 case 0x08: { // Modify original airport
3730 byte subs_id = buf->ReadByte();
3732 if (subs_id == 0xFF) {
3733 /* Instead of defining a new airport, an airport id
3734 * of 0xFF disables the old airport with the current id. */
3735 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3736 continue;
3737 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3738 /* The substitute id must be one of the original airports. */
3739 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3740 continue;
3743 /* Allocate space for this airport.
3744 * Only need to do it once. If ever it is called again, it should not
3745 * do anything */
3746 if (as == NULL) {
3747 as = CloneAirportSpec (AirportSpec::GetWithoutOverride(subs_id));
3748 _cur.grffile->airportspec[airport + i] = as;
3750 as->enabled = true;
3751 as->grf_prop.local_id = airport + i;
3752 as->grf_prop.subst_id = subs_id;
3753 as->grf_prop.grffile = _cur.grffile;
3754 /* override the default airport */
3755 _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3757 break;
3760 case 0x0A: { // Set airport layout
3761 as->num_table = buf->ReadByte(); // Number of layaouts
3762 as->rotation = xmalloct<Direction>(as->num_table);
3763 uint32 defsize = buf->ReadDWord(); // Total size of the definition
3764 AirportTileTable **tile_table = xcalloct<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3765 AirportTileTable *att = xcalloct<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
3766 int size;
3767 const AirportTileTable *copy_from;
3768 try {
3769 for (byte j = 0; j < as->num_table; j++) {
3770 as->rotation[j] = (Direction)buf->ReadByte();
3771 for (int k = 0;; k++) {
3772 att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3773 att[k].ti.y = buf->ReadByte();
3775 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3776 /* Not the same terminator. The one we are using is rather
3777 * x = -80, y = 0 . So, adjust it. */
3778 att[k].ti.x = -0x80;
3779 att[k].ti.y = 0;
3780 att[k].gfx = 0;
3782 size = k + 1;
3783 copy_from = att;
3784 break;
3787 att[k].gfx = buf->ReadByte();
3789 if (att[k].gfx == 0xFE) {
3790 /* Use a new tile from this GRF */
3791 int local_tile_id = buf->ReadWord();
3793 /* Read the ID from the _airporttile_mngr. */
3794 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3796 if (tempid == INVALID_AIRPORTTILE) {
3797 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3798 } else {
3799 /* Declared as been valid, can be used */
3800 att[k].gfx = tempid;
3801 size = k + 1;
3802 copy_from = att;
3804 } else if (att[k].gfx == 0xFF) {
3805 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3806 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3809 if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
3810 as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
3811 as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
3812 } else {
3813 as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
3814 as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
3817 tile_table[j] = xmemdupt (copy_from, size);
3819 /* Install final layout construction in the airport spec */
3820 as->table = tile_table;
3821 free(att);
3822 } catch (...) {
3823 for (int i = 0; i < as->num_table; i++) {
3824 free(tile_table[i]);
3826 free(tile_table);
3827 free(att);
3828 throw;
3830 break;
3833 case 0x0C:
3834 as->min_year = buf->ReadWord();
3835 as->max_year = buf->ReadWord();
3836 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3837 break;
3839 case 0x0D:
3840 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3841 break;
3843 case 0x0E:
3844 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3845 break;
3847 case 0x0F:
3848 as->noise_level = buf->ReadByte();
3849 break;
3851 case 0x10:
3852 AddStringForMapping(buf->ReadWord(), &as->name);
3853 break;
3855 case 0x11: // Maintenance cost factor
3856 as->maintenance_cost = buf->ReadWord();
3857 break;
3859 default:
3860 ret = CIR_UNKNOWN;
3861 break;
3865 return ret;
3869 * Ignore properties for objects
3870 * @param prop The property to ignore.
3871 * @param buf The property value.
3872 * @return ChangeInfoResult.
3874 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
3876 ChangeInfoResult ret = CIR_SUCCESS;
3878 switch (prop) {
3879 case 0x0B:
3880 case 0x0C:
3881 case 0x0D:
3882 case 0x12:
3883 case 0x14:
3884 case 0x16:
3885 case 0x17:
3886 buf->ReadByte();
3887 break;
3889 case 0x09:
3890 case 0x0A:
3891 case 0x10:
3892 case 0x11:
3893 case 0x13:
3894 case 0x15:
3895 buf->ReadWord();
3896 break;
3898 case 0x08:
3899 case 0x0E:
3900 case 0x0F:
3901 buf->ReadDWord();
3902 break;
3904 default:
3905 ret = CIR_UNKNOWN;
3906 break;
3909 return ret;
3913 * Define properties for objects
3914 * @param id Local ID of the object.
3915 * @param numinfo Number of subsequent objectIDs to change the property for.
3916 * @param prop The property to change.
3917 * @param buf The property value.
3918 * @return ChangeInfoResult.
3920 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
3922 ChangeInfoResult ret = CIR_SUCCESS;
3924 if (id + numinfo > NUM_OBJECTS_PER_GRF) {
3925 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
3926 return CIR_INVALID_ID;
3929 /* Allocate object specs if they haven't been allocated already. */
3930 if (_cur.grffile->objectspec == NULL) {
3931 _cur.grffile->objectspec = xcalloct<ObjectSpec*>(NUM_OBJECTS_PER_GRF);
3934 for (int i = 0; i < numinfo; i++) {
3935 ObjectSpec *spec = _cur.grffile->objectspec[id + i];
3937 if (prop != 0x08 && spec == NULL) {
3938 /* If the object property 08 is not yet set, ignore this property */
3939 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
3940 if (cir > ret) ret = cir;
3941 continue;
3944 switch (prop) {
3945 case 0x08: { // Class ID
3946 ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
3948 /* Allocate space for this object. */
3949 if (*ospec == NULL) {
3950 *ospec = xcalloct<ObjectSpec>();
3951 (*ospec)->views = 1; // Default for NewGRFs that don't set it.
3954 /* Swap classid because we read it in BE. */
3955 uint32 classid = buf->ReadDWord();
3956 (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
3957 (*ospec)->enabled = true;
3958 break;
3961 case 0x09: { // Class name
3962 ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
3963 AddStringForMapping(buf->ReadWord(), &objclass->name);
3964 break;
3967 case 0x0A: // Object name
3968 AddStringForMapping(buf->ReadWord(), &spec->name);
3969 break;
3971 case 0x0B: // Climate mask
3972 spec->climate = buf->ReadByte();
3973 break;
3975 case 0x0C: // Size
3976 spec->size = buf->ReadByte();
3977 break;
3979 case 0x0D: // Build cost multipler
3980 spec->build_cost_multiplier = buf->ReadByte();
3981 spec->clear_cost_multiplier = spec->build_cost_multiplier;
3982 break;
3984 case 0x0E: // Introduction date
3985 spec->introduction_date = buf->ReadDWord();
3986 break;
3988 case 0x0F: // End of life
3989 spec->end_of_life_date = buf->ReadDWord();
3990 break;
3992 case 0x10: // Flags
3993 spec->flags = (ObjectFlags)buf->ReadWord();
3994 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
3995 break;
3997 case 0x11: // Animation info
3998 spec->animation.frames = buf->ReadByte();
3999 spec->animation.status = buf->ReadByte();
4000 break;
4002 case 0x12: // Animation speed
4003 spec->animation.speed = buf->ReadByte();
4004 break;
4006 case 0x13: // Animation triggers
4007 spec->animation.triggers = buf->ReadWord();
4008 break;
4010 case 0x14: // Removal cost multiplier
4011 spec->clear_cost_multiplier = buf->ReadByte();
4012 break;
4014 case 0x15: // Callback mask
4015 spec->callback_mask = buf->ReadWord();
4016 break;
4018 case 0x16: // Building height
4019 spec->height = buf->ReadByte();
4020 break;
4022 case 0x17: // Views
4023 spec->views = buf->ReadByte();
4024 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
4025 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
4026 spec->views = 1;
4028 break;
4030 case 0x18: // Amount placed on 256^2 map on map creation
4031 spec->generate_amount = buf->ReadByte();
4032 break;
4034 default:
4035 ret = CIR_UNKNOWN;
4036 break;
4040 return ret;
4044 * Define properties for railtypes
4045 * @param id ID of the railtype.
4046 * @param numinfo Number of subsequent IDs to change the property for.
4047 * @param prop The property to change.
4048 * @param buf The property value.
4049 * @return ChangeInfoResult.
4051 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4053 ChangeInfoResult ret = CIR_SUCCESS;
4055 extern RailtypeInfo _railtypes[RAILTYPE_END];
4057 if (id + numinfo > RAILTYPE_END) {
4058 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4059 return CIR_INVALID_ID;
4062 for (int i = 0; i < numinfo; i++) {
4063 RailType rt = _cur.grffile->railtype_map[id + i];
4064 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
4066 RailtypeInfo *rti = &_railtypes[rt];
4068 switch (prop) {
4069 case 0x08: // Label of rail type
4070 /* Skipped here as this is loaded during reservation stage. */
4071 buf->ReadDWord();
4072 break;
4074 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4075 uint16 str = buf->ReadWord();
4076 AddStringForMapping(str, &rti->strings.toolbar_caption);
4077 if (_cur.grffile->grf_version < 8) {
4078 AddStringForMapping(str, &rti->strings.name);
4080 break;
4083 case 0x0A: // Menu text of railtype
4084 AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4085 break;
4087 case 0x0B: // Build window caption
4088 AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4089 break;
4091 case 0x0C: // Autoreplace text
4092 AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4093 break;
4095 case 0x0D: // New locomotive text
4096 AddStringForMapping(buf->ReadWord(), &rti->strings.new_loco);
4097 break;
4099 case 0x0E: // Compatible railtype list
4100 case 0x0F: // Powered railtype list
4101 case 0x18: // Railtype list required for date introduction
4102 case 0x19: // Introduced railtype list
4104 /* Rail type compatibility bits are added to the existing bits
4105 * to allow multiple GRFs to modify compatibility with the
4106 * default rail types. */
4107 int n = buf->ReadByte();
4108 for (int j = 0; j != n; j++) {
4109 RailTypeLabel label = buf->ReadDWord();
4110 RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
4111 if (rt != INVALID_RAILTYPE) {
4112 switch (prop) {
4113 case 0x0F: SetBit(rti->powered_railtypes, rt); // Powered implies compatible.
4114 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
4115 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
4116 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
4120 break;
4123 case 0x10: // Rail Type flags
4124 rti->flags = (RailTypeFlags)buf->ReadByte();
4125 break;
4127 case 0x11: // Curve speed advantage
4128 rti->curve_speed = buf->ReadByte();
4129 break;
4131 case 0x12: // Station graphic
4132 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
4133 break;
4135 case 0x13: // Construction cost factor
4136 rti->cost_multiplier = buf->ReadWord();
4137 break;
4139 case 0x14: // Speed limit
4140 rti->max_speed = buf->ReadWord();
4141 break;
4143 case 0x15: // Acceleration model
4144 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
4145 break;
4147 case 0x16: // Map colour
4148 rti->map_colour = buf->ReadByte();
4149 break;
4151 case 0x17: // Introduction date
4152 rti->introduction_date = buf->ReadDWord();
4153 break;
4155 case 0x1A: // Sort order
4156 rti->sorting_order = buf->ReadByte();
4157 break;
4159 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4160 AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4161 break;
4163 case 0x1C: // Maintenance cost factor
4164 rti->maintenance_multiplier = buf->ReadWord();
4165 break;
4167 case 0x1D: // Alternate rail type label list
4168 /* Skipped here as this is loaded during reservation stage. */
4169 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4170 break;
4172 default:
4173 ret = CIR_UNKNOWN;
4174 break;
4178 return ret;
4181 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4183 ChangeInfoResult ret = CIR_SUCCESS;
4185 extern RailtypeInfo _railtypes[RAILTYPE_END];
4187 if (id + numinfo > RAILTYPE_END) {
4188 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4189 return CIR_INVALID_ID;
4192 for (int i = 0; i < numinfo; i++) {
4193 switch (prop) {
4194 case 0x08: // Label of rail type
4196 RailTypeLabel rtl = buf->ReadDWord();
4197 rtl = BSWAP32(rtl);
4199 RailType rt = GetRailTypeByLabel(rtl, false);
4200 if (rt == INVALID_RAILTYPE) {
4201 /* Set up new rail type */
4202 rt = AllocateRailType(rtl);
4205 _cur.grffile->railtype_map[id + i] = rt;
4206 break;
4209 case 0x09: // Toolbar caption of railtype
4210 case 0x0A: // Menu text
4211 case 0x0B: // Build window caption
4212 case 0x0C: // Autoreplace text
4213 case 0x0D: // New loco
4214 case 0x13: // Construction cost
4215 case 0x14: // Speed limit
4216 case 0x1B: // Name of railtype
4217 case 0x1C: // Maintenance cost factor
4218 buf->ReadWord();
4219 break;
4221 case 0x1D: // Alternate rail type label list
4222 if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
4223 int n = buf->ReadByte();
4224 for (int j = 0; j != n; j++) {
4225 *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord());
4227 break;
4229 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
4230 /* FALL THROUGH */
4232 case 0x0E: // Compatible railtype list
4233 case 0x0F: // Powered railtype list
4234 case 0x18: // Railtype list required for date introduction
4235 case 0x19: // Introduced railtype list
4236 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4237 break;
4239 case 0x10: // Rail Type flags
4240 case 0x11: // Curve speed advantage
4241 case 0x12: // Station graphic
4242 case 0x15: // Acceleration model
4243 case 0x16: // Map colour
4244 case 0x1A: // Sort order
4245 buf->ReadByte();
4246 break;
4248 case 0x17: // Introduction date
4249 buf->ReadDWord();
4250 break;
4252 default:
4253 ret = CIR_UNKNOWN;
4254 break;
4258 return ret;
4261 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
4263 ChangeInfoResult ret = CIR_SUCCESS;
4265 if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
4266 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
4267 return CIR_INVALID_ID;
4270 /* Allocate airport tile specs if they haven't been allocated already. */
4271 if (_cur.grffile->airtspec == NULL) {
4272 _cur.grffile->airtspec = xcalloct<AirportTileSpec*>(NUM_AIRPORTTILES_PER_GRF);
4275 for (int i = 0; i < numinfo; i++) {
4276 AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
4278 if (prop != 0x08 && tsp == NULL) {
4279 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4280 return CIR_INVALID_ID;
4283 switch (prop) {
4284 case 0x08: { // Substitute airport tile type
4285 byte subs_id = buf->ReadByte();
4287 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
4288 /* The substitute id must be one of the original airport tiles. */
4289 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4290 continue;
4293 /* Allocate space for this airport tile. */
4294 if (tsp == NULL) {
4295 tsp = xmemdupt (AirportTileSpec::Get(subs_id));
4296 _cur.grffile->airtspec[airtid + i] = tsp;
4298 tsp->enabled = true;
4300 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
4302 tsp->grf_prop.local_id = airtid + i;
4303 tsp->grf_prop.subst_id = subs_id;
4304 tsp->grf_prop.grffile = _cur.grffile;
4305 _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
4307 break;
4310 case 0x09: { // Airport tile override
4311 byte override = buf->ReadByte();
4313 /* The airport tile being overridden must be an original airport tile. */
4314 if (override >= NEW_AIRPORTTILE_OFFSET) {
4315 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
4316 continue;
4319 _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
4320 break;
4323 case 0x0E: // Callback mask
4324 tsp->callback_mask = buf->ReadByte();
4325 break;
4327 case 0x0F: // Animation information
4328 tsp->animation.frames = buf->ReadByte();
4329 tsp->animation.status = buf->ReadByte();
4330 break;
4332 case 0x10: // Animation speed
4333 tsp->animation.speed = buf->ReadByte();
4334 break;
4336 case 0x11: // Animation triggers
4337 tsp->animation.triggers = buf->ReadByte();
4338 break;
4340 default:
4341 ret = CIR_UNKNOWN;
4342 break;
4346 return ret;
4349 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4351 switch (cir) {
4352 default: NOT_REACHED();
4354 case CIR_DISABLED:
4355 /* Error has already been printed; just stop parsing */
4356 return true;
4358 case CIR_SUCCESS:
4359 return false;
4361 case CIR_UNHANDLED:
4362 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4363 return false;
4365 case CIR_UNKNOWN:
4366 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4367 /* FALL THROUGH */
4369 case CIR_INVALID_ID: {
4370 /* No debug message for an invalid ID, as it has already been output */
4371 GRFError *error = DisableCur (cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4372 if (cir != CIR_INVALID_ID) error->param_value[1] = property;
4373 return true;
4378 /* Action 0x00 */
4379 static int FeatureChangeInfo (ByteReader *buf)
4381 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4383 * B feature
4384 * B num-props how many properties to change per vehicle/station
4385 * B num-info how many vehicles/stations to change
4386 * E id ID of first vehicle/station to change, if num-info is
4387 * greater than one, this one and the following
4388 * vehicles/stations will be changed
4389 * B property what property to change, depends on the feature
4390 * V new-info new bytes of info (variable size; depends on properties) */
4392 static const VCI_Handler handler[] = {
4393 /* GSF_TRAINS */ RailVehicleChangeInfo,
4394 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4395 /* GSF_SHIPS */ ShipVehicleChangeInfo,
4396 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4397 /* GSF_STATIONS */ StationChangeInfo,
4398 /* GSF_CANALS */ CanalChangeInfo,
4399 /* GSF_BRIDGES */ BridgeChangeInfo,
4400 /* GSF_HOUSES */ TownHouseChangeInfo,
4401 /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4402 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4403 /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4404 /* GSF_CARGOES */ NULL, // Cargo is handled during reservation
4405 /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4406 /* GSF_AIRPORTS */ AirportChangeInfo,
4407 /* GSF_SIGNALS */ NULL,
4408 /* GSF_OBJECTS */ ObjectChangeInfo,
4409 /* GSF_RAILTYPES */ RailTypeChangeInfo,
4410 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4413 uint8 feature = buf->ReadByte();
4414 uint8 numprops = buf->ReadByte();
4415 uint numinfo = buf->ReadByte();
4416 uint engine = buf->ReadExtendedByte();
4418 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4419 feature, numprops, engine, numinfo);
4421 if (feature >= lengthof(handler) || handler[feature] == NULL) {
4422 if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
4423 return 0;
4426 /* Mark the feature as used by the grf */
4427 SetBit(_cur.grffile->grf_features, feature);
4429 while (numprops-- && buf->HasData()) {
4430 uint8 prop = buf->ReadByte();
4432 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4433 if (HandleChangeInfoResult ("FeatureChangeInfo", cir, feature, prop)) {
4434 return -1;
4438 return 0;
4441 /* Action 0x00 (GLS_SAFETYSCAN) */
4442 static int SafeChangeInfo (ByteReader *buf)
4444 uint8 feature = buf->ReadByte();
4445 uint8 numprops = buf->ReadByte();
4446 uint numinfo = buf->ReadByte();
4447 buf->ReadExtendedByte(); // id
4449 if (feature == GSF_BRIDGES && numprops == 1) {
4450 uint8 prop = buf->ReadByte();
4451 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4452 * is considered safe. */
4453 if (prop == 0x0D) return 0;
4454 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4455 uint8 prop = buf->ReadByte();
4456 /* Engine ID Mappings are safe, if the source is static */
4457 if (prop == 0x11) {
4458 bool is_safe = true;
4459 for (uint i = 0; i < numinfo; i++) {
4460 uint32 s = buf->ReadDWord();
4461 buf->ReadDWord(); // dest
4462 const GRFConfig *grfconfig = GetGRFConfig(s);
4463 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
4464 is_safe = false;
4465 break;
4468 if (is_safe) return 0;
4472 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4474 /* Skip remainder of GRF */
4475 return -1;
4478 /* Action 0x00 (GLS_RESERVE) */
4479 static int ReserveChangeInfo (ByteReader *buf)
4481 uint8 feature = buf->ReadByte();
4483 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return 0;
4485 uint8 numprops = buf->ReadByte();
4486 uint8 numinfo = buf->ReadByte();
4487 uint8 index = buf->ReadExtendedByte();
4489 while (numprops-- && buf->HasData()) {
4490 uint8 prop = buf->ReadByte();
4491 ChangeInfoResult cir = CIR_SUCCESS;
4493 switch (feature) {
4494 default: NOT_REACHED();
4495 case GSF_CARGOES:
4496 cir = CargoChangeInfo(index, numinfo, prop, buf);
4497 break;
4499 case GSF_GLOBALVAR:
4500 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4501 break;
4503 case GSF_RAILTYPES:
4504 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4505 break;
4508 if (HandleChangeInfoResult ("ReserveChangeInfo", cir, feature, prop)) {
4509 return -1;
4513 return 0;
4516 /* Action 0x01 */
4517 static int NewSpriteSet (ByteReader *buf)
4519 /* Basic format: <01> <feature> <num-sets> <num-ent>
4520 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4522 * B feature feature to define sprites for
4523 * 0, 1, 2, 3: veh-type, 4: train stations
4524 * E first-set first sprite set to define
4525 * B num-sets number of sprite sets (extended byte in extended format)
4526 * E num-ent how many entries per sprite set
4527 * For vehicles, this is the number of different
4528 * vehicle directions in each sprite set
4529 * Set num-dirs=8, unless your sprites are symmetric.
4530 * In that case, use num-dirs=4.
4533 uint8 feature = buf->ReadByte();
4534 uint16 num_sets = buf->ReadByte();
4535 uint16 first_set = 0;
4537 if (num_sets == 0 && buf->HasData(3)) {
4538 /* Extended Action1 format.
4539 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4540 first_set = buf->ReadExtendedByte();
4541 num_sets = buf->ReadExtendedByte();
4543 uint16 num_ents = buf->ReadExtendedByte();
4545 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4547 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4548 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4551 for (int i = 0; i < num_sets * num_ents; i++) {
4552 _cur.nfo_line++;
4553 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
4556 return 0;
4559 /* Action 0x01 (SKIP) */
4560 static int SkipAct1 (ByteReader *buf)
4562 buf->ReadByte();
4563 uint16 num_sets = buf->ReadByte();
4565 if (num_sets == 0 && buf->HasData(3)) {
4566 /* Extended Action1 format.
4567 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4568 buf->ReadExtendedByte(); // first_set
4569 num_sets = buf->ReadExtendedByte();
4571 uint16 num_ents = buf->ReadExtendedByte();
4573 int skip = num_sets * num_ents;
4574 grfmsg (3, "SkipAct1: Skipping %d sprites", skip);
4575 return skip;
4578 /* Helper function to either create a callback or link to a previously
4579 * defined spritegroup. */
4580 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4582 if (HasBit(groupid, 15)) {
4583 assert(CallbackResultSpriteGroup::CanAllocateItem());
4584 return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
4587 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4588 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4589 return NULL;
4592 return _cur.spritegroups[groupid];
4596 * Helper function to either create a callback or a result sprite group.
4597 * @param feature GrfSpecFeature to define spritegroup for.
4598 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4599 * @param type Type of the currently being parsed Action2. (only for debug output)
4600 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4601 * @return Created spritegroup.
4603 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4605 if (HasBit(spriteid, 15)) {
4606 assert(CallbackResultSpriteGroup::CanAllocateItem());
4607 return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
4610 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4611 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4612 return NULL;
4615 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4616 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4618 /* Ensure that the sprites are loeded */
4619 assert(spriteset_start + num_sprites <= _cur.spriteid);
4621 assert(ResultSpriteGroup::CanAllocateItem());
4622 return new ResultSpriteGroup(spriteset_start, num_sprites);
4625 /* Action 0x02 */
4626 static int NewSpriteGroup (ByteReader *buf)
4628 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4630 * B feature see action 1
4631 * B set-id ID of this particular definition
4632 * B type/num-entries
4633 * if 80 or greater, this is a randomized or variational
4634 * list definition, see below
4635 * otherwise it specifies a number of entries, the exact
4636 * meaning depends on the feature
4637 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4638 SpriteGroup *act_group = NULL;
4640 uint8 feature = buf->ReadByte();
4641 uint8 setid = buf->ReadByte();
4642 uint8 type = buf->ReadByte();
4644 /* Sprite Groups are created here but they are allocated from a pool, so
4645 * we do not need to delete anything if there is an exception from the
4646 * ByteReader. */
4648 switch (type) {
4649 /* Deterministic Sprite Group */
4650 case 0x81: // Self scope, byte
4651 case 0x82: // Parent scope, byte
4652 case 0x85: // Self scope, word
4653 case 0x86: // Parent scope, word
4654 case 0x89: // Self scope, dword
4655 case 0x8A: // Parent scope, dword
4657 byte varadjust;
4658 byte varsize;
4660 assert(DeterministicSpriteGroup::CanAllocateItem());
4661 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
4662 act_group = group;
4663 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4665 switch (GB(type, 2, 2)) {
4666 default: NOT_REACHED();
4667 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
4668 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
4669 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
4672 static SmallVector<DeterministicSpriteGroupAdjust, 16> adjusts;
4673 adjusts.Clear();
4675 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4676 * from the outset, so we shall have to keep reallocing. */
4677 do {
4678 DeterministicSpriteGroupAdjust *adjust = adjusts.Append();
4680 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4681 adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
4682 adjust->variable = buf->ReadByte();
4683 if (adjust->variable == 0x7E) {
4684 /* Link subroutine group */
4685 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
4686 } else {
4687 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
4690 varadjust = buf->ReadByte();
4691 adjust->shift_num = GB(varadjust, 0, 5);
4692 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
4693 adjust->and_mask = buf->ReadVarSize(varsize);
4695 if (adjust->type != DSGA_TYPE_NONE) {
4696 adjust->add_val = buf->ReadVarSize(varsize);
4697 adjust->divmod_val = buf->ReadVarSize(varsize);
4698 } else {
4699 adjust->add_val = 0;
4700 adjust->divmod_val = 0;
4703 /* Continue reading var adjusts while bit 5 is set. */
4704 } while (HasBit(varadjust, 5));
4706 group->num_adjusts = adjusts.Length();
4707 group->adjusts = xmemdupt (adjusts.Begin(), group->num_adjusts);
4709 group->num_ranges = buf->ReadByte();
4710 if (group->num_ranges > 0) group->ranges = xcalloct<DeterministicSpriteGroupRange>(group->num_ranges);
4712 for (uint i = 0; i < group->num_ranges; i++) {
4713 group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4714 group->ranges[i].low = buf->ReadVarSize(varsize);
4715 group->ranges[i].high = buf->ReadVarSize(varsize);
4718 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4719 break;
4722 /* Randomized Sprite Group */
4723 case 0x80: // Self scope
4724 case 0x83: // Parent scope
4725 case 0x84: // Relative scope
4727 assert(RandomizedSpriteGroup::CanAllocateItem());
4728 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
4729 act_group = group;
4730 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4732 if (HasBit(type, 2)) {
4733 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
4734 group->count = buf->ReadByte();
4737 uint8 triggers = buf->ReadByte();
4738 group->triggers = GB(triggers, 0, 7);
4739 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
4740 group->lowest_randbit = buf->ReadByte();
4741 group->num_groups = buf->ReadByte();
4742 group->groups = xcalloct<const SpriteGroup*>(group->num_groups);
4744 for (uint i = 0; i < group->num_groups; i++) {
4745 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
4748 break;
4751 /* Neither a variable or randomized sprite group... must be a real group */
4752 default:
4754 switch (feature) {
4755 case GSF_TRAINS:
4756 case GSF_ROADVEHICLES:
4757 case GSF_SHIPS:
4758 case GSF_AIRCRAFT:
4759 case GSF_STATIONS:
4760 case GSF_CANALS:
4761 case GSF_CARGOES:
4762 case GSF_AIRPORTS:
4763 case GSF_RAILTYPES:
4765 byte num_loaded = type;
4766 byte num_loading = buf->ReadByte();
4768 if (!_cur.HasValidSpriteSets(feature)) {
4769 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4770 return 0;
4773 assert(RealSpriteGroup::CanAllocateItem());
4774 RealSpriteGroup *group = new RealSpriteGroup();
4775 act_group = group;
4777 group->num_loaded = num_loaded;
4778 group->num_loading = num_loading;
4779 if (num_loaded > 0) group->loaded = xcalloct<const SpriteGroup*>(num_loaded);
4780 if (num_loading > 0) group->loading = xcalloct<const SpriteGroup*>(num_loading);
4782 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4783 setid, num_loaded, num_loading);
4785 for (uint i = 0; i < num_loaded; i++) {
4786 uint16 spriteid = buf->ReadWord();
4787 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4788 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
4791 for (uint i = 0; i < num_loading; i++) {
4792 uint16 spriteid = buf->ReadWord();
4793 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4794 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
4797 break;
4800 case GSF_HOUSES:
4801 case GSF_AIRPORTTILES:
4802 case GSF_OBJECTS:
4803 case GSF_INDUSTRYTILES: {
4804 byte num_building_sprites = max((uint8)1, type);
4806 assert(TileLayoutSpriteGroup::CanAllocateItem());
4807 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
4808 act_group = group;
4810 /* On error, bail out immediately. Temporary GRF data was already freed */
4811 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) {
4812 return -1;
4814 break;
4817 case GSF_INDUSTRIES: {
4818 if (type > 1) {
4819 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
4820 break;
4823 assert(IndustryProductionSpriteGroup::CanAllocateItem());
4824 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
4825 act_group = group;
4826 group->version = type;
4827 if (type == 0) {
4828 for (uint i = 0; i < 3; i++) {
4829 group->subtract_input[i] = (int16)buf->ReadWord(); // signed
4831 for (uint i = 0; i < 2; i++) {
4832 group->add_output[i] = buf->ReadWord(); // unsigned
4834 group->again = buf->ReadByte();
4835 } else {
4836 for (uint i = 0; i < 3; i++) {
4837 group->subtract_input[i] = buf->ReadByte();
4839 for (uint i = 0; i < 2; i++) {
4840 group->add_output[i] = buf->ReadByte();
4842 group->again = buf->ReadByte();
4844 break;
4847 /* Loading of Tile Layout and Production Callback groups would happen here */
4848 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
4853 _cur.spritegroups[setid] = act_group;
4855 return 0;
4858 static CargoID TranslateCargo (uint8 ctype)
4860 /* Special cargo type for purchase list */
4861 if (ctype == 0xFF) return CT_PURCHASE;
4863 if (_cur.grffile->cargo_list.Length() == 0) {
4864 /* No cargo table, so use bitnum values */
4865 if (ctype >= 32) {
4866 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
4867 return CT_INVALID;
4870 const CargoSpec *cs;
4871 FOR_ALL_CARGOSPECS(cs) {
4872 if (cs->bitnum == ctype) {
4873 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
4874 return cs->Index();
4878 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
4879 return CT_INVALID;
4882 /* Check if the cargo type is out of bounds of the cargo translation table */
4883 if (ctype >= _cur.grffile->cargo_list.Length()) {
4884 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1);
4885 return CT_INVALID;
4888 /* Look up the cargo label from the translation table */
4889 CargoLabel cl = _cur.grffile->cargo_list[ctype];
4890 if (cl == 0) {
4891 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
4892 return CT_INVALID;
4895 ctype = GetCargoIDByLabel(cl);
4896 if (ctype == CT_INVALID) {
4897 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));
4898 return CT_INVALID;
4901 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);
4902 return ctype;
4906 static bool IsValidGroupID(uint16 groupid, const char *function)
4908 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4909 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
4910 return false;
4913 return true;
4916 static bool VehicleMapSpriteGroup (ByteReader *buf, byte feature, uint8 idcount)
4918 static EngineID *last_engines;
4919 static uint last_engines_count;
4920 bool wagover = false;
4922 /* Test for 'wagon override' flag */
4923 if (HasBit(idcount, 7)) {
4924 wagover = true;
4925 /* Strip off the flag */
4926 idcount = GB(idcount, 0, 7);
4928 if (last_engines_count == 0) {
4929 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4930 return true;
4933 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4934 last_engines_count, idcount);
4935 } else {
4936 if (last_engines_count != idcount) {
4937 last_engines = xrealloct (last_engines, idcount);
4938 last_engines_count = idcount;
4942 EngineID *engines = AllocaM(EngineID, idcount);
4943 for (uint i = 0; i < idcount; i++) {
4944 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
4945 if (e == NULL) {
4946 /* No engine could be allocated?!? Deal with it. Okay,
4947 * this might look bad. Also make sure this NewGRF
4948 * gets disabled, as a half loaded one is bad. */
4949 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
4950 return false;
4953 engines[i] = e->index;
4954 if (!wagover) last_engines[i] = engines[i];
4957 uint8 cidcount = buf->ReadByte();
4958 for (uint c = 0; c < cidcount; c++) {
4959 uint8 ctype = buf->ReadByte();
4960 uint16 groupid = buf->ReadWord();
4961 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
4963 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
4965 ctype = TranslateCargo (ctype);
4966 if (ctype == CT_INVALID) continue;
4968 for (uint i = 0; i < idcount; i++) {
4969 EngineID engine = engines[i];
4971 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
4973 if (wagover) {
4974 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
4975 } else {
4976 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
4981 uint16 groupid = buf->ReadWord();
4982 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return true;
4984 grfmsg(8, "-- Default group id 0x%04X", groupid);
4986 for (uint i = 0; i < idcount; i++) {
4987 EngineID engine = engines[i];
4989 if (wagover) {
4990 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
4991 } else {
4992 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
4993 SetEngineGRF(engine, _cur.grffile);
4997 return true;
5001 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
5003 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
5004 for (uint i = 0; i < idcount; i++) {
5005 cfs[i] = (CanalFeature)buf->ReadByte();
5008 uint8 cidcount = buf->ReadByte();
5009 buf->Skip(cidcount * 3);
5011 uint16 groupid = buf->ReadWord();
5012 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
5014 for (uint i = 0; i < idcount; i++) {
5015 CanalFeature cf = cfs[i];
5017 if (cf >= CF_END) {
5018 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5019 continue;
5022 _water_feature[cf].grffile = _cur.grffile;
5023 _water_feature[cf].group = _cur.spritegroups[groupid];
5028 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
5030 uint8 *stations = AllocaM(uint8, idcount);
5031 for (uint i = 0; i < idcount; i++) {
5032 stations[i] = buf->ReadByte();
5035 uint8 cidcount = buf->ReadByte();
5036 for (uint c = 0; c < cidcount; c++) {
5037 uint8 ctype = buf->ReadByte();
5038 uint16 groupid = buf->ReadWord();
5039 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
5041 if (ctype == 0xFE) {
5042 ctype = CT_DEFAULT_NA;
5043 } else {
5044 ctype = TranslateCargo (ctype);
5045 if (ctype == CT_INVALID) continue;
5048 for (uint i = 0; i < idcount; i++) {
5049 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5051 if (statspec == NULL) {
5052 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5053 continue;
5056 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5060 uint16 groupid = buf->ReadWord();
5061 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
5063 for (uint i = 0; i < idcount; i++) {
5064 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5066 if (statspec == NULL) {
5067 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5068 continue;
5071 if (statspec->grf_prop.grffile != NULL) {
5072 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5073 continue;
5076 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
5077 statspec->grf_prop.grffile = _cur.grffile;
5078 statspec->grf_prop.local_id = stations[i];
5079 StationClass::Assign(statspec);
5084 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
5086 uint8 *houses = AllocaM(uint8, idcount);
5087 for (uint i = 0; i < idcount; i++) {
5088 houses[i] = buf->ReadByte();
5091 /* Skip the cargo type section, we only care about the default group */
5092 uint8 cidcount = buf->ReadByte();
5093 buf->Skip(cidcount * 3);
5095 uint16 groupid = buf->ReadWord();
5096 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
5098 if (_cur.grffile->housespec == NULL) {
5099 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5100 return;
5103 for (uint i = 0; i < idcount; i++) {
5104 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
5106 if (hs == NULL) {
5107 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5108 continue;
5111 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5115 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5117 uint8 *industries = AllocaM(uint8, idcount);
5118 for (uint i = 0; i < idcount; i++) {
5119 industries[i] = buf->ReadByte();
5122 /* Skip the cargo type section, we only care about the default group */
5123 uint8 cidcount = buf->ReadByte();
5124 buf->Skip(cidcount * 3);
5126 uint16 groupid = buf->ReadWord();
5127 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5129 if (_cur.grffile->industryspec == NULL) {
5130 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5131 return;
5134 for (uint i = 0; i < idcount; i++) {
5135 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5137 if (indsp == NULL) {
5138 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5139 continue;
5142 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5146 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5148 uint8 *indtiles = AllocaM(uint8, idcount);
5149 for (uint i = 0; i < idcount; i++) {
5150 indtiles[i] = buf->ReadByte();
5153 /* Skip the cargo type section, we only care about the default group */
5154 uint8 cidcount = buf->ReadByte();
5155 buf->Skip(cidcount * 3);
5157 uint16 groupid = buf->ReadWord();
5158 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5160 if (_cur.grffile->indtspec == NULL) {
5161 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5162 return;
5165 for (uint i = 0; i < idcount; i++) {
5166 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5168 if (indtsp == NULL) {
5169 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5170 continue;
5173 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5177 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5179 CargoID *cargoes = AllocaM(CargoID, idcount);
5180 for (uint i = 0; i < idcount; i++) {
5181 cargoes[i] = buf->ReadByte();
5184 /* Skip the cargo type section, we only care about the default group */
5185 uint8 cidcount = buf->ReadByte();
5186 buf->Skip(cidcount * 3);
5188 uint16 groupid = buf->ReadWord();
5189 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5191 for (uint i = 0; i < idcount; i++) {
5192 CargoID cid = cargoes[i];
5194 if (cid >= NUM_CARGO) {
5195 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5196 continue;
5199 CargoSpec *cs = CargoSpec::Get(cid);
5200 cs->grffile = _cur.grffile;
5201 cs->group = _cur.spritegroups[groupid];
5205 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5207 if (_cur.grffile->objectspec == NULL) {
5208 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5209 return;
5212 uint8 *objects = AllocaM(uint8, idcount);
5213 for (uint i = 0; i < idcount; i++) {
5214 objects[i] = buf->ReadByte();
5217 uint8 cidcount = buf->ReadByte();
5218 for (uint c = 0; c < cidcount; c++) {
5219 uint8 ctype = buf->ReadByte();
5220 uint16 groupid = buf->ReadWord();
5221 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5223 switch (ctype) {
5224 case 0: break;
5225 case 0xFF: ctype = CT_PURCHASE_OBJECT; break;
5226 default:
5227 grfmsg(1, "ObjectMapSpriteGroup: Invalid cargo bitnum %d for objects, skipping.", ctype);
5228 continue;
5231 for (uint i = 0; i < idcount; i++) {
5232 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5234 if (spec == NULL) {
5235 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5236 continue;
5239 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5243 uint16 groupid = buf->ReadWord();
5244 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5246 for (uint i = 0; i < idcount; i++) {
5247 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5249 if (spec == NULL) {
5250 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5251 continue;
5254 if (spec->grf_prop.grffile != NULL) {
5255 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5256 continue;
5259 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5260 spec->grf_prop.grffile = _cur.grffile;
5261 spec->grf_prop.local_id = objects[i];
5265 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5267 uint8 *railtypes = AllocaM(uint8, idcount);
5268 for (uint i = 0; i < idcount; i++) {
5269 railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
5272 uint8 cidcount = buf->ReadByte();
5273 for (uint c = 0; c < cidcount; c++) {
5274 uint8 ctype = buf->ReadByte();
5275 uint16 groupid = buf->ReadWord();
5276 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5278 if (ctype >= RTSG_END) continue;
5280 extern RailtypeInfo _railtypes[RAILTYPE_END];
5281 for (uint i = 0; i < idcount; i++) {
5282 if (railtypes[i] != INVALID_RAILTYPE) {
5283 RailtypeInfo *rti = &_railtypes[railtypes[i]];
5285 rti->grffile[ctype] = _cur.grffile;
5286 rti->group[ctype] = _cur.spritegroups[groupid];
5291 /* Railtypes do not use the default group. */
5292 buf->ReadWord();
5295 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5297 uint8 *airports = AllocaM(uint8, idcount);
5298 for (uint i = 0; i < idcount; i++) {
5299 airports[i] = buf->ReadByte();
5302 /* Skip the cargo type section, we only care about the default group */
5303 uint8 cidcount = buf->ReadByte();
5304 buf->Skip(cidcount * 3);
5306 uint16 groupid = buf->ReadWord();
5307 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5309 if (_cur.grffile->airportspec == NULL) {
5310 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5311 return;
5314 for (uint i = 0; i < idcount; i++) {
5315 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5317 if (as == NULL) {
5318 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5319 continue;
5322 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5326 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5328 uint8 *airptiles = AllocaM(uint8, idcount);
5329 for (uint i = 0; i < idcount; i++) {
5330 airptiles[i] = buf->ReadByte();
5333 /* Skip the cargo type section, we only care about the default group */
5334 uint8 cidcount = buf->ReadByte();
5335 buf->Skip(cidcount * 3);
5337 uint16 groupid = buf->ReadWord();
5338 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5340 if (_cur.grffile->airtspec == NULL) {
5341 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5342 return;
5345 for (uint i = 0; i < idcount; i++) {
5346 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5348 if (airtsp == NULL) {
5349 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5350 continue;
5353 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5358 /* Action 0x03 */
5359 static int FeatureMapSpriteGroup (ByteReader *buf)
5361 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5362 * id-list := [<id>] [id-list]
5363 * cargo-list := <cargo-type> <cid> [cargo-list]
5365 * B feature see action 0
5366 * B n-id bits 0-6: how many IDs this definition applies to
5367 * bit 7: if set, this is a wagon override definition (see below)
5368 * B ids the IDs for which this definition applies
5369 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5370 * can be zero, in that case the def-cid is used always
5371 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5372 * W cid cargo ID (sprite group ID) for this type of cargo
5373 * W def-cid default cargo ID (sprite group ID) */
5375 uint8 feature = buf->ReadByte();
5376 uint8 idcount = buf->ReadByte();
5378 /* If idcount is zero, this is a feature callback */
5379 if (idcount == 0) {
5380 /* Skip number of cargo ids? */
5381 buf->ReadByte();
5382 uint16 groupid = buf->ReadWord();
5383 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return 0;
5385 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
5387 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5388 return 0;
5391 /* Mark the feature as used by the grf (generic callbacks do not count) */
5392 SetBit(_cur.grffile->grf_features, feature);
5394 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
5396 switch (feature) {
5397 case GSF_TRAINS:
5398 case GSF_ROADVEHICLES:
5399 case GSF_SHIPS:
5400 case GSF_AIRCRAFT:
5401 return VehicleMapSpriteGroup (buf, feature, idcount) ? 0 : -1;
5403 case GSF_CANALS:
5404 CanalMapSpriteGroup(buf, idcount);
5405 return 0;
5407 case GSF_STATIONS:
5408 StationMapSpriteGroup(buf, idcount);
5409 return 0;
5411 case GSF_HOUSES:
5412 TownHouseMapSpriteGroup(buf, idcount);
5413 return 0;
5415 case GSF_INDUSTRIES:
5416 IndustryMapSpriteGroup(buf, idcount);
5417 return 0;
5419 case GSF_INDUSTRYTILES:
5420 IndustrytileMapSpriteGroup(buf, idcount);
5421 return 0;
5423 case GSF_CARGOES:
5424 CargoMapSpriteGroup(buf, idcount);
5425 return 0;
5427 case GSF_AIRPORTS:
5428 AirportMapSpriteGroup(buf, idcount);
5429 return 0;
5431 case GSF_OBJECTS:
5432 ObjectMapSpriteGroup(buf, idcount);
5433 return 0;
5435 case GSF_RAILTYPES:
5436 RailTypeMapSpriteGroup(buf, idcount);
5437 return 0;
5439 case GSF_AIRPORTTILES:
5440 AirportTileMapSpriteGroup(buf, idcount);
5441 return 0;
5443 default:
5444 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
5445 return 0;
5449 /* Action 0x04 */
5450 static int FeatureNewName (ByteReader *buf)
5452 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5454 * B veh-type see action 0 (as 00..07, + 0A
5455 * But IF veh-type = 48, then generic text
5456 * B language-id If bit 6 is set, This is the extended language scheme,
5457 * with up to 64 language.
5458 * Otherwise, it is a mapping where set bits have meaning
5459 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5460 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5461 * B num-veh number of vehicles which are getting a new name
5462 * B/W offset number of the first vehicle that gets a new name
5463 * Byte : ID of vehicle to change
5464 * Word : ID of string to change/add
5465 * S data new texts, each of them zero-terminated, after
5466 * which the next name begins. */
5468 bool new_scheme = _cur.grffile->grf_version >= 7;
5470 uint8 feature = buf->ReadByte();
5471 uint8 lang = buf->ReadByte();
5472 uint8 num = buf->ReadByte();
5473 bool generic = HasBit(lang, 7);
5474 uint16 id;
5475 if (generic) {
5476 id = buf->ReadWord();
5477 } else if (feature <= GSF_AIRCRAFT) {
5478 id = buf->ReadExtendedByte();
5479 } else {
5480 id = buf->ReadByte();
5483 ClrBit(lang, 7);
5485 uint16 endid = id + num;
5487 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5488 id, endid, feature, lang);
5490 for (; id < endid && buf->HasData(); id++) {
5491 const char *name = buf->ReadString();
5492 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5494 switch (feature) {
5495 case GSF_TRAINS:
5496 case GSF_ROADVEHICLES:
5497 case GSF_SHIPS:
5498 case GSF_AIRCRAFT:
5499 if (!generic) {
5500 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
5501 if (e == NULL) break;
5502 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
5503 e->info.string_id = string;
5504 } else {
5505 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5507 break;
5509 case GSF_INDUSTRIES: {
5510 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5511 break;
5514 case GSF_HOUSES:
5515 default:
5516 switch (GB(id, 8, 8)) {
5517 case 0xC4: // Station class name
5518 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5519 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5520 } else {
5521 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
5522 StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5524 break;
5526 case 0xC5: // Station name
5527 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5528 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5529 } else {
5530 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5532 break;
5534 case 0xC7: // Airporttile name
5535 if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
5536 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
5537 } else {
5538 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5540 break;
5542 case 0xC9: // House name
5543 if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
5544 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
5545 } else {
5546 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5548 break;
5550 case 0xD0:
5551 case 0xD1:
5552 case 0xD2:
5553 case 0xD3:
5554 case 0xDC:
5555 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5556 break;
5558 default:
5559 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
5560 break;
5562 break;
5566 return 0;
5570 struct SpritePair {
5571 SpriteID old, spr;
5574 /* Shore sprite replacements for single-corner and inclined slopes. */
5575 static const SpritePair shore_sprites_1 [] = {
5576 { SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1 }, // SLOPE_W
5577 { SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2 }, // SLOPE_S
5578 { SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3 }, // SLOPE_SW
5579 { SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4 }, // SLOPE_E
5580 { SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6 }, // SLOPE_SE
5581 { SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8 }, // SLOPE_N
5582 { SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9 }, // SLOPE_NW
5583 { SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12 }, // SLOPE_NE
5586 /* Shore sprite replacements for three-corner and steep slopes. */
5587 static const SpritePair shore_sprites_2 [] = {
5588 { SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0 }, // SLOPE_STEEP_S
5589 { SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5 }, // SLOPE_STEEP_W
5590 { SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7 }, // SLOPE_WSE
5591 { SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10 }, // SLOPE_STEEP_N
5592 { SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11 }, // SLOPE_NWS
5593 { SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13 }, // SLOPE_ENW
5594 { SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14 }, // SLOPE_SEN
5595 { SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15 }, // SLOPE_STEEP_E
5596 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
5597 * If they would be used somewhen, then these grass tiles will most like not look as needed */
5598 { SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16 }, // SLOPE_EW
5599 { SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17 }, // SLOPE_NS
5603 /** The type of action 5 type. */
5604 enum Action5BlockType {
5605 A5BLOCK_FIXED, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5606 A5BLOCK_ALLOW_OFFSET, ///< Allow replacing any subset by specifiing an offset.
5607 A5BLOCK_INVALID, ///< unknown/not-implemented type
5609 /** Information about a single action 5 type. */
5610 struct Action5Type {
5611 Action5BlockType block_type; ///< How is this Action5 type processed?
5612 SpriteID sprite_base; ///< Load the sprites starting from this sprite.
5613 uint16 min_sprites; ///< If the Action5 contains less sprites, the whole block will be ignored.
5614 uint16 max_sprites; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5615 const char *name; ///< Name for error messages.
5618 /** The information about action 5 types. */
5619 static const Action5Type _action5_types[] = {
5620 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5621 /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
5622 /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
5623 /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
5624 /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
5625 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
5626 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Rail catenary graphics" },
5627 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
5628 /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5629 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
5630 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
5631 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
5632 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
5633 /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5634 /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
5635 /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5636 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
5637 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
5638 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
5639 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
5640 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
5641 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
5642 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
5643 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
5644 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
5645 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET, SPR_PALETTE_BASE, 1, PALETTE_SPRITE_COUNT, "Palette" },
5648 /* Action 0x05 */
5649 static int GraphicsNew (ByteReader *buf)
5651 /* <05> <graphics-type> <num-sprites> <other data...>
5653 * B graphics-type What set of graphics the sprites define.
5654 * E num-sprites How many sprites are in this set?
5655 * V other data Graphics type specific data. Currently unused. */
5656 /* TODO */
5658 uint8 type = buf->ReadByte();
5659 uint16 num = buf->ReadExtendedByte();
5660 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
5661 ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
5663 if ((type == 0x0D) && (num == 10) && HasBit(_cur.grfconfig->flags, GCF_SYSTEM)) {
5664 /* Special not-TTDP-compatible case used in openttd.grf
5665 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5666 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5667 for (uint i = 0; i < lengthof(shore_sprites_2); i++) {
5668 LoadNextSprite (shore_sprites_2[i].spr, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver);
5670 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
5671 return 0;
5674 /* Supported type? */
5675 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
5676 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
5677 return num;
5680 const Action5Type *action5_type = &_action5_types[type];
5682 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5683 * except for the long version of the shore type:
5684 * Ignore offset if not allowed */
5685 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
5686 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
5687 offset = 0;
5690 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5691 * This does not make sense, if <offset> is allowed */
5692 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
5693 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);
5694 return num;
5697 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5698 uint16 skip_num;
5699 if (offset >= action5_type->max_sprites) {
5700 grfmsg (1, "GraphicsNew: %s sprite offset must be less than %i, skipping", action5_type->name, action5_type->max_sprites);
5701 skip_num = num;
5702 num = 0;
5703 } else if (offset + num > action5_type->max_sprites) {
5704 grfmsg (4, "GraphicsNew: %s sprite overflow, truncating...", action5_type->name);
5705 uint rem = action5_type->max_sprites - offset;
5706 skip_num = num - rem;
5707 num = rem;
5708 } else {
5709 skip_num = 0;
5711 SpriteID replace = action5_type->sprite_base + offset;
5713 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5714 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);
5716 for (; num > 0; num--) {
5717 _cur.nfo_line++;
5718 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
5721 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
5723 return skip_num;
5726 /* Action 0x05 (SKIP) */
5727 static int SkipAct5 (ByteReader *buf)
5729 /* Ignore type byte */
5730 buf->ReadByte();
5732 /* Skip the sprites of this action */
5733 int skip = buf->ReadExtendedByte();
5734 grfmsg (3, "SkipAct5: Skipping %d sprites", skip);
5735 return skip;
5739 * Check whether we are (obviously) missing some of the extra
5740 * (Action 0x05) sprites that we like to use.
5741 * When missing sprites are found a warning will be shown.
5743 void CheckForMissingSprites()
5745 /* Don't break out quickly, but allow to check the other
5746 * sprites as well, so we can give the best information. */
5747 bool missing = false;
5748 for (uint8 i = 0; i < lengthof(_action5_types); i++) {
5749 const Action5Type *type = &_action5_types[i];
5750 if (type->block_type == A5BLOCK_INVALID) continue;
5752 for (uint j = 0; j < type->max_sprites; j++) {
5753 if (!SpriteExists(type->sprite_base + j)) {
5754 DEBUG(grf, 0, "%s sprites are missing", type->name);
5755 missing = true;
5756 /* No need to log more of the same. */
5757 break;
5762 if (missing) {
5763 ShowErrorMessage(IsReleasedVersion() ? STR_NEWGRF_ERROR_MISSING_SPRITES : STR_NEWGRF_ERROR_MISSING_SPRITES_UNSTABLE, INVALID_STRING_ID, WL_CRITICAL);
5768 * Reads a variable common to VarAction2 and Action7/9/D.
5770 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5771 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5773 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5774 * @param value returns the value of the variable.
5775 * @param grffile NewGRF querying the variable
5776 * @return true iff the variable is known and the value is returned in 'value'.
5778 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
5780 switch (param) {
5781 case 0x00: // current date
5782 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
5783 return true;
5785 case 0x01: // current year
5786 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
5787 return true;
5789 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)
5790 YearMonthDay ymd;
5791 ConvertDateToYMD(_date, &ymd);
5792 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
5793 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
5794 return true;
5797 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5798 *value = _settings_game.game_creation.landscape;
5799 return true;
5801 case 0x06: // road traffic side, bit 4 clear=left, set=right
5802 *value = _settings_game.vehicle.road_side << 4;
5803 return true;
5805 case 0x09: // date fraction
5806 *value = _date_fract * 885;
5807 return true;
5809 case 0x0A: // animation counter
5810 *value = _tick_counter;
5811 return true;
5813 case 0x0B: { // TTDPatch version
5814 uint major = 2;
5815 uint minor = 6;
5816 uint revision = 1; // special case: 2.0.1 is 2.0.10
5817 uint build = 1382;
5818 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
5819 return true;
5822 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5823 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
5824 return true;
5826 case 0x0E: // Y-offset for train sprites
5827 *value = _cur.grffile->traininfo_vehicle_pitch;
5828 return true;
5830 case 0x0F: // Rail track type cost factors
5831 *value = 0;
5832 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
5833 if (_settings_game.vehicle.disable_elrails) {
5834 /* skip elrail multiplier - disabled */
5835 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
5836 } else {
5837 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
5838 /* Skip monorail multiplier - no space in result */
5840 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
5841 return true;
5843 case 0x11: // current rail tool type
5844 *value = 0; // constant fake value to avoid desync
5845 return true;
5847 case 0x12: // Game mode
5848 *value = _game_mode;
5849 return true;
5851 /* case 0x13: // Tile refresh offset to left not implemented */
5852 /* case 0x14: // Tile refresh offset to right not implemented */
5853 /* case 0x15: // Tile refresh offset upwards not implemented */
5854 /* case 0x16: // Tile refresh offset downwards not implemented */
5855 /* case 0x17: // temperate snow line not implemented */
5857 case 0x1A: // Always -1
5858 *value = UINT_MAX;
5859 return true;
5861 case 0x1B: // Display options
5862 *value = 0x3F; // constant fake value to avoid desync
5863 return true;
5865 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5866 *value = 1;
5867 return true;
5869 case 0x1E: // Miscellaneous GRF features
5870 *value = _misc_grf_features;
5872 /* Add the local flags */
5873 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
5874 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
5875 return true;
5877 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5879 case 0x20: { // snow line height
5880 byte snowline = GetSnowLine();
5881 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= _settings_game.construction.max_heightlevel) {
5882 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
5883 } else {
5884 /* No snow */
5885 *value = 0xFF;
5887 return true;
5890 case 0x21: // OpenTTD version
5891 *value = _openttd_newgrf_version;
5892 return true;
5894 case 0x22: // difficulty level
5895 *value = SP_CUSTOM;
5896 return true;
5898 case 0x23: // long format date
5899 *value = _date;
5900 return true;
5902 case 0x24: // long format year
5903 *value = _cur_year;
5904 return true;
5906 default: return false;
5910 static uint32 GetParamVal(byte param, uint32 *cond_val)
5912 /* First handle variable common with VarAction2 */
5913 uint32 value;
5914 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
5916 /* Non-common variable */
5917 switch (param) {
5918 case 0x84: { // GRF loading stage
5919 uint32 res = 0;
5921 if (_cur.stage > GLS_INIT) SetBit(res, 0);
5922 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
5923 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
5924 return res;
5927 case 0x85: // TTDPatch flags, only for bit tests
5928 if (cond_val == NULL) {
5929 /* Supported in Action 0x07 and 0x09, not 0x0D */
5930 return 0;
5931 } else {
5932 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
5933 *cond_val %= 0x20;
5934 return param_val;
5937 case 0x88: // GRF ID check
5938 return 0;
5940 /* case 0x99: Global ID offset not implemented */
5942 default:
5943 /* GRF Parameter */
5944 if (param < 0x80) return _cur.grffile->GetParam(param);
5946 /* In-game variable. */
5947 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
5948 return UINT_MAX;
5952 /* Action 0x06 */
5953 static int CfgApply (ByteReader *buf)
5955 /* <06> <param-num> <param-size> <offset> ... <FF>
5957 * B param-num Number of parameter to substitute (First = "zero")
5958 * Ignored if that parameter was not specified in newgrf.cfg
5959 * B param-size How many bytes to replace. If larger than 4, the
5960 * bytes of the following parameter are used. In that
5961 * case, nothing is applied unless *all* parameters
5962 * were specified.
5963 * B offset Offset into data from beginning of next sprite
5964 * to place where parameter is to be stored. */
5966 /* Preload the next sprite */
5967 size_t pos = FioGetPos();
5968 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
5969 uint8 type = FioReadByte();
5971 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5972 if (type != 0xFF) {
5973 /* Reset the file position to the start of the next sprite */
5974 FioSeekTo(pos, SEEK_SET);
5976 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5977 return 0;
5980 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
5981 std::pair <GRFLineToSpriteOverride::iterator, bool> ins =
5982 _grf_line_to_action6_sprite_override.insert (std::make_pair (location, ttd_unique_free_ptr<byte>()));
5984 byte *preload_sprite;
5985 if (ins.second) {
5986 preload_sprite = xmalloct<byte> (num);
5987 ins.first->second.reset (preload_sprite);
5988 FioReadBlock (preload_sprite, num);
5989 } else {
5990 preload_sprite = ins.first->second.get();
5993 /* Reset the file position to the start of the next sprite */
5994 FioSeekTo (pos, SEEK_SET);
5996 /* Now perform the Action 0x06 on our data. */
5998 for (;;) {
5999 uint i;
6000 uint param_num;
6001 uint param_size;
6002 uint offset;
6003 bool add_value;
6005 /* Read the parameter to apply. 0xFF indicates no more data to change. */
6006 param_num = buf->ReadByte();
6007 if (param_num == 0xFF) break;
6009 /* Get the size of the parameter to use. If the size covers multiple
6010 * double words, sequential parameter values are used. */
6011 param_size = buf->ReadByte();
6013 /* Bit 7 of param_size indicates we should add to the original value
6014 * instead of replacing it. */
6015 add_value = HasBit(param_size, 7);
6016 param_size = GB(param_size, 0, 7);
6018 /* Where to apply the data to within the pseudo sprite data. */
6019 offset = buf->ReadExtendedByte();
6021 /* If the parameter is a GRF parameter (not an internal variable) check
6022 * if it (and all further sequential parameters) has been defined. */
6023 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
6024 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6025 break;
6028 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6030 bool carry = false;
6031 for (i = 0; i < param_size && offset + i < num; i++) {
6032 uint32 value = GetParamVal(param_num + i / 4, NULL);
6033 /* Reset carry flag for each iteration of the variable (only really
6034 * matters if param_size is greater than 4) */
6035 if (i % 4 == 0) carry = false;
6037 if (add_value) {
6038 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6039 preload_sprite[offset + i] = GB(new_value, 0, 8);
6040 /* Check if the addition overflowed */
6041 carry = new_value >= 256;
6042 } else {
6043 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
6048 return 0;
6052 * Disable a static NewGRF when it is influencing another (non-static)
6053 * NewGRF as this could cause desyncs.
6055 * We could just tell the NewGRF querying that the file doesn't exist,
6056 * but that might give unwanted results. Disabling the NewGRF gives the
6057 * best result as no NewGRF author can complain about that.
6058 * @param c The NewGRF to disable.
6060 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
6062 DisableGrf (STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
6065 /* Action 0x07
6066 * Action 0x09 */
6067 static int SkipIf (ByteReader *buf)
6069 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6071 * B param-num
6072 * B param-size
6073 * B condition-type
6074 * V value
6075 * B num-sprites */
6076 /* TODO: More params. More condition types. */
6077 uint32 cond_val = 0;
6078 uint32 mask = 0;
6079 bool result;
6081 uint8 param = buf->ReadByte();
6082 uint8 paramsize = buf->ReadByte();
6083 uint8 condtype = buf->ReadByte();
6085 if (condtype < 2) {
6086 /* Always 1 for bit tests, the given value should be ignored. */
6087 paramsize = 1;
6090 switch (paramsize) {
6091 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6092 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6093 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6094 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6095 default: break;
6098 if (param < 0x80 && _cur.grffile->param_end <= param) {
6099 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6100 return 0;
6103 uint32 param_val = GetParamVal(param, &cond_val);
6105 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
6108 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6109 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6110 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6111 * So, when the condition type is one of those, the specific variable
6112 * 0x88 code is skipped, so the "general" code for the cargo
6113 * availability conditions kicks in.
6115 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
6116 /* GRF ID checks */
6118 GRFConfig *c = GetGRFConfig(cond_val, mask);
6120 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6121 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6122 c = NULL;
6125 if (condtype != 10 && c == NULL) {
6126 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6127 return 0;
6130 switch (condtype) {
6131 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6132 case 0x06: // Is GRFID active?
6133 result = c->status == GCS_ACTIVATED;
6134 break;
6136 case 0x07: // Is GRFID non-active?
6137 result = c->status != GCS_ACTIVATED;
6138 break;
6140 case 0x08: // GRFID is not but will be active?
6141 result = c->status == GCS_INITIALISED;
6142 break;
6144 case 0x09: // GRFID is or will be active?
6145 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6146 break;
6148 case 0x0A: // GRFID is not nor will be active
6149 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6150 result = c == NULL || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6151 break;
6153 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return 0;
6155 } else {
6156 /* Parameter or variable tests */
6157 switch (condtype) {
6158 case 0x00: result = !!(param_val & (1 << cond_val));
6159 break;
6160 case 0x01: result = !(param_val & (1 << cond_val));
6161 break;
6162 case 0x02: result = (param_val & mask) == cond_val;
6163 break;
6164 case 0x03: result = (param_val & mask) != cond_val;
6165 break;
6166 case 0x04: result = (param_val & mask) < cond_val;
6167 break;
6168 case 0x05: result = (param_val & mask) > cond_val;
6169 break;
6170 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6171 break;
6172 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6173 break;
6174 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6175 break;
6176 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6177 break;
6179 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return 0;
6183 if (!result) {
6184 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6185 return 0;
6188 uint8 numsprites = buf->ReadByte();
6190 /* numsprites can be a GOTO label if it has been defined in the GRF
6191 * file. The jump will always be the first matching label that follows
6192 * the current nfo_line. If no matching label is found, the first matching
6193 * label in the file is used. */
6194 GRFLabel *choice = NULL;
6195 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
6196 if (label->label != numsprites) continue;
6198 /* Remember a goto before the current line */
6199 if (choice == NULL) choice = label;
6200 /* If we find a label here, this is definitely good */
6201 if (label->nfo_line > _cur.nfo_line) {
6202 choice = label;
6203 break;
6207 if (choice != NULL) {
6208 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6209 FioSeekTo(choice->pos, SEEK_SET);
6210 _cur.nfo_line = choice->nfo_line;
6211 return 0;
6214 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6216 if (numsprites != 0) return numsprites;
6218 /* If an action 8 hasn't been encountered yet, disable the grf. */
6219 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6220 DisableCur();
6223 /* Zero means there are no sprites to skip, so we use -1 to indicate
6224 * that all further sprites should be skipped. */
6225 return -1;
6229 /* Action 0x08 (GLS_FILESCAN) */
6230 static int ScanInfo (ByteReader *buf)
6232 uint8 grf_version = buf->ReadByte();
6233 uint32 grfid = buf->ReadDWord();
6234 const char *name = buf->ReadString();
6236 _cur.grfconfig->ident.grfid = grfid;
6238 if (grf_version < 2 || grf_version > 8) {
6239 SetBit(_cur.grfconfig->flags, GCF_INVALID);
6240 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);
6243 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6244 if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6246 _cur.grfconfig->name->add (0x7F, grfid, false, name);
6248 if (buf->HasData()) {
6249 const char *info = buf->ReadString();
6250 _cur.grfconfig->info->add (0x7F, grfid, true, info);
6253 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6254 return -1;
6257 /* Action 0x08 */
6258 static int GRFInfo (ByteReader *buf)
6260 /* <08> <version> <grf-id> <name> <info>
6262 * B version newgrf version, currently 06
6263 * 4*B grf-id globally unique ID of this .grf file
6264 * S name name of this .grf set
6265 * S info string describing the set, and e.g. author and copyright */
6267 uint8 version = buf->ReadByte();
6268 uint32 grfid = buf->ReadDWord();
6269 const char *name = buf->ReadString();
6271 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6272 DisableCur (STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6273 return -1;
6276 if (_cur.grffile->grfid != grfid) {
6277 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));
6278 _cur.grffile->grfid = grfid;
6281 _cur.grffile->grf_version = version;
6282 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6284 /* Do swap the GRFID for displaying purposes since people expect that */
6285 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);
6287 return 0;
6290 /* Action 0x0A */
6291 static int SpriteReplace (ByteReader *buf)
6293 /* <0A> <num-sets> <set1> [<set2> ...]
6294 * <set>: <num-sprites> <first-sprite>
6296 * B num-sets How many sets of sprites to replace.
6297 * Each set:
6298 * B num-sprites How many sprites are in this set
6299 * W first-sprite First sprite number to replace */
6301 uint8 num_sets = buf->ReadByte();
6303 for (uint i = 0; i < num_sets; i++) {
6304 uint8 num_sprites = buf->ReadByte();
6305 uint16 first_sprite = buf->ReadWord();
6307 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6308 i, num_sprites, first_sprite
6311 for (uint j = 0; j < num_sprites; j++) {
6312 int load_index = first_sprite + j;
6313 _cur.nfo_line++;
6314 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6316 /* Shore sprites now located at different addresses.
6317 * So detect when the old ones get replaced. */
6318 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6319 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
6324 return 0;
6327 /* Action 0x0A (SKIP) */
6328 static int SkipActA (ByteReader *buf)
6330 uint8 num_sets = buf->ReadByte();
6332 int skip = 0;
6333 for (uint i = 0; i < num_sets; i++) {
6334 /* Skip the sprites this replaces */
6335 skip += buf->ReadByte();
6336 /* But ignore where they go */
6337 buf->ReadWord();
6340 grfmsg (3, "SkipActA: Skipping %d sprites", skip);
6342 return skip;
6345 /* Action 0x0B */
6346 static int GRFLoadError (ByteReader *buf)
6348 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6350 * B severity 00: notice, contine loading grf file
6351 * 01: warning, continue loading grf file
6352 * 02: error, but continue loading grf file, and attempt
6353 * loading grf again when loading or starting next game
6354 * 03: error, abort loading and prevent loading again in
6355 * the future (only when restarting the patch)
6356 * B language-id see action 4, use 1F for built-in error messages
6357 * B message-id message to show, see below
6358 * S message for custom messages (message-id FF), text of the message
6359 * not present for built-in messages.
6360 * V data additional data for built-in (or custom) messages
6361 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6363 static const StringID msgstr[] = {
6364 STR_NEWGRF_ERROR_VERSION_NUMBER,
6365 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6366 STR_NEWGRF_ERROR_UNSET_SWITCH,
6367 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6368 STR_NEWGRF_ERROR_LOAD_BEFORE,
6369 STR_NEWGRF_ERROR_LOAD_AFTER,
6370 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6373 static const StringID sevstr[] = {
6374 STR_NEWGRF_ERROR_MSG_INFO,
6375 STR_NEWGRF_ERROR_MSG_WARNING,
6376 STR_NEWGRF_ERROR_MSG_ERROR,
6377 STR_NEWGRF_ERROR_MSG_FATAL
6380 byte severity = buf->ReadByte();
6381 byte lang = buf->ReadByte();
6382 byte message_id = buf->ReadByte();
6384 /* Skip the error if it isn't valid for the current language. */
6385 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return 0;
6387 /* Skip the error until the activation stage unless bit 7 of the severity
6388 * is set. */
6389 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6390 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6391 return 0;
6393 ClrBit(severity, 7);
6395 if (severity >= lengthof(sevstr)) {
6396 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6397 severity = 2;
6398 } else if (severity == 3) {
6399 /* This is a fatal error, so make sure the GRF is deactivated and no
6400 * more of it gets loaded. */
6401 DisableCur();
6403 /* Make sure we show fatal errors, instead of silly infos from before */
6404 delete _cur.grfconfig->error;
6405 _cur.grfconfig->error = NULL;
6408 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6409 grfmsg(7, "GRFLoadError: Invalid message id.");
6411 } else if (!buf->HasData (2)) {
6412 grfmsg(7, "GRFLoadError: No message data supplied.");
6414 } else if (_cur.grfconfig->error == NULL) {
6415 /* For now we can only show one message per newgrf file. */
6416 GRFError *error = new GRFError (sevstr[severity]);
6418 if (message_id != 0xFF) {
6419 error->message = msgstr[message_id];
6420 } else if (buf->HasData()) {
6421 /* This is a custom error message. */
6422 const char *message = buf->ReadString();
6423 error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, NULL, SCC_RAW_STRING_POINTER);
6424 } else {
6425 grfmsg(7, "GRFLoadError: No custom message supplied.");
6426 error->custom_message = xstrdup("");
6429 if (buf->HasData()) {
6430 const char *data = buf->ReadString();
6431 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6432 } else {
6433 grfmsg(7, "GRFLoadError: No message data supplied.");
6434 error->data = xstrdup("");
6437 /* Only two parameter numbers can be used in the string. */
6438 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6439 uint param_number = buf->ReadByte();
6440 error->param_value[i] = _cur.grffile->GetParam(param_number);
6443 _cur.grfconfig->error = error;
6446 return (severity == 3) ? -1 : 0;
6449 /* Action 0x0C */
6450 static int GRFComment (ByteReader *buf)
6452 /* <0C> [<ignored...>]
6454 * V ignored Anything following the 0C is ignored */
6456 if (buf->HasData()) grfmsg (2, "GRFComment: %s", buf->ReadString());
6458 return 0;
6461 /* Action 0x0D (GLS_SAFETYSCAN) */
6462 static int SafeParamSet (ByteReader *buf)
6464 uint8 target = buf->ReadByte();
6466 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6467 if (target < 0x80 || target == 0x9E) return 0;
6469 /* GRM could be unsafe, but as here it can only happen after other GRFs
6470 * are loaded, it should be okay. If the GRF tried to use the slots it
6471 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6472 * sprites is considered safe. */
6474 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6476 /* Skip remainder of GRF */
6477 return -1;
6481 static uint32 GetPatchVariable(uint8 param)
6483 switch (param) {
6484 /* start year - 1920 */
6485 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
6487 /* freight trains weight factor */
6488 case 0x0E: return _settings_game.vehicle.freight_trains;
6490 /* empty wagon speed increase */
6491 case 0x0F: return 0;
6493 /* plane speed factor; our patch option is reversed from TTDPatch's,
6494 * the following is good for 1x, 2x and 4x (most common?) and...
6495 * well not really for 3x. */
6496 case 0x10:
6497 switch (_settings_game.vehicle.plane_speed) {
6498 default:
6499 case 4: return 1;
6500 case 3: return 2;
6501 case 2: return 2;
6502 case 1: return 4;
6506 /* 2CC colourmap base sprite */
6507 case 0x11: return SPR_2CCMAP_BASE;
6509 /* map size: format = -MABXYSS
6510 * M : the type of map
6511 * bit 0 : set : squared map. Bit 1 is now not relevant
6512 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6513 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6514 * clear : X is the bigger edge.
6515 * A : minimum edge(log2) of the map
6516 * B : maximum edge(log2) of the map
6517 * XY : edges(log2) of each side of the map.
6518 * SS : combination of both X and Y, thus giving the size(log2) of the map
6520 case 0x13: {
6521 byte map_bits = 0;
6522 byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6523 byte log_Y = MapLogY() - 6;
6524 byte max_edge = max(log_X, log_Y);
6526 if (log_X == log_Y) { // we have a squared map, since both edges are identical
6527 SetBit(map_bits, 0);
6528 } else {
6529 if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
6532 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
6533 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
6536 /* The maximum height of the map. */
6537 case 0x14:
6538 return _settings_game.construction.max_heightlevel;
6540 /* Extra foundations base sprite */
6541 case 0x15:
6542 return SPR_SLOPES_BASE;
6544 /* Shore base sprite */
6545 case 0x16:
6546 return SPR_SHORE_BASE;
6548 default:
6549 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
6550 return 0;
6555 static bool PerformGRM (uint32 *grm, uint16 num_ids, uint16 count,
6556 uint8 op, uint8 target, uint32 *res, const char *type)
6558 uint start = 0;
6559 uint size = 0;
6561 if (op == 6) {
6562 /* Return GRFID of set that reserved ID */
6563 *res = grm[_cur.grffile->GetParam(target)];
6564 return true;
6567 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6568 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
6570 for (uint i = start; i < num_ids; i++) {
6571 if (grm[i] == 0) {
6572 size++;
6573 } else {
6574 if (op == 2 || op == 3) break;
6575 start = i + 1;
6576 size = 0;
6579 if (size == count) break;
6582 if (size == count) {
6583 /* Got the slot... */
6584 if (op == 0 || op == 3) {
6585 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
6586 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
6588 *res = start;
6589 return true;
6592 /* Unable to allocate */
6593 if (op != 4 && op != 5) {
6594 /* Deactivate GRF */
6595 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
6596 DisableCur (STR_NEWGRF_ERROR_GRM_FAILED);
6597 return false;
6600 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
6601 *res = UINT_MAX;
6602 return true;
6606 /** Action 0x0D: Set parameter */
6607 static int ParamSet (ByteReader *buf)
6609 /* <0D> <target> <operation> <source1> <source2> [<data>]
6611 * B target parameter number where result is stored
6612 * B operation operation to perform, see below
6613 * B source1 first source operand
6614 * B source2 second source operand
6615 * D data data to use in the calculation, not necessary
6616 * if both source1 and source2 refer to actual parameters
6618 * Operations
6619 * 00 Set parameter equal to source1
6620 * 01 Addition, source1 + source2
6621 * 02 Subtraction, source1 - source2
6622 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6623 * 04 Signed multiplication, source1 * source2 (both signed)
6624 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6625 * signed quantity; left shift if positive and right shift if
6626 * negative, source1 is unsigned)
6627 * 06 Signed bit shift, source1 by source2
6628 * (source2 like in 05, and source1 as well)
6631 uint8 target = buf->ReadByte();
6632 uint8 oper = buf->ReadByte();
6633 uint32 src1 = buf->ReadByte();
6634 uint32 src2 = buf->ReadByte();
6636 uint32 data = 0;
6637 if (buf->HasData (4)) data = buf->ReadDWord();
6639 /* You can add 80 to the operation to make it apply only if the target
6640 * is not defined yet. In this respect, a parameter is taken to be
6641 * defined if any of the following applies:
6642 * - it has been set to any value in the newgrf(w).cfg parameter list
6643 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6644 * an earlier action D */
6645 if (HasBit(oper, 7)) {
6646 if (target < 0x80 && target < _cur.grffile->param_end) {
6647 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
6648 return 0;
6651 oper = GB(oper, 0, 7);
6654 if (src2 != 0xFE) {
6655 /* The source1 and source2 operands refer to the grf parameter number
6656 * like in action 6 and 7. In addition, they can refer to the special
6657 * variables available in action 7, or they can be FF to use the value
6658 * of <data>. If referring to parameters that are undefined, a value
6659 * of 0 is used instead. */
6660 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
6661 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
6662 } else if (GB(data, 0, 8) != 0xFF) {
6663 /* Read another GRF File's parameter */
6664 const GRFFile *file = GetFileByGRFID(data);
6665 GRFConfig *c = GetGRFConfig(data);
6666 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6667 /* Disable the read GRF if it is a static NewGRF. */
6668 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6669 src1 = 0;
6670 } else if (file == NULL || c == NULL || c->status == GCS_DISABLED) {
6671 src1 = 0;
6672 } else if (src1 == 0xFE) {
6673 src1 = c->version;
6674 } else {
6675 src1 = file->GetParam(src1);
6677 } else if (data == 0x0000FFFF) {
6678 /* Patch variables */
6679 src1 = GetPatchVariable(src1);
6680 } else {
6681 /* GRF Resource Management */
6682 uint8 op = src1;
6683 uint8 feature = GB(data, 8, 8);
6684 uint16 count = GB(data, 16, 16);
6686 if (_cur.stage == GLS_RESERVE) {
6687 if (feature == 0x08) {
6688 /* General sprites */
6689 if (op == 0) {
6690 /* Check if the allocated sprites will fit below the original sprite limit */
6691 if (_cur.spriteid + count >= 16384) {
6692 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
6693 DisableCur (STR_NEWGRF_ERROR_GRM_FAILED);
6694 return -1;
6697 /* Reserve space at the current sprite ID */
6698 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
6699 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
6700 _cur.spriteid += count;
6703 /* Ignore GRM result during reservation */
6704 src1 = 0;
6705 } else if (_cur.stage == GLS_ACTIVATION) {
6706 switch (feature) {
6707 case 0x00: // Trains
6708 case 0x01: // Road Vehicles
6709 case 0x02: // Ships
6710 case 0x03: // Aircraft
6711 if (!_settings_game.vehicle.dynamic_engines) {
6712 if (!PerformGRM (&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, &src1, "vehicles")) {
6713 return -1;
6715 } else {
6716 /* GRM does not apply for dynamic engine allocation. */
6717 switch (op) {
6718 case 2:
6719 case 3:
6720 src1 = _cur.grffile->GetParam(target);
6721 break;
6723 default:
6724 src1 = 0;
6725 break;
6728 break;
6730 case 0x08: // General sprites
6731 switch (op) {
6732 case 0:
6733 /* Return space reserved during reservation stage */
6734 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
6735 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
6736 break;
6738 case 1:
6739 src1 = _cur.spriteid;
6740 break;
6742 default:
6743 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
6744 return 0;
6746 break;
6748 case 0x0B: // Cargo
6749 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6750 if (!PerformGRM (_grm_cargoes, NUM_CARGO * 2, count, op, target, &src1, "cargoes")) {
6751 return -1;
6753 break;
6755 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return 0;
6757 } else {
6758 /* Ignore GRM during initialization */
6759 src1 = 0;
6763 /* TODO: You can access the parameters of another GRF file by using
6764 * source2=FE, source1=the other GRF's parameter number and data=GRF
6765 * ID. This is only valid with operation 00 (set). If the GRF ID
6766 * cannot be found, a value of 0 is used for the parameter value
6767 * instead. */
6769 uint32 res;
6770 switch (oper) {
6771 case 0x00:
6772 res = src1;
6773 break;
6775 case 0x01:
6776 res = src1 + src2;
6777 break;
6779 case 0x02:
6780 res = src1 - src2;
6781 break;
6783 case 0x03:
6784 res = src1 * src2;
6785 break;
6787 case 0x04:
6788 res = (int32)src1 * (int32)src2;
6789 break;
6791 case 0x05:
6792 if ((int32)src2 < 0) {
6793 res = src1 >> -(int32)src2;
6794 } else {
6795 res = src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6797 break;
6799 case 0x06:
6800 if ((int32)src2 < 0) {
6801 res = (int32)src1 >> -(int32)src2;
6802 } else {
6803 res = (int32)src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6805 break;
6807 case 0x07: // Bitwise AND
6808 res = src1 & src2;
6809 break;
6811 case 0x08: // Bitwise OR
6812 res = src1 | src2;
6813 break;
6815 case 0x09: // Unsigned division
6816 if (src2 == 0) {
6817 res = src1;
6818 } else {
6819 res = src1 / src2;
6821 break;
6823 case 0x0A: // Signed divison
6824 if (src2 == 0) {
6825 res = src1;
6826 } else {
6827 res = (int32)src1 / (int32)src2;
6829 break;
6831 case 0x0B: // Unsigned modulo
6832 if (src2 == 0) {
6833 res = src1;
6834 } else {
6835 res = src1 % src2;
6837 break;
6839 case 0x0C: // Signed modulo
6840 if (src2 == 0) {
6841 res = src1;
6842 } else {
6843 res = (int32)src1 % (int32)src2;
6845 break;
6847 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return 0;
6850 switch (target) {
6851 case 0x8E: // Y-Offset for train sprites
6852 _cur.grffile->traininfo_vehicle_pitch = res;
6853 break;
6855 case 0x8F: { // Rail track type cost factors
6856 extern RailtypeInfo _railtypes[RAILTYPE_END];
6857 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
6858 if (_settings_game.vehicle.disable_elrails) {
6859 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
6860 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
6861 } else {
6862 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
6863 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
6865 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
6866 break;
6869 /* @todo implement */
6870 case 0x93: // Tile refresh offset to left
6871 case 0x94: // Tile refresh offset to right
6872 case 0x95: // Tile refresh offset upwards
6873 case 0x96: // Tile refresh offset downwards
6874 case 0x97: // Snow line height
6875 case 0x99: // Global ID offset
6876 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6877 break;
6879 case 0x9E: // Miscellaneous GRF features
6880 /* Set train list engine width */
6881 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
6882 /* Remove the local flags from the global flags */
6883 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
6885 /* Only copy safe bits for static grfs */
6886 if (HasBit(_cur.grfconfig->flags, GCF_STATIC)) {
6887 uint32 safe_bits = 0;
6888 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
6890 _misc_grf_features = (_misc_grf_features & ~safe_bits) | (res & safe_bits);
6891 } else {
6892 _misc_grf_features = res;
6894 break;
6896 case 0x9F: // locale-dependent settings
6897 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6898 break;
6900 default:
6901 if (target < 0x80) {
6902 _cur.grffile->param[target] = res;
6903 /* param is zeroed by default */
6904 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
6905 } else {
6906 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
6908 break;
6911 return 0;
6914 /* Action 0x0E (GLS_SAFETYSCAN) */
6915 static int SafeGRFInhibit (ByteReader *buf)
6917 /* <0E> <num> <grfids...>
6919 * B num Number of GRFIDs that follow
6920 * D grfids GRFIDs of the files to deactivate */
6922 uint8 num = buf->ReadByte();
6924 for (uint i = 0; i < num; i++) {
6925 uint32 grfid = buf->ReadDWord();
6927 /* GRF is unsafe it if tries to deactivate other GRFs */
6928 if (grfid != _cur.grfconfig->ident.grfid) {
6929 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6931 /* Skip remainder of GRF */
6932 return -1;
6936 return 0;
6939 /* Action 0x0E */
6940 static int GRFInhibit (ByteReader *buf)
6942 /* <0E> <num> <grfids...>
6944 * B num Number of GRFIDs that follow
6945 * D grfids GRFIDs of the files to deactivate */
6947 uint8 num = buf->ReadByte();
6949 for (uint i = 0; i < num; i++) {
6950 uint32 grfid = buf->ReadDWord();
6951 GRFConfig *file = GetGRFConfig(grfid);
6953 /* Unset activation flag */
6954 if (file != NULL && file != _cur.grfconfig) {
6955 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
6956 DisableGrf (STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
6960 return 0;
6963 /** Action 0x0F - Define Town names */
6964 static int FeatureTownName (ByteReader *buf)
6966 /* <0F> <id> <style-name> <num-parts> <parts>
6968 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6969 * V style-name Name of the style (only for final definition)
6970 * B num-parts Number of parts in this definition
6971 * V parts The parts */
6973 uint32 grfid = _cur.grffile->grfid;
6975 GRFTownName *townname = AddGRFTownName(grfid);
6977 byte id = buf->ReadByte();
6978 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
6980 if (HasBit(id, 7)) {
6981 /* Final definition */
6982 ClrBit(id, 7);
6983 bool new_scheme = _cur.grffile->grf_version >= 7;
6985 byte lang = buf->ReadByte();
6987 byte nb_gen = townname->nb_gen;
6988 do {
6989 ClrBit(lang, 7);
6991 const char *name = buf->ReadString();
6993 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
6994 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
6995 free(lang_name);
6997 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6999 lang = buf->ReadByte();
7000 } while (lang != 0);
7001 townname->id[nb_gen] = id;
7002 townname->nb_gen++;
7005 byte nb = buf->ReadByte();
7006 grfmsg(6, "FeatureTownName: %u parts", nb);
7008 townname->nbparts[id] = nb;
7009 townname->partlist[id] = xcalloct<NamePartList>(nb);
7011 for (int i = 0; i < nb; i++) {
7012 byte nbtext = buf->ReadByte();
7013 townname->partlist[id][i].bitstart = buf->ReadByte();
7014 townname->partlist[id][i].bitcount = buf->ReadByte();
7015 townname->partlist[id][i].maxprob = 0;
7016 townname->partlist[id][i].partcount = nbtext;
7017 townname->partlist[id][i].parts = xcalloct<NamePart>(nbtext);
7018 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);
7020 for (int j = 0; j < nbtext; j++) {
7021 byte prob = buf->ReadByte();
7023 if (HasBit(prob, 7)) {
7024 byte ref_id = buf->ReadByte();
7026 if (townname->nbparts[ref_id] == 0) {
7027 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7028 DelGRFTownName(grfid);
7029 DisableCur (STR_NEWGRF_ERROR_INVALID_ID);
7030 return -1;
7033 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7034 townname->partlist[id][i].parts[j].data.id = ref_id;
7035 } else {
7036 const char *text = buf->ReadString();
7037 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
7038 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
7040 townname->partlist[id][i].parts[j].prob = prob;
7041 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
7043 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
7046 return 0;
7049 /** Action 0x10 - Define goto label */
7050 static int DefineGotoLabel (ByteReader *buf)
7052 /* <10> <label> [<comment>]
7054 * B label The label to define
7055 * V comment Optional comment - ignored */
7057 byte nfo_label = buf->ReadByte();
7059 GRFLabel *label = xmalloct<GRFLabel>();
7060 label->label = nfo_label;
7061 label->nfo_line = _cur.nfo_line;
7062 label->pos = FioGetPos();
7063 label->next = NULL;
7065 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7066 if (_cur.grffile->label == NULL) {
7067 _cur.grffile->label = label;
7068 } else {
7069 /* Attach the label to the end of the list */
7070 GRFLabel *l;
7071 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
7072 l->next = label;
7075 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7077 return 0;
7081 * Process a sound import from another GRF file.
7082 * @param sound Destination for sound.
7084 static void ImportGRFSound(SoundEntry *sound)
7086 const GRFFile *file;
7087 uint32 grfid = FioReadDword();
7088 SoundID sound_id = FioReadWord();
7090 file = GetFileByGRFID(grfid);
7091 if (file == NULL || file->sound_offset == 0) {
7092 grfmsg(1, "ImportGRFSound: Source file not available");
7093 return;
7096 if (sound_id >= file->num_sounds) {
7097 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
7098 return;
7101 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7103 *sound = *GetSound(file->sound_offset + sound_id);
7105 /* Reset volume and priority, which TTDPatch doesn't copy */
7106 sound->volume = 128;
7107 sound->priority = 0;
7111 * Load a sound from a file.
7112 * @param offs File offset to read sound from.
7113 * @param sound Destination for sound.
7115 static void LoadGRFSound(size_t offs, SoundEntry *sound)
7117 /* Set default volume and priority */
7118 sound->volume = 0x80;
7119 sound->priority = 0;
7121 if (offs != SIZE_MAX) {
7122 /* Sound is present in the NewGRF. */
7123 sound->file_slot = _cur.file_index;
7124 sound->file_offset = offs;
7125 sound->grf_container_ver = _cur.grf_container_ver;
7129 /* Action 0x11 */
7130 static int GRFSound (ByteReader *buf)
7132 /* <11> <num>
7134 * W num Number of sound files that follow */
7136 uint16 num = buf->ReadWord();
7137 if (num == 0) return 0;
7139 SoundEntry *sound;
7140 if (_cur.grffile->sound_offset == 0) {
7141 _cur.grffile->sound_offset = GetNumSounds();
7142 _cur.grffile->num_sounds = num;
7143 sound = AllocateSound(num);
7144 } else {
7145 sound = GetSound(_cur.grffile->sound_offset);
7148 for (int i = 0; i < num; i++) {
7149 _cur.nfo_line++;
7151 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7152 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7153 bool invalid = i >= _cur.grffile->num_sounds;
7155 size_t offs = FioGetPos();
7157 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7158 byte type = FioReadByte();
7160 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7161 /* Reference to sprite section. */
7162 if (invalid) {
7163 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7164 FioSkipBytes(len);
7165 } else if (len != 4) {
7166 grfmsg(1, "GRFSound: Invalid sprite section import");
7167 FioSkipBytes(len);
7168 } else {
7169 uint32 id = FioReadDword();
7170 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7172 continue;
7175 if (type != 0xFF) {
7176 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7177 FioSkipBytes(7);
7178 SkipSpriteData(type, len - 8);
7179 continue;
7182 if (invalid) {
7183 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7184 FioSkipBytes(len);
7187 byte action = FioReadByte();
7188 switch (action) {
7189 case 0xFF:
7190 /* Allocate sound only in init stage. */
7191 if (_cur.stage == GLS_INIT) {
7192 if (_cur.grf_container_ver >= 2) {
7193 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7194 } else {
7195 LoadGRFSound(offs, sound + i);
7198 FioSkipBytes(len - 1); // already read <action>
7199 break;
7201 case 0xFE:
7202 if (_cur.stage == GLS_ACTIVATION) {
7203 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7204 * importing sounds, so this is probably all wrong... */
7205 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7206 ImportGRFSound(sound + i);
7207 } else {
7208 FioSkipBytes(len - 1); // already read <action>
7210 break;
7212 default:
7213 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7214 FioSkipBytes(len - 1); // already read <action>
7215 break;
7219 return 0;
7222 /* Action 0x11 (SKIP) */
7223 static int SkipAct11 (ByteReader *buf)
7225 /* <11> <num>
7227 * W num Number of sound files that follow */
7229 int skip = buf->ReadWord();
7230 grfmsg (3, "SkipAct11: Skipping %d sprites", skip);
7231 return skip;
7234 /** Action 0x12 */
7235 static int LoadFontGlyph (ByteReader *buf)
7237 /* <12> <num_def> <font_size> <num_char> <base_char>
7239 * B num_def Number of definitions
7240 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7241 * B num_char Number of consecutive glyphs
7242 * W base_char First character index */
7244 uint8 num_def = buf->ReadByte();
7246 for (uint i = 0; i < num_def; i++) {
7247 FontSize size = (FontSize)buf->ReadByte();
7248 uint8 num_char = buf->ReadByte();
7249 uint16 base_char = buf->ReadWord();
7251 FontCache *fc;
7252 if (size >= FS_END) {
7253 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7254 fc = NULL;
7255 } else {
7256 fc = FontCache::Get (size);
7259 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7261 for (uint c = 0; c < num_char; c++) {
7262 if (fc != NULL) fc->SetUnicodeGlyph (base_char + c, _cur.spriteid);
7263 _cur.nfo_line++;
7264 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7268 return 0;
7271 /** Action 0x12 (SKIP) */
7272 static int SkipAct12 (ByteReader *buf)
7274 /* <12> <num_def> <font_size> <num_char> <base_char>
7276 * B num_def Number of definitions
7277 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7278 * B num_char Number of consecutive glyphs
7279 * W base_char First character index */
7281 uint8 num_def = buf->ReadByte();
7283 int skip = 0;
7284 for (uint i = 0; i < num_def; i++) {
7285 /* Ignore 'size' byte */
7286 buf->ReadByte();
7288 /* Sum up number of characters */
7289 skip += buf->ReadByte();
7291 /* Ignore 'base_char' word */
7292 buf->ReadWord();
7295 grfmsg (3, "SkipAct12: Skipping %d sprites", skip);
7297 return skip;
7300 /** Action 0x13 */
7301 static int TranslateGRFStrings (ByteReader *buf)
7303 /* <13> <grfid> <num-ent> <offset> <text...>
7305 * 4*B grfid The GRFID of the file whose texts are to be translated
7306 * B num-ent Number of strings
7307 * W offset First text ID
7308 * S text... Zero-terminated strings */
7310 uint32 grfid = buf->ReadDWord();
7311 const GRFConfig *c = GetGRFConfig(grfid);
7312 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7313 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7314 return 0;
7317 if (c->status == GCS_INITIALISED) {
7318 /* If the file is not active but will be activated later, give an error
7319 * and disable this file. */
7320 GRFError *error = DisableCur (STR_NEWGRF_ERROR_LOAD_AFTER);
7322 char tmp[256];
7323 GetString (tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE);
7324 error->data = xstrdup(tmp);
7326 return -1;
7329 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7330 * to be added as a generic string, thus the language id of 0x7F. For this to work
7331 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7332 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7333 * not change anything if a string has been provided specifically for this language. */
7334 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7335 byte num_strings = buf->ReadByte();
7336 uint16 first_id = buf->ReadWord();
7338 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
7339 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7340 return 0;
7343 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7344 const char *string = buf->ReadString();
7346 if (StrEmpty(string)) {
7347 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7348 continue;
7351 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7354 return 0;
7357 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7358 static bool ChangeGRFName(byte langid, const char *str)
7360 _cur.grfconfig->name->add (langid, _cur.grfconfig->ident.grfid, false, str);
7361 return true;
7364 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7365 static bool ChangeGRFDescription(byte langid, const char *str)
7367 _cur.grfconfig->info->add (langid, _cur.grfconfig->ident.grfid, true, str);
7368 return true;
7371 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7372 static bool ChangeGRFURL(byte langid, const char *str)
7374 _cur.grfconfig->url->add (langid, _cur.grfconfig->ident.grfid, false, str);
7375 return true;
7378 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7379 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7381 if (len != 1) {
7382 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7383 buf->Skip(len);
7384 } else {
7385 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7387 return true;
7390 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7391 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7393 if (len != 1) {
7394 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7395 buf->Skip(len);
7396 } else {
7397 char data = buf->ReadByte();
7398 GRFPalette pal = GRFP_GRF_UNSET;
7399 switch (data) {
7400 case '*':
7401 case 'A': pal = GRFP_GRF_ANY; break;
7402 case 'W': pal = GRFP_GRF_WINDOWS; break;
7403 case 'D': pal = GRFP_GRF_DOS; break;
7404 default:
7405 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7406 break;
7408 if (pal != GRFP_GRF_UNSET) {
7409 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7410 _cur.grfconfig->palette |= pal;
7413 return true;
7416 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7417 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7419 if (len != 1) {
7420 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7421 buf->Skip(len);
7422 } else {
7423 char data = buf->ReadByte();
7424 GRFPalette pal = GRFP_BLT_UNSET;
7425 switch (data) {
7426 case '8': pal = GRFP_BLT_UNSET; break;
7427 case '3': pal = GRFP_BLT_32BPP; break;
7428 default:
7429 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7430 return true;
7432 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7433 _cur.grfconfig->palette |= pal;
7435 return true;
7438 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7439 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7441 if (len != 4) {
7442 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7443 buf->Skip(len);
7444 } else {
7445 /* Set min_loadable_version as well (default to minimal compatibility) */
7446 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7448 return true;
7451 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7452 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7454 if (len != 4) {
7455 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7456 buf->Skip(len);
7457 } else {
7458 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7459 if (_cur.grfconfig->version == 0) {
7460 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7461 _cur.grfconfig->min_loadable_version = 0;
7463 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7464 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7465 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
7468 return true;
7471 static GRFParameterInfo *_cur_parameter; ///< The parameter which info is currently changed by the newgrf.
7473 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7474 static bool ChangeGRFParamName(byte langid, const char *str)
7476 _cur_parameter->name.add (langid, _cur.grfconfig->ident.grfid, false, str);
7477 return true;
7480 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7481 static bool ChangeGRFParamDescription(byte langid, const char *str)
7483 _cur_parameter->desc.add (langid, _cur.grfconfig->ident.grfid, true, str);
7484 return true;
7487 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7488 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7490 if (len != 1) {
7491 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7492 buf->Skip(len);
7493 } else {
7494 GRFParameterType type = (GRFParameterType)buf->ReadByte();
7495 if (type < PTYPE_END) {
7496 _cur_parameter->type = type;
7497 } else {
7498 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7501 return true;
7504 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7505 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7507 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7508 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7509 buf->Skip(len);
7510 } else if (len != 8) {
7511 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7512 buf->Skip(len);
7513 } else {
7514 _cur_parameter->min_value = buf->ReadDWord();
7515 _cur_parameter->max_value = buf->ReadDWord();
7517 return true;
7520 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7521 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7523 if (len < 1 || len > 3) {
7524 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7525 buf->Skip(len);
7526 } else {
7527 byte param_nr = buf->ReadByte();
7528 if (param_nr >= lengthof(_cur.grfconfig->param)) {
7529 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7530 buf->Skip(len - 1);
7531 } else {
7532 _cur_parameter->param_nr = param_nr;
7533 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
7534 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7538 return true;
7541 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7542 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7544 if (len != 4) {
7545 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7546 buf->Skip(len);
7547 } else {
7548 _cur_parameter->def_value = buf->ReadDWord();
7550 _cur.grfconfig->has_param_defaults = true;
7551 return true;
7555 * Data structure to store the allowed id/type combinations for action 14. The
7556 * data can be represented as a tree with 3 types of nodes:
7557 * 1. Branch nodes (identified by 'C' for choice).
7558 * 2. Binary leaf nodes (identified by 'B').
7559 * 3. Text leaf nodes (identified by 'T').
7561 struct AllowedSubtags {
7562 typedef bool (*DataHandler) (size_t, ByteReader *); ///< Type of callback function for binary nodes
7563 typedef bool (*TextHandler) (byte, const char *str); ///< Type of callback function for text nodes
7564 typedef bool (*BranchHandler) (ByteReader *); ///< Type of callback function for branch nodes
7566 uint32 id; ///< The identifier for this node
7567 byte type; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7568 byte nsub; ///< The number of subtags, or 0 if not applicable
7569 union {
7570 DataHandler data; ///< Callback function for a binary node, only valid if type == 'B'.
7571 TextHandler text; ///< Callback function for a text node, only valid if type == 'T'.
7572 BranchHandler branch; ///< Callback function for a branch node, only valid if type == 'C' && nsub == 0.
7573 const AllowedSubtags *subtags; ///< Pointer to a list of subtags, only valid if type == 'C' && nsub != 0.
7576 /** Create empty subtags object used to identify the end of a list. */
7577 CONSTEXPR AllowedSubtags() :
7578 id(0), type(0), nsub(0), subtags(NULL)
7582 * Create a binary leaf node.
7583 * @param id The id for this node.
7584 * @param handler The callback function to call.
7586 CONSTEXPR AllowedSubtags (uint32 id, DataHandler handler) :
7587 id(id), type('B'), nsub(0), data(handler)
7592 * Create a text leaf node.
7593 * @param id The id for this node.
7594 * @param handler The callback function to call.
7596 CONSTEXPR AllowedSubtags (uint32 id, TextHandler handler) :
7597 id(id), type('T'), nsub(0), text(handler)
7602 * Create a branch node with a callback handler
7603 * @param id The id for this node.
7604 * @param handler The callback function to call.
7606 CONSTEXPR AllowedSubtags (uint32 id, BranchHandler handler) :
7607 id(id), type('C'), nsub(0), branch(handler)
7612 * Create a branch node with a list of sub-nodes.
7613 * @param id The id for this node.
7614 * @param subtags Array with all valid subtags.
7616 template <uint N>
7617 CONSTEXPR AllowedSubtags (uint32 id, const AllowedSubtags (&subtags) [N]) :
7618 id(id), type('C'), nsub(N), subtags(subtags)
7620 assert_tcompile (N > 0);
7621 assert_tcompile (N <= UINT8_MAX);
7625 static bool SkipUnknownInfo(ByteReader *buf, byte type);
7626 static bool HandleNodes(ByteReader *buf, const AllowedSubtags *tags);
7629 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7630 * of some parameter values (type uint/enum) or the names of some bits
7631 * (type bitmask). In both cases the format is the same:
7632 * Each subnode should be a text node with the value/bit number as id.
7634 static bool ChangeGRFParamValueNames(ByteReader *buf)
7636 for (;;) {
7637 byte type = buf->ReadByte();
7638 if (type == 0) break;
7640 uint32 id = buf->ReadDWord();
7641 if (type != 'T' || id > _cur_parameter->max_value) {
7642 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7643 if (!SkipUnknownInfo(buf, type)) return false;
7644 continue;
7647 byte langid = buf->ReadByte();
7648 const char *name_string = buf->ReadString();
7650 _cur_parameter->value_names[id].add (langid,
7651 _cur.grfconfig->ident.grfid, false, name_string);
7653 return true;
7656 /** Action14 parameter tags */
7657 static const AllowedSubtags _tags_parameters[] = {
7658 AllowedSubtags('NAME', ChangeGRFParamName),
7659 AllowedSubtags('DESC', ChangeGRFParamDescription),
7660 AllowedSubtags('TYPE', ChangeGRFParamType),
7661 AllowedSubtags('LIMI', ChangeGRFParamLimits),
7662 AllowedSubtags('MASK', ChangeGRFParamMask),
7663 AllowedSubtags('VALU', ChangeGRFParamValueNames),
7664 AllowedSubtags('DFLT', ChangeGRFParamDefault),
7665 AllowedSubtags()
7669 * Callback function for 'INFO'->'PARA' to set extra information about the
7670 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7671 * the parameter number as id. The first parameter has id 0. The maximum
7672 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7674 static bool HandleParameterInfo(ByteReader *buf)
7676 for (;;) {
7677 byte type = buf->ReadByte();
7678 if (type == 0) break;
7680 uint32 id = buf->ReadDWord();
7681 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
7682 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7683 if (!SkipUnknownInfo(buf, type)) return false;
7684 continue;
7687 if (id >= _cur.grfconfig->param_info.Length()) {
7688 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
7689 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
7690 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
7692 if (_cur.grfconfig->param_info[id] == NULL) {
7693 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
7695 _cur_parameter = _cur.grfconfig->param_info[id];
7696 /* Read all parameter-data and process each node. */
7697 if (!HandleNodes(buf, _tags_parameters)) return false;
7699 return true;
7702 /** Action14 tags for the INFO node */
7703 static const AllowedSubtags _tags_info[] = {
7704 AllowedSubtags('NAME', ChangeGRFName),
7705 AllowedSubtags('DESC', ChangeGRFDescription),
7706 AllowedSubtags('URL_', ChangeGRFURL),
7707 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
7708 AllowedSubtags('PALS', ChangeGRFPalette),
7709 AllowedSubtags('BLTR', ChangeGRFBlitter),
7710 AllowedSubtags('VRSN', ChangeGRFVersion),
7711 AllowedSubtags('MINV', ChangeGRFMinVersion),
7712 AllowedSubtags('PARA', HandleParameterInfo),
7713 AllowedSubtags()
7716 /** Action14 root tags */
7717 static const AllowedSubtags _tags_root[] = {
7718 AllowedSubtags('INFO', _tags_info),
7719 AllowedSubtags()
7724 * Try to skip the current node and all subnodes (if it's a branch node).
7725 * @param buf Buffer.
7726 * @param type The node type to skip.
7727 * @return True if we could skip the node, false if an error occurred.
7729 static bool SkipUnknownInfo(ByteReader *buf, byte type)
7731 /* type and id are already read */
7732 switch (type) {
7733 case 'C':
7734 for (;;) {
7735 byte new_type = buf->ReadByte();
7736 if (new_type == 0) break;
7737 buf->ReadDWord(); // skip the id
7738 if (!SkipUnknownInfo(buf, new_type)) return false;
7740 break;
7742 case 'T':
7743 buf->ReadByte(); // lang
7744 buf->ReadString(); // actual text
7745 break;
7747 case 'B': {
7748 uint16 size = buf->ReadWord();
7749 buf->Skip(size);
7750 break;
7753 default:
7754 return false;
7757 return true;
7761 * Handle the nodes of an Action14
7762 * @param type Type of node.
7763 * @param id ID.
7764 * @param buf Buffer.
7765 * @param subtags Allowed subtags.
7766 * @return Whether all tags could be handled.
7768 static bool HandleNode (byte type, uint32 id, ByteReader *buf, const AllowedSubtags *subtags)
7770 for (const AllowedSubtags *tag = subtags; tag->type != 0; tag++) {
7771 if (tag->id != BSWAP32(id) || tag->type != type) continue;
7772 switch (type) {
7773 default: NOT_REACHED();
7775 case 'T': {
7776 byte langid = buf->ReadByte();
7777 return tag->text (langid, buf->ReadString());
7780 case 'B': {
7781 size_t len = buf->ReadWord();
7782 if (!buf->HasData (len)) return false;
7783 return tag->data (len, buf);
7786 case 'C': {
7787 if (tag->nsub == 0) {
7788 return tag->branch (buf);
7790 return HandleNodes (buf, tag->subtags);
7794 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
7795 return SkipUnknownInfo(buf, type);
7799 * Handle the contents of a 'C' choice of an Action14
7800 * @param buf Buffer.
7801 * @param subtags List of subtags.
7802 * @return Whether the nodes could all be handled.
7804 static bool HandleNodes (ByteReader *buf, const AllowedSubtags *subtags)
7806 for (;;) {
7807 byte type = buf->ReadByte();
7808 if (type == 0) break;
7809 uint32 id = buf->ReadDWord();
7810 if (!HandleNode(type, id, buf, subtags)) return false;
7812 return true;
7816 * Handle Action 0x14
7817 * @param buf Buffer.
7819 static int StaticGRFInfo (ByteReader *buf)
7821 /* <14> <type> <id> <text/data...> */
7822 HandleNodes(buf, _tags_root);
7823 return 0;
7827 * Set the current NewGRF as unsafe for static use
7828 * @param buf Unused.
7829 * @note Used during safety scan on unsafe actions.
7831 static int GRFUnsafe (ByteReader *buf)
7833 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7835 /* Skip remainder of GRF */
7836 return -1;
7840 /** Initialize the TTDPatch flags */
7841 static void InitializeGRFSpecial()
7843 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
7844 | (1 << 0x0D) // newairports
7845 | (1 << 0x0E) // largestations
7846 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
7847 | (0 << 0x10) // loadtime
7848 | (1 << 0x12) // presignals
7849 | (1 << 0x13) // extpresignals
7850 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
7851 | (1 << 0x1B) // multihead
7852 | (1 << 0x1D) // lowmemory
7853 | (1 << 0x1E); // generalfixes
7855 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
7856 | (1 << 0x08) // mammothtrains
7857 | (1 << 0x09) // trainrefit
7858 | (0 << 0x0B) // subsidiaries
7859 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
7860 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7861 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7862 | (1 << 0x14) // bridgespeedlimits
7863 | (1 << 0x16) // eternalgame
7864 | (1 << 0x17) // newtrains
7865 | (1 << 0x18) // newrvs
7866 | (1 << 0x19) // newships
7867 | (1 << 0x1A) // newplanes
7868 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7869 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
7871 _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
7872 | (1 << 0x03) // semaphores
7873 | (1 << 0x0A) // newobjects
7874 | (0 << 0x0B) // enhancedgui
7875 | (0 << 0x0C) // newagerating
7876 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
7877 | (1 << 0x0E) // fullloadany
7878 | (1 << 0x0F) // planespeed
7879 | (0 << 0x10) // moreindustriesperclimate - obsolete
7880 | (0 << 0x11) // moretoylandfeatures
7881 | (1 << 0x12) // newstations
7882 | (1 << 0x13) // tracktypecostdiff
7883 | (1 << 0x14) // manualconvert
7884 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
7885 | (1 << 0x16) // canals
7886 | (1 << 0x17) // newstartyear
7887 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
7888 | (1 << 0x19) // newhouses
7889 | (1 << 0x1A) // newbridges
7890 | (1 << 0x1B) // newtownnames
7891 | (1 << 0x1C) // moreanimation
7892 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
7893 | (1 << 0x1E) // newshistory
7894 | (0 << 0x1F); // custombridgeheads
7896 _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
7897 | (1 << 0x01) // windowsnap
7898 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
7899 | (1 << 0x03) // pathbasedsignalling
7900 | (0 << 0x04) // aichoosechance
7901 | (1 << 0x05) // resolutionwidth
7902 | (1 << 0x06) // resolutionheight
7903 | (1 << 0x07) // newindustries
7904 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
7905 | (0 << 0x09) // townroadbranchprob
7906 | (0 << 0x0A) // tempsnowline
7907 | (1 << 0x0B) // newcargo
7908 | (1 << 0x0C) // enhancemultiplayer
7909 | (1 << 0x0D) // onewayroads
7910 | (1 << 0x0E) // irregularstations
7911 | (1 << 0x0F) // statistics
7912 | (1 << 0x10) // newsounds
7913 | (1 << 0x11) // autoreplace
7914 | (1 << 0x12) // autoslope
7915 | (0 << 0x13) // followvehicle
7916 | (1 << 0x14) // trams
7917 | (0 << 0x15) // enhancetunnels
7918 | (1 << 0x16) // shortrvs
7919 | (1 << 0x17) // articulatedrvs
7920 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
7921 | (1 << 0x1E) // variablerunningcosts
7922 | (1 << 0x1F); // any switch is on
7925 /** Reset and clear all NewGRF stations */
7926 static void ResetCustomStations()
7928 const GRFFile * const *end = _grf_files.End();
7929 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7930 StationSpec **&stations = (*file)->stations;
7931 if (stations == NULL) continue;
7932 for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
7933 if (stations[i] == NULL) continue;
7934 StationSpec *statspec = stations[i];
7936 delete[] statspec->renderdata;
7938 /* Release platforms and layouts */
7939 if (!statspec->copied_layouts) {
7940 for (uint l = 0; l < statspec->lengths; l++) {
7941 for (uint p = 0; p < statspec->platforms[l]; p++) {
7942 free(statspec->layouts[l][p]);
7944 free(statspec->layouts[l]);
7946 free(statspec->layouts);
7947 free(statspec->platforms);
7950 /* Release this station */
7951 free(statspec);
7954 /* Free and reset the station data */
7955 free(stations);
7956 stations = NULL;
7960 /** Reset and clear all NewGRF houses */
7961 static void ResetCustomHouses()
7963 const GRFFile * const *end = _grf_files.End();
7964 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7965 HouseSpec **&housespec = (*file)->housespec;
7966 if (housespec == NULL) continue;
7967 for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
7968 free(housespec[i]);
7971 free(housespec);
7972 housespec = NULL;
7976 /** Reset and clear all NewGRF airports */
7977 static void ResetCustomAirports()
7979 const GRFFile * const *end = _grf_files.End();
7980 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7981 AirportSpec **aslist = (*file)->airportspec;
7982 if (aslist != NULL) {
7983 for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
7984 AirportSpec *as = aslist[i];
7986 if (as != NULL) {
7987 /* We need to remove the tiles layouts */
7988 for (int j = 0; j < as->num_table; j++) {
7989 /* remove the individual layouts */
7990 free(as->table[j]);
7992 free(as->table);
7993 free(as->depot_table);
7995 free(as);
7998 free(aslist);
7999 (*file)->airportspec = NULL;
8002 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8003 if (airporttilespec != NULL) {
8004 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8005 free(airporttilespec[i]);
8007 free(airporttilespec);
8008 airporttilespec = NULL;
8013 /** Reset and clear all NewGRF industries */
8014 static void ResetCustomIndustries()
8016 const GRFFile * const *end = _grf_files.End();
8017 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8018 IndustrySpec **&industryspec = (*file)->industryspec;
8019 IndustryTileSpec **&indtspec = (*file)->indtspec;
8021 /* We are verifiying both tiles and industries specs loaded from the grf file
8022 * First, let's deal with industryspec */
8023 if (industryspec != NULL) {
8024 for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8025 IndustrySpec *ind = industryspec[i];
8026 if (ind == NULL) continue;
8028 /* We need to remove the sounds array */
8029 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
8030 free(ind->random_sounds);
8033 /* We need to remove the tiles layouts */
8034 CleanIndustryTileTable(ind);
8036 free(ind);
8039 free(industryspec);
8040 industryspec = NULL;
8043 if (indtspec == NULL) continue;
8044 for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8045 free(indtspec[i]);
8048 free(indtspec);
8049 indtspec = NULL;
8053 /** Reset and clear all NewObjects */
8054 static void ResetCustomObjects()
8056 const GRFFile * const *end = _grf_files.End();
8057 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8058 ObjectSpec **&objectspec = (*file)->objectspec;
8059 if (objectspec == NULL) continue;
8060 for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8061 free(objectspec[i]);
8064 free(objectspec);
8065 objectspec = NULL;
8069 /** Reset and clear all NewGRFs */
8070 static void ResetNewGRF()
8072 const GRFFile * const *end = _grf_files.End();
8073 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8074 delete *file;
8077 _grf_files.Clear();
8078 _cur.grffile = NULL;
8081 /** Clear all NewGRF errors */
8082 static void ResetNewGRFErrors()
8084 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
8085 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
8086 delete c->error;
8087 c->error = NULL;
8093 * Reset all NewGRF loaded data
8094 * TODO
8096 void ResetNewGRFData()
8098 CleanUpStrings();
8099 CleanUpGRFTownNames();
8101 /* Copy/reset original engine info data */
8102 SetupEngines();
8104 /* Copy/reset original bridge info data */
8105 ResetBridges();
8107 /* Reset rail type information */
8108 ResetRailTypes();
8110 /* Allocate temporary refit/cargo class data */
8111 _gted = xcalloct<GRFTempEngineData>(Engine::GetPoolSize());
8113 /* Fill rail type label temporary data for default trains */
8114 Engine *e;
8115 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
8116 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
8119 /* Reset GRM reservations */
8120 memset(&_grm_engines, 0, sizeof(_grm_engines));
8121 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
8123 /* Reset generic feature callback lists */
8124 ResetGenericCallbacks();
8126 /* Reset price base data */
8127 ResetPriceBaseMultipliers();
8129 /* Reset the curencies array */
8130 ResetCurrencies();
8132 /* Reset the house array */
8133 ResetCustomHouses();
8134 ResetHouses();
8136 /* Reset the industries structures*/
8137 ResetCustomIndustries();
8138 ResetIndustries();
8140 /* Reset the objects. */
8141 ObjectClass::Reset();
8142 ResetCustomObjects();
8143 ResetObjects();
8145 /* Reset station classes */
8146 StationClass::Reset();
8147 ResetCustomStations();
8149 /* Reset airport-related structures */
8150 AirportClass::Reset();
8151 ResetCustomAirports();
8152 AirportSpec::ResetAirports();
8153 AirportTileSpec::ResetAirportTiles();
8155 /* Reset canal sprite groups and flags */
8156 memset(_water_feature, 0, sizeof(_water_feature));
8158 /* Reset the snowline table. */
8159 ClearSnowLine();
8161 /* Reset NewGRF files */
8162 ResetNewGRF();
8164 /* Reset NewGRF errors. */
8165 ResetNewGRFErrors();
8167 /* Set up the default cargo types */
8168 SetupCargoForClimate(_settings_game.game_creation.landscape);
8170 /* Reset misc GRF features and train list display variables */
8171 _misc_grf_features = 0;
8173 _loaded_newgrf_features.has_2CC = false;
8174 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8175 _loaded_newgrf_features.has_newhouses = false;
8176 _loaded_newgrf_features.has_newindustries = false;
8177 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
8179 /* Clear all GRF overrides */
8180 _grf_id_overrides.clear();
8182 InitializeSoundPool();
8183 SpriteGroup::pool.CleanPool();
8187 * Reset NewGRF data which is stored persistently in savegames.
8189 void ResetPersistentNewGRFData()
8191 /* Reset override managers */
8192 _engine_mngr.ResetToDefaultMapping();
8193 _house_mngr.ResetMapping();
8194 _industry_mngr.ResetMapping();
8195 _industile_mngr.ResetMapping();
8196 _airport_mngr.ResetMapping();
8197 _airporttile_mngr.ResetMapping();
8201 * Construct the Cargo Mapping
8202 * @note This is the reverse of a cargo translation table
8204 static void BuildCargoTranslationMap()
8206 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8208 for (CargoID c = 0; c < NUM_CARGO; c++) {
8209 const CargoSpec *cs = CargoSpec::Get(c);
8210 if (!cs->IsValid()) continue;
8212 if (_cur.grffile->cargo_list.Length() == 0) {
8213 /* Default translation table, so just a straight mapping to bitnum */
8214 _cur.grffile->cargo_map[c] = cs->bitnum;
8215 } else {
8216 /* Check the translation table for this cargo's label */
8217 int index = _cur.grffile->cargo_list.FindIndex(cs->label);
8218 if (index >= 0) _cur.grffile->cargo_map[c] = index;
8224 * Constructor for GRFFile
8225 * @param config GRFConfig to copy name, grfid and parameters from.
8227 GRFFile::GRFFile(const GRFConfig *config)
8229 this->filename = xstrdup(config->filename);
8230 this->grfid = config->ident.grfid;
8232 /* Initialise local settings to defaults */
8233 this->traininfo_vehicle_pitch = 0;
8234 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8236 /* Mark price_base_multipliers as 'not set' */
8237 for (Price i = PR_BEGIN; i < PR_END; i++) {
8238 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8241 /* Initialise rail type map with default rail types */
8242 memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
8243 this->railtype_map[0] = RAILTYPE_RAIL;
8244 this->railtype_map[1] = RAILTYPE_ELECTRIC;
8245 this->railtype_map[2] = RAILTYPE_MONO;
8246 this->railtype_map[3] = RAILTYPE_MAGLEV;
8248 /* Copy the initial parameter list
8249 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8250 assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8252 assert(config->num_params <= lengthof(config->param));
8253 this->param_end = config->num_params;
8254 if (this->param_end > 0) {
8255 MemCpyT(this->param, config->param, this->param_end);
8259 GRFFile::~GRFFile()
8261 free(this->filename);
8262 delete[] this->language_map;
8267 * List of what cargo labels are refittable for the given the vehicle-type.
8268 * Only currently active labels are applied.
8270 static const CargoLabel _default_refitmasks_rail[] = {
8271 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8272 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8273 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8274 'PLST', 'FZDR',
8275 0 };
8277 static const CargoLabel _default_refitmasks_road[] = {
8278 0 };
8280 static const CargoLabel _default_refitmasks_ships[] = {
8281 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8282 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8283 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8284 'PLST', 'FZDR',
8285 0 };
8287 static const CargoLabel _default_refitmasks_aircraft[] = {
8288 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8289 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8290 0 };
8292 static const CargoLabel * const _default_refitmasks[] = {
8293 _default_refitmasks_rail,
8294 _default_refitmasks_road,
8295 _default_refitmasks_ships,
8296 _default_refitmasks_aircraft,
8301 * Precalculate refit masks from cargo classes for all vehicles.
8303 static void CalculateRefitMasks()
8305 Engine *e;
8307 FOR_ALL_ENGINES(e) {
8308 EngineID engine = e->index;
8309 EngineInfo *ei = &e->info;
8310 bool only_defaultcargo; ///< Set if the vehicle shall carry only the default cargo
8312 /* Did the newgrf specify any refitting? If not, use defaults. */
8313 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8314 uint32 mask = 0;
8315 uint32 not_mask = 0;
8316 uint32 xor_mask = ei->refit_mask;
8318 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8319 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8320 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8322 if (_gted[engine].cargo_allowed != 0) {
8323 /* Build up the list of cargo types from the set cargo classes. */
8324 const CargoSpec *cs;
8325 FOR_ALL_CARGOSPECS(cs) {
8326 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8327 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8331 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8333 /* Apply explicit refit includes/excludes. */
8334 ei->refit_mask |= _gted[engine].ctt_include_mask;
8335 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8336 } else {
8337 uint32 xor_mask = 0;
8339 /* Don't apply default refit mask to wagons nor engines with no capacity */
8340 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8341 const CargoLabel *cl = _default_refitmasks[e->type];
8342 for (uint i = 0;; i++) {
8343 if (cl[i] == 0) break;
8345 CargoID cargo = GetCargoIDByLabel(cl[i]);
8346 if (cargo == CT_INVALID) continue;
8348 SetBit(xor_mask, cargo);
8352 ei->refit_mask = xor_mask & _cargo_mask;
8354 /* If the mask is zero, the vehicle shall only carry the default cargo */
8355 only_defaultcargo = (ei->refit_mask == 0);
8358 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8359 if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8361 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8362 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8363 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8364 ei->cargo_type = CT_INVALID;
8367 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8368 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8369 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8370 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8371 const uint8 *cargo_map_for_first_refittable = NULL;
8373 const GRFFile *file = _gted[engine].defaultcargo_grf;
8374 if (file == NULL) file = e->GetGRF();
8375 if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
8376 cargo_map_for_first_refittable = file->cargo_map;
8380 if (cargo_map_for_first_refittable != NULL) {
8381 /* Use first refittable cargo from cargo translation table */
8382 byte best_local_slot = 0xFF;
8383 CargoID cargo_type;
8384 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8385 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8386 if (local_slot < best_local_slot) {
8387 best_local_slot = local_slot;
8388 ei->cargo_type = cargo_type;
8393 if (ei->cargo_type == CT_INVALID) {
8394 /* Use first refittable cargo slot */
8395 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8398 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8400 /* Clear refit_mask for not refittable ships */
8401 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8402 ei->refit_mask = 0;
8407 /** Set to use the correct action0 properties for each canal feature */
8408 static void FinaliseCanals()
8410 for (uint i = 0; i < CF_END; i++) {
8411 if (_water_feature[i].grffile != NULL) {
8412 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
8413 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
8418 /** Check for invalid engines */
8419 static void FinaliseEngineArray()
8421 Engine *e;
8423 FOR_ALL_ENGINES(e) {
8424 if (e->GetGRF() == NULL) {
8425 const EngineIDMapping &eid = _engine_mngr[e->index];
8426 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8427 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8431 /* When the train does not set property 27 (misc flags), but it
8432 * is overridden by a NewGRF graphically we want to disable the
8433 * flipping possibility. */
8434 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
8435 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8438 /* Skip wagons, there livery is defined via the engine */
8439 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8440 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
8441 SetBit(_loaded_newgrf_features.used_liveries, ls);
8442 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8444 if (e->type == VEH_TRAIN) {
8445 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8446 switch (ls) {
8447 case LS_STEAM:
8448 case LS_DIESEL:
8449 case LS_ELECTRIC:
8450 case LS_MONORAIL:
8451 case LS_MAGLEV:
8452 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8453 break;
8455 case LS_DMU:
8456 case LS_EMU:
8457 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8458 break;
8460 default: NOT_REACHED();
8467 /** Check for invalid cargoes */
8468 static void FinaliseCargoArray()
8470 for (CargoID c = 0; c < NUM_CARGO; c++) {
8471 CargoSpec *cs = CargoSpec::Get(c);
8472 if (!cs->IsValid()) {
8473 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8474 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8475 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8481 * Check if a given housespec is valid and disable it if it's not.
8482 * The housespecs that follow it are used to check the validity of
8483 * multitile houses.
8484 * @param hs The housespec to check.
8485 * @param next1 The housespec that follows \c hs.
8486 * @param next2 The housespec that follows \c next1.
8487 * @param next3 The housespec that follows \c next2.
8488 * @param filename The filename of the newgrf this house was defined in.
8489 * @return Whether the given housespec is valid.
8491 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8493 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8494 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8495 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8496 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8497 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8498 hs->enabled = false;
8499 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);
8500 return false;
8503 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8504 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8505 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8506 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8507 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8508 hs->enabled = false;
8509 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);
8510 return false;
8513 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8514 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8515 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8516 hs->enabled = false;
8517 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);
8518 return false;
8521 /* Make sure that additional parts of multitile houses are not available. */
8522 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
8523 hs->enabled = false;
8524 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);
8525 return false;
8528 return true;
8532 * Make sure there is at least one house available in the year 0 for the given
8533 * climate.
8534 * @param bitmask The climate to check for. Exactly one climate bit should be
8535 * set.
8537 static void EnsureEarlyHouses (HouseZones climate_mask)
8539 for (uint z = 0; z < HZB_END; z++) {
8540 HouseZones bitmask = (HouseZones)(1U << z) | climate_mask;
8541 Year min_year = MAX_YEAR;
8543 for (int i = 0; i < NUM_HOUSES; i++) {
8544 const HouseSpec *hs = HouseSpec::Get(i);
8545 if (hs == NULL || !hs->enabled) continue;
8546 if ((hs->building_availability & bitmask) != bitmask) continue;
8547 if (hs->min_year < min_year) min_year = hs->min_year;
8550 if (min_year == 0) continue;
8552 for (int i = 0; i < NUM_HOUSES; i++) {
8553 HouseSpec *hs = HouseSpec::Get(i);
8554 if (hs == NULL || !hs->enabled) continue;
8555 if ((hs->building_availability & bitmask) != bitmask) continue;
8556 if (hs->min_year == min_year) hs->min_year = 0;
8562 * Add all new houses to the house array. House properties can be set at any
8563 * time in the GRF file, so we can only add a house spec to the house array
8564 * after the file has finished loading. We also need to check the dates, due to
8565 * the TTDPatch behaviour described below that we need to emulate.
8567 static void FinaliseHouseArray()
8569 /* If there are no houses with start dates before 1930, then all houses
8570 * with start dates of 1930 have them reset to 0. This is in order to be
8571 * compatible with TTDPatch, where if no houses have start dates before
8572 * 1930 and the date is before 1930, the game pretends that this is 1930.
8573 * If there have been any houses defined with start dates before 1930 then
8574 * the dates are left alone.
8575 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8576 * minimum introduction date to 0.
8578 const GRFFile * const *end = _grf_files.End();
8579 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8580 HouseSpec **&housespec = (*file)->housespec;
8581 if (housespec == NULL) continue;
8583 for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8584 HouseSpec *hs = housespec[i];
8586 if (hs == NULL) continue;
8588 const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : NULL);
8589 const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : NULL);
8590 const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : NULL);
8592 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
8594 _house_mngr.SetEntitySpec(hs);
8598 for (int i = 0; i < NUM_HOUSES; i++) {
8599 HouseSpec *hs = HouseSpec::Get(i);
8600 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : NULL);
8601 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : NULL);
8602 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : NULL);
8604 /* We need to check all houses again to we are sure that multitile houses
8605 * did get consecutive IDs and none of the parts are missing. */
8606 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
8607 /* GetHouseNorthPart checks 3 houses that are directly before
8608 * it in the house pool. If any of those houses have multi-tile
8609 * flags set it assumes it's part of a multitile house. Since
8610 * we can have invalid houses in the pool marked as disabled, we
8611 * don't want to have them influencing valid tiles. As such set
8612 * building_flags to zero here to make sure any house following
8613 * this one in the pool is properly handled as 1x1 house. */
8614 hs->building_flags = TILE_NO_FLAG;
8618 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
8619 EnsureEarlyHouses (climate_mask);
8621 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
8622 EnsureEarlyHouses (HZ_SUBARTC_ABOVE);
8627 * Add all new industries to the industry array. Industry properties can be set at any
8628 * time in the GRF file, so we can only add a industry spec to the industry array
8629 * after the file has finished loading.
8631 static void FinaliseIndustriesArray()
8633 const GRFFile * const *end = _grf_files.End();
8634 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8635 IndustrySpec **&industryspec = (*file)->industryspec;
8636 IndustryTileSpec **&indtspec = (*file)->indtspec;
8637 if (industryspec != NULL) {
8638 for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8639 IndustrySpec *indsp = industryspec[i];
8641 if (indsp != NULL && indsp->enabled) {
8642 StringID strid;
8643 /* process the conversion of text at the end, so to be sure everything will be fine
8644 * and available. Check if it does not return undefind marker, which is a very good sign of a
8645 * substitute industry who has not changed the string been examined, thus using it as such */
8646 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
8647 if (strid != STR_UNDEFINED) indsp->name = strid;
8649 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
8650 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
8652 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
8653 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
8655 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
8656 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
8658 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
8659 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
8661 if (indsp->station_name != STR_NULL) {
8662 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8663 * station's name. Don't want to lose the value, therefore, do not process. */
8664 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
8665 if (strid != STR_UNDEFINED) indsp->station_name = strid;
8668 _industry_mngr.SetEntitySpec(indsp);
8669 _loaded_newgrf_features.has_newindustries = true;
8674 if (indtspec != NULL) {
8675 for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8676 IndustryTileSpec *indtsp = indtspec[i];
8677 if (indtsp != NULL) {
8678 _industile_mngr.SetEntitySpec(indtsp);
8684 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
8685 IndustrySpec *indsp = &_industry_specs[j];
8686 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
8687 for (uint i = 0; i < 3; i++) {
8688 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
8691 if (!indsp->enabled) {
8692 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
8698 * Add all new objects to the object array. Object properties can be set at any
8699 * time in the GRF file, so we can only add an object spec to the object array
8700 * after the file has finished loading.
8702 static void FinaliseObjectsArray()
8704 const GRFFile * const *end = _grf_files.End();
8705 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8706 ObjectSpec **&objectspec = (*file)->objectspec;
8707 if (objectspec != NULL) {
8708 for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8709 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
8710 _object_mngr.SetEntitySpec(objectspec[i]);
8718 * Add all new airports to the airport array. Airport properties can be set at any
8719 * time in the GRF file, so we can only add a airport spec to the airport array
8720 * after the file has finished loading.
8722 static void FinaliseAirportsArray()
8724 const GRFFile * const *end = _grf_files.End();
8725 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8726 AirportSpec **&airportspec = (*file)->airportspec;
8727 if (airportspec != NULL) {
8728 for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8729 if (airportspec[i] != NULL && airportspec[i]->enabled) {
8730 _airport_mngr.SetEntitySpec(airportspec[i]);
8735 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8736 if (airporttilespec != NULL) {
8737 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8738 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
8739 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
8746 /* Here we perform initial decoding of some special sprites (as are they
8747 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8748 * partial implementation yet).
8749 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8750 * a crafted invalid GRF file. We should tell that to the user somehow, or
8751 * better make this more robust in the future. */
8752 static int DecodeSpecialSprite (byte *buf, uint num, GrfLoadingStage stage)
8754 /* XXX: There is a difference between staged loading in TTDPatch and
8755 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8756 * during stage 1, whilst action 3 is carried out during stage 2 (to
8757 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8758 * IDs are valid only within a given set (action 1) block, and may be
8759 * overwritten after action 3 associates them. But overwriting happens
8760 * in an earlier stage than associating, so... We just process actions
8761 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8762 * --pasky
8763 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8764 * is not in memory and scanning the file every time would be too expensive.
8765 * In other stages we skip action 0x10 since it's already dealt with. */
8766 static const SpecialSpriteHandler handlers[][GLS_END] = {
8767 /* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
8768 /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
8769 /* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
8770 /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
8771 /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
8772 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
8773 /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
8774 /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
8775 /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
8776 /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
8777 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
8778 /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
8779 /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
8780 /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
8781 /* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
8782 /* 0x0F */ { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
8783 /* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
8784 /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
8785 /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
8786 /* 0x13 */ { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
8787 /* 0x14 */ { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
8790 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
8792 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
8793 if (it == _grf_line_to_action6_sprite_override.end()) {
8794 /* No preloaded sprite to work with; read the
8795 * pseudo sprite content. */
8796 FioReadBlock(buf, num);
8797 } else {
8798 /* Use the preloaded sprite data. */
8799 buf = it->second.get();
8800 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8802 /* Skip the real (original) content of this action. */
8803 FioSeekTo(num, SEEK_CUR);
8806 ByteReader br(buf, buf + num);
8807 ByteReader *bufp = &br;
8809 try {
8810 byte action = bufp->ReadByte();
8812 if (action == 0xFF) {
8813 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8814 } else if (action == 0xFE) {
8815 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8816 } else if (action >= lengthof(handlers)) {
8817 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
8818 } else if (handlers[action][stage] == NULL) {
8819 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
8820 } else {
8821 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
8822 return handlers[action][stage](bufp);
8824 } catch (...) {
8825 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8826 DisableCur (STR_NEWGRF_ERROR_READ_BOUNDS);
8827 return -1;
8830 return 0;
8834 /** Signature of a container version 2 GRF. */
8835 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8838 * Get the container version of the currently opened GRF file.
8839 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
8841 byte GetGRFContainerVersion()
8843 size_t pos = FioGetPos();
8845 if (FioReadWord() == 0) {
8846 /* Check for GRF container version 2, which is identified by the bytes
8847 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8848 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
8849 if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
8852 return 2;
8855 /* Container version 1 has no header, rewind to start. */
8856 FioSeekTo(pos, SEEK_SET);
8857 return 1;
8861 * Load a particular NewGRF.
8862 * @param config The configuration of the to be loaded NewGRF.
8863 * @param file_index The Fio index of the first NewGRF to load.
8864 * @param stage The loading stage of the NewGRF.
8865 * @param subdir The sub directory to find the NewGRF in.
8867 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
8869 const char *filename = config->filename;
8871 if (file_index > LAST_GRF_SLOT) {
8872 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
8873 config->status = GCS_DISABLED;
8874 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
8875 return;
8878 FioOpenFile(file_index, filename, subdir);
8879 _cur.file_index = file_index; // XXX
8880 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
8882 _cur.grfconfig = config;
8884 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
8886 _cur.grf_container_ver = GetGRFContainerVersion();
8887 if (_cur.grf_container_ver == 0) {
8888 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8889 return;
8892 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
8893 /* We need the sprite offsets in the init stage for NewGRF sounds
8894 * and in the activation stage for real sprites. */
8895 ReadGRFSpriteOffsets(_cur.grf_container_ver);
8896 } else {
8897 /* Skip sprite section offset if present. */
8898 if (_cur.grf_container_ver >= 2) FioReadDword();
8901 if (_cur.grf_container_ver >= 2) {
8902 /* Read compression value. */
8903 byte compression = FioReadByte();
8904 if (compression != 0) {
8905 DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
8906 return;
8910 /* Skip the first sprite; we don't care about how many sprites this
8911 * does contain; newest TTDPatches and George's longvehicles don't
8912 * neither, apparently. */
8913 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
8914 if (num == 4 && FioReadByte() == 0xFF) {
8915 FioReadDword();
8916 } else {
8917 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8918 return;
8921 _cur.ClearDataForNextFile();
8923 ReusableBuffer<byte> buf;
8924 int skip_sprites = 0;
8926 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
8927 byte type = FioReadByte();
8928 _cur.nfo_line++;
8930 if (type == 0xFF) {
8931 if (skip_sprites == 0) {
8932 skip_sprites = DecodeSpecialSprite (buf.Allocate(num), num, stage);
8934 /* Stop all processing if we are to skip the remaining sprites */
8935 if (skip_sprites == -1) break;
8937 continue;
8938 } else {
8939 FioSkipBytes(num);
8941 } else {
8942 if (skip_sprites == 0) {
8943 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8944 DisableCur (STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
8945 break;
8948 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
8949 /* Reference to data section. Container version >= 2 only. */
8950 FioSkipBytes(num);
8951 } else {
8952 FioSkipBytes(7);
8953 SkipSpriteData(type, num - 8);
8957 if (skip_sprites > 0) skip_sprites--;
8962 * Relocates the old shore sprites at new positions.
8964 * 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)
8965 * 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)
8966 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
8968 static void ActivateOldShore()
8970 /* Use default graphics, if no shore sprites were loaded.
8971 * Should not happen, as the base set's extra grf should include some. */
8972 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
8974 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
8975 for (uint i = 0; i < lengthof(shore_sprites_1); i++) {
8976 DupSprite (shore_sprites_1[i].old, shore_sprites_1[i].spr);
8980 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
8981 for (uint i = 0; i < lengthof(shore_sprites_2); i++) {
8982 DupSprite (shore_sprites_2[i].old, shore_sprites_2[i].spr);
8988 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
8990 static void FinalisePriceBaseMultipliers()
8992 extern const PriceBaseSpec _price_base_specs[];
8993 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
8994 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
8996 /* Evaluate grf overrides */
8997 int num_grfs = _grf_files.Length();
8998 int *grf_overrides = AllocaM(int, num_grfs);
8999 for (int i = 0; i < num_grfs; i++) {
9000 grf_overrides[i] = -1;
9002 GRFFile *source = _grf_files[i];
9003 uint32 override = _grf_id_overrides[source->grfid];
9004 if (override == 0) continue;
9006 GRFFile *dest = GetFileByGRFID(override);
9007 if (dest == NULL) continue;
9009 grf_overrides[i] = _grf_files.FindIndex(dest);
9010 assert(grf_overrides[i] >= 0);
9013 /* Override features and price base multipliers of earlier loaded grfs */
9014 for (int i = 0; i < num_grfs; i++) {
9015 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
9016 GRFFile *source = _grf_files[i];
9017 GRFFile *dest = _grf_files[grf_overrides[i]];
9019 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9020 source->grf_features |= features;
9021 dest->grf_features |= features;
9023 for (Price p = PR_BEGIN; p < PR_END; p++) {
9024 /* No price defined -> nothing to do */
9025 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
9026 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9027 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9031 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9032 for (int i = num_grfs - 1; i >= 0; i--) {
9033 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
9034 GRFFile *source = _grf_files[i];
9035 GRFFile *dest = _grf_files[grf_overrides[i]];
9037 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9038 source->grf_features |= features;
9039 dest->grf_features |= features;
9041 for (Price p = PR_BEGIN; p < PR_END; p++) {
9042 /* Already a price defined -> nothing to do */
9043 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
9044 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9045 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9049 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9050 for (int i = 0; i < num_grfs; i++) {
9051 if (grf_overrides[i] < 0) continue;
9052 GRFFile *source = _grf_files[i];
9053 GRFFile *dest = _grf_files[grf_overrides[i]];
9055 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9056 source->grf_features |= features;
9057 dest->grf_features |= features;
9059 for (Price p = PR_BEGIN; p < PR_END; p++) {
9060 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
9061 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
9062 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9064 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
9068 /* Apply fallback prices for grf version < 8 */
9069 const GRFFile * const *end = _grf_files.End();
9070 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9071 if ((*file)->grf_version >= 8) continue;
9072 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9073 for (Price p = PR_BEGIN; p < PR_END; p++) {
9074 Price fallback_price = _price_base_specs[p].fallback_price;
9075 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9076 /* No price multiplier has been set.
9077 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9078 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9083 /* Decide local/global scope of price base multipliers */
9084 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9085 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9086 for (Price p = PR_BEGIN; p < PR_END; p++) {
9087 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9088 /* No multiplier was set; set it to a neutral value */
9089 price_base_multipliers[p] = 0;
9090 } else {
9091 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
9092 /* The grf does not define any objects of the feature,
9093 * so it must be a difficulty setting. Apply it globally */
9094 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
9095 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9096 price_base_multipliers[p] = 0;
9097 } else {
9098 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
9105 extern void InitGRFTownGeneratorNames();
9107 /** Finish loading NewGRFs and execute needed post-processing */
9108 static void AfterLoadGRFs()
9110 for (StringIDMapping *it = _string_to_grf_mapping.Begin(); it != _string_to_grf_mapping.End(); it++) {
9111 *it->target = MapGRFStringID(it->grfid, it->source);
9113 _string_to_grf_mapping.Clear();
9115 /* Free the action 6 override sprites. */
9116 _grf_line_to_action6_sprite_override.clear();
9118 /* Polish cargoes */
9119 FinaliseCargoArray();
9121 /* Pre-calculate all refit masks after loading GRF files. */
9122 CalculateRefitMasks();
9124 /* Polish engines */
9125 FinaliseEngineArray();
9127 /* Set the actually used Canal properties */
9128 FinaliseCanals();
9130 /* Add all new houses to the house array. */
9131 FinaliseHouseArray();
9133 /* Add all new industries to the industry array. */
9134 FinaliseIndustriesArray();
9136 /* Add all new objects to the object array. */
9137 FinaliseObjectsArray();
9139 InitializeSortedCargoSpecs();
9141 /* Sort the list of industry types. */
9142 SortIndustryTypes();
9144 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9145 BuildIndustriesLegend();
9147 /* Build the routemap legend, based on the available cargos */
9148 BuildLinkStatsLegend();
9150 /* Add all new airports to the airports array. */
9151 FinaliseAirportsArray();
9152 BindAirportSpecs();
9154 /* Update the townname generators list */
9155 InitGRFTownGeneratorNames();
9157 /* Run all queued vehicle list order changes */
9158 CommitVehicleListOrderChanges();
9160 /* Load old shore sprites in new position, if they were replaced by ActionA */
9161 ActivateOldShore();
9163 /* Set up custom rail types */
9164 InitRailTypes();
9166 Engine *e;
9167 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
9168 if (_gted[e->index].rv_max_speed != 0) {
9169 /* Set RV maximum speed from the mph/0.8 unit value */
9170 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9174 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
9175 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9176 if (railtype == INVALID_RAILTYPE) {
9177 /* Rail type is not available, so disable this engine */
9178 e->info.climates = 0;
9179 } else {
9180 e->u.rail.railtype = railtype;
9184 SetYearEngineAgingStops();
9186 FinalisePriceBaseMultipliers();
9188 /* Deallocate temporary loading data */
9189 free(_gted);
9190 _grm_sprites.clear();
9194 * Load all the NewGRFs.
9195 * @param load_index The offset for the first sprite to add.
9196 * @param file_index The Fio index of the first NewGRF to load.
9198 void LoadNewGRF(uint load_index, uint file_index)
9200 /* In case of networking we need to "sync" the start values
9201 * so all NewGRFs are loaded equally. For this we use the
9202 * start date of the game and we set the counters, etc. to
9203 * 0 so they're the same too. */
9204 Date date = _date;
9205 Year year = _cur_year;
9206 DateFract date_fract = _date_fract;
9207 uint16 tick_counter = _tick_counter;
9208 byte display_opt = _display_opt;
9210 if (_networking) {
9211 _cur_year = _settings_game.game_creation.starting_year;
9212 _date = ConvertYMDToDate(_cur_year, 0, 1);
9213 _date_fract = 0;
9214 _tick_counter = 0;
9215 _display_opt = 0;
9218 InitializeGRFSpecial();
9220 ResetNewGRFData();
9223 * Reset the status of all files, so we can 'retry' to load them.
9224 * This is needed when one for example rearranges the NewGRFs in-game
9225 * and a previously disabled NewGRF becomes useable. If it would not
9226 * be reset, the NewGRF would remain disabled even though it should
9227 * have been enabled.
9229 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9230 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9233 _cur.spriteid = load_index;
9235 /* Load newgrf sprites
9236 * in each loading stage, (try to) open each file specified in the config
9237 * and load information from it. */
9238 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9239 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9240 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9241 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9242 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9245 if (stage == GLS_RESERVE) {
9246 static const uint32 overrides[][2] = {
9247 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9248 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9249 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9251 for (size_t i = 0; i < lengthof(overrides); i++) {
9252 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9256 uint slot = file_index;
9258 _cur.stage = stage;
9259 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9260 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9261 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9263 Subdirectory subdir = slot == file_index ? BASESET_DIR : NEWGRF_DIR;
9264 if (!FioCheckFileExists(c->filename, subdir)) {
9265 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9266 c->status = GCS_NOT_FOUND;
9267 continue;
9270 /* A .grf file is activated only if it was active
9271 * when the game was started. If a game is loaded,
9272 * only its active .grfs will be reactivated, unless
9273 * "loadallgraphics on" is used. A .grf file is
9274 * considered active if its action 8 has been
9275 * processed, i.e. its action 8 hasn't been skipped
9276 * using an action 7.
9278 * During activation, only actions 0, 1, 2, 3, 4, 5,
9279 * 7, 8, 9, 0A and 0B are carried out. All others
9280 * are ignored, because they only need to be
9281 * processed once at initialization. */
9283 if (stage == GLS_LABELSCAN) {
9284 GRFFile *newfile = GetFileByFilename (c->filename);
9285 if (newfile == NULL) {
9286 newfile = new GRFFile (c);
9287 *_grf_files.Append() = newfile;
9289 _cur.grffile = newfile;
9292 if (stage != GLS_LABELSCAN) {
9293 _cur.grffile = GetFileByFilename (c->filename);
9294 if (_cur.grffile == NULL) usererror ("File '%s' lost in cache.\n", c->filename);
9295 if (stage == GLS_RESERVE && c->status != GCS_INITIALISED) return;
9296 if (stage == GLS_ACTIVATION && !HasBit(c->flags, GCF_RESERVED)) return;
9299 LoadNewGRFFile(c, slot++, stage, subdir);
9300 if (stage == GLS_RESERVE) {
9301 SetBit(c->flags, GCF_RESERVED);
9302 } else if (stage == GLS_ACTIVATION) {
9303 ClrBit(c->flags, GCF_RESERVED);
9304 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9305 ClearTemporaryNewGRFData(_cur.grffile);
9306 BuildCargoTranslationMap();
9307 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9308 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9309 /* We're not going to activate this, so free whatever data we allocated */
9310 ClearTemporaryNewGRFData(_cur.grffile);
9315 /* Pseudo sprite processing is finished; free temporary stuff */
9316 _cur.ClearDataForNextFile();
9318 /* Call any functions that should be run after GRFs have been loaded. */
9319 AfterLoadGRFs();
9321 /* Now revert back to the original situation */
9322 _cur_year = year;
9323 _date = date;
9324 _date_fract = date_fract;
9325 _tick_counter = tick_counter;
9326 _display_opt = display_opt;