Remove unused parameter from TranslateTTDPatchCodes
[openttd/fttd.git] / src / newgrf.cpp
blobd646c613632c6ec5b021f3d10776084f94b52f26
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 * Reads a variable common to VarAction2 and Action7/9/D.
5741 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5742 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5744 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5745 * @param value returns the value of the variable.
5746 * @param grffile NewGRF querying the variable
5747 * @return true iff the variable is known and the value is returned in 'value'.
5749 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
5751 switch (param) {
5752 case 0x00: // current date
5753 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
5754 return true;
5756 case 0x01: // current year
5757 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
5758 return true;
5760 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)
5761 YearMonthDay ymd;
5762 ConvertDateToYMD(_date, &ymd);
5763 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
5764 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
5765 return true;
5768 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5769 *value = _settings_game.game_creation.landscape;
5770 return true;
5772 case 0x06: // road traffic side, bit 4 clear=left, set=right
5773 *value = _settings_game.vehicle.road_side << 4;
5774 return true;
5776 case 0x09: // date fraction
5777 *value = _date_fract * 885;
5778 return true;
5780 case 0x0A: // animation counter
5781 *value = _tick_counter;
5782 return true;
5784 case 0x0B: { // TTDPatch version
5785 uint major = 2;
5786 uint minor = 6;
5787 uint revision = 1; // special case: 2.0.1 is 2.0.10
5788 uint build = 1382;
5789 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
5790 return true;
5793 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5794 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
5795 return true;
5797 case 0x0E: // Y-offset for train sprites
5798 *value = _cur.grffile->traininfo_vehicle_pitch;
5799 return true;
5801 case 0x0F: // Rail track type cost factors
5802 *value = 0;
5803 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
5804 if (_settings_game.vehicle.disable_elrails) {
5805 /* skip elrail multiplier - disabled */
5806 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
5807 } else {
5808 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
5809 /* Skip monorail multiplier - no space in result */
5811 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
5812 return true;
5814 case 0x11: // current rail tool type
5815 *value = 0; // constant fake value to avoid desync
5816 return true;
5818 case 0x12: // Game mode
5819 *value = _game_mode;
5820 return true;
5822 /* case 0x13: // Tile refresh offset to left not implemented */
5823 /* case 0x14: // Tile refresh offset to right not implemented */
5824 /* case 0x15: // Tile refresh offset upwards not implemented */
5825 /* case 0x16: // Tile refresh offset downwards not implemented */
5826 /* case 0x17: // temperate snow line not implemented */
5828 case 0x1A: // Always -1
5829 *value = UINT_MAX;
5830 return true;
5832 case 0x1B: // Display options
5833 *value = 0x3F; // constant fake value to avoid desync
5834 return true;
5836 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5837 *value = 1;
5838 return true;
5840 case 0x1E: // Miscellaneous GRF features
5841 *value = _misc_grf_features;
5843 /* Add the local flags */
5844 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
5845 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
5846 return true;
5848 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5850 case 0x20: { // snow line height
5851 byte snowline = GetSnowLine();
5852 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= _settings_game.construction.max_heightlevel) {
5853 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
5854 } else {
5855 /* No snow */
5856 *value = 0xFF;
5858 return true;
5861 case 0x21: // OpenTTD version
5862 *value = _openttd_newgrf_version;
5863 return true;
5865 case 0x22: // difficulty level
5866 *value = SP_CUSTOM;
5867 return true;
5869 case 0x23: // long format date
5870 *value = _date;
5871 return true;
5873 case 0x24: // long format year
5874 *value = _cur_year;
5875 return true;
5877 default: return false;
5881 static uint32 GetParamVal(byte param, uint32 *cond_val)
5883 /* First handle variable common with VarAction2 */
5884 uint32 value;
5885 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
5887 /* Non-common variable */
5888 switch (param) {
5889 case 0x84: { // GRF loading stage
5890 uint32 res = 0;
5892 if (_cur.stage > GLS_INIT) SetBit(res, 0);
5893 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
5894 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
5895 return res;
5898 case 0x85: // TTDPatch flags, only for bit tests
5899 if (cond_val == NULL) {
5900 /* Supported in Action 0x07 and 0x09, not 0x0D */
5901 return 0;
5902 } else {
5903 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
5904 *cond_val %= 0x20;
5905 return param_val;
5908 case 0x88: // GRF ID check
5909 return 0;
5911 /* case 0x99: Global ID offset not implemented */
5913 default:
5914 /* GRF Parameter */
5915 if (param < 0x80) return _cur.grffile->GetParam(param);
5917 /* In-game variable. */
5918 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
5919 return UINT_MAX;
5923 /* Action 0x06 */
5924 static int CfgApply (ByteReader *buf)
5926 /* <06> <param-num> <param-size> <offset> ... <FF>
5928 * B param-num Number of parameter to substitute (First = "zero")
5929 * Ignored if that parameter was not specified in newgrf.cfg
5930 * B param-size How many bytes to replace. If larger than 4, the
5931 * bytes of the following parameter are used. In that
5932 * case, nothing is applied unless *all* parameters
5933 * were specified.
5934 * B offset Offset into data from beginning of next sprite
5935 * to place where parameter is to be stored. */
5937 /* Preload the next sprite */
5938 size_t pos = FioGetPos();
5939 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
5940 uint8 type = FioReadByte();
5942 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5943 if (type != 0xFF) {
5944 /* Reset the file position to the start of the next sprite */
5945 FioSeekTo(pos, SEEK_SET);
5947 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5948 return 0;
5951 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
5952 std::pair <GRFLineToSpriteOverride::iterator, bool> ins =
5953 _grf_line_to_action6_sprite_override.insert (std::make_pair (location, ttd_unique_free_ptr<byte>()));
5955 byte *preload_sprite;
5956 if (ins.second) {
5957 preload_sprite = xmalloct<byte> (num);
5958 ins.first->second.reset (preload_sprite);
5959 FioReadBlock (preload_sprite, num);
5960 } else {
5961 preload_sprite = ins.first->second.get();
5964 /* Reset the file position to the start of the next sprite */
5965 FioSeekTo (pos, SEEK_SET);
5967 /* Now perform the Action 0x06 on our data. */
5969 for (;;) {
5970 uint i;
5971 uint param_num;
5972 uint param_size;
5973 uint offset;
5974 bool add_value;
5976 /* Read the parameter to apply. 0xFF indicates no more data to change. */
5977 param_num = buf->ReadByte();
5978 if (param_num == 0xFF) break;
5980 /* Get the size of the parameter to use. If the size covers multiple
5981 * double words, sequential parameter values are used. */
5982 param_size = buf->ReadByte();
5984 /* Bit 7 of param_size indicates we should add to the original value
5985 * instead of replacing it. */
5986 add_value = HasBit(param_size, 7);
5987 param_size = GB(param_size, 0, 7);
5989 /* Where to apply the data to within the pseudo sprite data. */
5990 offset = buf->ReadExtendedByte();
5992 /* If the parameter is a GRF parameter (not an internal variable) check
5993 * if it (and all further sequential parameters) has been defined. */
5994 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
5995 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
5996 break;
5999 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6001 bool carry = false;
6002 for (i = 0; i < param_size && offset + i < num; i++) {
6003 uint32 value = GetParamVal(param_num + i / 4, NULL);
6004 /* Reset carry flag for each iteration of the variable (only really
6005 * matters if param_size is greater than 4) */
6006 if (i % 4 == 0) carry = false;
6008 if (add_value) {
6009 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6010 preload_sprite[offset + i] = GB(new_value, 0, 8);
6011 /* Check if the addition overflowed */
6012 carry = new_value >= 256;
6013 } else {
6014 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
6019 return 0;
6023 * Disable a static NewGRF when it is influencing another (non-static)
6024 * NewGRF as this could cause desyncs.
6026 * We could just tell the NewGRF querying that the file doesn't exist,
6027 * but that might give unwanted results. Disabling the NewGRF gives the
6028 * best result as no NewGRF author can complain about that.
6029 * @param c The NewGRF to disable.
6031 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
6033 DisableGrf (STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
6036 /* Action 0x07
6037 * Action 0x09 */
6038 static int SkipIf (ByteReader *buf)
6040 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6042 * B param-num
6043 * B param-size
6044 * B condition-type
6045 * V value
6046 * B num-sprites */
6047 /* TODO: More params. More condition types. */
6048 uint32 cond_val = 0;
6049 uint32 mask = 0;
6050 bool result;
6052 uint8 param = buf->ReadByte();
6053 uint8 paramsize = buf->ReadByte();
6054 uint8 condtype = buf->ReadByte();
6056 if (condtype < 2) {
6057 /* Always 1 for bit tests, the given value should be ignored. */
6058 paramsize = 1;
6061 switch (paramsize) {
6062 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6063 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6064 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6065 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6066 default: break;
6069 if (param < 0x80 && _cur.grffile->param_end <= param) {
6070 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6071 return 0;
6074 uint32 param_val = GetParamVal(param, &cond_val);
6076 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
6079 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6080 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6081 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6082 * So, when the condition type is one of those, the specific variable
6083 * 0x88 code is skipped, so the "general" code for the cargo
6084 * availability conditions kicks in.
6086 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
6087 /* GRF ID checks */
6089 GRFConfig *c = GetGRFConfig(cond_val, mask);
6091 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6092 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6093 c = NULL;
6096 if (condtype != 10 && c == NULL) {
6097 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6098 return 0;
6101 switch (condtype) {
6102 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6103 case 0x06: // Is GRFID active?
6104 result = c->status == GCS_ACTIVATED;
6105 break;
6107 case 0x07: // Is GRFID non-active?
6108 result = c->status != GCS_ACTIVATED;
6109 break;
6111 case 0x08: // GRFID is not but will be active?
6112 result = c->status == GCS_INITIALISED;
6113 break;
6115 case 0x09: // GRFID is or will be active?
6116 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6117 break;
6119 case 0x0A: // GRFID is not nor will be active
6120 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6121 result = c == NULL || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6122 break;
6124 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return 0;
6126 } else {
6127 /* Parameter or variable tests */
6128 switch (condtype) {
6129 case 0x00: result = !!(param_val & (1 << cond_val));
6130 break;
6131 case 0x01: result = !(param_val & (1 << cond_val));
6132 break;
6133 case 0x02: result = (param_val & mask) == cond_val;
6134 break;
6135 case 0x03: result = (param_val & mask) != cond_val;
6136 break;
6137 case 0x04: result = (param_val & mask) < cond_val;
6138 break;
6139 case 0x05: result = (param_val & mask) > cond_val;
6140 break;
6141 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6142 break;
6143 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6144 break;
6145 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6146 break;
6147 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6148 break;
6150 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return 0;
6154 if (!result) {
6155 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6156 return 0;
6159 uint8 numsprites = buf->ReadByte();
6161 /* numsprites can be a GOTO label if it has been defined in the GRF
6162 * file. The jump will always be the first matching label that follows
6163 * the current nfo_line. If no matching label is found, the first matching
6164 * label in the file is used. */
6165 GRFLabel *choice = NULL;
6166 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
6167 if (label->label != numsprites) continue;
6169 /* Remember a goto before the current line */
6170 if (choice == NULL) choice = label;
6171 /* If we find a label here, this is definitely good */
6172 if (label->nfo_line > _cur.nfo_line) {
6173 choice = label;
6174 break;
6178 if (choice != NULL) {
6179 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6180 FioSeekTo(choice->pos, SEEK_SET);
6181 _cur.nfo_line = choice->nfo_line;
6182 return 0;
6185 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6187 if (numsprites != 0) return numsprites;
6189 /* If an action 8 hasn't been encountered yet, disable the grf. */
6190 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6191 DisableCur();
6194 /* Zero means there are no sprites to skip, so we use -1 to indicate
6195 * that all further sprites should be skipped. */
6196 return -1;
6200 /* Action 0x08 (GLS_FILESCAN) */
6201 static int ScanInfo (ByteReader *buf)
6203 uint8 grf_version = buf->ReadByte();
6204 uint32 grfid = buf->ReadDWord();
6205 const char *name = buf->ReadString();
6207 _cur.grfconfig->ident.grfid = grfid;
6209 if (grf_version < 2 || grf_version > 8) {
6210 SetBit(_cur.grfconfig->flags, GCF_INVALID);
6211 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);
6214 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6215 if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6217 _cur.grfconfig->name->add (0x7F, grfid, false, name);
6219 if (buf->HasData()) {
6220 const char *info = buf->ReadString();
6221 _cur.grfconfig->info->add (0x7F, grfid, true, info);
6224 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6225 return -1;
6228 /* Action 0x08 */
6229 static int GRFInfo (ByteReader *buf)
6231 /* <08> <version> <grf-id> <name> <info>
6233 * B version newgrf version, currently 06
6234 * 4*B grf-id globally unique ID of this .grf file
6235 * S name name of this .grf set
6236 * S info string describing the set, and e.g. author and copyright */
6238 uint8 version = buf->ReadByte();
6239 uint32 grfid = buf->ReadDWord();
6240 const char *name = buf->ReadString();
6242 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6243 DisableCur (STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6244 return -1;
6247 if (_cur.grffile->grfid != grfid) {
6248 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));
6249 _cur.grffile->grfid = grfid;
6252 _cur.grffile->grf_version = version;
6253 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6255 /* Do swap the GRFID for displaying purposes since people expect that */
6256 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);
6258 return 0;
6261 /* Action 0x0A */
6262 static int SpriteReplace (ByteReader *buf)
6264 /* <0A> <num-sets> <set1> [<set2> ...]
6265 * <set>: <num-sprites> <first-sprite>
6267 * B num-sets How many sets of sprites to replace.
6268 * Each set:
6269 * B num-sprites How many sprites are in this set
6270 * W first-sprite First sprite number to replace */
6272 uint8 num_sets = buf->ReadByte();
6274 for (uint i = 0; i < num_sets; i++) {
6275 uint8 num_sprites = buf->ReadByte();
6276 uint16 first_sprite = buf->ReadWord();
6278 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6279 i, num_sprites, first_sprite
6282 for (uint j = 0; j < num_sprites; j++) {
6283 int load_index = first_sprite + j;
6284 _cur.nfo_line++;
6285 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6287 /* Shore sprites now located at different addresses.
6288 * So detect when the old ones get replaced. */
6289 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6290 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
6295 return 0;
6298 /* Action 0x0A (SKIP) */
6299 static int SkipActA (ByteReader *buf)
6301 uint8 num_sets = buf->ReadByte();
6303 int skip = 0;
6304 for (uint i = 0; i < num_sets; i++) {
6305 /* Skip the sprites this replaces */
6306 skip += buf->ReadByte();
6307 /* But ignore where they go */
6308 buf->ReadWord();
6311 grfmsg (3, "SkipActA: Skipping %d sprites", skip);
6313 return skip;
6316 /* Action 0x0B */
6317 static int GRFLoadError (ByteReader *buf)
6319 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6321 * B severity 00: notice, contine loading grf file
6322 * 01: warning, continue loading grf file
6323 * 02: error, but continue loading grf file, and attempt
6324 * loading grf again when loading or starting next game
6325 * 03: error, abort loading and prevent loading again in
6326 * the future (only when restarting the patch)
6327 * B language-id see action 4, use 1F for built-in error messages
6328 * B message-id message to show, see below
6329 * S message for custom messages (message-id FF), text of the message
6330 * not present for built-in messages.
6331 * V data additional data for built-in (or custom) messages
6332 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6334 static const StringID msgstr[] = {
6335 STR_NEWGRF_ERROR_VERSION_NUMBER,
6336 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6337 STR_NEWGRF_ERROR_UNSET_SWITCH,
6338 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6339 STR_NEWGRF_ERROR_LOAD_BEFORE,
6340 STR_NEWGRF_ERROR_LOAD_AFTER,
6341 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6344 static const StringID sevstr[] = {
6345 STR_NEWGRF_ERROR_MSG_INFO,
6346 STR_NEWGRF_ERROR_MSG_WARNING,
6347 STR_NEWGRF_ERROR_MSG_ERROR,
6348 STR_NEWGRF_ERROR_MSG_FATAL
6351 byte severity = buf->ReadByte();
6352 byte lang = buf->ReadByte();
6353 byte message_id = buf->ReadByte();
6355 /* Skip the error if it isn't valid for the current language. */
6356 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return 0;
6358 /* Skip the error until the activation stage unless bit 7 of the severity
6359 * is set. */
6360 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6361 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6362 return 0;
6364 ClrBit(severity, 7);
6366 if (severity >= lengthof(sevstr)) {
6367 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6368 severity = 2;
6369 } else if (severity == 3) {
6370 /* This is a fatal error, so make sure the GRF is deactivated and no
6371 * more of it gets loaded. */
6372 DisableCur();
6374 /* Make sure we show fatal errors, instead of silly infos from before */
6375 delete _cur.grfconfig->error;
6376 _cur.grfconfig->error = NULL;
6379 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6380 grfmsg(7, "GRFLoadError: Invalid message id.");
6382 } else if (!buf->HasData (2)) {
6383 grfmsg(7, "GRFLoadError: No message data supplied.");
6385 } else if (_cur.grfconfig->error == NULL) {
6386 /* For now we can only show one message per newgrf file. */
6387 GRFError *error = new GRFError (sevstr[severity]);
6389 if (message_id != 0xFF) {
6390 error->message = msgstr[message_id];
6391 } else if (buf->HasData()) {
6392 /* This is a custom error message. */
6393 const char *message = buf->ReadString();
6394 error->custom_message = TranslateTTDPatchCodes (_cur.grffile->grfid, lang, true, message, SCC_RAW_STRING_POINTER);
6395 } else {
6396 grfmsg(7, "GRFLoadError: No custom message supplied.");
6397 error->custom_message = xstrdup("");
6400 if (buf->HasData()) {
6401 const char *data = buf->ReadString();
6402 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6403 } else {
6404 grfmsg(7, "GRFLoadError: No message data supplied.");
6405 error->data = xstrdup("");
6408 /* Only two parameter numbers can be used in the string. */
6409 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6410 uint param_number = buf->ReadByte();
6411 error->param_value[i] = _cur.grffile->GetParam(param_number);
6414 _cur.grfconfig->error = error;
6417 return (severity == 3) ? -1 : 0;
6420 /* Action 0x0C */
6421 static int GRFComment (ByteReader *buf)
6423 /* <0C> [<ignored...>]
6425 * V ignored Anything following the 0C is ignored */
6427 if (buf->HasData()) grfmsg (2, "GRFComment: %s", buf->ReadString());
6429 return 0;
6432 /* Action 0x0D (GLS_SAFETYSCAN) */
6433 static int SafeParamSet (ByteReader *buf)
6435 uint8 target = buf->ReadByte();
6437 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6438 if (target < 0x80 || target == 0x9E) return 0;
6440 /* GRM could be unsafe, but as here it can only happen after other GRFs
6441 * are loaded, it should be okay. If the GRF tried to use the slots it
6442 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6443 * sprites is considered safe. */
6445 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6447 /* Skip remainder of GRF */
6448 return -1;
6452 static uint32 GetPatchVariable(uint8 param)
6454 switch (param) {
6455 /* start year - 1920 */
6456 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
6458 /* freight trains weight factor */
6459 case 0x0E: return _settings_game.vehicle.freight_trains;
6461 /* empty wagon speed increase */
6462 case 0x0F: return 0;
6464 /* plane speed factor; our patch option is reversed from TTDPatch's,
6465 * the following is good for 1x, 2x and 4x (most common?) and...
6466 * well not really for 3x. */
6467 case 0x10:
6468 switch (_settings_game.vehicle.plane_speed) {
6469 default:
6470 case 4: return 1;
6471 case 3: return 2;
6472 case 2: return 2;
6473 case 1: return 4;
6477 /* 2CC colourmap base sprite */
6478 case 0x11: return SPR_2CCMAP_BASE;
6480 /* map size: format = -MABXYSS
6481 * M : the type of map
6482 * bit 0 : set : squared map. Bit 1 is now not relevant
6483 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6484 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6485 * clear : X is the bigger edge.
6486 * A : minimum edge(log2) of the map
6487 * B : maximum edge(log2) of the map
6488 * XY : edges(log2) of each side of the map.
6489 * SS : combination of both X and Y, thus giving the size(log2) of the map
6491 case 0x13: {
6492 byte map_bits = 0;
6493 byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6494 byte log_Y = MapLogY() - 6;
6495 byte max_edge = max(log_X, log_Y);
6497 if (log_X == log_Y) { // we have a squared map, since both edges are identical
6498 SetBit(map_bits, 0);
6499 } else {
6500 if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
6503 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
6504 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
6507 /* The maximum height of the map. */
6508 case 0x14:
6509 return _settings_game.construction.max_heightlevel;
6511 /* Extra foundations base sprite */
6512 case 0x15:
6513 return SPR_SLOPES_BASE;
6515 /* Shore base sprite */
6516 case 0x16:
6517 return SPR_SHORE_BASE;
6519 default:
6520 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
6521 return 0;
6526 static bool PerformGRM (uint32 *grm, uint16 num_ids, uint16 count,
6527 uint8 op, uint8 target, uint32 *res, const char *type)
6529 uint start = 0;
6530 uint size = 0;
6532 if (op == 6) {
6533 /* Return GRFID of set that reserved ID */
6534 *res = grm[_cur.grffile->GetParam(target)];
6535 return true;
6538 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6539 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
6541 for (uint i = start; i < num_ids; i++) {
6542 if (grm[i] == 0) {
6543 size++;
6544 } else {
6545 if (op == 2 || op == 3) break;
6546 start = i + 1;
6547 size = 0;
6550 if (size == count) break;
6553 if (size == count) {
6554 /* Got the slot... */
6555 if (op == 0 || op == 3) {
6556 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
6557 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
6559 *res = start;
6560 return true;
6563 /* Unable to allocate */
6564 if (op != 4 && op != 5) {
6565 /* Deactivate GRF */
6566 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
6567 DisableCur (STR_NEWGRF_ERROR_GRM_FAILED);
6568 return false;
6571 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
6572 *res = UINT_MAX;
6573 return true;
6577 /** Action 0x0D: Set parameter */
6578 static int ParamSet (ByteReader *buf)
6580 /* <0D> <target> <operation> <source1> <source2> [<data>]
6582 * B target parameter number where result is stored
6583 * B operation operation to perform, see below
6584 * B source1 first source operand
6585 * B source2 second source operand
6586 * D data data to use in the calculation, not necessary
6587 * if both source1 and source2 refer to actual parameters
6589 * Operations
6590 * 00 Set parameter equal to source1
6591 * 01 Addition, source1 + source2
6592 * 02 Subtraction, source1 - source2
6593 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6594 * 04 Signed multiplication, source1 * source2 (both signed)
6595 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6596 * signed quantity; left shift if positive and right shift if
6597 * negative, source1 is unsigned)
6598 * 06 Signed bit shift, source1 by source2
6599 * (source2 like in 05, and source1 as well)
6602 uint8 target = buf->ReadByte();
6603 uint8 oper = buf->ReadByte();
6604 uint32 src1 = buf->ReadByte();
6605 uint32 src2 = buf->ReadByte();
6607 uint32 data = 0;
6608 if (buf->HasData (4)) data = buf->ReadDWord();
6610 /* You can add 80 to the operation to make it apply only if the target
6611 * is not defined yet. In this respect, a parameter is taken to be
6612 * defined if any of the following applies:
6613 * - it has been set to any value in the newgrf(w).cfg parameter list
6614 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6615 * an earlier action D */
6616 if (HasBit(oper, 7)) {
6617 if (target < 0x80 && target < _cur.grffile->param_end) {
6618 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
6619 return 0;
6622 oper = GB(oper, 0, 7);
6625 if (src2 != 0xFE) {
6626 /* The source1 and source2 operands refer to the grf parameter number
6627 * like in action 6 and 7. In addition, they can refer to the special
6628 * variables available in action 7, or they can be FF to use the value
6629 * of <data>. If referring to parameters that are undefined, a value
6630 * of 0 is used instead. */
6631 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
6632 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
6633 } else if (GB(data, 0, 8) != 0xFF) {
6634 /* Read another GRF File's parameter */
6635 const GRFFile *file = GetFileByGRFID(data);
6636 GRFConfig *c = GetGRFConfig(data);
6637 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6638 /* Disable the read GRF if it is a static NewGRF. */
6639 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6640 src1 = 0;
6641 } else if (file == NULL || c == NULL || c->status == GCS_DISABLED) {
6642 src1 = 0;
6643 } else if (src1 == 0xFE) {
6644 src1 = c->version;
6645 } else {
6646 src1 = file->GetParam(src1);
6648 } else if (data == 0x0000FFFF) {
6649 /* Patch variables */
6650 src1 = GetPatchVariable(src1);
6651 } else {
6652 /* GRF Resource Management */
6653 uint8 op = src1;
6654 uint8 feature = GB(data, 8, 8);
6655 uint16 count = GB(data, 16, 16);
6657 if (_cur.stage == GLS_RESERVE) {
6658 if (feature == 0x08) {
6659 /* General sprites */
6660 if (op == 0) {
6661 /* Check if the allocated sprites will fit below the original sprite limit */
6662 if (_cur.spriteid + count >= 16384) {
6663 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
6664 DisableCur (STR_NEWGRF_ERROR_GRM_FAILED);
6665 return -1;
6668 /* Reserve space at the current sprite ID */
6669 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
6670 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
6671 _cur.spriteid += count;
6674 /* Ignore GRM result during reservation */
6675 src1 = 0;
6676 } else if (_cur.stage == GLS_ACTIVATION) {
6677 switch (feature) {
6678 case 0x00: // Trains
6679 case 0x01: // Road Vehicles
6680 case 0x02: // Ships
6681 case 0x03: // Aircraft
6682 if (!_settings_game.vehicle.dynamic_engines) {
6683 if (!PerformGRM (&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, &src1, "vehicles")) {
6684 return -1;
6686 } else {
6687 /* GRM does not apply for dynamic engine allocation. */
6688 switch (op) {
6689 case 2:
6690 case 3:
6691 src1 = _cur.grffile->GetParam(target);
6692 break;
6694 default:
6695 src1 = 0;
6696 break;
6699 break;
6701 case 0x08: // General sprites
6702 switch (op) {
6703 case 0:
6704 /* Return space reserved during reservation stage */
6705 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
6706 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
6707 break;
6709 case 1:
6710 src1 = _cur.spriteid;
6711 break;
6713 default:
6714 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
6715 return 0;
6717 break;
6719 case 0x0B: // Cargo
6720 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6721 if (!PerformGRM (_grm_cargoes, NUM_CARGO * 2, count, op, target, &src1, "cargoes")) {
6722 return -1;
6724 break;
6726 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return 0;
6728 } else {
6729 /* Ignore GRM during initialization */
6730 src1 = 0;
6734 /* TODO: You can access the parameters of another GRF file by using
6735 * source2=FE, source1=the other GRF's parameter number and data=GRF
6736 * ID. This is only valid with operation 00 (set). If the GRF ID
6737 * cannot be found, a value of 0 is used for the parameter value
6738 * instead. */
6740 uint32 res;
6741 switch (oper) {
6742 case 0x00:
6743 res = src1;
6744 break;
6746 case 0x01:
6747 res = src1 + src2;
6748 break;
6750 case 0x02:
6751 res = src1 - src2;
6752 break;
6754 case 0x03:
6755 res = src1 * src2;
6756 break;
6758 case 0x04:
6759 res = (int32)src1 * (int32)src2;
6760 break;
6762 case 0x05:
6763 if ((int32)src2 < 0) {
6764 res = src1 >> -(int32)src2;
6765 } else {
6766 res = src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6768 break;
6770 case 0x06:
6771 if ((int32)src2 < 0) {
6772 res = (int32)src1 >> -(int32)src2;
6773 } else {
6774 res = (int32)src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6776 break;
6778 case 0x07: // Bitwise AND
6779 res = src1 & src2;
6780 break;
6782 case 0x08: // Bitwise OR
6783 res = src1 | src2;
6784 break;
6786 case 0x09: // Unsigned division
6787 if (src2 == 0) {
6788 res = src1;
6789 } else {
6790 res = src1 / src2;
6792 break;
6794 case 0x0A: // Signed divison
6795 if (src2 == 0) {
6796 res = src1;
6797 } else {
6798 res = (int32)src1 / (int32)src2;
6800 break;
6802 case 0x0B: // Unsigned modulo
6803 if (src2 == 0) {
6804 res = src1;
6805 } else {
6806 res = src1 % src2;
6808 break;
6810 case 0x0C: // Signed modulo
6811 if (src2 == 0) {
6812 res = src1;
6813 } else {
6814 res = (int32)src1 % (int32)src2;
6816 break;
6818 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return 0;
6821 switch (target) {
6822 case 0x8E: // Y-Offset for train sprites
6823 _cur.grffile->traininfo_vehicle_pitch = res;
6824 break;
6826 case 0x8F: { // Rail track type cost factors
6827 extern RailtypeInfo _railtypes[RAILTYPE_END];
6828 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
6829 if (_settings_game.vehicle.disable_elrails) {
6830 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
6831 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
6832 } else {
6833 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
6834 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
6836 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
6837 break;
6840 /* @todo implement */
6841 case 0x93: // Tile refresh offset to left
6842 case 0x94: // Tile refresh offset to right
6843 case 0x95: // Tile refresh offset upwards
6844 case 0x96: // Tile refresh offset downwards
6845 case 0x97: // Snow line height
6846 case 0x99: // Global ID offset
6847 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6848 break;
6850 case 0x9E: // Miscellaneous GRF features
6851 /* Set train list engine width */
6852 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
6853 /* Remove the local flags from the global flags */
6854 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
6856 /* Only copy safe bits for static grfs */
6857 if (HasBit(_cur.grfconfig->flags, GCF_STATIC)) {
6858 uint32 safe_bits = 0;
6859 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
6861 _misc_grf_features = (_misc_grf_features & ~safe_bits) | (res & safe_bits);
6862 } else {
6863 _misc_grf_features = res;
6865 break;
6867 case 0x9F: // locale-dependent settings
6868 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6869 break;
6871 default:
6872 if (target < 0x80) {
6873 _cur.grffile->param[target] = res;
6874 /* param is zeroed by default */
6875 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
6876 } else {
6877 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
6879 break;
6882 return 0;
6885 /* Action 0x0E (GLS_SAFETYSCAN) */
6886 static int SafeGRFInhibit (ByteReader *buf)
6888 /* <0E> <num> <grfids...>
6890 * B num Number of GRFIDs that follow
6891 * D grfids GRFIDs of the files to deactivate */
6893 uint8 num = buf->ReadByte();
6895 for (uint i = 0; i < num; i++) {
6896 uint32 grfid = buf->ReadDWord();
6898 /* GRF is unsafe it if tries to deactivate other GRFs */
6899 if (grfid != _cur.grfconfig->ident.grfid) {
6900 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6902 /* Skip remainder of GRF */
6903 return -1;
6907 return 0;
6910 /* Action 0x0E */
6911 static int GRFInhibit (ByteReader *buf)
6913 /* <0E> <num> <grfids...>
6915 * B num Number of GRFIDs that follow
6916 * D grfids GRFIDs of the files to deactivate */
6918 uint8 num = buf->ReadByte();
6920 for (uint i = 0; i < num; i++) {
6921 uint32 grfid = buf->ReadDWord();
6922 GRFConfig *file = GetGRFConfig(grfid);
6924 /* Unset activation flag */
6925 if (file != NULL && file != _cur.grfconfig) {
6926 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
6927 DisableGrf (STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
6931 return 0;
6934 /** Action 0x0F - Define Town names */
6935 static int FeatureTownName (ByteReader *buf)
6937 /* <0F> <id> <style-name> <num-parts> <parts>
6939 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6940 * V style-name Name of the style (only for final definition)
6941 * B num-parts Number of parts in this definition
6942 * V parts The parts */
6944 uint32 grfid = _cur.grffile->grfid;
6946 GRFTownName *townname = AddGRFTownName(grfid);
6948 byte id = buf->ReadByte();
6949 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
6951 if (HasBit(id, 7)) {
6952 /* Final definition */
6953 ClrBit(id, 7);
6954 bool new_scheme = _cur.grffile->grf_version >= 7;
6956 byte lang = buf->ReadByte();
6958 byte nb_gen = townname->nb_gen;
6959 do {
6960 ClrBit(lang, 7);
6962 const char *name = buf->ReadString();
6964 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
6965 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
6966 free(lang_name);
6968 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6970 lang = buf->ReadByte();
6971 } while (lang != 0);
6972 townname->id[nb_gen] = id;
6973 townname->nb_gen++;
6976 byte nb = buf->ReadByte();
6977 grfmsg(6, "FeatureTownName: %u parts", nb);
6979 townname->nbparts[id] = nb;
6980 townname->partlist[id] = xcalloct<NamePartList>(nb);
6982 for (int i = 0; i < nb; i++) {
6983 byte nbtext = buf->ReadByte();
6984 townname->partlist[id][i].bitstart = buf->ReadByte();
6985 townname->partlist[id][i].bitcount = buf->ReadByte();
6986 townname->partlist[id][i].maxprob = 0;
6987 townname->partlist[id][i].partcount = nbtext;
6988 townname->partlist[id][i].parts = xcalloct<NamePart>(nbtext);
6989 grfmsg(6, "FeatureTownName: part %d contains %d texts and will use GB(seed, %d, %d)", i, nbtext, townname->partlist[id][i].bitstart, townname->partlist[id][i].bitcount);
6991 for (int j = 0; j < nbtext; j++) {
6992 byte prob = buf->ReadByte();
6994 if (HasBit(prob, 7)) {
6995 byte ref_id = buf->ReadByte();
6997 if (townname->nbparts[ref_id] == 0) {
6998 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
6999 DelGRFTownName(grfid);
7000 DisableCur (STR_NEWGRF_ERROR_INVALID_ID);
7001 return -1;
7004 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7005 townname->partlist[id][i].parts[j].data.id = ref_id;
7006 } else {
7007 const char *text = buf->ReadString();
7008 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
7009 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
7011 townname->partlist[id][i].parts[j].prob = prob;
7012 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
7014 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
7017 return 0;
7020 /** Action 0x10 - Define goto label */
7021 static int DefineGotoLabel (ByteReader *buf)
7023 /* <10> <label> [<comment>]
7025 * B label The label to define
7026 * V comment Optional comment - ignored */
7028 byte nfo_label = buf->ReadByte();
7030 GRFLabel *label = xmalloct<GRFLabel>();
7031 label->label = nfo_label;
7032 label->nfo_line = _cur.nfo_line;
7033 label->pos = FioGetPos();
7034 label->next = NULL;
7036 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7037 if (_cur.grffile->label == NULL) {
7038 _cur.grffile->label = label;
7039 } else {
7040 /* Attach the label to the end of the list */
7041 GRFLabel *l;
7042 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
7043 l->next = label;
7046 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7048 return 0;
7052 * Process a sound import from another GRF file.
7053 * @param sound Destination for sound.
7055 static void ImportGRFSound(SoundEntry *sound)
7057 const GRFFile *file;
7058 uint32 grfid = FioReadDword();
7059 SoundID sound_id = FioReadWord();
7061 file = GetFileByGRFID(grfid);
7062 if (file == NULL || file->sound_offset == 0) {
7063 grfmsg(1, "ImportGRFSound: Source file not available");
7064 return;
7067 if (sound_id >= file->num_sounds) {
7068 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
7069 return;
7072 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7074 *sound = *GetSound(file->sound_offset + sound_id);
7076 /* Reset volume and priority, which TTDPatch doesn't copy */
7077 sound->volume = 128;
7078 sound->priority = 0;
7082 * Load a sound from a file.
7083 * @param offs File offset to read sound from.
7084 * @param sound Destination for sound.
7086 static void LoadGRFSound(size_t offs, SoundEntry *sound)
7088 /* Set default volume and priority */
7089 sound->volume = 0x80;
7090 sound->priority = 0;
7092 if (offs != SIZE_MAX) {
7093 /* Sound is present in the NewGRF. */
7094 sound->file_slot = _cur.file_index;
7095 sound->file_offset = offs;
7096 sound->grf_container_ver = _cur.grf_container_ver;
7100 /* Action 0x11 */
7101 static int GRFSound (ByteReader *buf)
7103 /* <11> <num>
7105 * W num Number of sound files that follow */
7107 uint16 num = buf->ReadWord();
7108 if (num == 0) return 0;
7110 SoundEntry *sound;
7111 if (_cur.grffile->sound_offset == 0) {
7112 _cur.grffile->sound_offset = GetNumSounds();
7113 _cur.grffile->num_sounds = num;
7114 sound = AllocateSound(num);
7115 } else {
7116 sound = GetSound(_cur.grffile->sound_offset);
7119 for (int i = 0; i < num; i++) {
7120 _cur.nfo_line++;
7122 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7123 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7124 bool invalid = i >= _cur.grffile->num_sounds;
7126 size_t offs = FioGetPos();
7128 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7129 byte type = FioReadByte();
7131 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7132 /* Reference to sprite section. */
7133 if (invalid) {
7134 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7135 FioSkipBytes(len);
7136 } else if (len != 4) {
7137 grfmsg(1, "GRFSound: Invalid sprite section import");
7138 FioSkipBytes(len);
7139 } else {
7140 uint32 id = FioReadDword();
7141 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7143 continue;
7146 if (type != 0xFF) {
7147 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7148 FioSkipBytes(7);
7149 SkipSpriteData(type, len - 8);
7150 continue;
7153 if (invalid) {
7154 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7155 FioSkipBytes(len);
7158 byte action = FioReadByte();
7159 switch (action) {
7160 case 0xFF:
7161 /* Allocate sound only in init stage. */
7162 if (_cur.stage == GLS_INIT) {
7163 if (_cur.grf_container_ver >= 2) {
7164 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7165 } else {
7166 LoadGRFSound(offs, sound + i);
7169 FioSkipBytes(len - 1); // already read <action>
7170 break;
7172 case 0xFE:
7173 if (_cur.stage == GLS_ACTIVATION) {
7174 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7175 * importing sounds, so this is probably all wrong... */
7176 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7177 ImportGRFSound(sound + i);
7178 } else {
7179 FioSkipBytes(len - 1); // already read <action>
7181 break;
7183 default:
7184 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7185 FioSkipBytes(len - 1); // already read <action>
7186 break;
7190 return 0;
7193 /* Action 0x11 (SKIP) */
7194 static int SkipAct11 (ByteReader *buf)
7196 /* <11> <num>
7198 * W num Number of sound files that follow */
7200 int skip = buf->ReadWord();
7201 grfmsg (3, "SkipAct11: Skipping %d sprites", skip);
7202 return skip;
7205 /** Action 0x12 */
7206 static int LoadFontGlyph (ByteReader *buf)
7208 /* <12> <num_def> <font_size> <num_char> <base_char>
7210 * B num_def Number of definitions
7211 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7212 * B num_char Number of consecutive glyphs
7213 * W base_char First character index */
7215 uint8 num_def = buf->ReadByte();
7217 for (uint i = 0; i < num_def; i++) {
7218 FontSize size = (FontSize)buf->ReadByte();
7219 uint8 num_char = buf->ReadByte();
7220 uint16 base_char = buf->ReadWord();
7222 FontCache *fc;
7223 if (size >= FS_END) {
7224 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7225 fc = NULL;
7226 } else {
7227 fc = FontCache::Get (size);
7230 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7232 for (uint c = 0; c < num_char; c++) {
7233 if (fc != NULL) fc->SetUnicodeGlyph (base_char + c, _cur.spriteid);
7234 _cur.nfo_line++;
7235 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7239 return 0;
7242 /** Action 0x12 (SKIP) */
7243 static int SkipAct12 (ByteReader *buf)
7245 /* <12> <num_def> <font_size> <num_char> <base_char>
7247 * B num_def Number of definitions
7248 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7249 * B num_char Number of consecutive glyphs
7250 * W base_char First character index */
7252 uint8 num_def = buf->ReadByte();
7254 int skip = 0;
7255 for (uint i = 0; i < num_def; i++) {
7256 /* Ignore 'size' byte */
7257 buf->ReadByte();
7259 /* Sum up number of characters */
7260 skip += buf->ReadByte();
7262 /* Ignore 'base_char' word */
7263 buf->ReadWord();
7266 grfmsg (3, "SkipAct12: Skipping %d sprites", skip);
7268 return skip;
7271 /** Action 0x13 */
7272 static int TranslateGRFStrings (ByteReader *buf)
7274 /* <13> <grfid> <num-ent> <offset> <text...>
7276 * 4*B grfid The GRFID of the file whose texts are to be translated
7277 * B num-ent Number of strings
7278 * W offset First text ID
7279 * S text... Zero-terminated strings */
7281 uint32 grfid = buf->ReadDWord();
7282 const GRFConfig *c = GetGRFConfig(grfid);
7283 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7284 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7285 return 0;
7288 if (c->status == GCS_INITIALISED) {
7289 /* If the file is not active but will be activated later, give an error
7290 * and disable this file. */
7291 GRFError *error = DisableCur (STR_NEWGRF_ERROR_LOAD_AFTER);
7293 char tmp[256];
7294 GetString (tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE);
7295 error->data = xstrdup(tmp);
7297 return -1;
7300 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7301 * to be added as a generic string, thus the language id of 0x7F. For this to work
7302 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7303 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7304 * not change anything if a string has been provided specifically for this language. */
7305 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7306 byte num_strings = buf->ReadByte();
7307 uint16 first_id = buf->ReadWord();
7309 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
7310 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7311 return 0;
7314 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7315 const char *string = buf->ReadString();
7317 if (StrEmpty(string)) {
7318 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7319 continue;
7322 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7325 return 0;
7328 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7329 static bool ChangeGRFName(byte langid, const char *str)
7331 _cur.grfconfig->name->add (langid, _cur.grfconfig->ident.grfid, false, str);
7332 return true;
7335 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7336 static bool ChangeGRFDescription(byte langid, const char *str)
7338 _cur.grfconfig->info->add (langid, _cur.grfconfig->ident.grfid, true, str);
7339 return true;
7342 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7343 static bool ChangeGRFURL(byte langid, const char *str)
7345 _cur.grfconfig->url->add (langid, _cur.grfconfig->ident.grfid, false, str);
7346 return true;
7349 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7350 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7352 if (len != 1) {
7353 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7354 buf->Skip(len);
7355 } else {
7356 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7358 return true;
7361 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7362 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7364 if (len != 1) {
7365 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7366 buf->Skip(len);
7367 } else {
7368 char data = buf->ReadByte();
7369 GRFPalette pal = GRFP_GRF_UNSET;
7370 switch (data) {
7371 case '*':
7372 case 'A': pal = GRFP_GRF_ANY; break;
7373 case 'W': pal = GRFP_GRF_WINDOWS; break;
7374 case 'D': pal = GRFP_GRF_DOS; break;
7375 default:
7376 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7377 break;
7379 if (pal != GRFP_GRF_UNSET) {
7380 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7381 _cur.grfconfig->palette |= pal;
7384 return true;
7387 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7388 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7390 if (len != 1) {
7391 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7392 buf->Skip(len);
7393 } else {
7394 char data = buf->ReadByte();
7395 GRFPalette pal = GRFP_BLT_UNSET;
7396 switch (data) {
7397 case '8': pal = GRFP_BLT_UNSET; break;
7398 case '3': pal = GRFP_BLT_32BPP; break;
7399 default:
7400 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7401 return true;
7403 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7404 _cur.grfconfig->palette |= pal;
7406 return true;
7409 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7410 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7412 if (len != 4) {
7413 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7414 buf->Skip(len);
7415 } else {
7416 /* Set min_loadable_version as well (default to minimal compatibility) */
7417 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7419 return true;
7422 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7423 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7425 if (len != 4) {
7426 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7427 buf->Skip(len);
7428 } else {
7429 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7430 if (_cur.grfconfig->version == 0) {
7431 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7432 _cur.grfconfig->min_loadable_version = 0;
7434 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7435 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7436 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
7439 return true;
7442 static GRFParameterInfo *_cur_parameter; ///< The parameter which info is currently changed by the newgrf.
7444 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7445 static bool ChangeGRFParamName(byte langid, const char *str)
7447 _cur_parameter->name.add (langid, _cur.grfconfig->ident.grfid, false, str);
7448 return true;
7451 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7452 static bool ChangeGRFParamDescription(byte langid, const char *str)
7454 _cur_parameter->desc.add (langid, _cur.grfconfig->ident.grfid, true, str);
7455 return true;
7458 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7459 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7461 if (len != 1) {
7462 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7463 buf->Skip(len);
7464 } else {
7465 GRFParameterType type = (GRFParameterType)buf->ReadByte();
7466 if (type < PTYPE_END) {
7467 _cur_parameter->type = type;
7468 } else {
7469 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7472 return true;
7475 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7476 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7478 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7479 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7480 buf->Skip(len);
7481 } else if (len != 8) {
7482 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7483 buf->Skip(len);
7484 } else {
7485 _cur_parameter->min_value = buf->ReadDWord();
7486 _cur_parameter->max_value = buf->ReadDWord();
7488 return true;
7491 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7492 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7494 if (len < 1 || len > 3) {
7495 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7496 buf->Skip(len);
7497 } else {
7498 byte param_nr = buf->ReadByte();
7499 if (param_nr >= lengthof(_cur.grfconfig->param)) {
7500 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7501 buf->Skip(len - 1);
7502 } else {
7503 _cur_parameter->param_nr = param_nr;
7504 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
7505 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7509 return true;
7512 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7513 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7515 if (len != 4) {
7516 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7517 buf->Skip(len);
7518 } else {
7519 _cur_parameter->def_value = buf->ReadDWord();
7521 _cur.grfconfig->has_param_defaults = true;
7522 return true;
7526 * Data structure to store the allowed id/type combinations for action 14. The
7527 * data can be represented as a tree with 3 types of nodes:
7528 * 1. Branch nodes (identified by 'C' for choice).
7529 * 2. Binary leaf nodes (identified by 'B').
7530 * 3. Text leaf nodes (identified by 'T').
7532 struct AllowedSubtags {
7533 typedef bool (*DataHandler) (size_t, ByteReader *); ///< Type of callback function for binary nodes
7534 typedef bool (*TextHandler) (byte, const char *str); ///< Type of callback function for text nodes
7535 typedef bool (*BranchHandler) (ByteReader *); ///< Type of callback function for branch nodes
7537 uint32 id; ///< The identifier for this node
7538 byte type; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7539 byte nsub; ///< The number of subtags, or 0 if not applicable
7540 union {
7541 DataHandler data; ///< Callback function for a binary node, only valid if type == 'B'.
7542 TextHandler text; ///< Callback function for a text node, only valid if type == 'T'.
7543 BranchHandler branch; ///< Callback function for a branch node, only valid if type == 'C' && nsub == 0.
7544 const AllowedSubtags *subtags; ///< Pointer to a list of subtags, only valid if type == 'C' && nsub != 0.
7547 /** Create empty subtags object used to identify the end of a list. */
7548 CONSTEXPR AllowedSubtags() :
7549 id(0), type(0), nsub(0), subtags(NULL)
7553 * Create a binary leaf node.
7554 * @param id The id for this node.
7555 * @param handler The callback function to call.
7557 CONSTEXPR AllowedSubtags (uint32 id, DataHandler handler) :
7558 id(id), type('B'), nsub(0), data(handler)
7563 * Create a text leaf node.
7564 * @param id The id for this node.
7565 * @param handler The callback function to call.
7567 CONSTEXPR AllowedSubtags (uint32 id, TextHandler handler) :
7568 id(id), type('T'), nsub(0), text(handler)
7573 * Create a branch node with a callback handler
7574 * @param id The id for this node.
7575 * @param handler The callback function to call.
7577 CONSTEXPR AllowedSubtags (uint32 id, BranchHandler handler) :
7578 id(id), type('C'), nsub(0), branch(handler)
7583 * Create a branch node with a list of sub-nodes.
7584 * @param id The id for this node.
7585 * @param subtags Array with all valid subtags.
7587 template <uint N>
7588 CONSTEXPR AllowedSubtags (uint32 id, const AllowedSubtags (&subtags) [N]) :
7589 id(id), type('C'), nsub(N), subtags(subtags)
7591 assert_tcompile (N > 0);
7592 assert_tcompile (N <= UINT8_MAX);
7596 static bool SkipUnknownInfo(ByteReader *buf, byte type);
7597 static bool HandleNodes(ByteReader *buf, const AllowedSubtags *tags);
7600 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7601 * of some parameter values (type uint/enum) or the names of some bits
7602 * (type bitmask). In both cases the format is the same:
7603 * Each subnode should be a text node with the value/bit number as id.
7605 static bool ChangeGRFParamValueNames(ByteReader *buf)
7607 for (;;) {
7608 byte type = buf->ReadByte();
7609 if (type == 0) break;
7611 uint32 id = buf->ReadDWord();
7612 if (type != 'T' || id > _cur_parameter->max_value) {
7613 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7614 if (!SkipUnknownInfo(buf, type)) return false;
7615 continue;
7618 byte langid = buf->ReadByte();
7619 const char *name_string = buf->ReadString();
7621 _cur_parameter->value_names[id].add (langid,
7622 _cur.grfconfig->ident.grfid, false, name_string);
7624 return true;
7627 /** Action14 parameter tags */
7628 static const AllowedSubtags _tags_parameters[] = {
7629 AllowedSubtags('NAME', ChangeGRFParamName),
7630 AllowedSubtags('DESC', ChangeGRFParamDescription),
7631 AllowedSubtags('TYPE', ChangeGRFParamType),
7632 AllowedSubtags('LIMI', ChangeGRFParamLimits),
7633 AllowedSubtags('MASK', ChangeGRFParamMask),
7634 AllowedSubtags('VALU', ChangeGRFParamValueNames),
7635 AllowedSubtags('DFLT', ChangeGRFParamDefault),
7636 AllowedSubtags()
7640 * Callback function for 'INFO'->'PARA' to set extra information about the
7641 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7642 * the parameter number as id. The first parameter has id 0. The maximum
7643 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7645 static bool HandleParameterInfo(ByteReader *buf)
7647 for (;;) {
7648 byte type = buf->ReadByte();
7649 if (type == 0) break;
7651 uint32 id = buf->ReadDWord();
7652 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
7653 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7654 if (!SkipUnknownInfo(buf, type)) return false;
7655 continue;
7658 if (id >= _cur.grfconfig->param_info.Length()) {
7659 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
7660 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
7661 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
7663 if (_cur.grfconfig->param_info[id] == NULL) {
7664 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
7666 _cur_parameter = _cur.grfconfig->param_info[id];
7667 /* Read all parameter-data and process each node. */
7668 if (!HandleNodes(buf, _tags_parameters)) return false;
7670 return true;
7673 /** Action14 tags for the INFO node */
7674 static const AllowedSubtags _tags_info[] = {
7675 AllowedSubtags('NAME', ChangeGRFName),
7676 AllowedSubtags('DESC', ChangeGRFDescription),
7677 AllowedSubtags('URL_', ChangeGRFURL),
7678 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
7679 AllowedSubtags('PALS', ChangeGRFPalette),
7680 AllowedSubtags('BLTR', ChangeGRFBlitter),
7681 AllowedSubtags('VRSN', ChangeGRFVersion),
7682 AllowedSubtags('MINV', ChangeGRFMinVersion),
7683 AllowedSubtags('PARA', HandleParameterInfo),
7684 AllowedSubtags()
7687 /** Action14 root tags */
7688 static const AllowedSubtags _tags_root[] = {
7689 AllowedSubtags('INFO', _tags_info),
7690 AllowedSubtags()
7695 * Try to skip the current node and all subnodes (if it's a branch node).
7696 * @param buf Buffer.
7697 * @param type The node type to skip.
7698 * @return True if we could skip the node, false if an error occurred.
7700 static bool SkipUnknownInfo(ByteReader *buf, byte type)
7702 /* type and id are already read */
7703 switch (type) {
7704 case 'C':
7705 for (;;) {
7706 byte new_type = buf->ReadByte();
7707 if (new_type == 0) break;
7708 buf->ReadDWord(); // skip the id
7709 if (!SkipUnknownInfo(buf, new_type)) return false;
7711 break;
7713 case 'T':
7714 buf->ReadByte(); // lang
7715 buf->ReadString(); // actual text
7716 break;
7718 case 'B': {
7719 uint16 size = buf->ReadWord();
7720 buf->Skip(size);
7721 break;
7724 default:
7725 return false;
7728 return true;
7732 * Handle the nodes of an Action14
7733 * @param type Type of node.
7734 * @param id ID.
7735 * @param buf Buffer.
7736 * @param subtags Allowed subtags.
7737 * @return Whether all tags could be handled.
7739 static bool HandleNode (byte type, uint32 id, ByteReader *buf, const AllowedSubtags *subtags)
7741 for (const AllowedSubtags *tag = subtags; tag->type != 0; tag++) {
7742 if (tag->id != BSWAP32(id) || tag->type != type) continue;
7743 switch (type) {
7744 default: NOT_REACHED();
7746 case 'T': {
7747 byte langid = buf->ReadByte();
7748 return tag->text (langid, buf->ReadString());
7751 case 'B': {
7752 size_t len = buf->ReadWord();
7753 if (!buf->HasData (len)) return false;
7754 return tag->data (len, buf);
7757 case 'C': {
7758 if (tag->nsub == 0) {
7759 return tag->branch (buf);
7761 return HandleNodes (buf, tag->subtags);
7765 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
7766 return SkipUnknownInfo(buf, type);
7770 * Handle the contents of a 'C' choice of an Action14
7771 * @param buf Buffer.
7772 * @param subtags List of subtags.
7773 * @return Whether the nodes could all be handled.
7775 static bool HandleNodes (ByteReader *buf, const AllowedSubtags *subtags)
7777 for (;;) {
7778 byte type = buf->ReadByte();
7779 if (type == 0) break;
7780 uint32 id = buf->ReadDWord();
7781 if (!HandleNode(type, id, buf, subtags)) return false;
7783 return true;
7787 * Handle Action 0x14
7788 * @param buf Buffer.
7790 static int StaticGRFInfo (ByteReader *buf)
7792 /* <14> <type> <id> <text/data...> */
7793 HandleNodes(buf, _tags_root);
7794 return 0;
7798 * Set the current NewGRF as unsafe for static use
7799 * @param buf Unused.
7800 * @note Used during safety scan on unsafe actions.
7802 static int GRFUnsafe (ByteReader *buf)
7804 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7806 /* Skip remainder of GRF */
7807 return -1;
7811 /** Initialize the TTDPatch flags */
7812 static void InitializeGRFSpecial()
7814 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
7815 | (1 << 0x0D) // newairports
7816 | (1 << 0x0E) // largestations
7817 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
7818 | (0 << 0x10) // loadtime
7819 | (1 << 0x12) // presignals
7820 | (1 << 0x13) // extpresignals
7821 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
7822 | (1 << 0x1B) // multihead
7823 | (1 << 0x1D) // lowmemory
7824 | (1 << 0x1E); // generalfixes
7826 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
7827 | (1 << 0x08) // mammothtrains
7828 | (1 << 0x09) // trainrefit
7829 | (0 << 0x0B) // subsidiaries
7830 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
7831 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7832 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7833 | (1 << 0x14) // bridgespeedlimits
7834 | (1 << 0x16) // eternalgame
7835 | (1 << 0x17) // newtrains
7836 | (1 << 0x18) // newrvs
7837 | (1 << 0x19) // newships
7838 | (1 << 0x1A) // newplanes
7839 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7840 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
7842 _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
7843 | (1 << 0x03) // semaphores
7844 | (1 << 0x0A) // newobjects
7845 | (0 << 0x0B) // enhancedgui
7846 | (0 << 0x0C) // newagerating
7847 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
7848 | (1 << 0x0E) // fullloadany
7849 | (1 << 0x0F) // planespeed
7850 | (0 << 0x10) // moreindustriesperclimate - obsolete
7851 | (0 << 0x11) // moretoylandfeatures
7852 | (1 << 0x12) // newstations
7853 | (1 << 0x13) // tracktypecostdiff
7854 | (1 << 0x14) // manualconvert
7855 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
7856 | (1 << 0x16) // canals
7857 | (1 << 0x17) // newstartyear
7858 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
7859 | (1 << 0x19) // newhouses
7860 | (1 << 0x1A) // newbridges
7861 | (1 << 0x1B) // newtownnames
7862 | (1 << 0x1C) // moreanimation
7863 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
7864 | (1 << 0x1E) // newshistory
7865 | (0 << 0x1F); // custombridgeheads
7867 _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
7868 | (1 << 0x01) // windowsnap
7869 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
7870 | (1 << 0x03) // pathbasedsignalling
7871 | (0 << 0x04) // aichoosechance
7872 | (1 << 0x05) // resolutionwidth
7873 | (1 << 0x06) // resolutionheight
7874 | (1 << 0x07) // newindustries
7875 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
7876 | (0 << 0x09) // townroadbranchprob
7877 | (0 << 0x0A) // tempsnowline
7878 | (1 << 0x0B) // newcargo
7879 | (1 << 0x0C) // enhancemultiplayer
7880 | (1 << 0x0D) // onewayroads
7881 | (1 << 0x0E) // irregularstations
7882 | (1 << 0x0F) // statistics
7883 | (1 << 0x10) // newsounds
7884 | (1 << 0x11) // autoreplace
7885 | (1 << 0x12) // autoslope
7886 | (0 << 0x13) // followvehicle
7887 | (1 << 0x14) // trams
7888 | (0 << 0x15) // enhancetunnels
7889 | (1 << 0x16) // shortrvs
7890 | (1 << 0x17) // articulatedrvs
7891 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
7892 | (1 << 0x1E) // variablerunningcosts
7893 | (1 << 0x1F); // any switch is on
7896 /** Reset and clear all NewGRF stations */
7897 static void ResetCustomStations()
7899 const GRFFile * const *end = _grf_files.End();
7900 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7901 StationSpec **&stations = (*file)->stations;
7902 if (stations == NULL) continue;
7903 for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
7904 if (stations[i] == NULL) continue;
7905 StationSpec *statspec = stations[i];
7907 delete[] statspec->renderdata;
7909 /* Release platforms and layouts */
7910 if (!statspec->copied_layouts) {
7911 for (uint l = 0; l < statspec->lengths; l++) {
7912 for (uint p = 0; p < statspec->platforms[l]; p++) {
7913 free(statspec->layouts[l][p]);
7915 free(statspec->layouts[l]);
7917 free(statspec->layouts);
7918 free(statspec->platforms);
7921 /* Release this station */
7922 free(statspec);
7925 /* Free and reset the station data */
7926 free(stations);
7927 stations = NULL;
7931 /** Reset and clear all NewGRF houses */
7932 static void ResetCustomHouses()
7934 const GRFFile * const *end = _grf_files.End();
7935 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7936 HouseSpec **&housespec = (*file)->housespec;
7937 if (housespec == NULL) continue;
7938 for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
7939 free(housespec[i]);
7942 free(housespec);
7943 housespec = NULL;
7947 /** Reset and clear all NewGRF airports */
7948 static void ResetCustomAirports()
7950 const GRFFile * const *end = _grf_files.End();
7951 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7952 AirportSpec **aslist = (*file)->airportspec;
7953 if (aslist != NULL) {
7954 for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
7955 AirportSpec *as = aslist[i];
7957 if (as != NULL) {
7958 /* We need to remove the tiles layouts */
7959 for (int j = 0; j < as->num_table; j++) {
7960 /* remove the individual layouts */
7961 free(as->table[j]);
7963 free(as->table);
7964 free(as->depot_table);
7966 free(as);
7969 free(aslist);
7970 (*file)->airportspec = NULL;
7973 AirportTileSpec **&airporttilespec = (*file)->airtspec;
7974 if (airporttilespec != NULL) {
7975 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
7976 free(airporttilespec[i]);
7978 free(airporttilespec);
7979 airporttilespec = NULL;
7984 /** Reset and clear all NewGRF industries */
7985 static void ResetCustomIndustries()
7987 const GRFFile * const *end = _grf_files.End();
7988 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7989 IndustrySpec **&industryspec = (*file)->industryspec;
7990 IndustryTileSpec **&indtspec = (*file)->indtspec;
7992 /* We are verifiying both tiles and industries specs loaded from the grf file
7993 * First, let's deal with industryspec */
7994 if (industryspec != NULL) {
7995 for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
7996 IndustrySpec *ind = industryspec[i];
7997 if (ind == NULL) continue;
7999 /* We need to remove the sounds array */
8000 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
8001 free(ind->random_sounds);
8004 /* We need to remove the tiles layouts */
8005 CleanIndustryTileTable(ind);
8007 free(ind);
8010 free(industryspec);
8011 industryspec = NULL;
8014 if (indtspec == NULL) continue;
8015 for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8016 free(indtspec[i]);
8019 free(indtspec);
8020 indtspec = NULL;
8024 /** Reset and clear all NewObjects */
8025 static void ResetCustomObjects()
8027 const GRFFile * const *end = _grf_files.End();
8028 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8029 ObjectSpec **&objectspec = (*file)->objectspec;
8030 if (objectspec == NULL) continue;
8031 for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8032 free(objectspec[i]);
8035 free(objectspec);
8036 objectspec = NULL;
8040 /** Reset and clear all NewGRFs */
8041 static void ResetNewGRF()
8043 const GRFFile * const *end = _grf_files.End();
8044 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8045 delete *file;
8048 _grf_files.Clear();
8049 _cur.grffile = NULL;
8052 /** Clear all NewGRF errors */
8053 static void ResetNewGRFErrors()
8055 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
8056 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
8057 delete c->error;
8058 c->error = NULL;
8064 * Reset all NewGRF loaded data
8065 * TODO
8067 void ResetNewGRFData()
8069 CleanUpStrings();
8070 CleanUpGRFTownNames();
8072 /* Copy/reset original engine info data */
8073 SetupEngines();
8075 /* Copy/reset original bridge info data */
8076 ResetBridges();
8078 /* Reset rail type information */
8079 ResetRailTypes();
8081 /* Allocate temporary refit/cargo class data */
8082 _gted = xcalloct<GRFTempEngineData>(Engine::GetPoolSize());
8084 /* Fill rail type label temporary data for default trains */
8085 Engine *e;
8086 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
8087 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
8090 /* Reset GRM reservations */
8091 memset(&_grm_engines, 0, sizeof(_grm_engines));
8092 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
8094 /* Reset generic feature callback lists */
8095 ResetGenericCallbacks();
8097 /* Reset price base data */
8098 ResetPriceBaseMultipliers();
8100 /* Reset the curencies array */
8101 ResetCurrencies();
8103 /* Reset the house array */
8104 ResetCustomHouses();
8105 ResetHouses();
8107 /* Reset the industries structures*/
8108 ResetCustomIndustries();
8109 ResetIndustries();
8111 /* Reset the objects. */
8112 ObjectClass::Reset();
8113 ResetCustomObjects();
8114 ResetObjects();
8116 /* Reset station classes */
8117 StationClass::Reset();
8118 ResetCustomStations();
8120 /* Reset airport-related structures */
8121 AirportClass::Reset();
8122 ResetCustomAirports();
8123 AirportSpec::ResetAirports();
8124 AirportTileSpec::ResetAirportTiles();
8126 /* Reset canal sprite groups and flags */
8127 memset(_water_feature, 0, sizeof(_water_feature));
8129 /* Reset the snowline table. */
8130 ClearSnowLine();
8132 /* Reset NewGRF files */
8133 ResetNewGRF();
8135 /* Reset NewGRF errors. */
8136 ResetNewGRFErrors();
8138 /* Set up the default cargo types */
8139 SetupCargoForClimate(_settings_game.game_creation.landscape);
8141 /* Reset misc GRF features and train list display variables */
8142 _misc_grf_features = 0;
8144 _loaded_newgrf_features.has_2CC = false;
8145 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8146 _loaded_newgrf_features.has_newhouses = false;
8147 _loaded_newgrf_features.has_newindustries = false;
8148 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
8150 /* Clear all GRF overrides */
8151 _grf_id_overrides.clear();
8153 InitializeSoundPool();
8154 SpriteGroup::pool.CleanPool();
8158 * Reset NewGRF data which is stored persistently in savegames.
8160 void ResetPersistentNewGRFData()
8162 /* Reset override managers */
8163 _engine_mngr.ResetToDefaultMapping();
8164 _house_mngr.ResetMapping();
8165 _industry_mngr.ResetMapping();
8166 _industile_mngr.ResetMapping();
8167 _airport_mngr.ResetMapping();
8168 _airporttile_mngr.ResetMapping();
8172 * Construct the Cargo Mapping
8173 * @note This is the reverse of a cargo translation table
8175 static void BuildCargoTranslationMap()
8177 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8179 for (CargoID c = 0; c < NUM_CARGO; c++) {
8180 const CargoSpec *cs = CargoSpec::Get(c);
8181 if (!cs->IsValid()) continue;
8183 if (_cur.grffile->cargo_list.Length() == 0) {
8184 /* Default translation table, so just a straight mapping to bitnum */
8185 _cur.grffile->cargo_map[c] = cs->bitnum;
8186 } else {
8187 /* Check the translation table for this cargo's label */
8188 int index = _cur.grffile->cargo_list.FindIndex(cs->label);
8189 if (index >= 0) _cur.grffile->cargo_map[c] = index;
8195 * Constructor for GRFFile
8196 * @param config GRFConfig to copy name, grfid and parameters from.
8198 GRFFile::GRFFile(const GRFConfig *config)
8200 this->filename = xstrdup(config->filename);
8201 this->grfid = config->ident.grfid;
8203 /* Initialise local settings to defaults */
8204 this->traininfo_vehicle_pitch = 0;
8205 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8207 /* Mark price_base_multipliers as 'not set' */
8208 for (Price i = PR_BEGIN; i < PR_END; i++) {
8209 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8212 /* Initialise rail type map with default rail types */
8213 memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
8214 this->railtype_map[0] = RAILTYPE_RAIL;
8215 this->railtype_map[1] = RAILTYPE_ELECTRIC;
8216 this->railtype_map[2] = RAILTYPE_MONO;
8217 this->railtype_map[3] = RAILTYPE_MAGLEV;
8219 /* Copy the initial parameter list
8220 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8221 assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8223 assert(config->num_params <= lengthof(config->param));
8224 this->param_end = config->num_params;
8225 if (this->param_end > 0) {
8226 MemCpyT(this->param, config->param, this->param_end);
8230 GRFFile::~GRFFile()
8232 free(this->filename);
8233 delete[] this->language_map;
8238 * List of what cargo labels are refittable for the given the vehicle-type.
8239 * Only currently active labels are applied.
8241 static const CargoLabel _default_refitmasks_rail[] = {
8242 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8243 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8244 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8245 'PLST', 'FZDR',
8246 0 };
8248 static const CargoLabel _default_refitmasks_road[] = {
8249 0 };
8251 static const CargoLabel _default_refitmasks_ships[] = {
8252 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8253 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8254 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8255 'PLST', 'FZDR',
8256 0 };
8258 static const CargoLabel _default_refitmasks_aircraft[] = {
8259 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8260 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8261 0 };
8263 static const CargoLabel * const _default_refitmasks[] = {
8264 _default_refitmasks_rail,
8265 _default_refitmasks_road,
8266 _default_refitmasks_ships,
8267 _default_refitmasks_aircraft,
8272 * Precalculate refit masks from cargo classes for all vehicles.
8274 static void CalculateRefitMasks()
8276 Engine *e;
8278 FOR_ALL_ENGINES(e) {
8279 EngineID engine = e->index;
8280 EngineInfo *ei = &e->info;
8281 bool only_defaultcargo; ///< Set if the vehicle shall carry only the default cargo
8283 /* Did the newgrf specify any refitting? If not, use defaults. */
8284 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8285 uint32 mask = 0;
8286 uint32 not_mask = 0;
8287 uint32 xor_mask = ei->refit_mask;
8289 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8290 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8291 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8293 if (_gted[engine].cargo_allowed != 0) {
8294 /* Build up the list of cargo types from the set cargo classes. */
8295 const CargoSpec *cs;
8296 FOR_ALL_CARGOSPECS(cs) {
8297 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8298 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8302 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8304 /* Apply explicit refit includes/excludes. */
8305 ei->refit_mask |= _gted[engine].ctt_include_mask;
8306 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8307 } else {
8308 uint32 xor_mask = 0;
8310 /* Don't apply default refit mask to wagons nor engines with no capacity */
8311 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8312 const CargoLabel *cl = _default_refitmasks[e->type];
8313 for (uint i = 0;; i++) {
8314 if (cl[i] == 0) break;
8316 CargoID cargo = GetCargoIDByLabel(cl[i]);
8317 if (cargo == CT_INVALID) continue;
8319 SetBit(xor_mask, cargo);
8323 ei->refit_mask = xor_mask & _cargo_mask;
8325 /* If the mask is zero, the vehicle shall only carry the default cargo */
8326 only_defaultcargo = (ei->refit_mask == 0);
8329 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8330 if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8332 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8333 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8334 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8335 ei->cargo_type = CT_INVALID;
8338 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8339 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8340 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8341 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8342 const uint8 *cargo_map_for_first_refittable = NULL;
8344 const GRFFile *file = _gted[engine].defaultcargo_grf;
8345 if (file == NULL) file = e->GetGRF();
8346 if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
8347 cargo_map_for_first_refittable = file->cargo_map;
8351 if (cargo_map_for_first_refittable != NULL) {
8352 /* Use first refittable cargo from cargo translation table */
8353 byte best_local_slot = 0xFF;
8354 CargoID cargo_type;
8355 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8356 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8357 if (local_slot < best_local_slot) {
8358 best_local_slot = local_slot;
8359 ei->cargo_type = cargo_type;
8364 if (ei->cargo_type == CT_INVALID) {
8365 /* Use first refittable cargo slot */
8366 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8369 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8371 /* Clear refit_mask for not refittable ships */
8372 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8373 ei->refit_mask = 0;
8378 /** Set to use the correct action0 properties for each canal feature */
8379 static void FinaliseCanals()
8381 for (uint i = 0; i < CF_END; i++) {
8382 if (_water_feature[i].grffile != NULL) {
8383 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
8384 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
8389 /** Check for invalid engines */
8390 static void FinaliseEngineArray()
8392 Engine *e;
8394 FOR_ALL_ENGINES(e) {
8395 if (e->GetGRF() == NULL) {
8396 const EngineIDMapping &eid = _engine_mngr[e->index];
8397 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8398 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8402 /* When the train does not set property 27 (misc flags), but it
8403 * is overridden by a NewGRF graphically we want to disable the
8404 * flipping possibility. */
8405 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
8406 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8409 /* Skip wagons, there livery is defined via the engine */
8410 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8411 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
8412 SetBit(_loaded_newgrf_features.used_liveries, ls);
8413 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8415 if (e->type == VEH_TRAIN) {
8416 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8417 switch (ls) {
8418 case LS_STEAM:
8419 case LS_DIESEL:
8420 case LS_ELECTRIC:
8421 case LS_MONORAIL:
8422 case LS_MAGLEV:
8423 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8424 break;
8426 case LS_DMU:
8427 case LS_EMU:
8428 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8429 break;
8431 default: NOT_REACHED();
8438 /** Check for invalid cargoes */
8439 static void FinaliseCargoArray()
8441 for (CargoID c = 0; c < NUM_CARGO; c++) {
8442 CargoSpec *cs = CargoSpec::Get(c);
8443 if (!cs->IsValid()) {
8444 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8445 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8446 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8452 * Check if a given housespec is valid and disable it if it's not.
8453 * The housespecs that follow it are used to check the validity of
8454 * multitile houses.
8455 * @param hs The housespec to check.
8456 * @param next1 The housespec that follows \c hs.
8457 * @param next2 The housespec that follows \c next1.
8458 * @param next3 The housespec that follows \c next2.
8459 * @param filename The filename of the newgrf this house was defined in.
8460 * @return Whether the given housespec is valid.
8462 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8464 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8465 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8466 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8467 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8468 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8469 hs->enabled = false;
8470 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);
8471 return false;
8474 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8475 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8476 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8477 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8478 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8479 hs->enabled = false;
8480 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);
8481 return false;
8484 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8485 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8486 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8487 hs->enabled = false;
8488 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);
8489 return false;
8492 /* Make sure that additional parts of multitile houses are not available. */
8493 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
8494 hs->enabled = false;
8495 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);
8496 return false;
8499 return true;
8503 * Make sure there is at least one house available in the year 0 for the given
8504 * climate.
8505 * @param bitmask The climate to check for. Exactly one climate bit should be
8506 * set.
8508 static void EnsureEarlyHouses (HouseZones climate_mask)
8510 for (uint z = 0; z < HZB_END; z++) {
8511 HouseZones bitmask = (HouseZones)(1U << z) | climate_mask;
8512 Year min_year = MAX_YEAR;
8514 for (int i = 0; i < NUM_HOUSES; i++) {
8515 const HouseSpec *hs = HouseSpec::Get(i);
8516 if (hs == NULL || !hs->enabled) continue;
8517 if ((hs->building_availability & bitmask) != bitmask) continue;
8518 if (hs->min_year < min_year) min_year = hs->min_year;
8521 if (min_year == 0) continue;
8523 for (int i = 0; i < NUM_HOUSES; i++) {
8524 HouseSpec *hs = HouseSpec::Get(i);
8525 if (hs == NULL || !hs->enabled) continue;
8526 if ((hs->building_availability & bitmask) != bitmask) continue;
8527 if (hs->min_year == min_year) hs->min_year = 0;
8533 * Add all new houses to the house array. House properties can be set at any
8534 * time in the GRF file, so we can only add a house spec to the house array
8535 * after the file has finished loading. We also need to check the dates, due to
8536 * the TTDPatch behaviour described below that we need to emulate.
8538 static void FinaliseHouseArray()
8540 /* If there are no houses with start dates before 1930, then all houses
8541 * with start dates of 1930 have them reset to 0. This is in order to be
8542 * compatible with TTDPatch, where if no houses have start dates before
8543 * 1930 and the date is before 1930, the game pretends that this is 1930.
8544 * If there have been any houses defined with start dates before 1930 then
8545 * the dates are left alone.
8546 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8547 * minimum introduction date to 0.
8549 const GRFFile * const *end = _grf_files.End();
8550 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8551 HouseSpec **&housespec = (*file)->housespec;
8552 if (housespec == NULL) continue;
8554 for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8555 HouseSpec *hs = housespec[i];
8557 if (hs == NULL) continue;
8559 const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : NULL);
8560 const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : NULL);
8561 const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : NULL);
8563 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
8565 _house_mngr.SetEntitySpec(hs);
8569 for (int i = 0; i < NUM_HOUSES; i++) {
8570 HouseSpec *hs = HouseSpec::Get(i);
8571 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : NULL);
8572 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : NULL);
8573 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : NULL);
8575 /* We need to check all houses again to we are sure that multitile houses
8576 * did get consecutive IDs and none of the parts are missing. */
8577 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
8578 /* GetHouseNorthPart checks 3 houses that are directly before
8579 * it in the house pool. If any of those houses have multi-tile
8580 * flags set it assumes it's part of a multitile house. Since
8581 * we can have invalid houses in the pool marked as disabled, we
8582 * don't want to have them influencing valid tiles. As such set
8583 * building_flags to zero here to make sure any house following
8584 * this one in the pool is properly handled as 1x1 house. */
8585 hs->building_flags = TILE_NO_FLAG;
8589 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
8590 EnsureEarlyHouses (climate_mask);
8592 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
8593 EnsureEarlyHouses (HZ_SUBARTC_ABOVE);
8598 * Add all new industries to the industry array. Industry properties can be set at any
8599 * time in the GRF file, so we can only add a industry spec to the industry array
8600 * after the file has finished loading.
8602 static void FinaliseIndustriesArray()
8604 const GRFFile * const *end = _grf_files.End();
8605 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8606 IndustrySpec **&industryspec = (*file)->industryspec;
8607 IndustryTileSpec **&indtspec = (*file)->indtspec;
8608 if (industryspec != NULL) {
8609 for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8610 IndustrySpec *indsp = industryspec[i];
8612 if (indsp != NULL && indsp->enabled) {
8613 StringID strid;
8614 /* process the conversion of text at the end, so to be sure everything will be fine
8615 * and available. Check if it does not return undefind marker, which is a very good sign of a
8616 * substitute industry who has not changed the string been examined, thus using it as such */
8617 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
8618 if (strid != STR_UNDEFINED) indsp->name = strid;
8620 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
8621 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
8623 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
8624 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
8626 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
8627 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
8629 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
8630 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
8632 if (indsp->station_name != STR_NULL) {
8633 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8634 * station's name. Don't want to lose the value, therefore, do not process. */
8635 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
8636 if (strid != STR_UNDEFINED) indsp->station_name = strid;
8639 _industry_mngr.SetEntitySpec(indsp);
8640 _loaded_newgrf_features.has_newindustries = true;
8645 if (indtspec != NULL) {
8646 for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8647 IndustryTileSpec *indtsp = indtspec[i];
8648 if (indtsp != NULL) {
8649 _industile_mngr.SetEntitySpec(indtsp);
8655 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
8656 IndustrySpec *indsp = &_industry_specs[j];
8657 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
8658 for (uint i = 0; i < 3; i++) {
8659 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
8662 if (!indsp->enabled) {
8663 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
8669 * Add all new objects to the object array. Object properties can be set at any
8670 * time in the GRF file, so we can only add an object spec to the object array
8671 * after the file has finished loading.
8673 static void FinaliseObjectsArray()
8675 const GRFFile * const *end = _grf_files.End();
8676 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8677 ObjectSpec **&objectspec = (*file)->objectspec;
8678 if (objectspec != NULL) {
8679 for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8680 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
8681 _object_mngr.SetEntitySpec(objectspec[i]);
8689 * Add all new airports to the airport array. Airport properties can be set at any
8690 * time in the GRF file, so we can only add a airport spec to the airport array
8691 * after the file has finished loading.
8693 static void FinaliseAirportsArray()
8695 const GRFFile * const *end = _grf_files.End();
8696 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8697 AirportSpec **&airportspec = (*file)->airportspec;
8698 if (airportspec != NULL) {
8699 for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8700 if (airportspec[i] != NULL && airportspec[i]->enabled) {
8701 _airport_mngr.SetEntitySpec(airportspec[i]);
8706 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8707 if (airporttilespec != NULL) {
8708 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8709 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
8710 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
8717 /* Here we perform initial decoding of some special sprites (as are they
8718 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8719 * partial implementation yet).
8720 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8721 * a crafted invalid GRF file. We should tell that to the user somehow, or
8722 * better make this more robust in the future. */
8723 static int DecodeSpecialSprite (byte *buf, uint num, GrfLoadingStage stage)
8725 /* XXX: There is a difference between staged loading in TTDPatch and
8726 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8727 * during stage 1, whilst action 3 is carried out during stage 2 (to
8728 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8729 * IDs are valid only within a given set (action 1) block, and may be
8730 * overwritten after action 3 associates them. But overwriting happens
8731 * in an earlier stage than associating, so... We just process actions
8732 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8733 * --pasky
8734 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8735 * is not in memory and scanning the file every time would be too expensive.
8736 * In other stages we skip action 0x10 since it's already dealt with. */
8737 static const SpecialSpriteHandler handlers[][GLS_END] = {
8738 /* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
8739 /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
8740 /* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
8741 /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
8742 /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
8743 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
8744 /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
8745 /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
8746 /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
8747 /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
8748 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
8749 /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
8750 /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
8751 /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
8752 /* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
8753 /* 0x0F */ { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
8754 /* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
8755 /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
8756 /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
8757 /* 0x13 */ { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
8758 /* 0x14 */ { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
8761 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
8763 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
8764 if (it == _grf_line_to_action6_sprite_override.end()) {
8765 /* No preloaded sprite to work with; read the
8766 * pseudo sprite content. */
8767 FioReadBlock(buf, num);
8768 } else {
8769 /* Use the preloaded sprite data. */
8770 buf = it->second.get();
8771 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8773 /* Skip the real (original) content of this action. */
8774 FioSeekTo(num, SEEK_CUR);
8777 ByteReader br(buf, buf + num);
8778 ByteReader *bufp = &br;
8780 try {
8781 byte action = bufp->ReadByte();
8783 if (action == 0xFF) {
8784 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8785 } else if (action == 0xFE) {
8786 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8787 } else if (action >= lengthof(handlers)) {
8788 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
8789 } else if (handlers[action][stage] == NULL) {
8790 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
8791 } else {
8792 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
8793 return handlers[action][stage](bufp);
8795 } catch (...) {
8796 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8797 DisableCur (STR_NEWGRF_ERROR_READ_BOUNDS);
8798 return -1;
8801 return 0;
8805 /** Signature of a container version 2 GRF. */
8806 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8809 * Get the container version of the currently opened GRF file.
8810 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
8812 byte GetGRFContainerVersion()
8814 size_t pos = FioGetPos();
8816 if (FioReadWord() == 0) {
8817 /* Check for GRF container version 2, which is identified by the bytes
8818 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8819 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
8820 if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
8823 return 2;
8826 /* Container version 1 has no header, rewind to start. */
8827 FioSeekTo(pos, SEEK_SET);
8828 return 1;
8832 * Load a particular NewGRF.
8833 * @param config The configuration of the to be loaded NewGRF.
8834 * @param file_index The Fio index of the first NewGRF to load.
8835 * @param stage The loading stage of the NewGRF.
8836 * @param subdir The sub directory to find the NewGRF in.
8838 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
8840 assert (file_index < MAX_FILE_SLOTS);
8842 const char *filename = config->filename;
8844 FioOpenFile(file_index, filename, subdir);
8845 _cur.file_index = file_index; // XXX
8846 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
8848 _cur.grfconfig = config;
8850 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
8852 _cur.grf_container_ver = GetGRFContainerVersion();
8853 if (_cur.grf_container_ver == 0) {
8854 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8855 return;
8858 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
8859 /* We need the sprite offsets in the init stage for NewGRF sounds
8860 * and in the activation stage for real sprites. */
8861 ReadGRFSpriteOffsets(_cur.grf_container_ver);
8862 } else {
8863 /* Skip sprite section offset if present. */
8864 if (_cur.grf_container_ver >= 2) FioReadDword();
8867 if (_cur.grf_container_ver >= 2) {
8868 /* Read compression value. */
8869 byte compression = FioReadByte();
8870 if (compression != 0) {
8871 DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
8872 return;
8876 /* Skip the first sprite; we don't care about how many sprites this
8877 * does contain; newest TTDPatches and George's longvehicles don't
8878 * neither, apparently. */
8879 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
8880 if (num == 4 && FioReadByte() == 0xFF) {
8881 FioReadDword();
8882 } else {
8883 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8884 return;
8887 _cur.ClearDataForNextFile();
8889 ReusableBuffer<byte> buf;
8890 int skip_sprites = 0;
8892 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
8893 byte type = FioReadByte();
8894 _cur.nfo_line++;
8896 if (type == 0xFF) {
8897 if (skip_sprites == 0) {
8898 skip_sprites = DecodeSpecialSprite (buf.Allocate(num), num, stage);
8900 /* Stop all processing if we are to skip the remaining sprites */
8901 if (skip_sprites == -1) break;
8903 continue;
8904 } else {
8905 FioSkipBytes(num);
8907 } else {
8908 if (skip_sprites == 0) {
8909 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8910 DisableCur (STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
8911 break;
8914 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
8915 /* Reference to data section. Container version >= 2 only. */
8916 FioSkipBytes(num);
8917 } else {
8918 FioSkipBytes(7);
8919 SkipSpriteData(type, num - 8);
8923 if (skip_sprites > 0) skip_sprites--;
8928 * Relocates the old shore sprites at new positions.
8930 * 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)
8931 * 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)
8932 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
8934 static void ActivateOldShore()
8936 /* Use default graphics, if no shore sprites were loaded.
8937 * Should not happen, as the base set's extra grf should include some. */
8938 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
8940 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
8941 for (uint i = 0; i < lengthof(shore_sprites_1); i++) {
8942 DupSprite (shore_sprites_1[i].old, shore_sprites_1[i].spr);
8946 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
8947 for (uint i = 0; i < lengthof(shore_sprites_2); i++) {
8948 DupSprite (shore_sprites_2[i].old, shore_sprites_2[i].spr);
8954 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
8956 static void FinalisePriceBaseMultipliers()
8958 extern const PriceBaseSpec _price_base_specs[];
8959 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
8960 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
8962 /* Evaluate grf overrides */
8963 int num_grfs = _grf_files.Length();
8964 int *grf_overrides = AllocaM(int, num_grfs);
8965 for (int i = 0; i < num_grfs; i++) {
8966 grf_overrides[i] = -1;
8968 GRFFile *source = _grf_files[i];
8969 uint32 override = _grf_id_overrides[source->grfid];
8970 if (override == 0) continue;
8972 GRFFile *dest = GetFileByGRFID(override);
8973 if (dest == NULL) continue;
8975 grf_overrides[i] = _grf_files.FindIndex(dest);
8976 assert(grf_overrides[i] >= 0);
8979 /* Override features and price base multipliers of earlier loaded grfs */
8980 for (int i = 0; i < num_grfs; i++) {
8981 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
8982 GRFFile *source = _grf_files[i];
8983 GRFFile *dest = _grf_files[grf_overrides[i]];
8985 uint32 features = (source->grf_features | dest->grf_features) & override_features;
8986 source->grf_features |= features;
8987 dest->grf_features |= features;
8989 for (Price p = PR_BEGIN; p < PR_END; p++) {
8990 /* No price defined -> nothing to do */
8991 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
8992 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
8993 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
8997 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
8998 for (int i = num_grfs - 1; i >= 0; i--) {
8999 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
9000 GRFFile *source = _grf_files[i];
9001 GRFFile *dest = _grf_files[grf_overrides[i]];
9003 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9004 source->grf_features |= features;
9005 dest->grf_features |= features;
9007 for (Price p = PR_BEGIN; p < PR_END; p++) {
9008 /* Already a price defined -> nothing to do */
9009 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
9010 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9011 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9015 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9016 for (int i = 0; i < num_grfs; i++) {
9017 if (grf_overrides[i] < 0) continue;
9018 GRFFile *source = _grf_files[i];
9019 GRFFile *dest = _grf_files[grf_overrides[i]];
9021 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9022 source->grf_features |= features;
9023 dest->grf_features |= features;
9025 for (Price p = PR_BEGIN; p < PR_END; p++) {
9026 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
9027 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
9028 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9030 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
9034 /* Apply fallback prices for grf version < 8 */
9035 const GRFFile * const *end = _grf_files.End();
9036 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9037 if ((*file)->grf_version >= 8) continue;
9038 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9039 for (Price p = PR_BEGIN; p < PR_END; p++) {
9040 Price fallback_price = _price_base_specs[p].fallback_price;
9041 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9042 /* No price multiplier has been set.
9043 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9044 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9049 /* Decide local/global scope of price base multipliers */
9050 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9051 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9052 for (Price p = PR_BEGIN; p < PR_END; p++) {
9053 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9054 /* No multiplier was set; set it to a neutral value */
9055 price_base_multipliers[p] = 0;
9056 } else {
9057 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
9058 /* The grf does not define any objects of the feature,
9059 * so it must be a difficulty setting. Apply it globally */
9060 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
9061 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9062 price_base_multipliers[p] = 0;
9063 } else {
9064 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
9071 extern void InitGRFTownGeneratorNames();
9073 /** Finish loading NewGRFs and execute needed post-processing */
9074 static void AfterLoadGRFs()
9076 for (StringIDMapping *it = _string_to_grf_mapping.Begin(); it != _string_to_grf_mapping.End(); it++) {
9077 *it->target = MapGRFStringID(it->grfid, it->source);
9079 _string_to_grf_mapping.Clear();
9081 /* Free the action 6 override sprites. */
9082 _grf_line_to_action6_sprite_override.clear();
9084 /* Polish cargoes */
9085 FinaliseCargoArray();
9087 /* Pre-calculate all refit masks after loading GRF files. */
9088 CalculateRefitMasks();
9090 /* Polish engines */
9091 FinaliseEngineArray();
9093 /* Set the actually used Canal properties */
9094 FinaliseCanals();
9096 /* Add all new houses to the house array. */
9097 FinaliseHouseArray();
9099 /* Add all new industries to the industry array. */
9100 FinaliseIndustriesArray();
9102 /* Add all new objects to the object array. */
9103 FinaliseObjectsArray();
9105 InitializeSortedCargoSpecs();
9107 /* Sort the list of industry types. */
9108 SortIndustryTypes();
9110 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9111 BuildIndustriesLegend();
9113 /* Build the routemap legend, based on the available cargos */
9114 BuildLinkStatsLegend();
9116 /* Add all new airports to the airports array. */
9117 FinaliseAirportsArray();
9118 BindAirportSpecs();
9120 /* Update the townname generators list */
9121 InitGRFTownGeneratorNames();
9123 /* Run all queued vehicle list order changes */
9124 CommitVehicleListOrderChanges();
9126 /* Load old shore sprites in new position, if they were replaced by ActionA */
9127 ActivateOldShore();
9129 /* Set up custom rail types */
9130 InitRailTypes();
9132 Engine *e;
9133 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
9134 if (_gted[e->index].rv_max_speed != 0) {
9135 /* Set RV maximum speed from the mph/0.8 unit value */
9136 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9140 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
9141 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9142 if (railtype == INVALID_RAILTYPE) {
9143 /* Rail type is not available, so disable this engine */
9144 e->info.climates = 0;
9145 } else {
9146 e->u.rail.railtype = railtype;
9150 SetYearEngineAgingStops();
9152 FinalisePriceBaseMultipliers();
9154 /* Deallocate temporary loading data */
9155 free(_gted);
9156 _grm_sprites.clear();
9160 * Load all the NewGRFs.
9161 * @param load_index The offset for the first sprite to add.
9162 * @param file_index The Fio index of the first NewGRF to load.
9163 * @param num_baseset Number of NewGRFs at the front of the list to look up in the baseset dir instead of the newgrf dir.
9165 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9167 /* In case of networking we need to "sync" the start values
9168 * so all NewGRFs are loaded equally. For this we use the
9169 * start date of the game and we set the counters, etc. to
9170 * 0 so they're the same too. */
9171 Date date = _date;
9172 Year year = _cur_year;
9173 DateFract date_fract = _date_fract;
9174 uint16 tick_counter = _tick_counter;
9175 byte display_opt = _display_opt;
9177 if (_networking) {
9178 _cur_year = _settings_game.game_creation.starting_year;
9179 _date = ConvertYMDToDate(_cur_year, 0, 1);
9180 _date_fract = 0;
9181 _tick_counter = 0;
9182 _display_opt = 0;
9185 InitializeGRFSpecial();
9187 ResetNewGRFData();
9190 * Reset the status of all files, so we can 'retry' to load them.
9191 * This is needed when one for example rearranges the NewGRFs in-game
9192 * and a previously disabled NewGRF becomes useable. If it would not
9193 * be reset, the NewGRF would remain disabled even though it should
9194 * have been enabled.
9196 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9197 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9200 _cur.spriteid = load_index;
9202 /* Load newgrf sprites
9203 * in each loading stage, (try to) open each file specified in the config
9204 * and load information from it. */
9205 uint num_non_static = 0;
9206 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9207 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9208 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9209 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9210 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9213 if (stage == GLS_RESERVE) {
9214 static const uint32 overrides[][2] = {
9215 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9216 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9217 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9219 for (size_t i = 0; i < lengthof(overrides); i++) {
9220 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9224 uint slot = file_index;
9226 _cur.stage = stage;
9227 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9228 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9229 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9231 Subdirectory subdir = slot < file_index + num_baseset ? BASESET_DIR : NEWGRF_DIR;
9232 if (!FioCheckFileExists(c->filename, subdir)) {
9233 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9234 c->status = GCS_NOT_FOUND;
9235 continue;
9238 /* A .grf file is activated only if it was active
9239 * when the game was started. If a game is loaded,
9240 * only its active .grfs will be reactivated, unless
9241 * "loadallgraphics on" is used. A .grf file is
9242 * considered active if its action 8 has been
9243 * processed, i.e. its action 8 hasn't been skipped
9244 * using an action 7.
9246 * During activation, only actions 0, 1, 2, 3, 4, 5,
9247 * 7, 8, 9, 0A and 0B are carried out. All others
9248 * are ignored, because they only need to be
9249 * processed once at initialization. */
9251 _cur.grffile = GetFileByFilename (c->filename);
9252 if (stage == GLS_LABELSCAN) {
9253 if (_cur.grffile == NULL) {
9254 _cur.grffile = new GRFFile (c);
9255 *_grf_files.Append() = _cur.grffile;
9258 bool disable = false;
9259 if (slot == MAX_FILE_SLOTS) {
9260 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of file slots has been reached", c->filename);
9261 disable = true;
9262 } else if (!HasBit(c->flags, GCF_STATIC) && !HasBit(c->flags, GCF_SYSTEM)) {
9263 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
9264 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
9265 disable = true;
9266 } else {
9267 num_non_static++;
9270 if (disable) {
9271 c->status = GCS_DISABLED;
9272 c->error = new GRFError (STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9273 continue;
9275 } else {
9276 if (_cur.grffile == NULL) usererror ("File '%s' lost in cache.\n", c->filename);
9277 if (stage == GLS_RESERVE && c->status != GCS_INITIALISED) return;
9278 if (stage == GLS_ACTIVATION && !HasBit(c->flags, GCF_RESERVED)) return;
9281 assert (slot < MAX_FILE_SLOTS);
9283 LoadNewGRFFile(c, slot++, stage, subdir);
9284 if (stage == GLS_RESERVE) {
9285 SetBit(c->flags, GCF_RESERVED);
9286 } else if (stage == GLS_ACTIVATION) {
9287 ClrBit(c->flags, GCF_RESERVED);
9288 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9289 ClearTemporaryNewGRFData(_cur.grffile);
9290 BuildCargoTranslationMap();
9291 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9292 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9293 /* We're not going to activate this, so free whatever data we allocated */
9294 ClearTemporaryNewGRFData(_cur.grffile);
9299 /* Pseudo sprite processing is finished; free temporary stuff */
9300 _cur.ClearDataForNextFile();
9302 /* Call any functions that should be run after GRFs have been loaded. */
9303 AfterLoadGRFs();
9305 /* Now revert back to the original situation */
9306 _cur_year = year;
9307 _date = date;
9308 _date_fract = date_fract;
9309 _tick_counter = tick_counter;
9310 _display_opt = display_opt;