Translations update
[openttd/fttd.git] / src / newgrf.cpp
blobb9aab32d0fc14d862e804db15861408e1587a522
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);
203 static inline uint16 ReadWord (const byte *p)
205 return p[0] | (p[1] << 8);
208 static inline uint32 ReadDWord (const byte *p)
210 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
213 static uint32 ReadVarSize (const byte *p, byte size)
215 switch (size) {
216 case 1: return *p;
217 case 2: return ReadWord (p);
218 case 4: return ReadDWord (p);
219 default:
220 NOT_REACHED();
221 return 0;
225 /** Class to read from a NewGRF file */
226 class ByteReader {
227 protected:
228 byte *data;
229 byte *end;
231 public:
232 ByteReader(byte *data, byte *end) : data(data), end(end) { }
234 class out_of_data { };
236 inline byte ReadByte()
238 if (data < end) return *(data)++;
239 throw out_of_data();
242 uint16 ReadWord()
244 uint16 val = ReadByte();
245 return val | (ReadByte() << 8);
248 uint16 ReadExtendedByte()
250 uint16 val = ReadByte();
251 return val == 0xFF ? ReadWord() : val;
254 uint32 ReadDWord()
256 uint32 val = ReadWord();
257 return val | (ReadWord() << 16);
260 uint32 ReadLabel (void)
262 return BSWAP32(this->ReadDWord());
265 const char *ReadString (void);
267 inline size_t Remaining() const
269 return end - data;
272 inline bool HasData(size_t count = 1) const
274 return Remaining() >= count;
277 const byte *GetData (size_t n)
279 if (!HasData (n)) throw out_of_data();
280 const byte *p = data;
281 data += n;
282 return p;
285 const byte *GetData (void)
287 return data;
290 inline void Skip(size_t len)
292 data += len;
293 /* It is valid to move the buffer to exactly the end of the data,
294 * as there may not be any more data read. */
295 if (data > end) throw out_of_data();
298 byte *Dup (size_t len)
300 if (!HasData (len)) throw out_of_data();
302 byte *p = xmemdupt (data, len);
303 data += len;
304 return p;
308 const char *ByteReader::ReadString (void)
310 const char *string = reinterpret_cast<char *>(data);
312 size_t remaining = Remaining();
313 size_t string_length = ttd_strnlen (string, remaining);
315 if (string_length == remaining) {
316 /* String was not NUL terminated, so make sure it is now. */
317 grfmsg(7, "String was not terminated with a zero byte.");
318 data = end;
319 data[-1] = 0;
320 } else {
321 /* Increase the string length to include the NUL byte. */
322 string_length++;
323 data += string_length;
326 return string;
329 typedef int (*SpecialSpriteHandler) (ByteReader *buf);
331 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.
333 /** Temporary engine data used when loading only */
334 struct GRFTempEngineData {
335 /** Summary state of refittability properties */
336 enum Refittability {
337 UNSET = 0, ///< No properties assigned. Default refit masks shall be activated.
338 EMPTY, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
339 NONEMPTY, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
342 uint16 cargo_allowed;
343 uint16 cargo_disallowed;
344 RailTypeLabel railtypelabel;
345 const GRFFile *defaultcargo_grf; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
346 Refittability refittability; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
347 bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)?
348 uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
349 uint32 ctt_include_mask; ///< Cargo types always included in the refit mask.
350 uint32 ctt_exclude_mask; ///< Cargo types always excluded from the refit mask.
353 * Update the summary refittability on setting a refittability property.
354 * @param non_empty true if the GRF sets the vehicle to be refittable.
356 void UpdateRefittability(bool non_empty)
358 if (non_empty) {
359 this->refittability = NONEMPTY;
360 } else if (this->refittability == UNSET) {
361 this->refittability = EMPTY;
366 static GRFTempEngineData *_gted; ///< Temporary engine data used during NewGRF loading
369 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
370 * GRM for vehicles is only used if dynamic engine allocation is disabled,
371 * so 256 is the number of original engines. */
372 static uint32 _grm_engines[256];
374 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
375 static uint32 _grm_cargoes[NUM_CARGO * 2];
377 struct GRFLocation {
378 uint32 grfid;
379 uint32 nfoline;
381 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
383 bool operator<(const GRFLocation &other) const
385 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
388 bool operator == (const GRFLocation &other) const
390 return this->grfid == other.grfid && this->nfoline == other.nfoline;
394 static std::map<GRFLocation, SpriteID> _grm_sprites;
395 typedef std::map <GRFLocation, ttd_unique_free_ptr <byte> > GRFLineToSpriteOverride;
396 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
399 * DEBUG() function dedicated to newGRF debugging messages
400 * Function is essentially the same as DEBUG(grf, severity, ...) with the
401 * addition of file:line information when parsing grf files.
402 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
403 * loading/parsing grf files, not for runtime debug messages as there
404 * is no file information available during that time.
405 * @param severity debugging severity level, see debug.h
406 * @param str message in printf() format
408 void CDECL grfmsg(int severity, const char *str, ...)
410 char buf[1024];
411 va_list va;
413 va_start(va, str);
414 bstrvfmt (buf, str, va);
415 va_end(va);
417 DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
421 * Obtain a NewGRF file by its grfID
422 * @param grfid The grfID to obtain the file for
423 * @return The file.
425 static GRFFile *GetFileByGRFID(uint32 grfid)
427 const GRFFile * const *end = _grf_files.End();
428 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
429 if ((*file)->grfid == grfid) return *file;
431 return NULL;
435 * Obtain a NewGRF file by its filename
436 * @param filename The filename to obtain the file for.
437 * @return The file.
439 static GRFFile *GetFileByFilename(const char *filename)
441 const GRFFile * const *end = _grf_files.End();
442 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
443 if (strcmp((*file)->filename, filename) == 0) return *file;
445 return NULL;
448 /** Reset all NewGRFData that was used only while processing data */
449 static void ClearTemporaryNewGRFData(GRFFile *gf)
451 /* Clear the GOTO labels used for GRF processing */
452 for (GRFLabel *l = gf->label; l != NULL;) {
453 GRFLabel *l2 = l->next;
454 free(l);
455 l = l2;
457 gf->label = NULL;
461 * Disable the GRF being loaded
462 * @param message Error message or STR_NULL.
463 * @return Error message of the GRF for further customisation.
465 static GRFError *DisableCur (StringID message = STR_NULL)
467 GRFConfig *config = _cur.grfconfig;
469 config->status = GCS_DISABLED;
470 if (_cur.grffile != NULL) ClearTemporaryNewGRFData (_cur.grffile);
472 if (message != STR_NULL) {
473 delete config->error;
474 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
475 if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
478 return config->error;
482 * Disable a GRF
483 * @param message Error message.
484 * @param config GRFConfig to disable.
486 static void DisableGrf (StringID message, GRFConfig *config)
488 assert (config != NULL);
489 assert (config != _cur.grfconfig);
491 config->status = GCS_DISABLED;
493 GRFFile *file = GetFileByGRFID (config->ident.grfid);
494 if (file != NULL) ClearTemporaryNewGRFData(file);
496 delete config->error;
497 config->error = new GRFError (STR_NEWGRF_ERROR_MSG_FATAL, message);
498 config->error->data = xstrdup (_cur.grfconfig->GetName());
502 * Information for mapping static StringIDs.
504 struct StringIDMapping {
505 uint32 grfid; ///< Source NewGRF.
506 StringID source; ///< Source StringID (GRF local).
507 StringID *target; ///< Destination for mapping result.
509 typedef SmallVector<StringIDMapping, 16> StringIDMappingVector;
510 static StringIDMappingVector _string_to_grf_mapping;
513 * Record a static StringID for getting translated later.
514 * @param source Source StringID (GRF local).
515 * @param target Destination for the mapping result.
517 static void AddStringForMapping(StringID source, StringID *target)
519 *target = STR_UNDEFINED;
520 StringIDMapping *item = _string_to_grf_mapping.Append();
521 item->grfid = _cur.grffile->grfid;
522 item->source = source;
523 item->target = target;
527 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
528 * string IDs, but only for the ones we are aware off; the rest
529 * like likely unused and will show a warning.
530 * @param str the string ID to convert
531 * @return the converted string ID
533 static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
535 /* StringID table for TextIDs 0x4E->0x6D */
536 static const StringID units_volume[] = {
537 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
538 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
539 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
540 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
541 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
542 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
543 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
544 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
547 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
548 assert(!IsInsideMM(str, 0xD000, 0xD7FF));
550 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
551 assert_compile(stringend - stringid == end - begin); \
552 if (str >= begin && str <= end) return str + (stringid - begin)
554 /* We have some changes in our cargo strings, resulting in some missing. */
555 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
556 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
557 if (str >= 0x004E && str <= 0x006D) return units_volume[str - 0x004E];
558 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
559 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
560 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
562 /* Map building names according to our lang file changes. There are several
563 * ranges of house ids, all of which need to be remapped to allow newgrfs
564 * to use original house names. */
565 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
566 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
567 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
569 /* Same thing for industries */
570 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
571 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
572 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
573 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
574 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
576 switch (str) {
577 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
578 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
579 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
581 #undef TEXTID_TO_STRINGID
583 if (str == STR_NULL) return STR_EMPTY;
585 DEBUG(grf, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
587 return STR_EMPTY;
591 * Used when setting an object's property to map to the GRF's strings
592 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
593 * @param grfid Id of the grf file.
594 * @param str StringID that we want to have the equivalent in OoenTTD.
595 * @return The properly adjusted StringID.
597 StringID MapGRFStringID(uint32 grfid, StringID str)
599 if (IsInsideMM(str, 0xD800, 0xE000)) {
600 /* General text provided by NewGRF.
601 * In the specs this is called the 0xDCxx range (misc presistent texts),
602 * but we meanwhile extended the range to 0xD800-0xDFFF.
603 * Note: We are not involved in the "persistent" business, since we do not store
604 * any NewGRF strings in savegames. */
605 return GetGRFStringID(grfid, str);
606 } else if (IsInsideMM(str, 0xD000, 0xD800)) {
607 /* Callback text provided by NewGRF.
608 * In the specs this is called the 0xD0xx range (misc graphics texts).
609 * These texts can be returned by various callbacks.
611 * Due to how TTDP implements the GRF-local- to global-textid translation
612 * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
613 * We do not care about that difference and just mask out the 0x400 bit.
615 str &= ~0x400;
616 return GetGRFStringID(grfid, str);
617 } else {
618 /* The NewGRF wants to include/reference an original TTD string.
619 * Try our best to find an equivalent one. */
620 return TTDPStringIDToOTTDStringIDMapping(str);
624 static std::map<uint32, uint32> _grf_id_overrides;
627 * Set the override for a NewGRF
628 * @param source_grfid The grfID which wants to override another NewGRF.
629 * @param target_grfid The grfID which is being overridden.
631 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
633 _grf_id_overrides[source_grfid] = target_grfid;
634 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
638 * Returns the engine associated to a certain internal_id, resp. allocates it.
639 * @param file NewGRF that wants to change the engine.
640 * @param type Vehicle type.
641 * @param internal_id Engine ID inside the NewGRF.
642 * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04).
643 * @return The requested engine.
645 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
647 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
648 * them use the same engine slots. */
649 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
650 if (_settings_game.vehicle.dynamic_engines) {
651 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
652 scope_grfid = file->grfid;
653 uint32 override = _grf_id_overrides[file->grfid];
654 if (override != 0) {
655 scope_grfid = override;
656 const GRFFile *grf_match = GetFileByGRFID(override);
657 if (grf_match == NULL) {
658 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
659 } else {
660 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
664 /* Check if the engine is registered in the override manager */
665 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
666 if (engine != INVALID_ENGINE) {
667 Engine *e = Engine::Get(engine);
668 if (e->grf_prop.grffile == NULL) e->grf_prop.grffile = file;
669 return e;
673 /* Check if there is an unreserved slot */
674 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
675 if (engine != INVALID_ENGINE) {
676 Engine *e = Engine::Get(engine);
678 if (e->grf_prop.grffile == NULL) {
679 e->grf_prop.grffile = file;
680 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
683 /* Reserve the engine slot */
684 if (!static_access) {
685 EngineIDMapping *eid = _engine_mngr.Get(engine);
686 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
689 return e;
692 if (static_access) return NULL;
694 if (!Engine::CanAllocateItem()) {
695 grfmsg(0, "Can't allocate any more engines");
696 return NULL;
699 size_t engine_pool_size = Engine::GetPoolSize();
701 /* ... it's not, so create a new one based off an existing engine */
702 Engine *e = new Engine(type, internal_id);
703 e->grf_prop.grffile = file;
705 /* Reserve the engine slot */
706 assert(_engine_mngr.Length() == e->index);
707 EngineIDMapping *eid = _engine_mngr.Append();
708 eid->type = type;
709 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
710 eid->internal_id = internal_id;
711 eid->substitute_id = min(internal_id, _engine_counts[type]); // substitute_id == _engine_counts[subtype] means "no substitute"
713 if (engine_pool_size != Engine::GetPoolSize()) {
714 /* Resize temporary engine data ... */
715 _gted = xrealloct (_gted, Engine::GetPoolSize());
717 /* and blank the new block. */
718 size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
719 memset(_gted + engine_pool_size, 0, len);
721 if (type == VEH_TRAIN) {
722 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
725 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
727 return e;
731 * Return the ID of a new engine
732 * @param file The NewGRF file providing the engine.
733 * @param type The Vehicle type.
734 * @param internal_id NewGRF-internal ID of the engine.
735 * @return The new EngineID.
736 * @note depending on the dynamic_engine setting and a possible override
737 * property the grfID may be unique or overwriting or partially re-defining
738 * properties of an existing engine.
740 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
742 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
743 if (_settings_game.vehicle.dynamic_engines) {
744 scope_grfid = file->grfid;
745 uint32 override = _grf_id_overrides[file->grfid];
746 if (override != 0) scope_grfid = override;
749 return _engine_mngr.GetID(type, internal_id, scope_grfid);
753 * Read a sprite and paletteD from the GRF and map the colour modifiers
754 * of TTDPatch to those that Open is using.
755 * @param buf Input stream.
756 * @param grf_sprite Pointer to the structure to read.
758 static void ReadPalSprite (const byte *buf, PalSpriteID *grf_sprite)
760 SpriteID sprite = ReadWord (buf);
761 PaletteID pal = ReadWord (buf + 2);
763 if (HasBit(pal, 14)) {
764 ClrBit(pal, 14);
765 SetBit(sprite, SPRITE_MODIFIER_OPAQUE);
768 if (HasBit(sprite, 14)) {
769 ClrBit(sprite, 14);
770 SetBit(sprite, PALETTE_MODIFIER_TRANSPARENT);
773 if (HasBit(sprite, 15)) {
774 ClrBit(sprite, 15);
775 SetBit(sprite, PALETTE_MODIFIER_COLOUR);
778 grf_sprite->sprite = sprite;
779 grf_sprite->pal = pal;
783 * Read a sprite and paletteD from the GRF and map the colour modifiers
784 * of TTDPatch to those that Open is using.
785 * @param buf Input stream.
786 * @param grf_sprite Pointer to the structure to read.
788 static void ReadPalSprite (ByteReader *buf, PalSpriteID *grf_sprite)
790 ReadPalSprite (buf->GetData(4), grf_sprite);
794 * Adjust a sprite and a palette read from the GRF.
795 * @param grf_sprite Sprite and palette to adjust.
796 * @param feature GrfSpecFeature to use spritesets from.
797 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
798 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
799 * @param flags Tile layout flags.
800 * @param [out] max_offset Optionally returns the number of sprites in the spriteset of the sprite and palette (0 if no spritset).
801 * @return Whether reading succeeded.
803 static bool AdjustSpriteLayoutSprite (PalSpriteID *grf_sprite, int feature,
804 bool invert_action1_flag, bool use_cur_spritesets = false,
805 TileLayoutFlags flags = TLF_NOTHING, uint16 *max_offset = NULL)
807 bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
808 ClrBit(grf_sprite->pal, 15);
809 if (custom_sprite) {
810 /* Use sprite from Action 1 */
811 uint index = GB(grf_sprite->sprite, 0, 14);
812 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
813 grfmsg(1, "sprite layout uses undefined custom spriteset %d", index);
814 grf_sprite->sprite = SPR_IMG_QUERY;
815 grf_sprite->pal = PAL_NONE;
816 } else {
817 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
818 if (max_offset != NULL) max_offset[0] = use_cur_spritesets ? _cur.GetNumEnts (feature, index) : UINT16_MAX;
819 SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
820 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
822 } else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
823 grfmsg(1, "sprite layout specifies var10 value for non-action-1 sprite");
824 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
825 return false;
828 if (flags & TLF_CUSTOM_PALETTE) {
829 /* Use palette from Action 1 */
830 uint index = GB(grf_sprite->pal, 0, 14);
831 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
832 grfmsg(1, "sprite layout uses undefined custom spriteset %d for palette", index);
833 grf_sprite->pal = PAL_NONE;
834 } else {
835 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
836 if (max_offset != NULL) max_offset[1] = use_cur_spritesets ? _cur.GetNumEnts (feature, index) : UINT16_MAX;
837 SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
838 SetBit(grf_sprite->pal, SPRITE_MODIFIER_CUSTOM_SPRITE);
840 } else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
841 grfmsg(1, "sprite layout specifies var10 value for non-action-1 palette");
842 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
843 return false;
846 return true;
850 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
851 * @param buf Input stream.
852 * @param flags TileLayoutFlags to process.
853 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
854 * @param r Where to store the registers.
855 * @return Whether reading succeeded.
857 static bool ReadSpriteLayoutRegisters (ByteReader *buf, TileLayoutFlags flags,
858 bool is_parent, TileLayoutRegisters *r)
860 TileLayoutRegisters &regs = *r;
861 regs.flags = flags;
863 if (flags == TLF_NOTHING) return true; // nothing to read
865 if (flags & TLF_DODRAW) regs.dodraw = buf->ReadByte();
866 if (flags & TLF_SPRITE) regs.sprite = buf->ReadByte();
867 if (flags & TLF_PALETTE) regs.palette = buf->ReadByte();
869 if (is_parent) {
870 if (flags & TLF_BB_XY_OFFSET) {
871 regs.delta.parent[0] = buf->ReadByte();
872 regs.delta.parent[1] = buf->ReadByte();
874 if (flags & TLF_BB_Z_OFFSET) regs.delta.parent[2] = buf->ReadByte();
875 } else {
876 if (flags & TLF_CHILD_X_OFFSET) regs.delta.child[0] = buf->ReadByte();
877 if (flags & TLF_CHILD_Y_OFFSET) regs.delta.child[1] = buf->ReadByte();
880 if (flags & TLF_SPRITE_VAR10) {
881 regs.sprite_var10 = buf->ReadByte();
882 if (regs.sprite_var10 > TLR_MAX_VAR10) {
883 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
884 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
885 return false;
889 if (flags & TLF_PALETTE_VAR10) {
890 regs.palette_var10 = buf->ReadByte();
891 if (regs.palette_var10 > TLR_MAX_VAR10) {
892 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
893 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
894 return false;
898 return true;
901 struct SpriteLayoutReader {
902 static const uint MAX_BUILDING_SPRITES = 255;
904 PalSpriteID ground; ///< Ground sprite and palette.
905 DrawTileSeqStruct seq[MAX_BUILDING_SPRITES]; ///< Building sprites.
906 TileLayoutRegisters regs[MAX_BUILDING_SPRITES + 1]; ///< Registers.
907 uint num_building_sprites; ///< Amount of building sprites.
908 uint consistent_max_offset; ///< Maximum offset for sprites.
909 bool has_registers; ///< Any register is actually used.
913 * Read a spritelayout from the GRF.
914 * @param reader Where to read the sprite into.
915 * @param buf Input
916 * @param num_building_sprites Number of building sprites to read
917 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
918 * @param feature GrfSpecFeature to use spritesets from.
919 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
920 * @param no_z_position Whether bounding boxes have no Z offset
921 * @return True on error (GRF was disabled).
923 static bool ReadSpriteLayout (SpriteLayoutReader *reader, ByteReader *buf,
924 uint num_building_sprites, bool use_cur_spritesets, byte feature,
925 bool allow_var10, bool no_z_position)
927 assert (num_building_sprites <= lengthof(reader->seq));
928 assert (num_building_sprites < lengthof(reader->regs));
930 uint16 max_offset[2 * (SpriteLayoutReader::MAX_BUILDING_SPRITES + 1)]; // (sprite, palette) pairs
931 assert (2 * num_building_sprites < lengthof(max_offset));
932 memset (max_offset, 0, sizeof(max_offset));
934 bool has_flags = HasBit(num_building_sprites, 6);
935 ClrBit(num_building_sprites, 6);
936 reader->num_building_sprites = num_building_sprites;
937 TileLayoutFlags valid_flags = TLF_KNOWN_FLAGS;
938 if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
940 /* Groundsprite */
941 ReadPalSprite (buf, &reader->ground);
942 TileLayoutFlags flags = has_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
943 if (!AdjustSpriteLayoutSprite (&reader->ground, feature, false,
944 use_cur_spritesets, flags, max_offset)) {
945 return true;
948 if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
949 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
950 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
951 return true;
954 flags &= TLF_DRAWING_FLAGS;
955 bool has_registers = (flags != TLF_NOTHING);
956 if (!ReadSpriteLayoutRegisters (buf, flags, false, &reader->regs[0])) {
957 return true;
960 for (uint i = 0; i < num_building_sprites; i++) {
961 DrawTileSeqStruct *seq = &reader->seq[i];
963 ReadPalSprite (buf, &seq->image);
964 flags = has_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
965 if (!AdjustSpriteLayoutSprite (&seq->image, feature, false,
966 use_cur_spritesets, flags,
967 max_offset + 2 * (i + 1))) {
968 return true;
971 if (flags & ~valid_flags) {
972 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
973 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
974 return true;
977 seq->delta_x = buf->ReadByte();
978 seq->delta_y = buf->ReadByte();
979 seq->delta_z = no_z_position ? 0 : buf->ReadByte();
981 if (seq->IsParentSprite()) {
982 seq->size_x = buf->ReadByte();
983 seq->size_y = buf->ReadByte();
984 seq->size_z = buf->ReadByte();
987 flags &= TLF_DRAWING_FLAGS;
988 has_registers |= (flags != TLF_NOTHING);
990 if (!ReadSpriteLayoutRegisters (buf, flags, seq->IsParentSprite(), &reader->regs[i + 1])) {
991 return true;
995 /* Check if the number of sprites per spriteset is consistent */
996 uint consistent_max_offset = 0;
997 for (uint i = 0; i < 2 * (num_building_sprites + 1); i++) {
998 if (max_offset[i] > 0) {
999 if (consistent_max_offset == 0) {
1000 consistent_max_offset = max_offset[i];
1001 } else if (consistent_max_offset != max_offset[i]) {
1002 assert (use_cur_spritesets);
1003 /* Not consistent, so use registers. */
1004 has_registers = true;
1005 break;
1010 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
1011 assert (use_cur_spritesets || (consistent_max_offset == 0 || consistent_max_offset == UINT16_MAX));
1013 if (has_registers) {
1014 for (uint i = 0; i < num_building_sprites + 1; i++) {
1015 TileLayoutRegisters &regs = reader->regs[i];
1016 regs.max_sprite_offset = max_offset[2 * i];
1017 regs.max_palette_offset = max_offset[2 * i + 1];
1020 consistent_max_offset = 0;
1023 reader->consistent_max_offset = consistent_max_offset;
1024 reader->has_registers = has_registers;
1026 return false;
1030 * Translate the refit mask.
1032 static uint32 TranslateRefitMask(uint32 refit_mask)
1034 uint32 result = 0;
1035 uint8 bit;
1036 FOR_EACH_SET_BIT(bit, refit_mask) {
1037 CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true);
1038 if (cargo != CT_INVALID) SetBit(result, cargo);
1040 return result;
1044 * Converts TTD(P) Base Price pointers into the enum used by OTTD
1045 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
1046 * @param base_pointer TTD(P) Base Price Pointer
1047 * @param error_location Function name for grf error messages
1048 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
1050 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
1052 /* Special value for 'none' */
1053 if (base_pointer == 0) {
1054 *index = INVALID_PRICE;
1055 return;
1058 static const uint32 start = 0x4B34; ///< Position of first base price
1059 static const uint32 size = 6; ///< Size of each base price record
1061 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
1062 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
1063 return;
1066 *index = (Price)((base_pointer - start) / size);
1069 /** Possible return values for the FeatureChangeInfo functions */
1070 enum ChangeInfoResult {
1071 CIR_SUCCESS, ///< Variable was parsed and read
1072 CIR_DISABLED, ///< GRF was disabled due to error
1073 CIR_UNHANDLED, ///< Variable was parsed but unread
1074 CIR_UNKNOWN, ///< Variable is unknown
1075 CIR_INVALID_ID, ///< Attempt to modify an invalid ID
1078 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
1081 * Define properties common to all vehicles
1082 * @param ei Engine info.
1083 * @param prop The property to change.
1084 * @param buf The property value.
1085 * @return ChangeInfoResult.
1087 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
1089 switch (prop) {
1090 case 0x00: // Introduction date
1091 ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
1092 break;
1094 case 0x02: // Decay speed
1095 ei->decay_speed = buf->ReadByte();
1096 break;
1098 case 0x03: // Vehicle life
1099 ei->lifelength = buf->ReadByte();
1100 break;
1102 case 0x04: // Model life
1103 ei->base_life = buf->ReadByte();
1104 break;
1106 case 0x06: // Climates available
1107 ei->climates = buf->ReadByte();
1108 break;
1110 case PROP_VEHICLE_LOAD_AMOUNT: // 0x07 Loading speed
1111 /* Amount of cargo loaded during a vehicle's "loading tick" */
1112 ei->load_amount = buf->ReadByte();
1113 break;
1115 default:
1116 return CIR_UNKNOWN;
1119 return CIR_SUCCESS;
1123 * Define properties for rail vehicles
1124 * @param engine :ocal ID of the first vehicle.
1125 * @param numinfo Number of subsequent IDs to change the property for.
1126 * @param prop The property to change.
1127 * @param buf The property value.
1128 * @return ChangeInfoResult.
1130 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1132 ChangeInfoResult ret = CIR_SUCCESS;
1134 for (int i = 0; i < numinfo; i++) {
1135 Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i);
1136 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1138 EngineInfo *ei = &e->info;
1139 RailVehicleInfo *rvi = &e->u.rail;
1141 switch (prop) {
1142 case 0x05: { // Track type
1143 uint8 tracktype = buf->ReadByte();
1145 if (tracktype < _cur.grffile->railtype_list.Length()) {
1146 _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype];
1147 break;
1150 switch (tracktype) {
1151 case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
1152 case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
1153 case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
1154 default:
1155 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1156 break;
1158 break;
1161 case 0x08: // AI passenger service
1162 /* Tells the AI that this engine is designed for
1163 * passenger services and shouldn't be used for freight. */
1164 rvi->ai_passenger_only = buf->ReadByte();
1165 break;
1167 case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
1168 uint16 speed = buf->ReadWord();
1169 if (speed == 0xFFFF) speed = 0;
1171 rvi->max_speed = speed;
1172 break;
1175 case PROP_TRAIN_POWER: // 0x0B Power
1176 rvi->power = buf->ReadWord();
1178 /* Set engine / wagon state based on power */
1179 if (rvi->power != 0) {
1180 if (rvi->railveh_type == RAILVEH_WAGON) {
1181 rvi->railveh_type = RAILVEH_SINGLEHEAD;
1183 } else {
1184 rvi->railveh_type = RAILVEH_WAGON;
1186 break;
1188 case PROP_TRAIN_RUNNING_COST_FACTOR: // 0x0D Running cost factor
1189 rvi->running_cost = buf->ReadByte();
1190 break;
1192 case 0x0E: // Running cost base
1193 ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
1194 break;
1196 case 0x12: { // Sprite ID
1197 uint8 spriteid = buf->ReadByte();
1198 uint8 orig_spriteid = spriteid;
1200 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1201 * as an array index, so we need it to be half the original value. */
1202 if (spriteid < 0xFD) spriteid >>= 1;
1204 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1205 rvi->image_index = spriteid;
1206 } else {
1207 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1208 rvi->image_index = 0;
1210 break;
1213 case 0x13: { // Dual-headed
1214 uint8 dual = buf->ReadByte();
1216 if (dual != 0) {
1217 rvi->railveh_type = RAILVEH_MULTIHEAD;
1218 } else {
1219 rvi->railveh_type = rvi->power == 0 ?
1220 RAILVEH_WAGON : RAILVEH_SINGLEHEAD;
1222 break;
1225 case PROP_TRAIN_CARGO_CAPACITY: // 0x14 Cargo capacity
1226 rvi->capacity = buf->ReadByte();
1227 break;
1229 case 0x15: { // Cargo type
1230 _gted[e->index].defaultcargo_grf = _cur.grffile;
1231 uint8 ctype = buf->ReadByte();
1233 if (ctype == 0xFF) {
1234 /* 0xFF is specified as 'use first refittable' */
1235 ei->cargo_type = CT_INVALID;
1236 } else if (_cur.grffile->grf_version >= 8) {
1237 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1238 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1239 } else if (ctype < NUM_CARGO) {
1240 /* Use untranslated cargo. */
1241 ei->cargo_type = ctype;
1242 } else {
1243 ei->cargo_type = CT_INVALID;
1244 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1246 break;
1249 case PROP_TRAIN_WEIGHT: // 0x16 Weight
1250 SB(rvi->weight, 0, 8, buf->ReadByte());
1251 break;
1253 case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
1254 rvi->cost_factor = buf->ReadByte();
1255 break;
1257 case 0x18: // AI rank
1258 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1259 buf->ReadByte();
1260 break;
1262 case 0x19: { // Engine traction type
1263 /* What do the individual numbers mean?
1264 * 0x00 .. 0x07: Steam
1265 * 0x08 .. 0x27: Diesel
1266 * 0x28 .. 0x31: Electric
1267 * 0x32 .. 0x37: Monorail
1268 * 0x38 .. 0x41: Maglev
1270 uint8 traction = buf->ReadByte();
1271 EngineClass engclass;
1273 if (traction <= 0x07) {
1274 engclass = EC_STEAM;
1275 } else if (traction <= 0x27) {
1276 engclass = EC_DIESEL;
1277 } else if (traction <= 0x31) {
1278 engclass = EC_ELECTRIC;
1279 } else if (traction <= 0x37) {
1280 engclass = EC_MONORAIL;
1281 } else if (traction <= 0x41) {
1282 engclass = EC_MAGLEV;
1283 } else {
1284 break;
1287 if (_cur.grffile->railtype_list.Length() == 0) {
1288 /* Use traction type to select between normal and electrified
1289 * rail only when no translation list is in place. */
1290 if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1291 if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
1294 rvi->engclass = engclass;
1295 break;
1298 case 0x1A: // Alter purchase list sort order
1299 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1300 break;
1302 case 0x1B: // Powered wagons power bonus
1303 rvi->pow_wag_power = buf->ReadWord();
1304 break;
1306 case 0x1C: // Refit cost
1307 ei->refit_cost = buf->ReadByte();
1308 break;
1310 case 0x1D: { // Refit cargo
1311 uint32 mask = buf->ReadDWord();
1312 _gted[e->index].UpdateRefittability(mask != 0);
1313 ei->refit_mask = TranslateRefitMask(mask);
1314 _gted[e->index].defaultcargo_grf = _cur.grffile;
1315 break;
1318 case 0x1E: // Callback
1319 ei->callback_mask = buf->ReadByte();
1320 break;
1322 case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
1323 rvi->tractive_effort = buf->ReadByte();
1324 break;
1326 case 0x20: // Air drag
1327 rvi->air_drag = buf->ReadByte();
1328 break;
1330 case PROP_TRAIN_SHORTEN_FACTOR: // 0x21 Shorter vehicle
1331 rvi->shorten_factor = buf->ReadByte();
1332 break;
1334 case 0x22: // Visual effect
1335 rvi->visual_effect = buf->ReadByte();
1336 /* Avoid accidentally setting visual_effect to the default value
1337 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1338 if (rvi->visual_effect == VE_DEFAULT) {
1339 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1340 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1342 break;
1344 case 0x23: // Powered wagons weight bonus
1345 rvi->pow_wag_weight = buf->ReadByte();
1346 break;
1348 case 0x24: { // High byte of vehicle weight
1349 byte weight = buf->ReadByte();
1351 if (weight > 4) {
1352 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1353 } else {
1354 SB(rvi->weight, 8, 8, weight);
1356 break;
1359 case PROP_TRAIN_USER_DATA: // 0x25 User-defined bit mask to set when checking veh. var. 42
1360 rvi->user_def_data = buf->ReadByte();
1361 break;
1363 case 0x26: // Retire vehicle early
1364 ei->retire_early = buf->ReadByte();
1365 break;
1367 case 0x27: // Miscellaneous flags
1368 ei->misc_flags = buf->ReadByte();
1369 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1370 _gted[e->index].prop27_set = true;
1371 break;
1373 case 0x28: // Cargo classes allowed
1374 _gted[e->index].cargo_allowed = buf->ReadWord();
1375 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1376 _gted[e->index].defaultcargo_grf = _cur.grffile;
1377 break;
1379 case 0x29: // Cargo classes disallowed
1380 _gted[e->index].cargo_disallowed = buf->ReadWord();
1381 _gted[e->index].UpdateRefittability(false);
1382 break;
1384 case 0x2A: // Long format introduction date (days since year 0)
1385 ei->base_intro = buf->ReadDWord();
1386 break;
1388 case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
1389 ei->cargo_age_period = buf->ReadWord();
1390 break;
1392 case 0x2C: // CTT refit include list
1393 case 0x2D: { // CTT refit exclude list
1394 uint8 count = buf->ReadByte();
1395 _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
1396 if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile;
1397 uint32 &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1398 ctt = 0;
1399 while (count--) {
1400 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1401 if (ctype == CT_INVALID) continue;
1402 SetBit(ctt, ctype);
1404 break;
1407 default:
1408 ret = CommonVehicleChangeInfo(ei, prop, buf);
1409 break;
1413 return ret;
1417 * Define properties for road vehicles
1418 * @param engine Local ID of the first vehicle.
1419 * @param numinfo Number of subsequent IDs to change the property for.
1420 * @param prop The property to change.
1421 * @param buf The property value.
1422 * @return ChangeInfoResult.
1424 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1426 ChangeInfoResult ret = CIR_SUCCESS;
1428 for (int i = 0; i < numinfo; i++) {
1429 Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i);
1430 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1432 EngineInfo *ei = &e->info;
1433 RoadVehicleInfo *rvi = &e->u.road;
1435 switch (prop) {
1436 case 0x08: // Speed (1 unit is 0.5 kmh)
1437 rvi->max_speed = buf->ReadByte();
1438 break;
1440 case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1441 rvi->running_cost = buf->ReadByte();
1442 break;
1444 case 0x0A: // Running cost base
1445 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1446 break;
1448 case 0x0E: { // Sprite ID
1449 uint8 spriteid = buf->ReadByte();
1450 uint8 orig_spriteid = spriteid;
1452 /* cars have different custom id in the GRF file */
1453 if (spriteid == 0xFF) spriteid = 0xFD;
1455 if (spriteid < 0xFD) spriteid >>= 1;
1457 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1458 rvi->image_index = spriteid;
1459 } else {
1460 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1461 rvi->image_index = 0;
1463 break;
1466 case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1467 rvi->capacity = buf->ReadByte();
1468 break;
1470 case 0x10: { // Cargo type
1471 _gted[e->index].defaultcargo_grf = _cur.grffile;
1472 uint8 ctype = buf->ReadByte();
1474 if (ctype == 0xFF) {
1475 /* 0xFF is specified as 'use first refittable' */
1476 ei->cargo_type = CT_INVALID;
1477 } else if (_cur.grffile->grf_version >= 8) {
1478 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1479 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1480 } else if (ctype < NUM_CARGO) {
1481 /* Use untranslated cargo. */
1482 ei->cargo_type = ctype;
1483 } else {
1484 ei->cargo_type = CT_INVALID;
1485 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1487 break;
1490 case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1491 rvi->cost_factor = buf->ReadByte();
1492 break;
1494 case 0x12: // SFX
1495 rvi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1496 break;
1498 case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1499 rvi->power = buf->ReadByte();
1500 break;
1502 case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1503 rvi->weight = buf->ReadByte();
1504 break;
1506 case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1507 _gted[e->index].rv_max_speed = buf->ReadByte();
1508 break;
1510 case 0x16: { // Cargoes available for refitting
1511 uint32 mask = buf->ReadDWord();
1512 _gted[e->index].UpdateRefittability(mask != 0);
1513 ei->refit_mask = TranslateRefitMask(mask);
1514 _gted[e->index].defaultcargo_grf = _cur.grffile;
1515 break;
1518 case 0x17: // Callback mask
1519 ei->callback_mask = buf->ReadByte();
1520 break;
1522 case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1523 rvi->tractive_effort = buf->ReadByte();
1524 break;
1526 case 0x19: // Air drag
1527 rvi->air_drag = buf->ReadByte();
1528 break;
1530 case 0x1A: // Refit cost
1531 ei->refit_cost = buf->ReadByte();
1532 break;
1534 case 0x1B: // Retire vehicle early
1535 ei->retire_early = buf->ReadByte();
1536 break;
1538 case 0x1C: // Miscellaneous flags
1539 ei->misc_flags = buf->ReadByte();
1540 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1541 break;
1543 case 0x1D: // Cargo classes allowed
1544 _gted[e->index].cargo_allowed = buf->ReadWord();
1545 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1546 _gted[e->index].defaultcargo_grf = _cur.grffile;
1547 break;
1549 case 0x1E: // Cargo classes disallowed
1550 _gted[e->index].cargo_disallowed = buf->ReadWord();
1551 _gted[e->index].UpdateRefittability(false);
1552 break;
1554 case 0x1F: // Long format introduction date (days since year 0)
1555 ei->base_intro = buf->ReadDWord();
1556 break;
1558 case 0x20: // Alter purchase list sort order
1559 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1560 break;
1562 case 0x21: // Visual effect
1563 rvi->visual_effect = buf->ReadByte();
1564 /* Avoid accidentally setting visual_effect to the default value
1565 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1566 if (rvi->visual_effect == VE_DEFAULT) {
1567 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1568 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1570 break;
1572 case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1573 ei->cargo_age_period = buf->ReadWord();
1574 break;
1576 case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
1577 rvi->shorten_factor = buf->ReadByte();
1578 break;
1580 case 0x24: // CTT refit include list
1581 case 0x25: { // CTT refit exclude list
1582 uint8 count = buf->ReadByte();
1583 _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
1584 if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
1585 uint32 &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1586 ctt = 0;
1587 while (count--) {
1588 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1589 if (ctype == CT_INVALID) continue;
1590 SetBit(ctt, ctype);
1592 break;
1595 default:
1596 ret = CommonVehicleChangeInfo(ei, prop, buf);
1597 break;
1601 return ret;
1605 * Define properties for ships
1606 * @param engine Local ID of the first vehicle.
1607 * @param numinfo Number of subsequent IDs to change the property for.
1608 * @param prop The property to change.
1609 * @param buf The property value.
1610 * @return ChangeInfoResult.
1612 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1614 ChangeInfoResult ret = CIR_SUCCESS;
1616 for (int i = 0; i < numinfo; i++) {
1617 Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1618 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1620 EngineInfo *ei = &e->info;
1621 ShipVehicleInfo *svi = &e->u.ship;
1623 switch (prop) {
1624 case 0x08: { // Sprite ID
1625 uint8 spriteid = buf->ReadByte();
1626 uint8 orig_spriteid = spriteid;
1628 /* ships have different custom id in the GRF file */
1629 if (spriteid == 0xFF) spriteid = 0xFD;
1631 if (spriteid < 0xFD) spriteid >>= 1;
1633 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1634 svi->image_index = spriteid;
1635 } else {
1636 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1637 svi->image_index = 0;
1639 break;
1642 case 0x09: // Refittable
1643 svi->old_refittable = (buf->ReadByte() != 0);
1644 break;
1646 case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1647 svi->cost_factor = buf->ReadByte();
1648 break;
1650 case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1651 svi->max_speed = buf->ReadByte();
1652 break;
1654 case 0x0C: { // Cargo type
1655 _gted[e->index].defaultcargo_grf = _cur.grffile;
1656 uint8 ctype = buf->ReadByte();
1658 if (ctype == 0xFF) {
1659 /* 0xFF is specified as 'use first refittable' */
1660 ei->cargo_type = CT_INVALID;
1661 } else if (_cur.grffile->grf_version >= 8) {
1662 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1663 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1664 } else if (ctype < NUM_CARGO) {
1665 /* Use untranslated cargo. */
1666 ei->cargo_type = ctype;
1667 } else {
1668 ei->cargo_type = CT_INVALID;
1669 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1671 break;
1674 case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1675 svi->capacity = buf->ReadWord();
1676 break;
1678 case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1679 svi->running_cost = buf->ReadByte();
1680 break;
1682 case 0x10: // SFX
1683 svi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1684 break;
1686 case 0x11: { // Cargoes available for refitting
1687 uint32 mask = buf->ReadDWord();
1688 _gted[e->index].UpdateRefittability(mask != 0);
1689 ei->refit_mask = TranslateRefitMask(mask);
1690 _gted[e->index].defaultcargo_grf = _cur.grffile;
1691 break;
1694 case 0x12: // Callback mask
1695 ei->callback_mask = buf->ReadByte();
1696 break;
1698 case 0x13: // Refit cost
1699 ei->refit_cost = buf->ReadByte();
1700 break;
1702 case 0x14: // Ocean speed fraction
1703 svi->ocean_speed_frac = buf->ReadByte();
1704 break;
1706 case 0x15: // Canal speed fraction
1707 svi->canal_speed_frac = buf->ReadByte();
1708 break;
1710 case 0x16: // Retire vehicle early
1711 ei->retire_early = buf->ReadByte();
1712 break;
1714 case 0x17: // Miscellaneous flags
1715 ei->misc_flags = buf->ReadByte();
1716 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1717 break;
1719 case 0x18: // Cargo classes allowed
1720 _gted[e->index].cargo_allowed = buf->ReadWord();
1721 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1722 _gted[e->index].defaultcargo_grf = _cur.grffile;
1723 break;
1725 case 0x19: // Cargo classes disallowed
1726 _gted[e->index].cargo_disallowed = buf->ReadWord();
1727 _gted[e->index].UpdateRefittability(false);
1728 break;
1730 case 0x1A: // Long format introduction date (days since year 0)
1731 ei->base_intro = buf->ReadDWord();
1732 break;
1734 case 0x1B: // Alter purchase list sort order
1735 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1736 break;
1738 case 0x1C: // Visual effect
1739 svi->visual_effect = buf->ReadByte();
1740 /* Avoid accidentally setting visual_effect to the default value
1741 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1742 if (svi->visual_effect == VE_DEFAULT) {
1743 assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1744 SB(svi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1746 break;
1748 case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1749 ei->cargo_age_period = buf->ReadWord();
1750 break;
1752 case 0x1E: // CTT refit include list
1753 case 0x1F: { // CTT refit exclude list
1754 uint8 count = buf->ReadByte();
1755 _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
1756 if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
1757 uint32 &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1758 ctt = 0;
1759 while (count--) {
1760 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1761 if (ctype == CT_INVALID) continue;
1762 SetBit(ctt, ctype);
1764 break;
1767 default:
1768 ret = CommonVehicleChangeInfo(ei, prop, buf);
1769 break;
1773 return ret;
1777 * Define properties for aircraft
1778 * @param engine Local ID of the aircraft.
1779 * @param numinfo Number of subsequent IDs to change the property for.
1780 * @param prop The property to change.
1781 * @param buf The property value.
1782 * @return ChangeInfoResult.
1784 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1786 ChangeInfoResult ret = CIR_SUCCESS;
1788 for (int i = 0; i < numinfo; i++) {
1789 Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1790 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1792 EngineInfo *ei = &e->info;
1793 AircraftVehicleInfo *avi = &e->u.air;
1795 switch (prop) {
1796 case 0x08: { // Sprite ID
1797 uint8 spriteid = buf->ReadByte();
1798 uint8 orig_spriteid = spriteid;
1800 /* aircraft have different custom id in the GRF file */
1801 if (spriteid == 0xFF) spriteid = 0xFD;
1803 if (spriteid < 0xFD) spriteid >>= 1;
1805 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1806 avi->image_index = spriteid;
1807 } else {
1808 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1809 avi->image_index = 0;
1811 break;
1814 case 0x09: // Helicopter
1815 if (buf->ReadByte() == 0) {
1816 avi->subtype = AIR_HELI;
1817 } else {
1818 SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1820 break;
1822 case 0x0A: // Large
1823 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1824 break;
1826 case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1827 avi->cost_factor = buf->ReadByte();
1828 break;
1830 case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1831 avi->max_speed = (buf->ReadByte() * 128) / 10;
1832 break;
1834 case 0x0D: // Acceleration
1835 avi->acceleration = buf->ReadByte();
1836 break;
1838 case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1839 avi->running_cost = buf->ReadByte();
1840 break;
1842 case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1843 avi->passenger_capacity = buf->ReadWord();
1844 break;
1846 case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1847 avi->mail_capacity = buf->ReadByte();
1848 break;
1850 case 0x12: // SFX
1851 avi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1852 break;
1854 case 0x13: { // Cargoes available for refitting
1855 uint32 mask = buf->ReadDWord();
1856 _gted[e->index].UpdateRefittability(mask != 0);
1857 ei->refit_mask = TranslateRefitMask(mask);
1858 _gted[e->index].defaultcargo_grf = _cur.grffile;
1859 break;
1862 case 0x14: // Callback mask
1863 ei->callback_mask = buf->ReadByte();
1864 break;
1866 case 0x15: // Refit cost
1867 ei->refit_cost = buf->ReadByte();
1868 break;
1870 case 0x16: // Retire vehicle early
1871 ei->retire_early = buf->ReadByte();
1872 break;
1874 case 0x17: // Miscellaneous flags
1875 ei->misc_flags = buf->ReadByte();
1876 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1877 break;
1879 case 0x18: // Cargo classes allowed
1880 _gted[e->index].cargo_allowed = buf->ReadWord();
1881 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1882 _gted[e->index].defaultcargo_grf = _cur.grffile;
1883 break;
1885 case 0x19: // Cargo classes disallowed
1886 _gted[e->index].cargo_disallowed = buf->ReadWord();
1887 _gted[e->index].UpdateRefittability(false);
1888 break;
1890 case 0x1A: // Long format introduction date (days since year 0)
1891 ei->base_intro = buf->ReadDWord();
1892 break;
1894 case 0x1B: // Alter purchase list sort order
1895 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1896 break;
1898 case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1899 ei->cargo_age_period = buf->ReadWord();
1900 break;
1902 case 0x1D: // CTT refit include list
1903 case 0x1E: { // CTT refit exclude list
1904 uint8 count = buf->ReadByte();
1905 _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
1906 if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
1907 uint32 &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1908 ctt = 0;
1909 while (count--) {
1910 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1911 if (ctype == CT_INVALID) continue;
1912 SetBit(ctt, ctype);
1914 break;
1917 case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
1918 avi->max_range = buf->ReadWord();
1919 break;
1921 default:
1922 ret = CommonVehicleChangeInfo(ei, prop, buf);
1923 break;
1927 return ret;
1930 /** Sprite layout for a station tile. */
1931 struct StationTileSpriteLayout : NewGRFSpriteLayout, FlexArrayBase {
1932 private:
1933 template <typename T>
1934 static CONSTEXPR T *offset_pointer (void *ptr, size_t offset)
1936 return (T*) (((char*)ptr) + offset);
1939 static CONSTEXPR size_t seq_offset (void)
1941 return ttd_align_up<DrawTileSeqStruct> (sizeof(StationTileSpriteLayout));
1944 StationTileSpriteLayout (const PalSpriteID &ground, uint n,
1945 DrawTileSeqStruct **pseq)
1947 this->ground = ground;
1949 DrawTileSeqStruct *q = offset_pointer<DrawTileSeqStruct> (this, seq_offset());
1950 q[n].MakeTerminator();
1951 this->seq = q;
1953 this->registers = NULL;
1955 this->consistent_max_offset = UINT16_MAX;
1957 *pseq = q;
1960 StationTileSpriteLayout (const PalSpriteID &ground, uint n,
1961 const DrawTileSeqStruct *seq, size_t regs_offset,
1962 const TileLayoutRegisters *regs,
1963 uint consistent_max_offset)
1965 this->ground = ground;
1967 DrawTileSeqStruct *q = offset_pointer<DrawTileSeqStruct> (this, seq_offset());
1968 memcpy (q, seq, n * sizeof(DrawTileSeqStruct));
1969 q[n].MakeTerminator();
1970 this->seq = q;
1972 if (regs != NULL) {
1973 TileLayoutRegisters *r = offset_pointer<TileLayoutRegisters> (this, regs_offset);
1974 memcpy (r, regs, (n + 1) * sizeof(TileLayoutRegisters));
1975 this->registers = r;
1976 } else {
1977 this->registers = NULL;
1980 this->consistent_max_offset = consistent_max_offset;
1983 /** Custom operator new to account for the extra storage. */
1984 void *operator new (size_t size, size_t total, size_t = 1)
1986 assert (total >= size);
1987 return ::operator new (total);
1990 public:
1991 static StationTileSpriteLayout *create (const PalSpriteID &ground,
1992 uint n, const DrawTileSeqStruct *seq,
1993 const TileLayoutRegisters *regs, uint consistent_max_offset);
1995 static StationTileSpriteLayout *clone (const PalSpriteID &ground,
1996 const DrawTileSeqStruct *seq)
1998 size_t n = 1; // 1 for the terminator
1999 const DrawTileSeqStruct *dtss;
2000 foreach_draw_tile_seq(dtss, seq) n++;
2002 return create (ground, n, seq, NULL, UINT16_MAX);
2005 static StationTileSpriteLayout *clone (const NewGRFSpriteLayout *src)
2007 size_t n = 1; // 1 for the terminator
2008 const DrawTileSeqStruct *dtss;
2009 foreach_draw_tile_seq(dtss, src->seq) n++;
2011 return create (src->ground, n, src->seq, src->registers,
2012 src->consistent_max_offset);
2015 static StationTileSpriteLayout *init (const PalSpriteID &ground,
2016 uint n, DrawTileSeqStruct **p)
2018 /* Make room for terminator. */
2019 size_t seq_end = seq_offset() + (n + 1) * sizeof(DrawTileSeqStruct);
2020 size_t total_size = ttd_align_up<TileLayoutSpriteGroup> (seq_end);
2021 return new (total_size) StationTileSpriteLayout (ground, n, p);
2025 StationTileSpriteLayout *StationTileSpriteLayout::create (const PalSpriteID &ground,
2026 uint n, const DrawTileSeqStruct *seq, const TileLayoutRegisters *regs,
2027 uint consistent_max_offset)
2029 /* Make room for terminator. */
2030 size_t seq_end = seq_offset() + (n + 1) * sizeof(DrawTileSeqStruct);
2032 size_t regs_offset, regs_end;
2033 if (regs != NULL) {
2034 regs_offset = ttd_align_up<TileLayoutRegisters> (seq_end);
2035 regs_end = regs_offset + (n + 1) * sizeof(TileLayoutRegisters);
2036 } else {
2037 regs_offset = 0;
2038 regs_end = seq_end;
2041 size_t total_size = ttd_align_up<TileLayoutSpriteGroup> (regs_end);
2042 return new (total_size) StationTileSpriteLayout (ground, n, seq,
2043 regs_offset, regs, consistent_max_offset);
2047 * Define properties for stations
2048 * @param stdid StationID of the first station tile.
2049 * @param numinfo Number of subsequent station tiles to change the property for.
2050 * @param prop The property to change.
2051 * @param buf The property value.
2052 * @return ChangeInfoResult.
2054 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
2056 ChangeInfoResult ret = CIR_SUCCESS;
2058 if (stid + numinfo > NUM_STATIONS_PER_GRF) {
2059 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
2060 return CIR_INVALID_ID;
2063 /* Allocate station specs if necessary */
2064 if (_cur.grffile->stations == NULL) _cur.grffile->stations = xcalloct<StationSpec*>(NUM_STATIONS_PER_GRF);
2066 for (int i = 0; i < numinfo; i++) {
2067 StationSpec *statspec = _cur.grffile->stations[stid + i];
2069 /* Check that the station we are modifying is defined. */
2070 if (statspec == NULL && prop != 0x08) {
2071 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
2072 return CIR_INVALID_ID;
2075 switch (prop) {
2076 case 0x08: { // Class ID
2077 StationSpec **spec = &_cur.grffile->stations[stid + i];
2079 /* Property 0x08 is special; it is where the station is allocated */
2080 if (*spec == NULL) *spec = new StationSpec;
2082 /* Swap classid because we read it in BE meaning WAYP or DFLT */
2083 uint32 classid = buf->ReadLabel();
2084 (*spec)->cls_id = StationClass::Allocate (classid);
2085 break;
2088 case 0x09: { // Define sprite layout
2089 statspec->renderdata.clear(); // delete earlier loaded stuff
2090 uint n = buf->ReadExtendedByte();
2091 statspec->renderdata.reserve (n);
2093 for (uint t = 0; t < n; t++) {
2094 assert (statspec->renderdata.size() == t);
2096 const byte *gp = buf->GetData (4);
2098 if (ReadDWord (gp) == 0) {
2099 extern const DrawTileSprites _station_display_datas_rail[8];
2100 const DrawTileSprites *src = &_station_display_datas_rail[t % 8];
2101 NewGRFSpriteLayout *dts = StationTileSpriteLayout::clone (src->ground, src->seq);
2102 statspec->renderdata.push_back (ttd_unique_ptr<NewGRFSpriteLayout> (dts));
2103 continue;
2106 /* On error, bail out immediately. Temporary GRF data was already freed */
2107 PalSpriteID ground;
2108 ReadPalSprite (gp, &ground);
2109 if (!AdjustSpriteLayoutSprite (&ground, GSF_STATIONS, false)) {
2110 return CIR_DISABLED;
2113 const byte *p = buf->GetData();
2114 uint num_building_sprites = 0;
2115 while (buf->ReadByte() != 0x80) {
2116 buf->Skip (9);
2117 num_building_sprites++;
2120 DrawTileSeqStruct *seq;
2121 NewGRFSpriteLayout *dts = StationTileSpriteLayout::init (ground, num_building_sprites, &seq);
2122 statspec->renderdata.push_back (ttd_unique_ptr<NewGRFSpriteLayout> (dts));
2123 for (uint i = 0; i < num_building_sprites; i++) {
2124 /* no relative bounding box support */
2125 DrawTileSeqStruct *dtss = &seq[i];
2126 MemSetT(dtss, 0);
2128 dtss->delta_x = *p++;
2129 dtss->delta_y = *p++;
2130 dtss->delta_z = *p++;
2131 dtss->size_x = *p++;
2132 dtss->size_y = *p++;
2133 dtss->size_z = *p++;
2135 /* On error, bail out immediately. Temporary GRF data was already freed */
2136 ReadPalSprite (p, &dtss->image);
2137 if (!AdjustSpriteLayoutSprite (&dtss->image, GSF_STATIONS, true)) {
2138 return CIR_DISABLED;
2140 p += 4;
2143 break;
2146 case 0x0A: { // Copy sprite layout
2147 byte srcid = buf->ReadByte();
2148 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
2150 if (srcstatspec == NULL) {
2151 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
2152 continue;
2155 statspec->renderdata.clear(); // delete earlier loaded stuff
2156 uint n = srcstatspec->renderdata.size();
2157 statspec->renderdata.reserve (n);
2159 for (uint t = 0; t < n; t++) {
2160 assert (statspec->renderdata.size() == t);
2161 const NewGRFSpriteLayout *src = srcstatspec->renderdata[t].get();
2162 NewGRFSpriteLayout *dts = StationTileSpriteLayout::clone (src);
2163 statspec->renderdata.push_back (ttd_unique_ptr<NewGRFSpriteLayout> (dts));
2165 break;
2168 case 0x0B: // Callback mask
2169 statspec->callback_mask = buf->ReadByte();
2170 break;
2172 case 0x0C: // Disallowed number of platforms
2173 statspec->disallowed_platforms = buf->ReadByte();
2174 break;
2176 case 0x0D: // Disallowed platform lengths
2177 statspec->disallowed_lengths = buf->ReadByte();
2178 break;
2180 case 0x0E: { // Define custom layout
2181 byte max_length [256]; // 0 is max width
2182 memset (max_length, 0, sizeof(max_length));
2183 byte &max_width = max_length[0];
2185 const byte *p = buf->GetData();
2187 /* Total layout size. */
2188 size_t size = 0;
2190 while (buf->HasData()) {
2191 byte length = buf->ReadByte();
2192 byte number = buf->ReadByte();
2194 if (length == 0 || number == 0) break;
2196 max_width = max (max_width, number);
2197 max_length[number] = max (max_length[number], length);
2199 uint n = length * number;
2200 size += n;
2201 buf->Skip (n);
2204 /* Compute how many pointers we need. */
2205 uint nptr = max_width;
2206 for (uint i = 1; i <= max_width; i++) {
2207 nptr += max_length[i];
2210 assert_compile (sizeof(void*) == sizeof(byte*));
2211 assert_compile (sizeof(void*) == sizeof(byte**));
2213 void **alloc = (void**) xmalloc (nptr * sizeof(void*) + max_width + size);
2214 memset (alloc, 0, nptr * sizeof(void*));
2216 byte ***layouts = (byte***) alloc;
2217 byte **q = (byte**) (alloc + max_width);
2218 for (uint i = 1; i <= max_width; i++) {
2219 if (max_length[i] != 0) {
2220 layouts[i - 1] = q;
2221 q += max_length[i];
2224 assert ((void*)(alloc + nptr) == (void*)q);
2226 struct delete_free {
2227 void operator() (void *p) { free(p); }
2230 byte *buffer = (byte*) q;
2231 statspec->layouts.reset (layouts, delete_free());
2232 statspec->max_layout_length = buffer - 1;
2233 statspec->max_layout_width = max_width;
2235 memcpy (buffer, &max_length[1], max_width);
2236 buffer += max_width;
2238 for (;;) {
2239 byte length = *p++;
2240 byte number = *p++;
2242 if (length == 0 || number == 0) break;
2244 layouts[number - 1][length - 1] = buffer;
2246 uint n = length * number;
2247 memcpy (buffer, p, n);
2248 buffer += n;
2249 p += n;
2252 assert (p == buf->GetData());
2254 break;
2257 case 0x0F: { // Copy custom layout
2258 byte srcid = buf->ReadByte();
2259 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
2261 if (srcstatspec == NULL) {
2262 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2263 continue;
2266 statspec->layouts = srcstatspec->layouts;
2267 statspec->max_layout_length = srcstatspec->max_layout_length;
2268 statspec->max_layout_width = srcstatspec->max_layout_width;
2269 break;
2272 case 0x10: // Little/lots cargo threshold
2273 statspec->cargo_threshold = buf->ReadWord();
2274 break;
2276 case 0x11: // Pylon placement
2277 statspec->pylons = buf->ReadByte();
2278 break;
2280 case 0x12: // Cargo types for random triggers
2281 statspec->cargo_triggers = buf->ReadDWord();
2282 if (_cur.grffile->grf_version >= 7) {
2283 statspec->cargo_triggers = TranslateRefitMask(statspec->cargo_triggers);
2285 break;
2287 case 0x13: // General flags
2288 statspec->flags = buf->ReadByte();
2289 break;
2291 case 0x14: // Overhead wire placement
2292 statspec->wires = buf->ReadByte();
2293 break;
2295 case 0x15: // Blocked tiles
2296 statspec->blocked = buf->ReadByte();
2297 break;
2299 case 0x16: // Animation info
2300 statspec->animation.frames = buf->ReadByte();
2301 statspec->animation.status = buf->ReadByte();
2302 break;
2304 case 0x17: // Animation speed
2305 statspec->animation.speed = buf->ReadByte();
2306 break;
2308 case 0x18: // Animation triggers
2309 statspec->animation.triggers = buf->ReadWord();
2310 break;
2312 case 0x1A: { // Advanced sprite layout
2313 statspec->renderdata.clear(); // delete earlier loaded stuff
2314 uint n = buf->ReadExtendedByte();
2315 statspec->renderdata.reserve (n);
2317 for (uint t = 0; t < n; t++) {
2318 assert (statspec->renderdata.size() == t);
2319 uint num_building_sprites = buf->ReadByte();
2320 /* On error, bail out immediately. Temporary GRF data was already freed */
2321 SpriteLayoutReader reader;
2322 if (ReadSpriteLayout (&reader, buf, num_building_sprites, false, GSF_STATIONS, true, false)) {
2323 return CIR_DISABLED;
2326 NewGRFSpriteLayout *dts = StationTileSpriteLayout::create (reader.ground,
2327 reader.num_building_sprites, reader.seq,
2328 reader.has_registers ? reader.regs : NULL,
2329 reader.consistent_max_offset);
2330 statspec->renderdata.push_back (ttd_unique_ptr<NewGRFSpriteLayout> (dts));
2332 break;
2335 default:
2336 ret = CIR_UNKNOWN;
2337 break;
2341 return ret;
2345 * Define properties for water features
2346 * @param id Type of the first water feature.
2347 * @param numinfo Number of subsequent water feature ids to change the property for.
2348 * @param prop The property to change.
2349 * @param buf The property value.
2350 * @return ChangeInfoResult.
2352 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
2354 ChangeInfoResult ret = CIR_SUCCESS;
2356 if (id + numinfo > CF_END) {
2357 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id + numinfo, CF_END);
2358 return CIR_INVALID_ID;
2361 for (int i = 0; i < numinfo; i++) {
2362 CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
2364 switch (prop) {
2365 case 0x08:
2366 cp->callback_mask = buf->ReadByte();
2367 break;
2369 case 0x09:
2370 cp->flags = buf->ReadByte();
2371 break;
2373 default:
2374 ret = CIR_UNKNOWN;
2375 break;
2379 return ret;
2383 * Define properties for bridges
2384 * @param brid BridgeID of the bridge.
2385 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2386 * @param prop The property to change.
2387 * @param buf The property value.
2388 * @return ChangeInfoResult.
2390 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
2392 ChangeInfoResult ret = CIR_SUCCESS;
2394 if (brid + numinfo > MAX_BRIDGES) {
2395 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
2396 return CIR_INVALID_ID;
2399 for (int i = 0; i < numinfo; i++) {
2400 BridgeSpec *bridge = &_bridge[brid + i];
2402 switch (prop) {
2403 case 0x08: { // Year of availability
2404 /* We treat '0' as always available */
2405 byte year = buf->ReadByte();
2406 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
2407 break;
2410 case 0x09: // Minimum length
2411 bridge->min_length = buf->ReadByte();
2412 break;
2414 case 0x0A: // Maximum length
2415 bridge->max_length = buf->ReadByte();
2416 if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
2417 break;
2419 case 0x0B: // Cost factor
2420 bridge->price = buf->ReadByte();
2421 break;
2423 case 0x0C: // Maximum speed
2424 bridge->speed = buf->ReadWord();
2425 break;
2427 case 0x0D: { // Bridge sprite tables
2428 byte tableid = buf->ReadByte();
2429 byte numtables = buf->ReadByte();
2431 if (bridge->sprite_table == NULL) {
2432 /* Allocate memory for sprite table pointers and zero out */
2433 bridge->sprite_table = xcalloct<PalSpriteID*>(7);
2436 for (; numtables-- != 0; tableid++) {
2437 if (tableid >= 7) { // skip invalid data
2438 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2439 buf->Skip (32 * 4);
2440 continue;
2443 if (bridge->sprite_table[tableid] == NULL) {
2444 bridge->sprite_table[tableid] = xmalloct<PalSpriteID>(32);
2447 for (byte sprite = 0; sprite < 32; sprite++) {
2448 ReadPalSprite (buf, &bridge->sprite_table[tableid][sprite]);
2451 break;
2454 case 0x0E: // Flags; bit 0 - disable far pillars
2455 bridge->flags = buf->ReadByte();
2456 break;
2458 case 0x0F: // Long format year of availability (year since year 0)
2459 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
2460 break;
2462 case 0x10: { // purchase string
2463 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2464 if (newone != STR_UNDEFINED) bridge->material = newone;
2465 break;
2468 case 0x11: // description of bridge with rails or roads
2469 case 0x12: {
2470 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2471 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
2472 break;
2475 case 0x13: // 16 bits cost multiplier
2476 bridge->price = buf->ReadWord();
2477 break;
2479 case 0x14: // purchase sprite
2480 bridge->sprite = buf->ReadWord();
2481 bridge->pal = buf->ReadWord();
2482 break;
2484 default:
2485 ret = CIR_UNKNOWN;
2486 break;
2490 return ret;
2494 * Ignore a house property
2495 * @param prop Property to read.
2496 * @param buf Property value.
2497 * @return ChangeInfoResult.
2499 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
2501 static const byte skip[] = {
2502 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2503 /* 00 */ 1, 2, 1, 1, 1, 1, 1,
2504 /* 10 */ 2, 1, 2, 2, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 4, 1,
2505 /* 20 */ 0, 2, 2,
2508 uint k = prop - 0x09;
2509 if (k >= lengthof(skip)) return CIR_UNKNOWN;
2511 byte s = skip[k];
2512 buf->Skip (s != 0 ? s : buf->ReadByte());
2513 return CIR_SUCCESS;
2517 * Define properties for houses
2518 * @param hid HouseID of the house.
2519 * @param numinfo Number of subsequent houseIDs to change the property for.
2520 * @param prop The property to change.
2521 * @param buf The property value.
2522 * @return ChangeInfoResult.
2524 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2526 ChangeInfoResult ret = CIR_SUCCESS;
2528 if (hid + numinfo > NUM_HOUSES_PER_GRF) {
2529 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
2530 return CIR_INVALID_ID;
2533 /* Allocate house specs if they haven't been allocated already. */
2534 if (_cur.grffile->housespec == NULL) {
2535 _cur.grffile->housespec = xcalloct<HouseSpec*>(NUM_HOUSES_PER_GRF);
2538 for (int i = 0; i < numinfo; i++) {
2539 HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2541 if (prop != 0x08 && housespec == NULL) {
2542 /* If the house property 08 is not yet set, ignore this property */
2543 ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2544 if (cir > ret) ret = cir;
2545 continue;
2548 switch (prop) {
2549 case 0x08: { // Substitute building type, and definition of a new house
2550 HouseSpec **house = &_cur.grffile->housespec[hid + i];
2551 byte subs_id = buf->ReadByte();
2553 if (subs_id == 0xFF) {
2554 /* Instead of defining a new house, a substitute house id
2555 * of 0xFF disables the old house with the current id. */
2556 HouseSpec::Get(hid + i)->enabled = false;
2557 continue;
2558 } else if (subs_id >= NEW_HOUSE_OFFSET) {
2559 /* The substitute id must be one of the original houses. */
2560 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2561 continue;
2564 /* Allocate space for this house. */
2565 if (*house == NULL) *house = xcalloct<HouseSpec>();
2567 housespec = *house;
2569 MemCpyT(housespec, HouseSpec::Get(subs_id));
2571 housespec->enabled = true;
2572 housespec->grf_prop.local_id = hid + i;
2573 housespec->grf_prop.subst_id = subs_id;
2574 housespec->grf_prop.grffile = _cur.grffile;
2575 housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2576 housespec->random_colour[1] = 0x08; // for all new houses
2577 housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2578 housespec->random_colour[3] = 0x06;
2580 /* Make sure that the third cargo type is valid in this
2581 * climate. This can cause problems when copying the properties
2582 * of a house that accepts food, where the new house is valid
2583 * in the temperate climate. */
2584 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2585 housespec->cargo_acceptance[2] = 0;
2588 _loaded_newgrf_features.has_newhouses = true;
2589 break;
2592 case 0x09: // Building flags
2593 housespec->building_flags = (BuildingFlags)buf->ReadByte();
2594 break;
2596 case 0x0A: { // Availability years
2597 uint16 years = buf->ReadWord();
2598 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2599 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2600 break;
2603 case 0x0B: // Population
2604 housespec->population = buf->ReadByte();
2605 break;
2607 case 0x0C: // Mail generation multiplier
2608 housespec->mail_generation = buf->ReadByte();
2609 break;
2611 case 0x0D: // Passenger acceptance
2612 case 0x0E: // Mail acceptance
2613 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2614 break;
2616 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2617 int8 goods = buf->ReadByte();
2619 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2620 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2621 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2622 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2624 /* Make sure the cargo type is valid in this climate. */
2625 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2627 housespec->accepts_cargo[2] = cid;
2628 housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2629 break;
2632 case 0x10: // Local authority rating decrease on removal
2633 housespec->remove_rating_decrease = buf->ReadWord();
2634 break;
2636 case 0x11: // Removal cost multiplier
2637 housespec->removal_cost = buf->ReadByte();
2638 break;
2640 case 0x12: // Building name ID
2641 AddStringForMapping(buf->ReadWord(), &housespec->building_name);
2642 break;
2644 case 0x13: // Building availability mask
2645 housespec->building_availability = (HouseZones)buf->ReadWord();
2646 break;
2648 case 0x14: // House callback mask
2649 housespec->callback_mask |= buf->ReadByte();
2650 break;
2652 case 0x15: { // House override byte
2653 byte override = buf->ReadByte();
2655 /* The house being overridden must be an original house. */
2656 if (override >= NEW_HOUSE_OFFSET) {
2657 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2658 continue;
2661 _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2662 break;
2665 case 0x16: // Periodic refresh multiplier
2666 housespec->processing_time = min(buf->ReadByte(), 63);
2667 break;
2669 case 0x17: // Four random colours to use
2670 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2671 break;
2673 case 0x18: // Relative probability of appearing
2674 housespec->probability = buf->ReadByte();
2675 break;
2677 case 0x19: // Extra flags
2678 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2679 break;
2681 case 0x1A: // Animation frames
2682 housespec->animation.frames = buf->ReadByte();
2683 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2684 SB(housespec->animation.frames, 7, 1, 0);
2685 break;
2687 case 0x1B: // Animation speed
2688 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2689 break;
2691 case 0x1C: // Class of the building type
2692 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2693 break;
2695 case 0x1D: // Callback mask part 2
2696 housespec->callback_mask |= (buf->ReadByte() << 8);
2697 break;
2699 case 0x1E: { // Accepted cargo types
2700 uint32 cargotypes = buf->ReadDWord();
2702 /* Check if the cargo types should not be changed */
2703 if (cargotypes == 0xFFFFFFFF) break;
2705 for (uint j = 0; j < 3; j++) {
2706 /* Get the cargo number from the 'list' */
2707 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2708 CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2710 if (cargo == CT_INVALID) {
2711 /* Disable acceptance of invalid cargo type */
2712 housespec->cargo_acceptance[j] = 0;
2713 } else {
2714 housespec->accepts_cargo[j] = cargo;
2717 break;
2720 case 0x1F: // Minimum life span
2721 housespec->minimum_life = buf->ReadByte();
2722 break;
2724 case 0x20: { // Cargo acceptance watch list
2725 byte count = buf->ReadByte();
2726 for (byte j = 0; j < count; j++) {
2727 CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2728 if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
2730 break;
2733 case 0x21: // long introduction year
2734 housespec->min_year = buf->ReadWord();
2735 break;
2737 case 0x22: // long maximum year
2738 housespec->max_year = buf->ReadWord();
2739 break;
2741 default:
2742 ret = CIR_UNKNOWN;
2743 break;
2747 return ret;
2751 * Get the language map associated with a given NewGRF and language.
2752 * @param grfid The NewGRF to get the map for.
2753 * @param language_id The (NewGRF) language ID to get the map for.
2754 * @return The LanguageMap, or NULL if it couldn't be found.
2756 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2758 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2759 const GRFFile *grffile = GetFileByGRFID(grfid);
2760 return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
2764 * Load a cargo- or railtype-translation table.
2765 * @param gvid ID of the global variable. This is basically only checked for zerones.
2766 * @param numinfo Number of subsequent IDs to change the property for.
2767 * @param buf The property value.
2768 * @param [in,out] translation_table Storage location for the translation table.
2769 * @param name Name of the table for debug output.
2770 * @return ChangeInfoResult.
2772 template <typename T>
2773 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
2775 if (gvid != 0) {
2776 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
2777 return CIR_INVALID_ID;
2780 translation_table.Clear();
2781 for (int i = 0; i < numinfo; i++) {
2782 *translation_table.Append() = buf->ReadLabel();
2785 return CIR_SUCCESS;
2788 /** Get the currency spec for a given NewGRF currency index. */
2789 static CurrencySpec *GetNewgrfCurrencySpec (uint id)
2791 /* Mapping of NewGRF (TTDPatch) currency indices to ours. */
2792 static const byte ttdp_map[] = {
2793 CURRENCY_GBP, CURRENCY_USD, CURRENCY_FRF, CURRENCY_DEM,
2794 CURRENCY_JPY, CURRENCY_ESP, CURRENCY_HUF, CURRENCY_PLN,
2795 CURRENCY_ATS, CURRENCY_BEF, CURRENCY_DKK, CURRENCY_FIM,
2796 CURRENCY_GRD, CURRENCY_CHF, CURRENCY_NLG, CURRENCY_ITL,
2797 CURRENCY_SEK, CURRENCY_RUR, CURRENCY_EUR,
2800 assert_compile (lengthof(ttdp_map) < CURRENCY_END);
2802 if (id < lengthof(ttdp_map)) {
2803 id = ttdp_map[id];
2804 } else if (id >= CURRENCY_END) {
2805 grfmsg (1, "GlobalVarChangeInfo: Currency id %u out of range, ignoring", id);
2806 return NULL;
2809 return &_currency_specs[id];
2813 * Define properties for global variables
2814 * @param gvid ID of the global variable.
2815 * @param numinfo Number of subsequent IDs to change the property for.
2816 * @param prop The property to change.
2817 * @param buf The property value.
2818 * @return ChangeInfoResult.
2820 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2822 /* Properties which are handled as a whole */
2823 switch (prop) {
2824 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2825 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2827 case 0x10: // Snow line height table
2828 if (numinfo != 1 || IsSnowLineSet()) {
2829 grfmsg (1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2830 } else if (!buf->HasData (SNOW_LINE_MONTHS * SNOW_LINE_DAYS)) {
2831 grfmsg (1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2832 } else {
2833 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2835 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2836 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2837 table[i][j] = buf->ReadByte();
2838 if (_cur.grffile->grf_version >= 8) {
2839 if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 256;
2840 } else {
2841 if (table[i][j] >= 128) {
2842 /* no snow */
2843 table[i][j] = 0xFF;
2844 } else {
2845 table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 128;
2850 SetSnowLine (table);
2852 return CIR_SUCCESS;
2854 case 0x11: // GRF match for engine allocation
2855 /* This is loaded during the reservation stage,
2856 * so just skip it here. Each entry is 8 bytes. */
2857 buf->Skip (8 * numinfo);
2858 return CIR_SUCCESS;
2860 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2861 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2863 default:
2864 break;
2867 /* Properties which are handled per item */
2868 ChangeInfoResult ret = CIR_SUCCESS;
2869 for (; numinfo-- > 0; gvid++) {
2870 switch (prop) {
2871 case 0x08: { // Cost base factor
2872 int factor = buf->ReadByte();
2873 if (gvid < PR_END) {
2874 _cur.grffile->price_base_multipliers[gvid] = min<int> (factor - 8, MAX_PRICE_MODIFIER);
2875 } else {
2876 grfmsg (1, "GlobalVarChangeInfo: Price %d out of range, ignoring", gvid);
2878 break;
2881 case 0x0A: { // Currency display names
2882 CurrencySpec *cur = GetNewgrfCurrencySpec (gvid);
2883 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2885 if ((newone != STR_UNDEFINED) && (cur != NULL)) {
2886 cur->name = newone;
2888 break;
2891 case 0x0B: { // Currency multipliers
2892 CurrencySpec *cur = GetNewgrfCurrencySpec (gvid);
2893 uint32 rate = buf->ReadDWord();
2895 if (cur != NULL) {
2896 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2897 * which OTTD does not. For this reason, divide grf value by 1000,
2898 * to be compatible */
2899 cur->rate = rate / 1000;
2901 break;
2904 case 0x0C: { // Currency options
2905 CurrencySpec *cur = GetNewgrfCurrencySpec (gvid);
2906 uint16 options = buf->ReadWord();
2908 if (cur != NULL) {
2909 cur->separator[0] = GB(options, 0, 8);
2910 cur->separator[1] = '\0';
2911 /* By specifying only one bit, we prevent errors,
2912 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2913 cur->symbol_pos = GB(options, 8, 1);
2915 break;
2918 case 0x0D: // Currency prefix symbol
2919 case 0x0E: { // Currency suffix symbol
2920 CurrencySpec *cur = GetNewgrfCurrencySpec (gvid);
2921 uint32 tempfix = buf->ReadDWord();
2923 if (cur != NULL) {
2924 assert_compile (lengthof(cur->prefix) > 4);
2925 assert_compile (lengthof(cur->suffix) > 4);
2926 char *s = (prop == 0x0E) ? cur->suffix : cur->prefix;
2927 memcpy (s, &tempfix, 4);
2928 s[4] = 0;
2930 break;
2933 case 0x0F: { // Euro introduction dates
2934 CurrencySpec *cur = GetNewgrfCurrencySpec (gvid);
2935 Year year_euro = buf->ReadWord();
2937 if (cur != NULL) {
2938 cur->to_euro = year_euro;
2940 break;
2943 case 0x13: // Gender translation table
2944 case 0x14: // Case translation table
2945 case 0x15: { // Plural form translation
2946 const LanguageMetadata *lang = gvid < MAX_LANG ? GetLanguage(gvid) : NULL;
2947 if (lang == NULL) {
2948 grfmsg (1, "GlobalVarChangeInfo: Language %d is not known, ignoring", gvid);
2949 /* Skip over the data. */
2950 if (prop == 0x15) {
2951 buf->ReadByte();
2952 } else {
2953 while (buf->ReadByte() != 0) {
2954 buf->ReadString();
2957 break;
2960 if (_cur.grffile->language_map == NULL) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2962 if (prop == 0x15) {
2963 uint plural_form = buf->ReadByte();
2964 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2965 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2966 } else {
2967 _cur.grffile->language_map[gvid].plural_form = plural_form;
2969 break;
2972 for (;;) {
2973 byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2974 if (newgrf_id == 0) break;
2976 const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2978 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2979 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2980 * is just a subset of UTF8, or they need the bigger UTF8 characters
2981 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2982 skip_nfo_utf8_identifier (&name);
2984 LanguageMap::Mapping map;
2985 map.newgrf_id = newgrf_id;
2986 if (prop == 0x13) {
2987 map.openttd_id = lang->GetGenderIndex(name);
2988 if (map.openttd_id >= MAX_NUM_GENDERS) {
2989 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2990 } else {
2991 *_cur.grffile->language_map[gvid].gender_map.Append() = map;
2993 } else {
2994 map.openttd_id = lang->GetCaseIndex(name);
2995 if (map.openttd_id >= MAX_NUM_CASES) {
2996 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2997 } else {
2998 *_cur.grffile->language_map[gvid].case_map.Append() = map;
3002 break;
3005 default:
3006 ret = CIR_UNKNOWN;
3007 break;
3011 return ret;
3014 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
3016 /* Properties which are handled as a whole */
3017 switch (prop) {
3018 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
3019 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
3021 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
3022 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
3024 default:
3025 break;
3028 /* Properties which are handled per item */
3029 ChangeInfoResult ret = CIR_SUCCESS;
3030 for (int i = 0; i < numinfo; i++) {
3031 switch (prop) {
3032 case 0x08: // Cost base factor
3033 case 0x15: // Plural form translation
3034 buf->ReadByte();
3035 break;
3037 case 0x0A: // Currency display names
3038 case 0x0C: // Currency options
3039 case 0x0F: // Euro introduction dates
3040 buf->ReadWord();
3041 break;
3043 case 0x0B: // Currency multipliers
3044 case 0x0D: // Currency prefix symbol
3045 case 0x0E: // Currency suffix symbol
3046 buf->ReadDWord();
3047 break;
3049 case 0x10: // Snow line height table
3050 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
3051 break;
3053 case 0x11: { // GRF match for engine allocation
3054 uint32 s = buf->ReadDWord();
3055 uint32 t = buf->ReadDWord();
3056 SetNewGRFOverride(s, t);
3057 break;
3060 case 0x13: // Gender translation table
3061 case 0x14: // Case translation table
3062 while (buf->ReadByte() != 0) {
3063 buf->ReadString();
3065 break;
3067 default:
3068 ret = CIR_UNKNOWN;
3069 break;
3073 return ret;
3078 * Define properties for cargoes
3079 * @param cid Local ID of the cargo.
3080 * @param numinfo Number of subsequent IDs to change the property for.
3081 * @param prop The property to change.
3082 * @param buf The property value.
3083 * @return ChangeInfoResult.
3085 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
3087 ChangeInfoResult ret = CIR_SUCCESS;
3089 if (cid + numinfo > NUM_CARGO) {
3090 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
3091 return CIR_INVALID_ID;
3094 for (int i = 0; i < numinfo; i++) {
3095 CargoSpec *cs = CargoSpec::Get(cid + i);
3097 switch (prop) {
3098 case 0x08: // Bit number of cargo
3099 cs->bitnum = buf->ReadByte();
3100 if (cs->IsValid()) {
3101 cs->grffile = _cur.grffile;
3102 SetBit(_cargo_mask, cid + i);
3103 } else {
3104 ClrBit(_cargo_mask, cid + i);
3106 break;
3108 case 0x09: // String ID for cargo type name
3109 AddStringForMapping(buf->ReadWord(), &cs->name);
3110 break;
3112 case 0x0A: // String for 1 unit of cargo
3113 AddStringForMapping(buf->ReadWord(), &cs->name_single);
3114 break;
3116 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
3117 case 0x1B: // String for cargo units
3118 /* String for units of cargo. This is different in OpenTTD
3119 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
3120 * Property 1B is used to set OpenTTD's behaviour. */
3121 AddStringForMapping(buf->ReadWord(), &cs->units_volume);
3122 break;
3124 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
3125 case 0x1C: // String for any amount of cargo
3126 /* Strings for an amount of cargo. This is different in OpenTTD
3127 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
3128 * Property 1C is used to set OpenTTD's behaviour. */
3129 AddStringForMapping(buf->ReadWord(), &cs->quantifier);
3130 break;
3132 case 0x0D: // String for two letter cargo abbreviation
3133 AddStringForMapping(buf->ReadWord(), &cs->abbrev);
3134 break;
3136 case 0x0E: // Sprite ID for cargo icon
3137 cs->sprite = buf->ReadWord();
3138 break;
3140 case 0x0F: // Weight of one unit of cargo
3141 cs->weight = buf->ReadByte();
3142 break;
3144 case 0x10: // Used for payment calculation
3145 cs->transit_days[0] = buf->ReadByte();
3146 break;
3148 case 0x11: // Used for payment calculation
3149 cs->transit_days[1] = buf->ReadByte();
3150 break;
3152 case 0x12: // Base cargo price
3153 cs->initial_payment = buf->ReadDWord();
3154 break;
3156 case 0x13: // Colour for station rating bars
3157 cs->rating_colour = buf->ReadByte();
3158 break;
3160 case 0x14: // Colour for cargo graph
3161 cs->legend_colour = buf->ReadByte();
3162 break;
3164 case 0x15: // Freight status
3165 cs->is_freight = (buf->ReadByte() != 0);
3166 break;
3168 case 0x16: // Cargo classes
3169 cs->classes = buf->ReadWord();
3170 break;
3172 case 0x17: // Cargo label
3173 cs->label = buf->ReadLabel();
3174 break;
3176 case 0x18: { // Town growth substitute type
3177 uint8 substitute_type = buf->ReadByte();
3179 switch (substitute_type) {
3180 case 0x00: cs->town_effect = TE_PASSENGERS; break;
3181 case 0x02: cs->town_effect = TE_MAIL; break;
3182 case 0x05: cs->town_effect = TE_GOODS; break;
3183 case 0x09: cs->town_effect = TE_WATER; break;
3184 case 0x0B: cs->town_effect = TE_FOOD; break;
3185 default:
3186 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
3187 FALLTHROUGH;
3188 case 0xFF: cs->town_effect = TE_NONE; break;
3190 break;
3193 case 0x19: // Town growth coefficient
3194 cs->multipliertowngrowth = buf->ReadWord();
3195 break;
3197 case 0x1A: // Bitmask of callbacks to use
3198 cs->callback_mask = buf->ReadByte();
3199 break;
3201 case 0x1D: // Vehicle capacity muliplier
3202 cs->multiplier = max<uint16>(1u, buf->ReadWord());
3203 break;
3205 default:
3206 ret = CIR_UNKNOWN;
3207 break;
3211 return ret;
3216 * Define properties for sound effects
3217 * @param sid Local ID of the sound.
3218 * @param numinfo Number of subsequent IDs to change the property for.
3219 * @param prop The property to change.
3220 * @param buf The property value.
3221 * @return ChangeInfoResult.
3223 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
3225 ChangeInfoResult ret = CIR_SUCCESS;
3227 if (_cur.grffile->sound_offset == 0) {
3228 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3229 return CIR_INVALID_ID;
3232 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
3233 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
3234 return CIR_INVALID_ID;
3237 for (int i = 0; i < numinfo; i++) {
3238 SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
3240 switch (prop) {
3241 case 0x08: // Relative volume
3242 sound->volume = buf->ReadByte();
3243 break;
3245 case 0x09: // Priority
3246 sound->priority = buf->ReadByte();
3247 break;
3249 case 0x0A: { // Override old sound
3250 SoundID orig_sound = buf->ReadByte();
3252 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
3253 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
3254 } else {
3255 SoundEntry *old_sound = GetSound(orig_sound);
3257 /* Literally copy the data of the new sound over the original */
3258 *old_sound = *sound;
3260 break;
3263 default:
3264 ret = CIR_UNKNOWN;
3265 break;
3269 return ret;
3273 * Ignore an industry tile property
3274 * @param prop The property to ignore.
3275 * @param buf The property value.
3276 * @return ChangeInfoResult.
3278 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
3280 static const byte skip[] = {
3281 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
3282 /* 00 */ 1, 2, 2, 2, 1, 1, 2,
3283 /* 10 */ 1, 1, 1,
3286 uint k = prop - 0x09;
3287 if (k >= lengthof(skip)) return CIR_UNKNOWN;
3289 byte s = skip[k];
3290 buf->Skip (s);
3291 return CIR_SUCCESS;
3295 * Define properties for industry tiles
3296 * @param indtid Local ID of the industry tile.
3297 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3298 * @param prop The property to change.
3299 * @param buf The property value.
3300 * @return ChangeInfoResult.
3302 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
3304 ChangeInfoResult ret = CIR_SUCCESS;
3306 if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
3307 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
3308 return CIR_INVALID_ID;
3311 /* Allocate industry tile specs if they haven't been allocated already. */
3312 if (_cur.grffile->indtspec == NULL) {
3313 _cur.grffile->indtspec = xcalloct<IndustryTileSpec*>(NUM_INDUSTRYTILES_PER_GRF);
3316 for (int i = 0; i < numinfo; i++) {
3317 IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
3319 if (prop != 0x08 && tsp == NULL) {
3320 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
3321 if (cir > ret) ret = cir;
3322 continue;
3325 switch (prop) {
3326 case 0x08: { // Substitute industry tile type
3327 byte subs_id = buf->ReadByte();
3329 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
3330 /* The substitute id must be one of the original industry tile. */
3331 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3332 continue;
3335 /* Allocate space for this industry. */
3336 if (tsp == NULL) {
3337 tsp = xmemdupt (&_industry_tile_specs[subs_id]);
3338 _cur.grffile->indtspec[indtid + i] = tsp;
3340 tsp->enabled = true;
3342 /* A copied tile should not have the animation infos copied too.
3343 * The anim_state should be left untouched, though
3344 * It is up to the author to animate them himself */
3345 tsp->anim_production = INDUSTRYTILE_NOANIM;
3346 tsp->anim_next = INDUSTRYTILE_NOANIM;
3348 tsp->grf_prop.local_id = indtid + i;
3349 tsp->grf_prop.subst_id = subs_id;
3350 tsp->grf_prop.grffile = _cur.grffile;
3351 _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3353 break;
3356 case 0x09: { // Industry tile override
3357 byte ovrid = buf->ReadByte();
3359 /* The industry being overridden must be an original industry. */
3360 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
3361 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3362 continue;
3365 _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
3366 break;
3369 case 0x0A: // Tile acceptance
3370 case 0x0B:
3371 case 0x0C: {
3372 uint16 acctp = buf->ReadWord();
3373 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
3374 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
3375 break;
3378 case 0x0D: // Land shape flags
3379 tsp->slopes_refused = (Slope)buf->ReadByte();
3380 break;
3382 case 0x0E: // Callback mask
3383 tsp->callback_mask = buf->ReadByte();
3384 break;
3386 case 0x0F: // Animation information
3387 tsp->animation.frames = buf->ReadByte();
3388 tsp->animation.status = buf->ReadByte();
3389 break;
3391 case 0x10: // Animation speed
3392 tsp->animation.speed = buf->ReadByte();
3393 break;
3395 case 0x11: // Triggers for callback 25
3396 tsp->animation.triggers = buf->ReadByte();
3397 break;
3399 case 0x12: // Special flags
3400 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
3401 break;
3403 default:
3404 ret = CIR_UNKNOWN;
3405 break;
3409 return ret;
3413 * Ignore an industry property
3414 * @param prop The property to ignore.
3415 * @param buf The property value.
3416 * @return ChangeInfoResult.
3418 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
3420 if (prop == 0x0A) {
3421 for (byte j = buf->ReadByte(); j > 0; j--) {
3422 for (uint k = 0;; k++) {
3423 byte x = buf->ReadByte();
3424 if (x == 0xFE && k == 0) {
3425 buf->ReadByte();
3426 buf->ReadByte();
3427 break;
3430 byte y = buf->ReadByte();
3431 if (x == 0 && y == 0x80) break;
3433 byte gfx = buf->ReadByte();
3434 if (gfx == 0xFE) buf->ReadWord();
3437 return CIR_SUCCESS;
3440 static const byte skip[] = {
3441 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
3442 /* 00 */ 1, 0, 1, 2, 2, 2, 1,
3443 /* 10 */ 2, 4, 1, 1, 1, 0, 3, 1, 1, 1, 4, 2, 4, 4, 4, 2,
3444 /* 20 */ 4, 1, 1, 4, 2,
3447 uint k = prop - 0x09;
3448 if (k >= lengthof(skip)) return CIR_UNKNOWN;
3450 byte s = skip[k];
3451 buf->Skip (s != 0 ? s : buf->ReadByte());
3452 return CIR_SUCCESS;
3456 * Validate the industry layout; e.g. to prevent duplicate tiles.
3457 * @param layout The layout to check.
3458 * @param size The size of the layout.
3459 * @return True if the layout is deemed valid.
3461 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
3463 for (int i = 0; i < size - 1; i++) {
3464 for (int j = i + 1; j < size; j++) {
3465 if (layout[i].ti.x == layout[j].ti.x &&
3466 layout[i].ti.y == layout[j].ti.y) {
3467 return false;
3471 return true;
3474 /** Clean the tile table of the IndustrySpec if it's needed. */
3475 static void CleanIndustryTileTable(IndustrySpec *ind)
3477 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
3478 free(ind->table);
3479 ind->table = NULL;
3484 * Define properties for industries
3485 * @param indid Local ID of the industry.
3486 * @param numinfo Number of subsequent industry IDs to change the property for.
3487 * @param prop The property to change.
3488 * @param buf The property value.
3489 * @return ChangeInfoResult.
3491 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3493 ChangeInfoResult ret = CIR_SUCCESS;
3495 if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
3496 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
3497 return CIR_INVALID_ID;
3500 /* Allocate industry specs if they haven't been allocated already. */
3501 if (_cur.grffile->industryspec == NULL) {
3502 _cur.grffile->industryspec = xcalloct<IndustrySpec*>(NUM_INDUSTRYTYPES_PER_GRF);
3505 for (int i = 0; i < numinfo; i++) {
3506 IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3508 if (prop != 0x08 && indsp == NULL) {
3509 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3510 if (cir > ret) ret = cir;
3511 continue;
3514 switch (prop) {
3515 case 0x08: { // Substitute industry type
3516 byte subs_id = buf->ReadByte();
3518 if (subs_id == 0xFF) {
3519 /* Instead of defining a new industry, a substitute industry id
3520 * of 0xFF disables the old industry with the current id. */
3521 _industry_specs[indid + i].enabled = false;
3522 continue;
3523 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3524 /* The substitute id must be one of the original industry. */
3525 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3526 continue;
3529 /* Allocate space for this industry.
3530 * Only need to do it once. If ever it is called again, it should not
3531 * do anything */
3532 if (indsp == NULL) {
3533 indsp = xmemdupt (&_origin_industry_specs[subs_id]);
3534 _cur.grffile->industryspec[indid + i] = indsp;
3536 indsp->enabled = true;
3537 indsp->grf_prop.local_id = indid + i;
3538 indsp->grf_prop.subst_id = subs_id;
3539 indsp->grf_prop.grffile = _cur.grffile;
3540 /* If the grf industry needs to check its surounding upon creation, it should
3541 * rely on callbacks, not on the original placement functions */
3542 indsp->check_proc = CHECK_NOTHING;
3544 break;
3547 case 0x09: { // Industry type override
3548 byte ovrid = buf->ReadByte();
3550 /* The industry being overridden must be an original industry. */
3551 if (ovrid >= NEW_INDUSTRYOFFSET) {
3552 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3553 continue;
3555 indsp->grf_prop.override = ovrid;
3556 _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3557 break;
3560 case 0x0A: { // Set industry layout(s)
3561 struct {
3562 const byte *p;
3563 size_t size;
3564 } layouts [256];
3565 size_t total_tiles = 0;
3567 byte new_num_layouts = buf->ReadByte(); // Number of layaouts
3568 /* Discard total size in bytes. */
3569 buf->Skip (4);
3571 for (byte j = 0; j < new_num_layouts; j++) {
3572 const byte *p = buf->GetData (2);
3573 layouts[j].p = p;
3575 if (p[0] == 0xFE) {
3576 /* This means we have to borrow the layout from an old industry */
3577 buf->ReadByte();
3578 } else {
3579 /* Count the number of tiles. */
3580 size_t size = 0;
3581 for (; (p[0] != 0) || (p[1] != 0x80); size++) {
3582 byte gfx = buf->ReadByte();
3583 if (gfx == 0xFE) {
3584 buf->Skip (2);
3586 p = buf->GetData (2);
3588 layouts[j].size = size;
3589 total_tiles += size + 1;
3593 size_t table_offset = ttd_align_up<IndustryTileTable> (new_num_layouts * sizeof(IndustryTileTable*));
3594 void *alloc = malloc (table_offset + (total_tiles * sizeof(IndustryTileTable)));
3595 memset (alloc, 0, new_num_layouts * sizeof(IndustryTileTable*));
3596 const IndustryTileTable **tile_table = (const IndustryTileTable **) alloc;
3597 IndustryTileTable *itt = (IndustryTileTable*) (((char*)alloc) + table_offset);
3598 assert ((void*)itt >= (void*)(tile_table + new_num_layouts));
3600 uint n = 0; // Count number of valid layouts
3601 for (byte j = 0; j < new_num_layouts; j++) {
3602 const byte *p = layouts[j].p;
3604 if (p[0] == 0xFE) {
3605 /* This means we have to borrow the layout from an old industry */
3606 IndustryType type = p[1]; // industry holding required layout
3607 byte laynbr = p[2]; // layout number to borrow
3608 tile_table[n++] = _origin_industry_specs[type].table[laynbr];
3609 } else {
3610 tile_table[n] = itt;
3611 for (size_t k = layouts[j].size; k-- > 0; itt++) {
3612 assert (p[0] != 0 || p[1] != 0x80);
3613 itt->ti.x = *p++; // Offsets from northermost tile
3614 itt->ti.y = *p++;
3615 itt->gfx = *p++;
3617 if (itt->gfx == 0xFE) {
3618 /* Use a new tile from this GRF */
3619 int local_tile_id = ReadWord (p);
3620 p += 2;
3622 /* Read the ID from the _industile_mngr. */
3623 int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3625 if (tempid == INVALID_INDUSTRYTILE) {
3626 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3627 } else {
3628 /* Declared as been valid, can be used */
3629 itt->gfx = tempid;
3631 } else if (itt->gfx == 0xFF) {
3632 itt->ti.x = (int8)GB(itt->ti.x, 0, 8);
3633 itt->ti.y = (int8)GB(itt->ti.y, 0, 8);
3635 /* When there were only 256x256 maps, TileIndex was a uint16 and
3636 * itt->ti was just a TileIndexDiff that was added to it.
3637 * As such negative "x" values were shifted into the "y" position.
3638 * x = -1, y = 1 -> x = 255, y = 0
3639 * Since GRF version 8 the position is interpreted as pair of independent int8.
3640 * For GRF version < 8 we need to emulate the old shifting behaviour.
3642 if (_cur.grffile->grf_version < 8 && itt->ti.x < 0) itt->ti.y += 1;
3646 /* Append terminator. */
3647 assert (p[0] == 0);
3648 assert (p[1] == 0x80);
3649 itt->ti.x = -0x80;
3650 itt->ti.y = 0;
3651 itt->gfx = 0;
3652 itt++;
3654 if (!ValidateIndustryLayout (tile_table[n], layouts[j].size + 1)) {
3655 /* The industry layout was not valid, so skip this one. */
3656 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3657 } else {
3658 n++;
3663 /* Clean the tile table if it was already set by a previous prop A. */
3664 CleanIndustryTileTable(indsp);
3665 /* Install final layout construction in the industry spec */
3666 indsp->num_table = n;
3667 indsp->table = tile_table;
3668 SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
3669 break;
3672 case 0x0B: // Industry production flags
3673 indsp->life_type = (IndustryLifeType)buf->ReadByte();
3674 break;
3676 case 0x0C: // Industry closure message
3677 AddStringForMapping(buf->ReadWord(), &indsp->closure_text);
3678 break;
3680 case 0x0D: // Production increase message
3681 AddStringForMapping(buf->ReadWord(), &indsp->production_up_text);
3682 break;
3684 case 0x0E: // Production decrease message
3685 AddStringForMapping(buf->ReadWord(), &indsp->production_down_text);
3686 break;
3688 case 0x0F: // Fund cost multiplier
3689 indsp->cost_multiplier = buf->ReadByte();
3690 break;
3692 case 0x10: // Production cargo types
3693 for (byte j = 0; j < 2; j++) {
3694 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3696 break;
3698 case 0x11: // Acceptance cargo types
3699 for (byte j = 0; j < 3; j++) {
3700 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3702 buf->ReadByte(); // Unnused, eat it up
3703 break;
3705 case 0x12: // Production multipliers
3706 case 0x13:
3707 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3708 break;
3710 case 0x14: // Minimal amount of cargo distributed
3711 indsp->minimal_cargo = buf->ReadByte();
3712 break;
3714 case 0x15: { // Random sound effects
3715 indsp->number_of_sounds = buf->ReadByte();
3716 uint8 *sounds = buf->Dup (indsp->number_of_sounds);
3718 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3719 free(indsp->random_sounds);
3721 indsp->random_sounds = sounds;
3722 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
3723 break;
3726 case 0x16: // Conflicting industry types
3727 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3728 break;
3730 case 0x17: // Probability in random game
3731 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3732 break;
3734 case 0x18: // Probability during gameplay
3735 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3736 break;
3738 case 0x19: // Map colour
3739 indsp->map_colour = buf->ReadByte();
3740 break;
3742 case 0x1A: // Special industry flags to define special behavior
3743 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3744 break;
3746 case 0x1B: // New industry text ID
3747 AddStringForMapping(buf->ReadWord(), &indsp->new_industry_text);
3748 break;
3750 case 0x1C: // Input cargo multipliers for the three input cargo types
3751 case 0x1D:
3752 case 0x1E: {
3753 uint32 multiples = buf->ReadDWord();
3754 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3755 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3756 break;
3759 case 0x1F: // Industry name
3760 AddStringForMapping(buf->ReadWord(), &indsp->name);
3761 break;
3763 case 0x20: // Prospecting success chance
3764 indsp->prospecting_chance = buf->ReadDWord();
3765 break;
3767 case 0x21: // Callback mask
3768 case 0x22: { // Callback additional mask
3769 byte aflag = buf->ReadByte();
3770 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3771 break;
3774 case 0x23: // removal cost multiplier
3775 indsp->removal_cost_multiplier = buf->ReadDWord();
3776 break;
3778 case 0x24: { // name for nearby station
3779 uint16 str = buf->ReadWord();
3780 if (str == 0) {
3781 indsp->station_name = STR_NULL;
3782 } else {
3783 AddStringForMapping(str, &indsp->station_name);
3785 break;
3788 default:
3789 ret = CIR_UNKNOWN;
3790 break;
3794 return ret;
3798 * Clone an AirportSpec.
3799 * @param src The AirportSpec to clone.
3800 * @return A fresh copy of the AirportSpec
3802 static AirportSpec *CloneAirportSpec (const AirportSpec *src)
3804 AirportSpec *as = xmemdupt (src);
3806 AirportTileTable **table_list = xmalloct<AirportTileTable*> (src->num_table);
3807 for (uint i = 0; i < src->num_table; i++) {
3808 uint num_tiles = 1;
3809 const AirportTileTable *it = src->table[i];
3810 do {
3811 num_tiles++;
3812 } while ((++it)->ti.x != -0x80);
3813 table_list[i] = xmemdupt (src->table[i], num_tiles);
3815 as->table = table_list;
3817 return as;
3821 * Define properties for airports
3822 * @param airport Local ID of the airport.
3823 * @param numinfo Number of subsequent airport IDs to change the property for.
3824 * @param prop The property to change.
3825 * @param buf The property value.
3826 * @return ChangeInfoResult.
3828 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3830 ChangeInfoResult ret = CIR_SUCCESS;
3832 if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
3833 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
3834 return CIR_INVALID_ID;
3837 /* Allocate industry specs if they haven't been allocated already. */
3838 if (_cur.grffile->airportspec == NULL) {
3839 _cur.grffile->airportspec = xcalloct<AirportSpec*>(NUM_AIRPORTS_PER_GRF);
3842 for (int i = 0; i < numinfo; i++) {
3843 AirportSpec *as = _cur.grffile->airportspec[airport + i];
3845 if (as == NULL && prop != 0x08 && prop != 0x09) {
3846 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3847 return CIR_INVALID_ID;
3850 switch (prop) {
3851 case 0x08: { // Modify original airport
3852 byte subs_id = buf->ReadByte();
3854 if (subs_id == 0xFF) {
3855 /* Instead of defining a new airport, an airport id
3856 * of 0xFF disables the old airport with the current id. */
3857 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3858 continue;
3859 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3860 /* The substitute id must be one of the original airports. */
3861 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3862 continue;
3865 /* Allocate space for this airport.
3866 * Only need to do it once. If ever it is called again, it should not
3867 * do anything */
3868 if (as == NULL) {
3869 as = CloneAirportSpec (AirportSpec::GetWithoutOverride(subs_id));
3870 _cur.grffile->airportspec[airport + i] = as;
3872 as->enabled = true;
3873 as->grf_prop.local_id = airport + i;
3874 as->grf_prop.subst_id = subs_id;
3875 as->grf_prop.grffile = _cur.grffile;
3876 /* override the default airport */
3877 _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3879 break;
3882 case 0x0A: { // Set airport layout
3883 struct {
3884 const byte *p;
3885 size_t size;
3886 } layouts [256];
3888 uint new_num_layouts = buf->ReadByte(); // Number of layouts
3889 buf->Skip (4); // Total size of the definition
3891 for (uint j = 0; j < new_num_layouts; j++) {
3892 /* First byte is rotation. */
3893 const byte *p = buf->GetData (3);
3894 layouts[j].p = p++;
3896 /* Count the number of tiles. */
3897 size_t size = 0;
3898 for (; (p[0] != 0) || (p[1] != 0x80); size++) {
3899 byte gfx = buf->ReadByte();
3900 if (gfx == 0xFE) {
3901 buf->Skip (2);
3903 p = buf->GetData (2);
3905 layouts[j].size = size;
3908 as->num_table = new_num_layouts; // Number of layouts
3909 AirportTileTable **tile_table = xcalloct<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3911 for (uint j = 0; j < as->num_table; j++) {
3912 const byte *p = layouts[j].p;
3913 size_t size = layouts[j].size;
3914 AirportTileTable *att = xmalloct <AirportTileTable> (size + 1);
3915 att->rotation = *p++;
3917 for (size_t k = 0; k < size; k++) {
3918 assert (p[0] != 0 || p[1] != 0x80);
3919 att[k].ti.x = *p++; // Offsets from northermost tile
3920 att[k].ti.y = *p++;
3921 att[k].gfx = *p++;
3923 if (att[k].gfx == 0xFE) {
3924 /* Use a new tile from this GRF */
3925 int local_tile_id = ReadWord (p);
3926 p += 2;
3928 /* Read the ID from the _airporttile_mngr. */
3929 uint16 tempid = _airporttile_mngr.GetID (local_tile_id, _cur.grffile->grfid);
3931 if (tempid == INVALID_AIRPORTTILE) {
3932 grfmsg (2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3933 } else {
3934 /* Declared as been valid, can be used */
3935 att[k].gfx = tempid;
3937 } else if (att[k].gfx == 0xFF) {
3938 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3939 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3942 if (att->rotation == DIR_E || att->rotation == DIR_W) {
3943 as->size_x = max<byte> (as->size_x, att[k].ti.y + 1);
3944 as->size_y = max<byte> (as->size_y, att[k].ti.x + 1);
3945 } else {
3946 as->size_x = max<byte> (as->size_x, att[k].ti.x + 1);
3947 as->size_y = max<byte> (as->size_y, att[k].ti.y + 1);
3951 /* Append terminator. */
3952 assert (p[0] == 0);
3953 assert (p[1] == 0x80);
3954 att[size].ti.x = -0x80;
3955 att[size].ti.y = 0;
3956 att[size].gfx = 0;
3958 tile_table[j] = att;
3961 /* Install final layout construction in the airport spec */
3962 as->table = tile_table;
3963 break;
3966 case 0x0C:
3967 as->min_year = buf->ReadWord();
3968 as->max_year = buf->ReadWord();
3969 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3970 break;
3972 case 0x0D:
3973 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3974 break;
3976 case 0x0E:
3977 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3978 break;
3980 case 0x0F:
3981 as->noise_level = buf->ReadByte();
3982 break;
3984 case 0x10:
3985 AddStringForMapping(buf->ReadWord(), &as->name);
3986 break;
3988 case 0x11: // Maintenance cost factor
3989 as->maintenance_cost = buf->ReadWord();
3990 break;
3992 default:
3993 ret = CIR_UNKNOWN;
3994 break;
3998 return ret;
4002 * Ignore properties for objects
4003 * @param prop The property to ignore.
4004 * @param buf The property value.
4005 * @return ChangeInfoResult.
4007 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
4009 static const byte skip[] = {
4010 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
4011 /* 00 */ 4, 2, 2, 1, 1, 1, 4, 4,
4012 /* 10 */ 2, 2, 1, 2, 1, 2, 1, 1,
4015 uint k = prop - 0x08;
4016 if (k >= lengthof(skip)) return CIR_UNKNOWN;
4018 byte s = skip[k];
4019 buf->Skip (s);
4020 return CIR_SUCCESS;
4024 * Define properties for objects
4025 * @param id Local ID of the object.
4026 * @param numinfo Number of subsequent objectIDs to change the property for.
4027 * @param prop The property to change.
4028 * @param buf The property value.
4029 * @return ChangeInfoResult.
4031 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4033 ChangeInfoResult ret = CIR_SUCCESS;
4035 if (id + numinfo > NUM_OBJECTS_PER_GRF) {
4036 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
4037 return CIR_INVALID_ID;
4040 /* Allocate object specs if they haven't been allocated already. */
4041 if (_cur.grffile->objectspec == NULL) {
4042 _cur.grffile->objectspec = xcalloct<ObjectSpec*>(NUM_OBJECTS_PER_GRF);
4045 for (int i = 0; i < numinfo; i++) {
4046 ObjectSpec *spec = _cur.grffile->objectspec[id + i];
4048 if (prop != 0x08 && spec == NULL) {
4049 /* If the object property 08 is not yet set, ignore this property */
4050 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
4051 if (cir > ret) ret = cir;
4052 continue;
4055 switch (prop) {
4056 case 0x08: { // Class ID
4057 ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
4059 /* Allocate space for this object. */
4060 if (*ospec == NULL) {
4061 *ospec = xcalloct<ObjectSpec>();
4062 (*ospec)->views = 1; // Default for NewGRFs that don't set it.
4065 /* Swap classid because we read it in BE. */
4066 uint32 classid = buf->ReadLabel();
4067 (*ospec)->cls_id = ObjectClass::Allocate (classid);
4068 (*ospec)->enabled = true;
4069 break;
4072 case 0x09: { // Class name
4073 ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
4074 AddStringForMapping(buf->ReadWord(), &objclass->name);
4075 break;
4078 case 0x0A: // Object name
4079 AddStringForMapping(buf->ReadWord(), &spec->name);
4080 break;
4082 case 0x0B: // Climate mask
4083 spec->climate = buf->ReadByte();
4084 break;
4086 case 0x0C: // Size
4087 spec->size = buf->ReadByte();
4088 break;
4090 case 0x0D: // Build cost multipler
4091 spec->build_cost_multiplier = buf->ReadByte();
4092 spec->clear_cost_multiplier = spec->build_cost_multiplier;
4093 break;
4095 case 0x0E: // Introduction date
4096 spec->introduction_date = buf->ReadDWord();
4097 break;
4099 case 0x0F: // End of life
4100 spec->end_of_life_date = buf->ReadDWord();
4101 break;
4103 case 0x10: // Flags
4104 spec->flags = (ObjectFlags)buf->ReadWord();
4105 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
4106 break;
4108 case 0x11: // Animation info
4109 spec->animation.frames = buf->ReadByte();
4110 spec->animation.status = buf->ReadByte();
4111 break;
4113 case 0x12: // Animation speed
4114 spec->animation.speed = buf->ReadByte();
4115 break;
4117 case 0x13: // Animation triggers
4118 spec->animation.triggers = buf->ReadWord();
4119 break;
4121 case 0x14: // Removal cost multiplier
4122 spec->clear_cost_multiplier = buf->ReadByte();
4123 break;
4125 case 0x15: // Callback mask
4126 spec->callback_mask = buf->ReadWord();
4127 break;
4129 case 0x16: // Building height
4130 spec->height = buf->ReadByte();
4131 break;
4133 case 0x17: // Views
4134 spec->views = buf->ReadByte();
4135 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
4136 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
4137 spec->views = 1;
4139 break;
4141 case 0x18: // Amount placed on 256^2 map on map creation
4142 spec->generate_amount = buf->ReadByte();
4143 break;
4145 default:
4146 ret = CIR_UNKNOWN;
4147 break;
4151 return ret;
4155 * Define properties for railtypes
4156 * @param id ID of the railtype.
4157 * @param numinfo Number of subsequent IDs to change the property for.
4158 * @param prop The property to change.
4159 * @param buf The property value.
4160 * @return ChangeInfoResult.
4162 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4164 ChangeInfoResult ret = CIR_SUCCESS;
4166 extern RailtypeInfo _railtypes[RAILTYPE_END];
4168 if (id + numinfo > RAILTYPE_END) {
4169 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4170 return CIR_INVALID_ID;
4173 for (int i = 0; i < numinfo; i++) {
4174 RailType rt = _cur.grffile->railtype_map[id + i];
4175 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
4177 RailtypeInfo *rti = &_railtypes[rt];
4179 switch (prop) {
4180 case 0x08: // Label of rail type
4181 /* Skipped here as this is loaded during reservation stage. */
4182 buf->ReadDWord();
4183 break;
4185 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4186 uint16 str = buf->ReadWord();
4187 AddStringForMapping(str, &rti->strings.toolbar_caption);
4188 if (_cur.grffile->grf_version < 8) {
4189 AddStringForMapping(str, &rti->strings.name);
4191 break;
4194 case 0x0A: // Menu text of railtype
4195 AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4196 break;
4198 case 0x0B: // Build window caption
4199 AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4200 break;
4202 case 0x0C: // Autoreplace text
4203 AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4204 break;
4206 case 0x0D: // New locomotive text
4207 AddStringForMapping(buf->ReadWord(), &rti->strings.new_loco);
4208 break;
4210 case 0x0E: // Compatible railtype list
4211 case 0x0F: // Powered railtype list
4212 case 0x18: // Railtype list required for date introduction
4213 case 0x19: // Introduced railtype list
4215 /* Rail type compatibility bits are added to the existing bits
4216 * to allow multiple GRFs to modify compatibility with the
4217 * default rail types. */
4218 int n = buf->ReadByte();
4219 for (int j = 0; j != n; j++) {
4220 RailTypeLabel label = buf->ReadLabel();
4221 RailType rt = GetRailTypeByLabel (label, false);
4222 if (rt != INVALID_RAILTYPE) {
4223 switch (prop) {
4224 case 0x0F: SetBit(rti->powered_railtypes, rt); FALLTHROUGH; // Powered implies compatible.
4225 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
4226 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
4227 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
4231 break;
4234 case 0x10: // Rail Type flags
4235 rti->flags = (RailTypeFlags)buf->ReadByte();
4236 break;
4238 case 0x11: // Curve speed advantage
4239 rti->curve_speed = buf->ReadByte();
4240 break;
4242 case 0x12: // Station graphic
4243 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
4244 break;
4246 case 0x13: // Construction cost factor
4247 rti->cost_multiplier = buf->ReadWord();
4248 break;
4250 case 0x14: // Speed limit
4251 rti->max_speed = buf->ReadWord();
4252 break;
4254 case 0x15: // Acceleration model
4255 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
4256 break;
4258 case 0x16: // Map colour
4259 rti->map_colour = buf->ReadByte();
4260 break;
4262 case 0x17: // Introduction date
4263 rti->introduction_date = buf->ReadDWord();
4264 break;
4266 case 0x1A: // Sort order
4267 rti->sorting_order = buf->ReadByte();
4268 break;
4270 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4271 AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4272 break;
4274 case 0x1C: // Maintenance cost factor
4275 rti->maintenance_multiplier = buf->ReadWord();
4276 break;
4278 case 0x1D: // Alternate rail type label list
4279 /* Skipped here as this is loaded during reservation stage. */
4280 buf->Skip (4 * buf->ReadByte());
4281 break;
4283 default:
4284 ret = CIR_UNKNOWN;
4285 break;
4289 return ret;
4292 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4294 ChangeInfoResult ret = CIR_SUCCESS;
4296 extern RailtypeInfo _railtypes[RAILTYPE_END];
4298 if (id + numinfo > RAILTYPE_END) {
4299 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4300 return CIR_INVALID_ID;
4303 for (int i = 0; i < numinfo; i++) {
4304 switch (prop) {
4305 case 0x08: // Label of rail type
4307 RailTypeLabel rtl = buf->ReadLabel();
4309 RailType rt = GetRailTypeByLabel(rtl, false);
4310 if (rt == INVALID_RAILTYPE) {
4311 /* Set up new rail type */
4312 rt = AllocateRailType(rtl);
4315 _cur.grffile->railtype_map[id + i] = rt;
4316 break;
4319 case 0x09: // Toolbar caption of railtype
4320 case 0x0A: // Menu text
4321 case 0x0B: // Build window caption
4322 case 0x0C: // Autoreplace text
4323 case 0x0D: // New loco
4324 case 0x13: // Construction cost
4325 case 0x14: // Speed limit
4326 case 0x1B: // Name of railtype
4327 case 0x1C: // Maintenance cost factor
4328 buf->ReadWord();
4329 break;
4331 case 0x1D: // Alternate rail type label list
4332 if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
4333 int n = buf->ReadByte();
4334 for (int j = 0; j != n; j++) {
4335 *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = buf->ReadLabel();
4337 break;
4339 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
4340 FALLTHROUGH;
4342 case 0x0E: // Compatible railtype list
4343 case 0x0F: // Powered railtype list
4344 case 0x18: // Railtype list required for date introduction
4345 case 0x19: // Introduced railtype list
4346 buf->Skip (4 * buf->ReadByte());
4347 break;
4349 case 0x10: // Rail Type flags
4350 case 0x11: // Curve speed advantage
4351 case 0x12: // Station graphic
4352 case 0x15: // Acceleration model
4353 case 0x16: // Map colour
4354 case 0x1A: // Sort order
4355 buf->ReadByte();
4356 break;
4358 case 0x17: // Introduction date
4359 buf->ReadDWord();
4360 break;
4362 default:
4363 ret = CIR_UNKNOWN;
4364 break;
4368 return ret;
4371 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
4373 ChangeInfoResult ret = CIR_SUCCESS;
4375 if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
4376 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
4377 return CIR_INVALID_ID;
4380 /* Allocate airport tile specs if they haven't been allocated already. */
4381 if (_cur.grffile->airtspec == NULL) {
4382 _cur.grffile->airtspec = xcalloct<AirportTileSpec*>(NUM_AIRPORTTILES_PER_GRF);
4385 for (int i = 0; i < numinfo; i++) {
4386 AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
4388 if (prop != 0x08 && tsp == NULL) {
4389 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4390 return CIR_INVALID_ID;
4393 switch (prop) {
4394 case 0x08: { // Substitute airport tile type
4395 byte subs_id = buf->ReadByte();
4397 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
4398 /* The substitute id must be one of the original airport tiles. */
4399 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4400 continue;
4403 /* Allocate space for this airport tile. */
4404 if (tsp == NULL) {
4405 tsp = xmemdupt (AirportTileSpec::Get(subs_id));
4406 _cur.grffile->airtspec[airtid + i] = tsp;
4408 tsp->enabled = true;
4410 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
4412 tsp->grf_prop.local_id = airtid + i;
4413 tsp->grf_prop.subst_id = subs_id;
4414 tsp->grf_prop.grffile = _cur.grffile;
4415 _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
4417 break;
4420 case 0x09: { // Airport tile override
4421 byte override = buf->ReadByte();
4423 /* The airport tile being overridden must be an original airport tile. */
4424 if (override >= NEW_AIRPORTTILE_OFFSET) {
4425 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
4426 continue;
4429 _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
4430 break;
4433 case 0x0E: // Callback mask
4434 tsp->callback_mask = buf->ReadByte();
4435 break;
4437 case 0x0F: // Animation information
4438 tsp->animation.frames = buf->ReadByte();
4439 tsp->animation.status = buf->ReadByte();
4440 break;
4442 case 0x10: // Animation speed
4443 tsp->animation.speed = buf->ReadByte();
4444 break;
4446 case 0x11: // Animation triggers
4447 tsp->animation.triggers = buf->ReadByte();
4448 break;
4450 default:
4451 ret = CIR_UNKNOWN;
4452 break;
4456 return ret;
4459 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4461 switch (cir) {
4462 default: NOT_REACHED();
4464 case CIR_DISABLED:
4465 /* Error has already been printed; just stop parsing */
4466 return true;
4468 case CIR_SUCCESS:
4469 return false;
4471 case CIR_UNHANDLED:
4472 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4473 return false;
4475 case CIR_UNKNOWN:
4476 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4477 FALLTHROUGH;
4479 case CIR_INVALID_ID: {
4480 /* No debug message for an invalid ID, as it has already been output */
4481 GRFError *error = DisableCur (cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4482 if (cir != CIR_INVALID_ID) error->param_value[1] = property;
4483 return true;
4488 /* Action 0x00 */
4489 static int FeatureChangeInfo (ByteReader *buf)
4491 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4493 * B feature
4494 * B num-props how many properties to change per vehicle/station
4495 * B num-info how many vehicles/stations to change
4496 * E id ID of first vehicle/station to change, if num-info is
4497 * greater than one, this one and the following
4498 * vehicles/stations will be changed
4499 * B property what property to change, depends on the feature
4500 * V new-info new bytes of info (variable size; depends on properties) */
4502 static const VCI_Handler handler[] = {
4503 /* GSF_TRAINS */ RailVehicleChangeInfo,
4504 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4505 /* GSF_SHIPS */ ShipVehicleChangeInfo,
4506 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4507 /* GSF_STATIONS */ StationChangeInfo,
4508 /* GSF_CANALS */ CanalChangeInfo,
4509 /* GSF_BRIDGES */ BridgeChangeInfo,
4510 /* GSF_HOUSES */ TownHouseChangeInfo,
4511 /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4512 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4513 /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4514 /* GSF_CARGOES */ NULL, // Cargo is handled during reservation
4515 /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4516 /* GSF_AIRPORTS */ AirportChangeInfo,
4517 /* GSF_SIGNALS */ NULL,
4518 /* GSF_OBJECTS */ ObjectChangeInfo,
4519 /* GSF_RAILTYPES */ RailTypeChangeInfo,
4520 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4523 uint8 feature = buf->ReadByte();
4524 uint8 numprops = buf->ReadByte();
4525 uint numinfo = buf->ReadByte();
4526 uint engine = buf->ReadExtendedByte();
4528 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4529 feature, numprops, engine, numinfo);
4531 if (feature >= lengthof(handler) || handler[feature] == NULL) {
4532 if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
4533 return 0;
4536 /* Mark the feature as used by the grf */
4537 SetBit(_cur.grffile->grf_features, feature);
4539 while (numprops-- && buf->HasData()) {
4540 uint8 prop = buf->ReadByte();
4542 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4543 if (HandleChangeInfoResult ("FeatureChangeInfo", cir, feature, prop)) {
4544 return -1;
4548 return 0;
4551 /* Action 0x00 (GLS_SAFETYSCAN) */
4552 static int SafeChangeInfo (ByteReader *buf)
4554 uint8 feature = buf->ReadByte();
4555 uint8 numprops = buf->ReadByte();
4556 uint numinfo = buf->ReadByte();
4557 buf->ReadExtendedByte(); // id
4559 if (feature == GSF_BRIDGES && numprops == 1) {
4560 uint8 prop = buf->ReadByte();
4561 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4562 * is considered safe. */
4563 if (prop == 0x0D) return 0;
4564 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4565 uint8 prop = buf->ReadByte();
4566 /* Engine ID Mappings are safe, if the source is static */
4567 if (prop == 0x11) {
4568 bool is_safe = true;
4569 for (uint i = 0; i < numinfo; i++) {
4570 uint32 s = buf->ReadDWord();
4571 buf->ReadDWord(); // dest
4572 const GRFConfig *grfconfig = GetGRFConfig(s);
4573 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
4574 is_safe = false;
4575 break;
4578 if (is_safe) return 0;
4582 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4584 /* Skip remainder of GRF */
4585 return -1;
4588 /* Action 0x00 (GLS_RESERVE) */
4589 static int ReserveChangeInfo (ByteReader *buf)
4591 uint8 feature = buf->ReadByte();
4593 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return 0;
4595 uint8 numprops = buf->ReadByte();
4596 uint8 numinfo = buf->ReadByte();
4597 uint8 index = buf->ReadExtendedByte();
4599 while (numprops-- && buf->HasData()) {
4600 uint8 prop = buf->ReadByte();
4601 ChangeInfoResult cir = CIR_SUCCESS;
4603 switch (feature) {
4604 default: NOT_REACHED();
4605 case GSF_CARGOES:
4606 cir = CargoChangeInfo(index, numinfo, prop, buf);
4607 break;
4609 case GSF_GLOBALVAR:
4610 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4611 break;
4613 case GSF_RAILTYPES:
4614 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4615 break;
4618 if (HandleChangeInfoResult ("ReserveChangeInfo", cir, feature, prop)) {
4619 return -1;
4623 return 0;
4626 /* Action 0x01 */
4627 static int NewSpriteSet (ByteReader *buf)
4629 /* Basic format: <01> <feature> <num-sets> <num-ent>
4630 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4632 * B feature feature to define sprites for
4633 * 0, 1, 2, 3: veh-type, 4: train stations
4634 * E first-set first sprite set to define
4635 * B num-sets number of sprite sets (extended byte in extended format)
4636 * E num-ent how many entries per sprite set
4637 * For vehicles, this is the number of different
4638 * vehicle directions in each sprite set
4639 * Set num-dirs=8, unless your sprites are symmetric.
4640 * In that case, use num-dirs=4.
4643 uint8 feature = buf->ReadByte();
4644 uint16 num_sets = buf->ReadByte();
4645 uint16 first_set = 0;
4647 if (num_sets == 0 && buf->HasData(3)) {
4648 /* Extended Action1 format.
4649 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4650 first_set = buf->ReadExtendedByte();
4651 num_sets = buf->ReadExtendedByte();
4653 uint16 num_ents = buf->ReadExtendedByte();
4655 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4657 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4658 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4661 for (int i = 0; i < num_sets * num_ents; i++) {
4662 _cur.nfo_line++;
4663 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
4666 return 0;
4669 /* Action 0x01 (SKIP) */
4670 static int SkipAct1 (ByteReader *buf)
4672 buf->ReadByte();
4673 uint16 num_sets = buf->ReadByte();
4675 if (num_sets == 0 && buf->HasData(3)) {
4676 /* Extended Action1 format.
4677 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4678 buf->ReadExtendedByte(); // first_set
4679 num_sets = buf->ReadExtendedByte();
4681 uint16 num_ents = buf->ReadExtendedByte();
4683 int skip = num_sets * num_ents;
4684 grfmsg (3, "SkipAct1: Skipping %d sprites", skip);
4685 return skip;
4688 /* Helper function to either create a callback or link to a previously
4689 * defined spritegroup. */
4690 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4692 if (HasBit(groupid, 15)) {
4693 return CallbackResultSpriteGroup::create (groupid, _cur.grffile->grf_version >= 8);
4696 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4697 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4698 return NULL;
4701 return _cur.spritegroups[groupid];
4705 * Helper function to either create a callback or a result sprite group.
4706 * @param feature GrfSpecFeature to define spritegroup for.
4707 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4708 * @param type Type of the currently being parsed Action2. (only for debug output)
4709 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4710 * @return Created spritegroup.
4712 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4714 if (HasBit(spriteid, 15)) {
4715 return CallbackResultSpriteGroup::create (spriteid, _cur.grffile->grf_version >= 8);
4718 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4719 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4720 return NULL;
4723 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4724 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4726 /* Ensure that the sprites are loeded */
4727 assert(spriteset_start + num_sprites <= _cur.spriteid);
4729 return ResultSpriteGroup::create (spriteset_start, num_sprites);
4732 /* Action 0x02 */
4733 static int NewSpriteGroup (ByteReader *buf)
4735 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4737 * B feature see action 1
4738 * B set-id ID of this particular definition
4739 * B type/num-entries
4740 * if 80 or greater, this is a randomized or variational
4741 * list definition, see below
4742 * otherwise it specifies a number of entries, the exact
4743 * meaning depends on the feature
4744 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4745 SpriteGroup *act_group = NULL;
4747 uint8 feature = buf->ReadByte();
4748 uint8 setid = buf->ReadByte();
4749 uint8 type = buf->ReadByte();
4751 /* Sprite Groups are created here but they are allocated from a pool, so
4752 * we do not need to delete anything if there is an exception from the
4753 * ByteReader. */
4755 switch (type) {
4756 /* Deterministic Sprite Group */
4757 case 0x81: // Self scope, byte
4758 case 0x82: // Parent scope, byte
4759 case 0x85: // Self scope, word
4760 case 0x86: // Parent scope, word
4761 case 0x89: // Self scope, dword
4762 case 0x8A: // Parent scope, dword
4764 byte varsize = (1 << GB(type, 2, 2));
4766 /* Count the number of adjusts. */
4767 const byte *data = buf->GetData();
4768 uint num_adjusts = 1;
4769 for (;;) {
4770 byte variable = buf->ReadByte();
4771 if (IsInsideMM(variable, 0x60, 0x80)) buf->ReadByte();
4773 byte varadjust = buf->ReadByte();
4774 buf->Skip (GB(varadjust, 6, 2) != 0 ? 3 * varsize : varsize);
4776 /* Continue reading var adjusts while bit 5 is set. */
4777 if (!HasBit(varadjust, 5)) break;
4778 num_adjusts++;
4779 buf->ReadByte();
4782 byte num_ranges = buf->ReadByte();
4784 DeterministicSpriteGroup *group = DeterministicSpriteGroup::create (HasBit(type, 1),
4785 GB(type, 2, 2), num_adjusts, num_ranges);
4786 act_group = group;
4788 for (uint i = 0; i < num_adjusts; i++) {
4789 DeterministicSpriteGroup::Adjust *adjust = group->get_adjust (i);
4791 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4792 adjust->operation = (i == 0) ? 0 : *data++;
4793 adjust->variable = *data++;
4794 if (adjust->variable == 0x7E) {
4795 /* Link subroutine group */
4796 adjust->subroutine = GetGroupFromGroupID (setid, type, *data++);
4797 } else {
4798 adjust->parameter = IsInsideMM (adjust->variable, 0x60, 0x80) ? *data++ : 0;
4801 byte varadjust = *data++;
4802 adjust->shift_num = GB(varadjust, 0, 5);
4803 adjust->type = GB(varadjust, 6, 2);
4804 adjust->and_mask = ReadVarSize (data, varsize);
4805 data += varsize;
4807 if (adjust->type != 0) {
4808 adjust->add_val = ReadVarSize (data, varsize);
4809 data += varsize;
4810 adjust->divmod_val = ReadVarSize (data, varsize);
4811 data += varsize;
4812 } else {
4813 adjust->add_val = 0;
4814 adjust->divmod_val = 0;
4817 /* Continue reading var adjusts while bit 5 is set. */
4818 assert (HasBit(varadjust, 5) == (i + 1 != num_adjusts));
4821 data = buf->GetData (num_ranges * (2 * varsize + 2) + 2);
4823 const SpriteGroup *g;
4824 for (uint i = 0; ; i++) {
4825 g = GetGroupFromGroupID (setid, type, ReadWord (data));
4826 if (i == num_ranges) break;
4827 data += 2;
4828 uint32 low = ReadVarSize (data, varsize);
4829 data += varsize;
4830 uint32 high = ReadVarSize (data, varsize);
4831 data += varsize;
4832 group->set_range (i, g, low, high);
4835 group->set_default (g);
4836 break;
4839 /* Randomized Sprite Group */
4840 case 0x80: // Self scope
4841 case 0x83: // Parent scope
4842 case 0x84: // Relative scope
4844 VarSpriteGroupScope scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4845 byte count;
4846 if (HasBit(type, 2)) {
4847 if (feature <= GSF_AIRCRAFT) scope = VSG_SCOPE_RELATIVE;
4848 count = buf->ReadByte();
4849 } else {
4850 count = 0;
4853 uint8 triggers = buf->ReadByte();
4854 uint8 bit = buf->ReadByte();
4855 uint8 num = buf->ReadByte();
4857 RandomizedSpriteGroup *group = RandomizedSpriteGroup::create (scope,
4858 HasBit(triggers, 7), GB(triggers, 0, 7),
4859 count, bit, num);
4860 act_group = group;
4862 for (uint i = 0; i < num; i++) {
4863 group->set_group (i, GetGroupFromGroupID (setid, type, buf->ReadWord()));
4866 break;
4869 /* Neither a variable or randomized sprite group... must be a real group */
4870 default:
4872 switch (feature) {
4873 case GSF_TRAINS:
4874 case GSF_ROADVEHICLES:
4875 case GSF_SHIPS:
4876 case GSF_AIRCRAFT:
4877 case GSF_STATIONS:
4878 case GSF_CANALS:
4879 case GSF_CARGOES:
4880 case GSF_AIRPORTS:
4881 case GSF_RAILTYPES:
4883 byte num_loaded = type;
4884 byte num_loading = buf->ReadByte();
4886 if (!_cur.HasValidSpriteSets(feature)) {
4887 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4888 return 0;
4891 RealSpriteGroup *group = RealSpriteGroup::create (num_loaded, num_loading);
4892 act_group = group;
4894 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4895 setid, num_loaded, num_loading);
4897 uint total = (uint)num_loaded + (uint)num_loading;
4898 for (uint i = 0; i < total; i++) {
4899 uint16 spriteid = buf->ReadWord();
4900 group->set (i, CreateGroupFromGroupID (feature, setid, type, spriteid));
4901 grfmsg(8, "NewSpriteGroup: + rg->groups[%i] = subset %u", i, spriteid);
4904 break;
4907 case GSF_HOUSES:
4908 case GSF_AIRPORTTILES:
4909 case GSF_OBJECTS:
4910 case GSF_INDUSTRYTILES: {
4911 byte num_building_sprites = max((uint8)1, type);
4913 /* On error, bail out immediately. Temporary GRF data was already freed */
4914 SpriteLayoutReader reader;
4915 if (ReadSpriteLayout (&reader, buf, num_building_sprites, true, feature, false, type == 0)) {
4916 return -1;
4919 act_group = TileLayoutSpriteGroup::create (reader.ground,
4920 reader.num_building_sprites, reader.seq,
4921 reader.has_registers ? reader.regs : NULL,
4922 reader.consistent_max_offset);
4923 break;
4926 case GSF_INDUSTRIES: {
4927 if (type > 1) {
4928 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
4929 break;
4932 IndustryProductionSpriteGroup *group = IndustryProductionSpriteGroup::create (type);
4933 act_group = group;
4934 if (type == 0) {
4935 for (uint i = 0; i < 3; i++) {
4936 group->subtract_input[i] = (int16)buf->ReadWord(); // signed
4938 for (uint i = 0; i < 2; i++) {
4939 group->add_output[i] = buf->ReadWord(); // unsigned
4941 } else {
4942 for (uint i = 0; i < 3; i++) {
4943 group->subtract_input[i] = buf->ReadByte();
4945 for (uint i = 0; i < 2; i++) {
4946 group->add_output[i] = buf->ReadByte();
4949 group->again = buf->ReadByte();
4950 break;
4953 /* Loading of Tile Layout and Production Callback groups would happen here */
4954 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
4959 _cur.spritegroups[setid] = act_group;
4961 return 0;
4964 static CargoID TranslateCargo (uint8 ctype)
4966 /* Special cargo type for purchase list */
4967 if (ctype == 0xFF) return CT_PURCHASE;
4969 if (_cur.grffile->cargo_list.Length() == 0) {
4970 /* No cargo table, so use bitnum values */
4971 if (ctype >= 32) {
4972 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
4973 return CT_INVALID;
4976 const CargoSpec *cs;
4977 FOR_ALL_CARGOSPECS(cs) {
4978 if (cs->bitnum == ctype) {
4979 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
4980 return cs->Index();
4984 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
4985 return CT_INVALID;
4988 /* Check if the cargo type is out of bounds of the cargo translation table */
4989 if (ctype >= _cur.grffile->cargo_list.Length()) {
4990 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1);
4991 return CT_INVALID;
4994 /* Look up the cargo label from the translation table */
4995 CargoLabel cl = _cur.grffile->cargo_list[ctype];
4996 if (cl == 0) {
4997 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
4998 return CT_INVALID;
5001 ctype = GetCargoIDByLabel(cl);
5002 if (ctype == CT_INVALID) {
5003 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));
5004 return CT_INVALID;
5007 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);
5008 return ctype;
5012 static bool IsValidGroupID(uint16 groupid, const char *function)
5014 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
5015 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
5016 return false;
5019 return true;
5022 static bool VehicleMapSpriteGroup (ByteReader *buf, byte feature, uint8 idcount)
5024 static EngineID *last_engines;
5025 static uint last_engines_count;
5026 bool wagover = false;
5028 /* Test for 'wagon override' flag */
5029 if (HasBit(idcount, 7)) {
5030 wagover = true;
5031 /* Strip off the flag */
5032 idcount = GB(idcount, 0, 7);
5034 if (last_engines_count == 0) {
5035 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5036 return true;
5039 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5040 last_engines_count, idcount);
5041 } else {
5042 if (last_engines_count != idcount) {
5043 last_engines = xrealloct (last_engines, idcount);
5044 last_engines_count = idcount;
5048 EngineID engines[128];
5049 assert (idcount < lengthof(engines));
5051 for (uint i = 0; i < idcount; i++) {
5052 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
5053 if (e == NULL) {
5054 /* No engine could be allocated?!? Deal with it. Okay,
5055 * this might look bad. Also make sure this NewGRF
5056 * gets disabled, as a half loaded one is bad. */
5057 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
5058 return false;
5061 engines[i] = e->index;
5062 if (!wagover) last_engines[i] = engines[i];
5065 uint8 cidcount = buf->ReadByte();
5066 for (uint c = 0; c < cidcount; c++) {
5067 uint8 ctype = buf->ReadByte();
5068 uint16 groupid = buf->ReadWord();
5069 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
5071 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5073 ctype = TranslateCargo (ctype);
5074 if (ctype == CT_INVALID) continue;
5076 for (uint i = 0; i < idcount; i++) {
5077 EngineID engine = engines[i];
5079 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5081 if (wagover) {
5082 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5083 } else {
5084 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5089 uint16 groupid = buf->ReadWord();
5090 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return true;
5092 grfmsg(8, "-- Default group id 0x%04X", groupid);
5094 for (uint i = 0; i < idcount; i++) {
5095 EngineID engine = engines[i];
5097 if (wagover) {
5098 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5099 } else {
5100 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5101 SetEngineGRF(engine, _cur.grffile);
5105 return true;
5109 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
5111 const byte *cfs = buf->GetData (idcount);
5113 uint8 cidcount = buf->ReadByte();
5114 buf->Skip(cidcount * 3);
5116 uint16 groupid = buf->ReadWord();
5117 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
5119 for (uint i = 0; i < idcount; i++) {
5120 CanalFeature cf = (CanalFeature)cfs[i];
5122 if (cf >= CF_END) {
5123 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5124 continue;
5127 _water_feature[cf].grffile = _cur.grffile;
5128 _water_feature[cf].group = _cur.spritegroups[groupid];
5133 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
5135 const byte *stations = buf->GetData (idcount);
5137 uint8 cidcount = buf->ReadByte();
5138 for (uint c = 0; c < cidcount; c++) {
5139 uint8 ctype = buf->ReadByte();
5140 uint16 groupid = buf->ReadWord();
5141 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
5143 if (ctype == 0xFE) {
5144 ctype = CT_DEFAULT_NA;
5145 } else {
5146 ctype = TranslateCargo (ctype);
5147 if (ctype == CT_INVALID) continue;
5150 for (uint i = 0; i < idcount; i++) {
5151 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5153 if (statspec == NULL) {
5154 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5155 continue;
5158 statspec->spritegroup[ctype] = _cur.spritegroups[groupid];
5162 uint16 groupid = buf->ReadWord();
5163 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
5165 for (uint i = 0; i < idcount; i++) {
5166 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5168 if (statspec == NULL) {
5169 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5170 continue;
5173 if (statspec->grf_prop.grffile != NULL) {
5174 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5175 continue;
5178 statspec->spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
5179 statspec->grf_prop.grffile = _cur.grffile;
5180 statspec->grf_prop.local_id = stations[i];
5181 StationClass::Assign(statspec);
5186 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
5188 const byte *houses = buf->GetData (idcount);
5190 /* Skip the cargo type section, we only care about the default group */
5191 uint8 cidcount = buf->ReadByte();
5192 buf->Skip(cidcount * 3);
5194 uint16 groupid = buf->ReadWord();
5195 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
5197 if (_cur.grffile->housespec == NULL) {
5198 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5199 return;
5202 for (uint i = 0; i < idcount; i++) {
5203 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
5205 if (hs == NULL) {
5206 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5207 continue;
5210 hs->grf_prop.spritegroup = _cur.spritegroups[groupid];
5214 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5216 const byte *industries = buf->GetData (idcount);
5218 /* Skip the cargo type section, we only care about the default group */
5219 uint8 cidcount = buf->ReadByte();
5220 buf->Skip(cidcount * 3);
5222 uint16 groupid = buf->ReadWord();
5223 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5225 if (_cur.grffile->industryspec == NULL) {
5226 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5227 return;
5230 for (uint i = 0; i < idcount; i++) {
5231 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5233 if (indsp == NULL) {
5234 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5235 continue;
5238 indsp->grf_prop.spritegroup = _cur.spritegroups[groupid];
5242 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5244 const byte *indtiles = buf->GetData (idcount);
5246 /* Skip the cargo type section, we only care about the default group */
5247 uint8 cidcount = buf->ReadByte();
5248 buf->Skip(cidcount * 3);
5250 uint16 groupid = buf->ReadWord();
5251 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5253 if (_cur.grffile->indtspec == NULL) {
5254 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5255 return;
5258 for (uint i = 0; i < idcount; i++) {
5259 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5261 if (indtsp == NULL) {
5262 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5263 continue;
5266 indtsp->grf_prop.spritegroup = _cur.spritegroups[groupid];
5270 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5272 const byte *cargoes = buf->GetData (idcount);
5274 /* Skip the cargo type section, we only care about the default group */
5275 uint8 cidcount = buf->ReadByte();
5276 buf->Skip(cidcount * 3);
5278 uint16 groupid = buf->ReadWord();
5279 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5281 for (uint i = 0; i < idcount; i++) {
5282 CargoID cid = (CargoID)cargoes[i];
5284 if (cid >= NUM_CARGO) {
5285 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5286 continue;
5289 CargoSpec *cs = CargoSpec::Get(cid);
5290 cs->grffile = _cur.grffile;
5291 cs->group = _cur.spritegroups[groupid];
5295 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5297 if (_cur.grffile->objectspec == NULL) {
5298 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5299 return;
5302 const byte *objects = buf->GetData (idcount);
5304 uint8 cidcount = buf->ReadByte();
5305 for (uint c = 0; c < cidcount; c++) {
5306 uint8 ctype = buf->ReadByte();
5307 uint16 groupid = buf->ReadWord();
5308 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5310 switch (ctype) {
5311 case 0: break;
5312 case 0xFF: ctype = CT_PURCHASE_OBJECT; break;
5313 default:
5314 grfmsg(1, "ObjectMapSpriteGroup: Invalid cargo bitnum %d for objects, skipping.", ctype);
5315 continue;
5318 for (uint i = 0; i < idcount; i++) {
5319 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5321 if (spec == NULL) {
5322 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5323 continue;
5326 spec->spritegroup[ctype] = _cur.spritegroups[groupid];
5330 uint16 groupid = buf->ReadWord();
5331 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5333 for (uint i = 0; i < idcount; i++) {
5334 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5336 if (spec == NULL) {
5337 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5338 continue;
5341 if (spec->grf_prop.grffile != NULL) {
5342 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5343 continue;
5346 spec->spritegroup[0] = _cur.spritegroups[groupid];
5347 spec->grf_prop.grffile = _cur.grffile;
5348 spec->grf_prop.local_id = objects[i];
5352 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5354 const byte *railtypes = buf->GetData (idcount);
5356 uint8 cidcount = buf->ReadByte();
5357 for (uint c = 0; c < cidcount; c++) {
5358 uint8 ctype = buf->ReadByte();
5359 uint16 groupid = buf->ReadWord();
5360 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5362 if (ctype >= RTSG_END) continue;
5364 extern RailtypeInfo _railtypes[RAILTYPE_END];
5365 for (uint i = 0; i < idcount; i++) {
5366 RailType rt = _cur.grffile->railtype_map[railtypes[i]];
5367 if (rt != INVALID_RAILTYPE) {
5368 RailtypeInfo *rti = &_railtypes[rt];
5370 rti->grffile[ctype] = _cur.grffile;
5371 rti->group[ctype] = _cur.spritegroups[groupid];
5376 /* Railtypes do not use the default group. */
5377 buf->ReadWord();
5380 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5382 const byte *airports = buf->GetData (idcount);
5384 /* Skip the cargo type section, we only care about the default group */
5385 uint8 cidcount = buf->ReadByte();
5386 buf->Skip(cidcount * 3);
5388 uint16 groupid = buf->ReadWord();
5389 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5391 if (_cur.grffile->airportspec == NULL) {
5392 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5393 return;
5396 for (uint i = 0; i < idcount; i++) {
5397 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5399 if (as == NULL) {
5400 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5401 continue;
5404 as->grf_prop.spritegroup = _cur.spritegroups[groupid];
5408 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5410 const byte *airptiles = buf->GetData (idcount);
5412 /* Skip the cargo type section, we only care about the default group */
5413 uint8 cidcount = buf->ReadByte();
5414 buf->Skip(cidcount * 3);
5416 uint16 groupid = buf->ReadWord();
5417 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5419 if (_cur.grffile->airtspec == NULL) {
5420 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5421 return;
5424 for (uint i = 0; i < idcount; i++) {
5425 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5427 if (airtsp == NULL) {
5428 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5429 continue;
5432 airtsp->grf_prop.spritegroup = _cur.spritegroups[groupid];
5437 /* Action 0x03 */
5438 static int FeatureMapSpriteGroup (ByteReader *buf)
5440 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5441 * id-list := [<id>] [id-list]
5442 * cargo-list := <cargo-type> <cid> [cargo-list]
5444 * B feature see action 0
5445 * B n-id bits 0-6: how many IDs this definition applies to
5446 * bit 7: if set, this is a wagon override definition (see below)
5447 * B ids the IDs for which this definition applies
5448 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5449 * can be zero, in that case the def-cid is used always
5450 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5451 * W cid cargo ID (sprite group ID) for this type of cargo
5452 * W def-cid default cargo ID (sprite group ID) */
5454 uint8 feature = buf->ReadByte();
5455 uint8 idcount = buf->ReadByte();
5457 /* If idcount is zero, this is a feature callback */
5458 if (idcount == 0) {
5459 /* Skip number of cargo ids? */
5460 buf->ReadByte();
5461 uint16 groupid = buf->ReadWord();
5462 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return 0;
5464 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
5466 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5467 return 0;
5470 /* Mark the feature as used by the grf (generic callbacks do not count) */
5471 SetBit(_cur.grffile->grf_features, feature);
5473 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
5475 switch (feature) {
5476 case GSF_TRAINS:
5477 case GSF_ROADVEHICLES:
5478 case GSF_SHIPS:
5479 case GSF_AIRCRAFT:
5480 return VehicleMapSpriteGroup (buf, feature, idcount) ? 0 : -1;
5482 case GSF_CANALS:
5483 CanalMapSpriteGroup(buf, idcount);
5484 return 0;
5486 case GSF_STATIONS:
5487 StationMapSpriteGroup(buf, idcount);
5488 return 0;
5490 case GSF_HOUSES:
5491 TownHouseMapSpriteGroup(buf, idcount);
5492 return 0;
5494 case GSF_INDUSTRIES:
5495 IndustryMapSpriteGroup(buf, idcount);
5496 return 0;
5498 case GSF_INDUSTRYTILES:
5499 IndustrytileMapSpriteGroup(buf, idcount);
5500 return 0;
5502 case GSF_CARGOES:
5503 CargoMapSpriteGroup(buf, idcount);
5504 return 0;
5506 case GSF_AIRPORTS:
5507 AirportMapSpriteGroup(buf, idcount);
5508 return 0;
5510 case GSF_OBJECTS:
5511 ObjectMapSpriteGroup(buf, idcount);
5512 return 0;
5514 case GSF_RAILTYPES:
5515 RailTypeMapSpriteGroup(buf, idcount);
5516 return 0;
5518 case GSF_AIRPORTTILES:
5519 AirportTileMapSpriteGroup(buf, idcount);
5520 return 0;
5522 default:
5523 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
5524 return 0;
5528 /* Action 0x04 */
5529 static int FeatureNewName (ByteReader *buf)
5531 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5533 * B veh-type see action 0 (as 00..07, + 0A
5534 * But IF veh-type = 48, then generic text
5535 * B language-id If bit 6 is set, This is the extended language scheme,
5536 * with up to 64 language.
5537 * Otherwise, it is a mapping where set bits have meaning
5538 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5539 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5540 * B num-veh number of vehicles which are getting a new name
5541 * B/W offset number of the first vehicle that gets a new name
5542 * Byte : ID of vehicle to change
5543 * Word : ID of string to change/add
5544 * S data new texts, each of them zero-terminated, after
5545 * which the next name begins. */
5547 bool new_scheme = _cur.grffile->grf_version >= 7;
5549 uint8 feature = buf->ReadByte();
5550 uint8 lang = buf->ReadByte();
5551 uint8 num = buf->ReadByte();
5552 bool generic = HasBit(lang, 7);
5553 uint16 id;
5554 if (generic) {
5555 id = buf->ReadWord();
5556 } else if (feature <= GSF_AIRCRAFT) {
5557 id = buf->ReadExtendedByte();
5558 } else {
5559 id = buf->ReadByte();
5562 ClrBit(lang, 7);
5564 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5565 id, id + num, feature, lang);
5567 for (; num-- > 0 && buf->HasData(); id++) {
5568 const char *name = buf->ReadString();
5569 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5571 bool add_generic = false;
5572 bool add_name = false;
5573 StringID stringid = id;
5574 StringID def = STR_UNDEFINED;
5575 StringID *p;
5577 if (feature <= GSF_AIRCRAFT) {
5578 if (generic) {
5579 add_generic = true;
5580 } else {
5581 Engine *e = GetNewEngine (_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
5582 if (e != NULL) {
5583 stringid = e->index;
5584 def = e->info.string_id;
5585 p = &e->info.string_id;
5586 add_name = true;
5590 } else if (IsInsideMM (id, 0xD000, 0xD400) || IsInsideMM (id, 0xD800, 0xE000)) {
5591 add_generic = true;
5593 } else {
5594 switch (GB(id, 8, 8)) {
5595 case 0xC4: // Station class name
5596 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5597 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5598 } else {
5599 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
5600 p = &StationClass::Get(cls_id)->name;
5601 add_name = true;
5603 break;
5605 case 0xC5: // Station name
5606 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5607 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5608 } else {
5609 p = &_cur.grffile->stations[GB(id, 0, 8)]->name;
5610 add_name = true;
5612 break;
5614 case 0xC7: // Airporttile name
5615 if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
5616 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
5617 } else {
5618 p = &_cur.grffile->airtspec[GB(id, 0, 8)]->name;
5619 add_name = true;
5621 break;
5623 case 0xC9: // House name
5624 if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
5625 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
5626 } else {
5627 p = &_cur.grffile->housespec[GB(id, 0, 8)]->building_name;
5628 add_name = true;
5630 break;
5632 default:
5633 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
5634 break;
5638 if (add_generic) {
5639 AddGRFString (_cur.grffile->grfid, stringid, lang, new_scheme, true, name, def);
5640 } else if (add_name) {
5641 *p = AddGRFString (_cur.grffile->grfid, stringid, lang, new_scheme, false, name, def);
5645 return 0;
5649 struct SpritePair {
5650 SpriteID old, spr;
5653 /* Shore sprite replacements for single-corner and inclined slopes. */
5654 static const SpritePair shore_sprites_1 [] = {
5655 { SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1 }, // SLOPE_W
5656 { SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2 }, // SLOPE_S
5657 { SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3 }, // SLOPE_SW
5658 { SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4 }, // SLOPE_E
5659 { SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6 }, // SLOPE_SE
5660 { SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8 }, // SLOPE_N
5661 { SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9 }, // SLOPE_NW
5662 { SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12 }, // SLOPE_NE
5665 /* Shore sprite replacements for three-corner and steep slopes. */
5666 static const SpritePair shore_sprites_2 [] = {
5667 { SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0 }, // SLOPE_STEEP_S
5668 { SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5 }, // SLOPE_STEEP_W
5669 { SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7 }, // SLOPE_WSE
5670 { SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10 }, // SLOPE_STEEP_N
5671 { SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11 }, // SLOPE_NWS
5672 { SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13 }, // SLOPE_ENW
5673 { SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14 }, // SLOPE_SEN
5674 { SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15 }, // SLOPE_STEEP_E
5675 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
5676 * If they would be used somewhen, then these grass tiles will most like not look as needed */
5677 { SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16 }, // SLOPE_EW
5678 { SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17 }, // SLOPE_NS
5682 /** The type of action 5 type. */
5683 enum Action5BlockType {
5684 A5BLOCK_FIXED, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5685 A5BLOCK_ALLOW_OFFSET, ///< Allow replacing any subset by specifiing an offset.
5686 A5BLOCK_INVALID, ///< unknown/not-implemented type
5688 /** Information about a single action 5 type. */
5689 struct Action5Type {
5690 Action5BlockType block_type; ///< How is this Action5 type processed?
5691 SpriteID sprite_base; ///< Load the sprites starting from this sprite.
5692 uint16 min_sprites; ///< If the Action5 contains less sprites, the whole block will be ignored.
5693 uint16 max_sprites; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5694 const char *name; ///< Name for error messages.
5697 /** The information about action 5 types. */
5698 static const Action5Type _action5_types[] = {
5699 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5700 /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
5701 /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
5702 /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
5703 /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
5704 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
5705 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Rail catenary graphics" },
5706 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
5707 /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5708 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
5709 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
5710 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
5711 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
5712 /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5713 /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
5714 /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5715 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
5716 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
5717 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
5718 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
5719 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
5720 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
5721 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
5722 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
5723 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
5724 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET, SPR_PALETTE_BASE, 1, PALETTE_SPRITE_COUNT, "Palette" },
5727 /* Action 0x05 */
5728 static int GraphicsNew (ByteReader *buf)
5730 /* <05> <graphics-type> <num-sprites> <other data...>
5732 * B graphics-type What set of graphics the sprites define.
5733 * E num-sprites How many sprites are in this set?
5734 * V other data Graphics type specific data. Currently unused. */
5735 /* TODO */
5737 uint8 type = buf->ReadByte();
5738 uint16 num = buf->ReadExtendedByte();
5739 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
5740 ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
5742 if ((type == 0x0D) && (num == 10) && HasBit(_cur.grfconfig->flags, GCF_SYSTEM)) {
5743 /* Special not-TTDP-compatible case used in openttd.grf
5744 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5745 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5746 for (uint i = 0; i < lengthof(shore_sprites_2); i++) {
5747 LoadNextSprite (shore_sprites_2[i].spr, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver);
5749 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
5750 return 0;
5753 /* Supported type? */
5754 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
5755 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
5756 return num;
5759 const Action5Type *action5_type = &_action5_types[type];
5761 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5762 * except for the long version of the shore type:
5763 * Ignore offset if not allowed */
5764 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
5765 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
5766 offset = 0;
5769 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5770 * This does not make sense, if <offset> is allowed */
5771 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
5772 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);
5773 return num;
5776 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5777 uint16 skip_num;
5778 if (offset >= action5_type->max_sprites) {
5779 grfmsg (1, "GraphicsNew: %s sprite offset must be less than %i, skipping", action5_type->name, action5_type->max_sprites);
5780 skip_num = num;
5781 num = 0;
5782 } else if (offset + num > action5_type->max_sprites) {
5783 grfmsg (4, "GraphicsNew: %s sprite overflow, truncating...", action5_type->name);
5784 uint rem = action5_type->max_sprites - offset;
5785 skip_num = num - rem;
5786 num = rem;
5787 } else {
5788 skip_num = 0;
5790 SpriteID replace = action5_type->sprite_base + offset;
5792 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5793 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);
5795 for (; num > 0; num--) {
5796 _cur.nfo_line++;
5797 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
5800 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
5802 return skip_num;
5805 /* Action 0x05 (SKIP) */
5806 static int SkipAct5 (ByteReader *buf)
5808 /* Ignore type byte */
5809 buf->ReadByte();
5811 /* Skip the sprites of this action */
5812 int skip = buf->ReadExtendedByte();
5813 grfmsg (3, "SkipAct5: Skipping %d sprites", skip);
5814 return skip;
5818 * Reads a variable common to VarAction2 and Action7/9/D.
5820 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5821 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5823 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5824 * @param value returns the value of the variable.
5825 * @param grffile NewGRF querying the variable
5826 * @return true iff the variable is known and the value is returned in 'value'.
5828 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
5830 switch (param) {
5831 case 0x00: // current date
5832 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
5833 return true;
5835 case 0x01: // current year
5836 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
5837 return true;
5839 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)
5840 YearMonthDay ymd;
5841 ConvertDateToYMD(_date, &ymd);
5842 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
5843 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
5844 return true;
5847 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5848 *value = _settings_game.game_creation.landscape;
5849 return true;
5851 case 0x06: // road traffic side, bit 4 clear=left, set=right
5852 *value = _settings_game.vehicle.road_side << 4;
5853 return true;
5855 case 0x09: // date fraction
5856 *value = _date_fract * 885;
5857 return true;
5859 case 0x0A: // animation counter
5860 *value = _tick_counter;
5861 return true;
5863 case 0x0B: { // TTDPatch version
5864 uint major = 2;
5865 uint minor = 6;
5866 uint revision = 1; // special case: 2.0.1 is 2.0.10
5867 uint build = 1382;
5868 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
5869 return true;
5872 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5873 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
5874 return true;
5876 case 0x0E: // Y-offset for train sprites
5877 *value = _cur.grffile->traininfo_vehicle_pitch;
5878 return true;
5880 case 0x0F: // Rail track type cost factors
5881 *value = 0;
5882 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
5883 if (_settings_game.vehicle.disable_elrails) {
5884 /* skip elrail multiplier - disabled */
5885 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
5886 } else {
5887 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
5888 /* Skip monorail multiplier - no space in result */
5890 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
5891 return true;
5893 case 0x11: // current rail tool type
5894 *value = 0; // constant fake value to avoid desync
5895 return true;
5897 case 0x12: // Game mode
5898 *value = _game_mode;
5899 return true;
5901 /* case 0x13: // Tile refresh offset to left not implemented */
5902 /* case 0x14: // Tile refresh offset to right not implemented */
5903 /* case 0x15: // Tile refresh offset upwards not implemented */
5904 /* case 0x16: // Tile refresh offset downwards not implemented */
5905 /* case 0x17: // temperate snow line not implemented */
5907 case 0x1A: // Always -1
5908 *value = UINT_MAX;
5909 return true;
5911 case 0x1B: // Display options
5912 *value = 0x3F; // constant fake value to avoid desync
5913 return true;
5915 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5916 *value = 1;
5917 return true;
5919 case 0x1E: // Miscellaneous GRF features
5920 *value = _misc_grf_features;
5922 /* Add the local flags */
5923 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
5924 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
5925 return true;
5927 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5929 case 0x20: { // snow line height
5930 byte snowline = GetSnowLine();
5931 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= _settings_game.construction.max_heightlevel) {
5932 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
5933 } else {
5934 /* No snow */
5935 *value = 0xFF;
5937 return true;
5940 case 0x21: // OpenTTD version
5941 *value = _openttd_newgrf_version;
5942 return true;
5944 case 0x22: // difficulty level
5945 *value = SP_CUSTOM;
5946 return true;
5948 case 0x23: // long format date
5949 *value = _date;
5950 return true;
5952 case 0x24: // long format year
5953 *value = _cur_year;
5954 return true;
5956 default: return false;
5960 static uint32 GetParamVal(byte param, uint32 *cond_val)
5962 /* First handle variable common with VarAction2 */
5963 uint32 value;
5964 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
5966 /* Non-common variable */
5967 switch (param) {
5968 case 0x84: { // GRF loading stage
5969 uint32 res = 0;
5971 if (_cur.stage > GLS_INIT) SetBit(res, 0);
5972 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
5973 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
5974 return res;
5977 case 0x85: // TTDPatch flags, only for bit tests
5978 if (cond_val == NULL) {
5979 /* Supported in Action 0x07 and 0x09, not 0x0D */
5980 return 0;
5981 } else {
5982 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
5983 *cond_val %= 0x20;
5984 return param_val;
5987 case 0x88: // GRF ID check
5988 return 0;
5990 /* case 0x99: Global ID offset not implemented */
5992 default:
5993 /* GRF Parameter */
5994 if (param < 0x80) return _cur.grffile->GetParam(param);
5996 /* In-game variable. */
5997 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
5998 return UINT_MAX;
6002 /* Action 0x06 */
6003 static int CfgApply (ByteReader *buf)
6005 /* <06> <param-num> <param-size> <offset> ... <FF>
6007 * B param-num Number of parameter to substitute (First = "zero")
6008 * Ignored if that parameter was not specified in newgrf.cfg
6009 * B param-size How many bytes to replace. If larger than 4, the
6010 * bytes of the following parameter are used. In that
6011 * case, nothing is applied unless *all* parameters
6012 * were specified.
6013 * B offset Offset into data from beginning of next sprite
6014 * to place where parameter is to be stored. */
6016 /* Preload the next sprite */
6017 size_t pos = FioGetPos();
6018 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
6019 uint8 type = FioReadByte();
6021 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
6022 if (type != 0xFF) {
6023 /* Reset the file position to the start of the next sprite */
6024 FioSeekTo(pos, SEEK_SET);
6026 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
6027 return 0;
6030 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
6031 std::pair <GRFLineToSpriteOverride::iterator, bool> ins =
6032 _grf_line_to_action6_sprite_override.insert (std::make_pair (location, ttd_unique_free_ptr<byte>()));
6034 byte *preload_sprite;
6035 if (ins.second) {
6036 preload_sprite = xmalloct<byte> (num);
6037 ins.first->second.reset (preload_sprite);
6038 FioReadBlock (preload_sprite, num);
6039 } else {
6040 preload_sprite = ins.first->second.get();
6043 /* Reset the file position to the start of the next sprite */
6044 FioSeekTo (pos, SEEK_SET);
6046 /* Now perform the Action 0x06 on our data. */
6048 for (;;) {
6049 uint i;
6050 uint param_num;
6051 uint param_size;
6052 uint offset;
6053 bool add_value;
6055 /* Read the parameter to apply. 0xFF indicates no more data to change. */
6056 param_num = buf->ReadByte();
6057 if (param_num == 0xFF) break;
6059 /* Get the size of the parameter to use. If the size covers multiple
6060 * double words, sequential parameter values are used. */
6061 param_size = buf->ReadByte();
6063 /* Bit 7 of param_size indicates we should add to the original value
6064 * instead of replacing it. */
6065 add_value = HasBit(param_size, 7);
6066 param_size = GB(param_size, 0, 7);
6068 /* Where to apply the data to within the pseudo sprite data. */
6069 offset = buf->ReadExtendedByte();
6071 /* If the parameter is a GRF parameter (not an internal variable) check
6072 * if it (and all further sequential parameters) has been defined. */
6073 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
6074 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6075 break;
6078 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6080 bool carry = false;
6081 for (i = 0; i < param_size && offset + i < num; i++) {
6082 uint32 value = GetParamVal(param_num + i / 4, NULL);
6083 /* Reset carry flag for each iteration of the variable (only really
6084 * matters if param_size is greater than 4) */
6085 if (i % 4 == 0) carry = false;
6087 if (add_value) {
6088 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6089 preload_sprite[offset + i] = GB(new_value, 0, 8);
6090 /* Check if the addition overflowed */
6091 carry = new_value >= 256;
6092 } else {
6093 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
6098 return 0;
6102 * Disable a static NewGRF when it is influencing another (non-static)
6103 * NewGRF as this could cause desyncs.
6105 * We could just tell the NewGRF querying that the file doesn't exist,
6106 * but that might give unwanted results. Disabling the NewGRF gives the
6107 * best result as no NewGRF author can complain about that.
6108 * @param c The NewGRF to disable.
6110 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
6112 DisableGrf (STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
6115 /* Action 0x07
6116 * Action 0x09 */
6117 static int SkipIf (ByteReader *buf)
6119 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6121 * B param-num
6122 * B param-size
6123 * B condition-type
6124 * V value
6125 * B num-sprites */
6126 /* TODO: More params. More condition types. */
6127 uint32 cond_val = 0;
6128 uint32 mask = 0;
6129 bool result;
6131 uint8 param = buf->ReadByte();
6132 uint8 paramsize = buf->ReadByte();
6133 uint8 condtype = buf->ReadByte();
6135 if (condtype < 2) {
6136 /* Always 1 for bit tests, the given value should be ignored. */
6137 paramsize = 1;
6140 switch (paramsize) {
6141 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6142 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6143 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6144 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6145 default: break;
6148 if (param < 0x80 && _cur.grffile->param_end <= param) {
6149 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6150 return 0;
6153 uint32 param_val = GetParamVal(param, &cond_val);
6155 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
6158 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6159 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6160 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6161 * So, when the condition type is one of those, the specific variable
6162 * 0x88 code is skipped, so the "general" code for the cargo
6163 * availability conditions kicks in.
6165 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
6166 /* GRF ID checks */
6168 GRFConfig *c = GetGRFConfig(cond_val, mask);
6170 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6171 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6172 c = NULL;
6175 if (condtype != 10 && c == NULL) {
6176 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6177 return 0;
6180 switch (condtype) {
6181 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6182 case 0x06: // Is GRFID active?
6183 result = c->status == GCS_ACTIVATED;
6184 break;
6186 case 0x07: // Is GRFID non-active?
6187 result = c->status != GCS_ACTIVATED;
6188 break;
6190 case 0x08: // GRFID is not but will be active?
6191 result = c->status == GCS_INITIALISED;
6192 break;
6194 case 0x09: // GRFID is or will be active?
6195 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6196 break;
6198 case 0x0A: // GRFID is not nor will be active
6199 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6200 result = c == NULL || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6201 break;
6203 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return 0;
6205 } else {
6206 /* Parameter or variable tests */
6207 switch (condtype) {
6208 case 0x00: result = !!(param_val & (1 << cond_val));
6209 break;
6210 case 0x01: result = !(param_val & (1 << cond_val));
6211 break;
6212 case 0x02: result = (param_val & mask) == cond_val;
6213 break;
6214 case 0x03: result = (param_val & mask) != cond_val;
6215 break;
6216 case 0x04: result = (param_val & mask) < cond_val;
6217 break;
6218 case 0x05: result = (param_val & mask) > cond_val;
6219 break;
6220 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6221 break;
6222 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6223 break;
6224 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6225 break;
6226 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6227 break;
6229 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return 0;
6233 if (!result) {
6234 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6235 return 0;
6238 uint8 numsprites = buf->ReadByte();
6240 /* numsprites can be a GOTO label if it has been defined in the GRF
6241 * file. The jump will always be the first matching label that follows
6242 * the current nfo_line. If no matching label is found, the first matching
6243 * label in the file is used. */
6244 GRFLabel *choice = NULL;
6245 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
6246 if (label->label != numsprites) continue;
6248 /* Remember a goto before the current line */
6249 if (choice == NULL) choice = label;
6250 /* If we find a label here, this is definitely good */
6251 if (label->nfo_line > _cur.nfo_line) {
6252 choice = label;
6253 break;
6257 if (choice != NULL) {
6258 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6259 FioSeekTo(choice->pos, SEEK_SET);
6260 _cur.nfo_line = choice->nfo_line;
6261 return 0;
6264 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6266 if (numsprites != 0) return numsprites;
6268 /* If an action 8 hasn't been encountered yet, disable the grf. */
6269 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6270 DisableCur();
6273 /* Zero means there are no sprites to skip, so we use -1 to indicate
6274 * that all further sprites should be skipped. */
6275 return -1;
6279 /* Action 0x08 (GLS_FILESCAN) */
6280 static int ScanInfo (ByteReader *buf)
6282 uint8 grf_version = buf->ReadByte();
6283 uint32 grfid = buf->ReadDWord();
6284 const char *name = buf->ReadString();
6286 _cur.grfconfig->ident.grfid = grfid;
6288 if (grf_version < 2 || grf_version > 8) {
6289 SetBit(_cur.grfconfig->flags, GCF_INVALID);
6290 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);
6293 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6294 if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6296 _cur.grfconfig->name->add (0x7F, grfid, false, name);
6298 if (buf->HasData()) {
6299 const char *info = buf->ReadString();
6300 _cur.grfconfig->info->add (0x7F, grfid, true, info);
6303 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6304 return -1;
6307 /* Action 0x08 */
6308 static int GRFInfo (ByteReader *buf)
6310 /* <08> <version> <grf-id> <name> <info>
6312 * B version newgrf version, currently 06
6313 * 4*B grf-id globally unique ID of this .grf file
6314 * S name name of this .grf set
6315 * S info string describing the set, and e.g. author and copyright */
6317 uint8 version = buf->ReadByte();
6318 uint32 grfid = buf->ReadDWord();
6319 const char *name = buf->ReadString();
6321 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6322 DisableCur (STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6323 return -1;
6326 if (_cur.grffile->grfid != grfid) {
6327 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));
6328 _cur.grffile->grfid = grfid;
6331 _cur.grffile->grf_version = version;
6332 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6334 /* Do swap the GRFID for displaying purposes since people expect that */
6335 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);
6337 return 0;
6340 /* Action 0x0A */
6341 static int SpriteReplace (ByteReader *buf)
6343 /* <0A> <num-sets> <set1> [<set2> ...]
6344 * <set>: <num-sprites> <first-sprite>
6346 * B num-sets How many sets of sprites to replace.
6347 * Each set:
6348 * B num-sprites How many sprites are in this set
6349 * W first-sprite First sprite number to replace */
6351 uint8 num_sets = buf->ReadByte();
6353 for (uint i = 0; i < num_sets; i++) {
6354 uint8 num_sprites = buf->ReadByte();
6355 uint16 first_sprite = buf->ReadWord();
6357 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6358 i, num_sprites, first_sprite
6361 for (uint j = 0; j < num_sprites; j++) {
6362 int load_index = first_sprite + j;
6363 _cur.nfo_line++;
6364 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6366 /* Shore sprites now located at different addresses.
6367 * So detect when the old ones get replaced. */
6368 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6369 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
6374 return 0;
6377 /* Action 0x0A (SKIP) */
6378 static int SkipActA (ByteReader *buf)
6380 uint8 num_sets = buf->ReadByte();
6382 int skip = 0;
6383 for (uint i = 0; i < num_sets; i++) {
6384 /* Skip the sprites this replaces */
6385 skip += buf->ReadByte();
6386 /* But ignore where they go */
6387 buf->ReadWord();
6390 grfmsg (3, "SkipActA: Skipping %d sprites", skip);
6392 return skip;
6395 /* Action 0x0B */
6396 static int GRFLoadError (ByteReader *buf)
6398 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6400 * B severity 00: notice, contine loading grf file
6401 * 01: warning, continue loading grf file
6402 * 02: error, but continue loading grf file, and attempt
6403 * loading grf again when loading or starting next game
6404 * 03: error, abort loading and prevent loading again in
6405 * the future (only when restarting the patch)
6406 * B language-id see action 4, use 1F for built-in error messages
6407 * B message-id message to show, see below
6408 * S message for custom messages (message-id FF), text of the message
6409 * not present for built-in messages.
6410 * V data additional data for built-in (or custom) messages
6411 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6413 static const StringID msgstr[] = {
6414 STR_NEWGRF_ERROR_VERSION_NUMBER,
6415 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6416 STR_NEWGRF_ERROR_UNSET_SWITCH,
6417 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6418 STR_NEWGRF_ERROR_LOAD_BEFORE,
6419 STR_NEWGRF_ERROR_LOAD_AFTER,
6420 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6423 static const StringID sevstr[] = {
6424 STR_NEWGRF_ERROR_MSG_INFO,
6425 STR_NEWGRF_ERROR_MSG_WARNING,
6426 STR_NEWGRF_ERROR_MSG_ERROR,
6427 STR_NEWGRF_ERROR_MSG_FATAL
6430 byte severity = buf->ReadByte();
6431 byte lang = buf->ReadByte();
6432 byte message_id = buf->ReadByte();
6434 /* Skip the error if it isn't valid for the current language. */
6435 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return 0;
6437 /* Skip the error until the activation stage unless bit 7 of the severity
6438 * is set. */
6439 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6440 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6441 return 0;
6443 ClrBit(severity, 7);
6445 if (severity >= lengthof(sevstr)) {
6446 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6447 severity = 2;
6448 } else if (severity == 3) {
6449 /* This is a fatal error, so make sure the GRF is deactivated and no
6450 * more of it gets loaded. */
6451 DisableCur();
6453 /* Make sure we show fatal errors, instead of silly infos from before */
6454 delete _cur.grfconfig->error;
6455 _cur.grfconfig->error = NULL;
6458 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6459 grfmsg(7, "GRFLoadError: Invalid message id.");
6461 } else if (!buf->HasData (2)) {
6462 grfmsg(7, "GRFLoadError: No message data supplied.");
6464 } else if (_cur.grfconfig->error == NULL) {
6465 /* For now we can only show one message per newgrf file. */
6466 GRFError *error = new GRFError (sevstr[severity]);
6468 if (message_id != 0xFF) {
6469 error->message = msgstr[message_id];
6470 } else if (buf->HasData()) {
6471 /* This is a custom error message. */
6472 const char *message = buf->ReadString();
6473 error->custom_message = TranslateTTDPatchCodes (_cur.grffile->grfid, lang, true, message, SCC_RAW_STRING_POINTER);
6474 } else {
6475 grfmsg(7, "GRFLoadError: No custom message supplied.");
6476 error->custom_message = xstrdup("");
6479 if (buf->HasData()) {
6480 const char *data = buf->ReadString();
6481 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6482 } else {
6483 grfmsg(7, "GRFLoadError: No message data supplied.");
6484 error->data = xstrdup("");
6487 /* Only two parameter numbers can be used in the string. */
6488 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6489 uint param_number = buf->ReadByte();
6490 error->param_value[i] = _cur.grffile->GetParam(param_number);
6493 _cur.grfconfig->error = error;
6496 return (severity == 3) ? -1 : 0;
6499 /* Action 0x0C */
6500 static int GRFComment (ByteReader *buf)
6502 /* <0C> [<ignored...>]
6504 * V ignored Anything following the 0C is ignored */
6506 if (buf->HasData()) grfmsg (2, "GRFComment: %s", buf->ReadString());
6508 return 0;
6511 /* Action 0x0D (GLS_SAFETYSCAN) */
6512 static int SafeParamSet (ByteReader *buf)
6514 uint8 target = buf->ReadByte();
6516 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6517 if (target < 0x80 || target == 0x9E) return 0;
6519 /* GRM could be unsafe, but as here it can only happen after other GRFs
6520 * are loaded, it should be okay. If the GRF tried to use the slots it
6521 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6522 * sprites is considered safe. */
6524 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6526 /* Skip remainder of GRF */
6527 return -1;
6531 static uint32 GetPatchVariable(uint8 param)
6533 switch (param) {
6534 /* start year - 1920 */
6535 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
6537 /* freight trains weight factor */
6538 case 0x0E: return _settings_game.vehicle.freight_trains;
6540 /* empty wagon speed increase */
6541 case 0x0F: return 0;
6543 /* plane speed factor; our patch option is reversed from TTDPatch's,
6544 * the following is good for 1x, 2x and 4x (most common?) and...
6545 * well not really for 3x. */
6546 case 0x10:
6547 switch (_settings_game.vehicle.plane_speed) {
6548 default:
6549 case 4: return 1;
6550 case 3: return 2;
6551 case 2: return 2;
6552 case 1: return 4;
6556 /* 2CC colourmap base sprite */
6557 case 0x11: return SPR_2CCMAP_BASE;
6559 /* map size: format = -MABXYSS
6560 * M : the type of map
6561 * bit 0 : set : squared map. Bit 1 is now not relevant
6562 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6563 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6564 * clear : X is the bigger edge.
6565 * A : minimum edge(log2) of the map
6566 * B : maximum edge(log2) of the map
6567 * XY : edges(log2) of each side of the map.
6568 * SS : combination of both X and Y, thus giving the size(log2) of the map
6570 case 0x13: {
6571 byte map_bits = 0;
6572 byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6573 byte log_Y = MapLogY() - 6;
6574 byte max_edge = max(log_X, log_Y);
6576 if (log_X == log_Y) { // we have a squared map, since both edges are identical
6577 SetBit(map_bits, 0);
6578 } else {
6579 if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
6582 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
6583 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
6586 /* The maximum height of the map. */
6587 case 0x14:
6588 return _settings_game.construction.max_heightlevel;
6590 /* Extra foundations base sprite */
6591 case 0x15:
6592 return SPR_SLOPES_BASE;
6594 /* Shore base sprite */
6595 case 0x16:
6596 return SPR_SHORE_BASE;
6598 default:
6599 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
6600 return 0;
6605 static bool PerformGRM (uint32 *grm, uint16 num_ids, uint16 count,
6606 uint8 op, uint8 target, uint32 *res, const char *type)
6608 uint start = 0;
6609 uint size = 0;
6611 if (op == 6) {
6612 /* Return GRFID of set that reserved ID */
6613 *res = grm[_cur.grffile->GetParam(target)];
6614 return true;
6617 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6618 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
6620 for (uint i = start; i < num_ids; i++) {
6621 if (grm[i] == 0) {
6622 size++;
6623 } else {
6624 if (op == 2 || op == 3) break;
6625 start = i + 1;
6626 size = 0;
6629 if (size == count) break;
6632 if (size == count) {
6633 /* Got the slot... */
6634 if (op == 0 || op == 3) {
6635 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
6636 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
6638 *res = start;
6639 return true;
6642 /* Unable to allocate */
6643 if (op != 4 && op != 5) {
6644 /* Deactivate GRF */
6645 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
6646 DisableCur (STR_NEWGRF_ERROR_GRM_FAILED);
6647 return false;
6650 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
6651 *res = UINT_MAX;
6652 return true;
6656 /** Action 0x0D: Set parameter */
6657 static int ParamSet (ByteReader *buf)
6659 /* <0D> <target> <operation> <source1> <source2> [<data>]
6661 * B target parameter number where result is stored
6662 * B operation operation to perform, see below
6663 * B source1 first source operand
6664 * B source2 second source operand
6665 * D data data to use in the calculation, not necessary
6666 * if both source1 and source2 refer to actual parameters
6668 * Operations
6669 * 00 Set parameter equal to source1
6670 * 01 Addition, source1 + source2
6671 * 02 Subtraction, source1 - source2
6672 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6673 * 04 Signed multiplication, source1 * source2 (both signed)
6674 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6675 * signed quantity; left shift if positive and right shift if
6676 * negative, source1 is unsigned)
6677 * 06 Signed bit shift, source1 by source2
6678 * (source2 like in 05, and source1 as well)
6681 uint8 target = buf->ReadByte();
6682 uint8 oper = buf->ReadByte();
6683 uint32 src1 = buf->ReadByte();
6684 uint32 src2 = buf->ReadByte();
6686 uint32 data = 0;
6687 if (buf->HasData (4)) data = buf->ReadDWord();
6689 /* You can add 80 to the operation to make it apply only if the target
6690 * is not defined yet. In this respect, a parameter is taken to be
6691 * defined if any of the following applies:
6692 * - it has been set to any value in the newgrf(w).cfg parameter list
6693 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6694 * an earlier action D */
6695 if (HasBit(oper, 7)) {
6696 if (target < 0x80 && target < _cur.grffile->param_end) {
6697 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
6698 return 0;
6701 oper = GB(oper, 0, 7);
6704 if (src2 != 0xFE) {
6705 /* The source1 and source2 operands refer to the grf parameter number
6706 * like in action 6 and 7. In addition, they can refer to the special
6707 * variables available in action 7, or they can be FF to use the value
6708 * of <data>. If referring to parameters that are undefined, a value
6709 * of 0 is used instead. */
6710 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
6711 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
6712 } else if (GB(data, 0, 8) != 0xFF) {
6713 /* Read another GRF File's parameter */
6714 const GRFFile *file = GetFileByGRFID(data);
6715 GRFConfig *c = GetGRFConfig(data);
6716 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6717 /* Disable the read GRF if it is a static NewGRF. */
6718 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6719 src1 = 0;
6720 } else if (file == NULL || c == NULL || c->status == GCS_DISABLED) {
6721 src1 = 0;
6722 } else if (src1 == 0xFE) {
6723 src1 = c->version;
6724 } else {
6725 src1 = file->GetParam(src1);
6727 } else if (data == 0x0000FFFF) {
6728 /* Patch variables */
6729 src1 = GetPatchVariable(src1);
6730 } else {
6731 /* GRF Resource Management */
6732 uint8 op = src1;
6733 uint8 feature = GB(data, 8, 8);
6734 uint16 count = GB(data, 16, 16);
6736 if (_cur.stage == GLS_RESERVE) {
6737 if (feature == 0x08) {
6738 /* General sprites */
6739 if (op == 0) {
6740 /* Check if the allocated sprites will fit below the original sprite limit */
6741 if (_cur.spriteid + count >= 16384) {
6742 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
6743 DisableCur (STR_NEWGRF_ERROR_GRM_FAILED);
6744 return -1;
6747 /* Reserve space at the current sprite ID */
6748 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
6749 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
6750 _cur.spriteid += count;
6753 /* Ignore GRM result during reservation */
6754 src1 = 0;
6755 } else if (_cur.stage == GLS_ACTIVATION) {
6756 switch (feature) {
6757 case 0x00: // Trains
6758 case 0x01: // Road Vehicles
6759 case 0x02: // Ships
6760 case 0x03: // Aircraft
6761 if (!_settings_game.vehicle.dynamic_engines) {
6762 if (!PerformGRM (&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, &src1, "vehicles")) {
6763 return -1;
6765 } else {
6766 /* GRM does not apply for dynamic engine allocation. */
6767 switch (op) {
6768 case 2:
6769 case 3:
6770 src1 = _cur.grffile->GetParam(target);
6771 break;
6773 default:
6774 src1 = 0;
6775 break;
6778 break;
6780 case 0x08: // General sprites
6781 switch (op) {
6782 case 0:
6783 /* Return space reserved during reservation stage */
6784 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
6785 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
6786 break;
6788 case 1:
6789 src1 = _cur.spriteid;
6790 break;
6792 default:
6793 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
6794 return 0;
6796 break;
6798 case 0x0B: // Cargo
6799 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6800 if (!PerformGRM (_grm_cargoes, NUM_CARGO * 2, count, op, target, &src1, "cargoes")) {
6801 return -1;
6803 break;
6805 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return 0;
6807 } else {
6808 /* Ignore GRM during initialization */
6809 src1 = 0;
6813 /* TODO: You can access the parameters of another GRF file by using
6814 * source2=FE, source1=the other GRF's parameter number and data=GRF
6815 * ID. This is only valid with operation 00 (set). If the GRF ID
6816 * cannot be found, a value of 0 is used for the parameter value
6817 * instead. */
6819 uint32 res;
6820 switch (oper) {
6821 case 0x00:
6822 res = src1;
6823 break;
6825 case 0x01:
6826 res = src1 + src2;
6827 break;
6829 case 0x02:
6830 res = src1 - src2;
6831 break;
6833 case 0x03:
6834 res = src1 * src2;
6835 break;
6837 case 0x04:
6838 res = (int32)src1 * (int32)src2;
6839 break;
6841 case 0x05:
6842 if ((int32)src2 < 0) {
6843 res = src1 >> -(int32)src2;
6844 } else {
6845 res = src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6847 break;
6849 case 0x06:
6850 if ((int32)src2 < 0) {
6851 res = (int32)src1 >> -(int32)src2;
6852 } else {
6853 res = (int32)src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6855 break;
6857 case 0x07: // Bitwise AND
6858 res = src1 & src2;
6859 break;
6861 case 0x08: // Bitwise OR
6862 res = src1 | src2;
6863 break;
6865 case 0x09: // Unsigned division
6866 if (src2 == 0) {
6867 res = src1;
6868 } else {
6869 res = src1 / src2;
6871 break;
6873 case 0x0A: // Signed divison
6874 if (src2 == 0) {
6875 res = src1;
6876 } else {
6877 res = (int32)src1 / (int32)src2;
6879 break;
6881 case 0x0B: // Unsigned modulo
6882 if (src2 == 0) {
6883 res = src1;
6884 } else {
6885 res = src1 % src2;
6887 break;
6889 case 0x0C: // Signed modulo
6890 if (src2 == 0) {
6891 res = src1;
6892 } else {
6893 res = (int32)src1 % (int32)src2;
6895 break;
6897 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return 0;
6900 switch (target) {
6901 case 0x8E: // Y-Offset for train sprites
6902 _cur.grffile->traininfo_vehicle_pitch = res;
6903 break;
6905 case 0x8F: { // Rail track type cost factors
6906 extern RailtypeInfo _railtypes[RAILTYPE_END];
6907 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
6908 if (_settings_game.vehicle.disable_elrails) {
6909 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
6910 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
6911 } else {
6912 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
6913 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
6915 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
6916 break;
6919 /* @todo implement */
6920 case 0x93: // Tile refresh offset to left
6921 case 0x94: // Tile refresh offset to right
6922 case 0x95: // Tile refresh offset upwards
6923 case 0x96: // Tile refresh offset downwards
6924 case 0x97: // Snow line height
6925 case 0x99: // Global ID offset
6926 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6927 break;
6929 case 0x9E: // Miscellaneous GRF features
6930 /* Set train list engine width */
6931 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
6932 /* Remove the local flags from the global flags */
6933 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
6935 /* Only copy safe bits for static grfs */
6936 if (HasBit(_cur.grfconfig->flags, GCF_STATIC)) {
6937 uint32 safe_bits = 0;
6938 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
6940 _misc_grf_features = (_misc_grf_features & ~safe_bits) | (res & safe_bits);
6941 } else {
6942 _misc_grf_features = res;
6944 break;
6946 case 0x9F: // locale-dependent settings
6947 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6948 break;
6950 default:
6951 if (target < 0x80) {
6952 _cur.grffile->param[target] = res;
6953 /* param is zeroed by default */
6954 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
6955 } else {
6956 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
6958 break;
6961 return 0;
6964 /* Action 0x0E (GLS_SAFETYSCAN) */
6965 static int SafeGRFInhibit (ByteReader *buf)
6967 /* <0E> <num> <grfids...>
6969 * B num Number of GRFIDs that follow
6970 * D grfids GRFIDs of the files to deactivate */
6972 uint8 num = buf->ReadByte();
6974 for (uint i = 0; i < num; i++) {
6975 uint32 grfid = buf->ReadDWord();
6977 /* GRF is unsafe it if tries to deactivate other GRFs */
6978 if (grfid != _cur.grfconfig->ident.grfid) {
6979 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6981 /* Skip remainder of GRF */
6982 return -1;
6986 return 0;
6989 /* Action 0x0E */
6990 static int GRFInhibit (ByteReader *buf)
6992 /* <0E> <num> <grfids...>
6994 * B num Number of GRFIDs that follow
6995 * D grfids GRFIDs of the files to deactivate */
6997 uint8 num = buf->ReadByte();
6999 for (uint i = 0; i < num; i++) {
7000 uint32 grfid = buf->ReadDWord();
7001 GRFConfig *file = GetGRFConfig(grfid);
7003 /* Unset activation flag */
7004 if (file != NULL && file != _cur.grfconfig) {
7005 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
7006 DisableGrf (STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
7010 return 0;
7013 /** Action 0x0F - Define Town names */
7014 static int FeatureTownName (ByteReader *buf)
7016 /* <0F> <id> <style-name> <num-parts> <parts>
7018 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
7019 * V style-name Name of the style (only for final definition)
7020 * B num-parts Number of parts in this definition
7021 * V parts The parts */
7023 uint32 grfid = _cur.grffile->grfid;
7025 GRFTownName *townname = AddGRFTownName(grfid);
7027 byte id = buf->ReadByte();
7028 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
7030 if (HasBit(id, 7)) {
7031 /* Final definition */
7032 ClrBit(id, 7);
7033 bool new_scheme = _cur.grffile->grf_version >= 7;
7035 byte lang = buf->ReadByte();
7037 byte nb_gen = townname->nb_gen;
7038 do {
7039 ClrBit(lang, 7);
7041 const char *name = buf->ReadString();
7043 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
7044 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
7045 free(lang_name);
7047 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
7049 lang = buf->ReadByte();
7050 } while (lang != 0);
7051 townname->id[nb_gen] = id;
7052 townname->nb_gen++;
7055 byte nb = buf->ReadByte();
7056 grfmsg(6, "FeatureTownName: %u parts", nb);
7058 townname->nbparts[id] = nb;
7059 townname->partlist[id] = xcalloct<NamePartList>(nb);
7061 for (int i = 0; i < nb; i++) {
7062 byte nbtext = buf->ReadByte();
7063 townname->partlist[id][i].bitstart = buf->ReadByte();
7064 townname->partlist[id][i].bitcount = buf->ReadByte();
7065 townname->partlist[id][i].maxprob = 0;
7066 townname->partlist[id][i].partcount = nbtext;
7067 townname->partlist[id][i].parts = xcalloct<NamePart>(nbtext);
7068 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);
7070 for (int j = 0; j < nbtext; j++) {
7071 byte prob = buf->ReadByte();
7073 if (HasBit(prob, 7)) {
7074 byte ref_id = buf->ReadByte();
7076 if (townname->nbparts[ref_id] == 0) {
7077 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7078 DelGRFTownName(grfid);
7079 DisableCur (STR_NEWGRF_ERROR_INVALID_ID);
7080 return -1;
7083 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7084 townname->partlist[id][i].parts[j].data.id = ref_id;
7085 } else {
7086 const char *text = buf->ReadString();
7087 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
7088 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
7090 townname->partlist[id][i].parts[j].prob = prob;
7091 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
7093 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
7096 return 0;
7099 /** Action 0x10 - Define goto label */
7100 static int DefineGotoLabel (ByteReader *buf)
7102 /* <10> <label> [<comment>]
7104 * B label The label to define
7105 * V comment Optional comment - ignored */
7107 byte nfo_label = buf->ReadByte();
7109 GRFLabel *label = xmalloct<GRFLabel>();
7110 label->label = nfo_label;
7111 label->nfo_line = _cur.nfo_line;
7112 label->pos = FioGetPos();
7113 label->next = NULL;
7115 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7116 if (_cur.grffile->label == NULL) {
7117 _cur.grffile->label = label;
7118 } else {
7119 /* Attach the label to the end of the list */
7120 GRFLabel *l;
7121 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
7122 l->next = label;
7125 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7127 return 0;
7131 * Process a sound import from another GRF file.
7132 * @param sound Destination for sound.
7134 static void ImportGRFSound(SoundEntry *sound)
7136 const GRFFile *file;
7137 uint32 grfid = FioReadDword();
7138 SoundID sound_id = FioReadWord();
7140 file = GetFileByGRFID(grfid);
7141 if (file == NULL || file->sound_offset == 0) {
7142 grfmsg(1, "ImportGRFSound: Source file not available");
7143 return;
7146 if (sound_id >= file->num_sounds) {
7147 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
7148 return;
7151 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7153 *sound = *GetSound(file->sound_offset + sound_id);
7155 /* Reset volume and priority, which TTDPatch doesn't copy */
7156 sound->volume = 128;
7157 sound->priority = 0;
7161 * Load a sound from a file.
7162 * @param offs File offset to read sound from.
7163 * @param sound Destination for sound.
7165 static void LoadGRFSound(size_t offs, SoundEntry *sound)
7167 /* Set default volume and priority */
7168 sound->volume = 0x80;
7169 sound->priority = 0;
7171 if (offs != SIZE_MAX) {
7172 /* Sound is present in the NewGRF. */
7173 sound->file_slot = _cur.file_index;
7174 sound->file_offset = offs;
7175 sound->grf_container_ver = _cur.grf_container_ver;
7179 /* Action 0x11 */
7180 static int GRFSound (ByteReader *buf)
7182 /* <11> <num>
7184 * W num Number of sound files that follow */
7186 uint16 num = buf->ReadWord();
7187 if (num == 0) return 0;
7189 SoundEntry *sound;
7190 if (_cur.grffile->sound_offset == 0) {
7191 _cur.grffile->sound_offset = GetNumSounds();
7192 _cur.grffile->num_sounds = num;
7193 sound = AllocateSound(num);
7194 } else {
7195 sound = GetSound(_cur.grffile->sound_offset);
7198 for (int i = 0; i < num; i++) {
7199 _cur.nfo_line++;
7201 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7202 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7203 bool invalid = i >= _cur.grffile->num_sounds;
7205 size_t offs = FioGetPos();
7207 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7208 byte type = FioReadByte();
7210 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7211 /* Reference to sprite section. */
7212 if (invalid) {
7213 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7214 FioSkipBytes(len);
7215 } else if (len != 4) {
7216 grfmsg(1, "GRFSound: Invalid sprite section import");
7217 FioSkipBytes(len);
7218 } else {
7219 uint32 id = FioReadDword();
7220 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7222 continue;
7225 if (type != 0xFF) {
7226 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7227 SkipSpriteData (type, len);
7228 continue;
7231 if (invalid) {
7232 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7233 FioSkipBytes(len);
7236 byte action = FioReadByte();
7237 switch (action) {
7238 case 0xFF:
7239 /* Allocate sound only in init stage. */
7240 if (_cur.stage == GLS_INIT) {
7241 if (_cur.grf_container_ver >= 2) {
7242 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7243 } else {
7244 LoadGRFSound(offs, sound + i);
7247 FioSkipBytes(len - 1); // already read <action>
7248 break;
7250 case 0xFE:
7251 if (_cur.stage == GLS_ACTIVATION) {
7252 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7253 * importing sounds, so this is probably all wrong... */
7254 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7255 ImportGRFSound(sound + i);
7256 } else {
7257 FioSkipBytes(len - 1); // already read <action>
7259 break;
7261 default:
7262 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7263 FioSkipBytes(len - 1); // already read <action>
7264 break;
7268 return 0;
7271 /* Action 0x11 (SKIP) */
7272 static int SkipAct11 (ByteReader *buf)
7274 /* <11> <num>
7276 * W num Number of sound files that follow */
7278 int skip = buf->ReadWord();
7279 grfmsg (3, "SkipAct11: Skipping %d sprites", skip);
7280 return skip;
7283 /** Action 0x12 */
7284 static int LoadFontGlyph (ByteReader *buf)
7286 /* <12> <num_def> <font_size> <num_char> <base_char>
7288 * B num_def Number of definitions
7289 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7290 * B num_char Number of consecutive glyphs
7291 * W base_char First character index */
7293 uint8 num_def = buf->ReadByte();
7295 for (uint i = 0; i < num_def; i++) {
7296 FontSize size = (FontSize)buf->ReadByte();
7297 uint8 num_char = buf->ReadByte();
7298 uint16 base_char = buf->ReadWord();
7300 FontCache *fc;
7301 if (size >= FS_END) {
7302 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7303 fc = NULL;
7304 } else {
7305 fc = FontCache::Get (size);
7308 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7310 for (uint c = 0; c < num_char; c++) {
7311 if (fc != NULL) fc->SetUnicodeGlyph (base_char + c, _cur.spriteid);
7312 _cur.nfo_line++;
7313 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7317 return 0;
7320 /** Action 0x12 (SKIP) */
7321 static int SkipAct12 (ByteReader *buf)
7323 /* <12> <num_def> <font_size> <num_char> <base_char>
7325 * B num_def Number of definitions
7326 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7327 * B num_char Number of consecutive glyphs
7328 * W base_char First character index */
7330 uint8 num_def = buf->ReadByte();
7332 int skip = 0;
7333 for (uint i = 0; i < num_def; i++) {
7334 /* Ignore 'size' byte */
7335 buf->ReadByte();
7337 /* Sum up number of characters */
7338 skip += buf->ReadByte();
7340 /* Ignore 'base_char' word */
7341 buf->ReadWord();
7344 grfmsg (3, "SkipAct12: Skipping %d sprites", skip);
7346 return skip;
7349 /** Action 0x13 */
7350 static int TranslateGRFStrings (ByteReader *buf)
7352 /* <13> <grfid> <num-ent> <offset> <text...>
7354 * 4*B grfid The GRFID of the file whose texts are to be translated
7355 * B num-ent Number of strings
7356 * W offset First text ID
7357 * S text... Zero-terminated strings */
7359 uint32 grfid = buf->ReadDWord();
7360 const GRFConfig *c = GetGRFConfig(grfid);
7361 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7362 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7363 return 0;
7366 if (c->status == GCS_INITIALISED) {
7367 /* If the file is not active but will be activated later, give an error
7368 * and disable this file. */
7369 GRFError *error = DisableCur (STR_NEWGRF_ERROR_LOAD_AFTER);
7371 char tmp[256];
7372 GetString (tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE);
7373 error->data = xstrdup(tmp);
7375 return -1;
7378 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7379 * to be added as a generic string, thus the language id of 0x7F. For this to work
7380 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7381 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7382 * not change anything if a string has been provided specifically for this language. */
7383 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7384 byte num_strings = buf->ReadByte();
7385 uint16 first_id = buf->ReadWord();
7387 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7388 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7389 return 0;
7392 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7393 const char *string = buf->ReadString();
7395 if (StrEmpty(string)) {
7396 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7397 continue;
7400 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7403 return 0;
7406 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7407 static bool ChangeGRFName(byte langid, const char *str)
7409 _cur.grfconfig->name->add (langid, _cur.grfconfig->ident.grfid, false, str);
7410 return true;
7413 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7414 static bool ChangeGRFDescription(byte langid, const char *str)
7416 _cur.grfconfig->info->add (langid, _cur.grfconfig->ident.grfid, true, str);
7417 return true;
7420 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7421 static bool ChangeGRFURL(byte langid, const char *str)
7423 _cur.grfconfig->url->add (langid, _cur.grfconfig->ident.grfid, false, str);
7424 return true;
7427 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7428 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7430 if (len != 1) {
7431 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7432 buf->Skip(len);
7433 } else {
7434 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7436 return true;
7439 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7440 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7442 if (len != 1) {
7443 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7444 buf->Skip(len);
7445 } else {
7446 char data = buf->ReadByte();
7447 GRFPalette pal = GRFP_GRF_UNSET;
7448 switch (data) {
7449 case '*':
7450 case 'A': pal = GRFP_GRF_ANY; break;
7451 case 'W': pal = GRFP_GRF_WINDOWS; break;
7452 case 'D': pal = GRFP_GRF_DOS; break;
7453 default:
7454 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7455 break;
7457 if (pal != GRFP_GRF_UNSET) {
7458 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7459 _cur.grfconfig->palette |= pal;
7462 return true;
7465 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7466 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7468 if (len != 1) {
7469 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7470 buf->Skip(len);
7471 } else {
7472 char data = buf->ReadByte();
7473 GRFPalette pal = GRFP_BLT_UNSET;
7474 switch (data) {
7475 case '8': pal = GRFP_BLT_UNSET; break;
7476 case '3': pal = GRFP_BLT_32BPP; break;
7477 default:
7478 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7479 return true;
7481 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7482 _cur.grfconfig->palette |= pal;
7484 return true;
7487 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7488 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7490 if (len != 4) {
7491 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7492 buf->Skip(len);
7493 } else {
7494 /* Set min_loadable_version as well (default to minimal compatibility) */
7495 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7497 return true;
7500 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7501 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7503 if (len != 4) {
7504 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7505 buf->Skip(len);
7506 } else {
7507 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7508 if (_cur.grfconfig->version == 0) {
7509 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7510 _cur.grfconfig->min_loadable_version = 0;
7512 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7513 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7514 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
7517 return true;
7520 static GRFParameterInfo *_cur_parameter; ///< The parameter which info is currently changed by the newgrf.
7522 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7523 static bool ChangeGRFParamName(byte langid, const char *str)
7525 _cur_parameter->name.add (langid, _cur.grfconfig->ident.grfid, false, str);
7526 return true;
7529 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7530 static bool ChangeGRFParamDescription(byte langid, const char *str)
7532 _cur_parameter->desc.add (langid, _cur.grfconfig->ident.grfid, true, str);
7533 return true;
7536 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7537 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7539 if (len != 1) {
7540 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7541 buf->Skip(len);
7542 } else {
7543 GRFParameterType type = (GRFParameterType)buf->ReadByte();
7544 if (type < PTYPE_END) {
7545 _cur_parameter->type = type;
7546 } else {
7547 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7550 return true;
7553 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7554 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7556 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7557 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7558 buf->Skip(len);
7559 } else if (len != 8) {
7560 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7561 buf->Skip(len);
7562 } else {
7563 _cur_parameter->min_value = buf->ReadDWord();
7564 _cur_parameter->max_value = buf->ReadDWord();
7566 return true;
7569 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7570 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7572 if (len < 1 || len > 3) {
7573 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7574 buf->Skip(len);
7575 } else {
7576 byte param_nr = buf->ReadByte();
7577 if (param_nr >= lengthof(_cur.grfconfig->param)) {
7578 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7579 buf->Skip(len - 1);
7580 } else {
7581 _cur_parameter->param_nr = param_nr;
7582 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
7583 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7587 return true;
7590 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7591 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7593 if (len != 4) {
7594 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7595 buf->Skip(len);
7596 } else {
7597 _cur_parameter->def_value = buf->ReadDWord();
7599 _cur.grfconfig->has_param_defaults = true;
7600 return true;
7604 * Data structure to store the allowed id/type combinations for action 14. The
7605 * data can be represented as a tree with 3 types of nodes:
7606 * 1. Branch nodes (identified by 'C' for choice).
7607 * 2. Binary leaf nodes (identified by 'B').
7608 * 3. Text leaf nodes (identified by 'T').
7610 struct AllowedSubtags {
7611 typedef bool (*DataHandler) (size_t, ByteReader *); ///< Type of callback function for binary nodes
7612 typedef bool (*TextHandler) (byte, const char *str); ///< Type of callback function for text nodes
7613 typedef bool (*BranchHandler) (ByteReader *); ///< Type of callback function for branch nodes
7615 uint32 id; ///< The identifier for this node
7616 byte type; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7617 byte nsub; ///< The number of subtags, or 0 if not applicable
7618 union {
7619 DataHandler data; ///< Callback function for a binary node, only valid if type == 'B'.
7620 TextHandler text; ///< Callback function for a text node, only valid if type == 'T'.
7621 BranchHandler branch; ///< Callback function for a branch node, only valid if type == 'C' && nsub == 0.
7622 const AllowedSubtags *subtags; ///< Pointer to a list of subtags, only valid if type == 'C' && nsub != 0.
7625 /** Create empty subtags object used to identify the end of a list. */
7626 CONSTEXPR AllowedSubtags() :
7627 id(0), type(0), nsub(0), subtags(NULL)
7631 * Create a binary leaf node.
7632 * @param id The id for this node.
7633 * @param handler The callback function to call.
7635 CONSTEXPR AllowedSubtags (uint32 id, DataHandler handler) :
7636 id(id), type('B'), nsub(0), data(handler)
7641 * Create a text leaf node.
7642 * @param id The id for this node.
7643 * @param handler The callback function to call.
7645 CONSTEXPR AllowedSubtags (uint32 id, TextHandler handler) :
7646 id(id), type('T'), nsub(0), text(handler)
7651 * Create a branch node with a callback handler
7652 * @param id The id for this node.
7653 * @param handler The callback function to call.
7655 CONSTEXPR AllowedSubtags (uint32 id, BranchHandler handler) :
7656 id(id), type('C'), nsub(0), branch(handler)
7661 * Create a branch node with a list of sub-nodes.
7662 * @param id The id for this node.
7663 * @param subtags Array with all valid subtags.
7665 template <uint N>
7666 CONSTEXPR AllowedSubtags (uint32 id, const AllowedSubtags (&subtags) [N]) :
7667 id(id), type('C'), nsub(N), subtags(subtags)
7669 assert_tcompile (N > 0);
7670 assert_tcompile (N <= UINT8_MAX);
7674 static bool SkipUnknownInfo(ByteReader *buf, byte type);
7675 static bool HandleNodes(ByteReader *buf, const AllowedSubtags *tags);
7678 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7679 * of some parameter values (type uint/enum) or the names of some bits
7680 * (type bitmask). In both cases the format is the same:
7681 * Each subnode should be a text node with the value/bit number as id.
7683 static bool ChangeGRFParamValueNames(ByteReader *buf)
7685 for (;;) {
7686 byte type = buf->ReadByte();
7687 if (type == 0) break;
7689 uint32 id = buf->ReadDWord();
7690 if (type != 'T' || id > _cur_parameter->max_value) {
7691 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7692 if (!SkipUnknownInfo(buf, type)) return false;
7693 continue;
7696 byte langid = buf->ReadByte();
7697 const char *name_string = buf->ReadString();
7699 _cur_parameter->value_names[id].add (langid,
7700 _cur.grfconfig->ident.grfid, false, name_string);
7702 return true;
7705 /** Action14 parameter tags */
7706 static const AllowedSubtags _tags_parameters[] = {
7707 AllowedSubtags('NAME', ChangeGRFParamName),
7708 AllowedSubtags('DESC', ChangeGRFParamDescription),
7709 AllowedSubtags('TYPE', ChangeGRFParamType),
7710 AllowedSubtags('LIMI', ChangeGRFParamLimits),
7711 AllowedSubtags('MASK', ChangeGRFParamMask),
7712 AllowedSubtags('VALU', ChangeGRFParamValueNames),
7713 AllowedSubtags('DFLT', ChangeGRFParamDefault),
7714 AllowedSubtags()
7718 * Callback function for 'INFO'->'PARA' to set extra information about the
7719 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7720 * the parameter number as id. The first parameter has id 0. The maximum
7721 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7723 static bool HandleParameterInfo(ByteReader *buf)
7725 for (;;) {
7726 byte type = buf->ReadByte();
7727 if (type == 0) break;
7729 uint32 id = buf->ReadDWord();
7730 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
7731 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7732 if (!SkipUnknownInfo(buf, type)) return false;
7733 continue;
7736 if (id >= _cur.grfconfig->param_info.Length()) {
7737 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
7738 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
7739 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
7741 if (_cur.grfconfig->param_info[id] == NULL) {
7742 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
7744 _cur_parameter = _cur.grfconfig->param_info[id];
7745 /* Read all parameter-data and process each node. */
7746 if (!HandleNodes(buf, _tags_parameters)) return false;
7748 return true;
7751 /** Action14 tags for the INFO node */
7752 static const AllowedSubtags _tags_info[] = {
7753 AllowedSubtags('NAME', ChangeGRFName),
7754 AllowedSubtags('DESC', ChangeGRFDescription),
7755 AllowedSubtags('URL_', ChangeGRFURL),
7756 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
7757 AllowedSubtags('PALS', ChangeGRFPalette),
7758 AllowedSubtags('BLTR', ChangeGRFBlitter),
7759 AllowedSubtags('VRSN', ChangeGRFVersion),
7760 AllowedSubtags('MINV', ChangeGRFMinVersion),
7761 AllowedSubtags('PARA', HandleParameterInfo),
7762 AllowedSubtags()
7765 /** Action14 root tags */
7766 static const AllowedSubtags _tags_root[] = {
7767 AllowedSubtags('INFO', _tags_info),
7768 AllowedSubtags()
7773 * Try to skip the current node and all subnodes (if it's a branch node).
7774 * @param buf Buffer.
7775 * @param type The node type to skip.
7776 * @return True if we could skip the node, false if an error occurred.
7778 static bool SkipUnknownInfo(ByteReader *buf, byte type)
7780 /* type and id are already read */
7781 switch (type) {
7782 case 'C':
7783 for (;;) {
7784 byte new_type = buf->ReadByte();
7785 if (new_type == 0) break;
7786 buf->ReadDWord(); // skip the id
7787 if (!SkipUnknownInfo(buf, new_type)) return false;
7789 break;
7791 case 'T':
7792 buf->ReadByte(); // lang
7793 buf->ReadString(); // actual text
7794 break;
7796 case 'B': {
7797 uint16 size = buf->ReadWord();
7798 buf->Skip(size);
7799 break;
7802 default:
7803 return false;
7806 return true;
7810 * Handle the nodes of an Action14
7811 * @param type Type of node.
7812 * @param id ID.
7813 * @param buf Buffer.
7814 * @param subtags Allowed subtags.
7815 * @return Whether all tags could be handled.
7817 static bool HandleNode (byte type, uint32 id, ByteReader *buf, const AllowedSubtags *subtags)
7819 for (const AllowedSubtags *tag = subtags; tag->type != 0; tag++) {
7820 if (tag->id != BSWAP32(id) || tag->type != type) continue;
7821 switch (type) {
7822 default: NOT_REACHED();
7824 case 'T': {
7825 byte langid = buf->ReadByte();
7826 return tag->text (langid, buf->ReadString());
7829 case 'B': {
7830 size_t len = buf->ReadWord();
7831 if (!buf->HasData (len)) return false;
7832 return tag->data (len, buf);
7835 case 'C': {
7836 if (tag->nsub == 0) {
7837 return tag->branch (buf);
7839 return HandleNodes (buf, tag->subtags);
7843 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
7844 return SkipUnknownInfo(buf, type);
7848 * Handle the contents of a 'C' choice of an Action14
7849 * @param buf Buffer.
7850 * @param subtags List of subtags.
7851 * @return Whether the nodes could all be handled.
7853 static bool HandleNodes (ByteReader *buf, const AllowedSubtags *subtags)
7855 for (;;) {
7856 byte type = buf->ReadByte();
7857 if (type == 0) break;
7858 uint32 id = buf->ReadDWord();
7859 if (!HandleNode(type, id, buf, subtags)) return false;
7861 return true;
7865 * Handle Action 0x14
7866 * @param buf Buffer.
7868 static int StaticGRFInfo (ByteReader *buf)
7870 /* <14> <type> <id> <text/data...> */
7871 HandleNodes(buf, _tags_root);
7872 return 0;
7876 * Set the current NewGRF as unsafe for static use
7877 * @param buf Unused.
7878 * @note Used during safety scan on unsafe actions.
7880 static int GRFUnsafe (ByteReader *buf)
7882 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7884 /* Skip remainder of GRF */
7885 return -1;
7889 /** Initialize the TTDPatch flags */
7890 static void InitializeGRFSpecial()
7892 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
7893 | (1 << 0x0D) // newairports
7894 | (1 << 0x0E) // largestations
7895 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
7896 | (0 << 0x10) // loadtime
7897 | (1 << 0x12) // presignals
7898 | (1 << 0x13) // extpresignals
7899 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
7900 | (1 << 0x1B) // multihead
7901 | (1 << 0x1D) // lowmemory
7902 | (1 << 0x1E); // generalfixes
7904 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
7905 | (1 << 0x08) // mammothtrains
7906 | (1 << 0x09) // trainrefit
7907 | (0 << 0x0B) // subsidiaries
7908 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
7909 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7910 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7911 | (1 << 0x14) // bridgespeedlimits
7912 | (1 << 0x16) // eternalgame
7913 | (1 << 0x17) // newtrains
7914 | (1 << 0x18) // newrvs
7915 | (1 << 0x19) // newships
7916 | (1 << 0x1A) // newplanes
7917 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7918 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
7920 _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
7921 | (1 << 0x03) // semaphores
7922 | (1 << 0x0A) // newobjects
7923 | (0 << 0x0B) // enhancedgui
7924 | (0 << 0x0C) // newagerating
7925 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
7926 | (1 << 0x0E) // fullloadany
7927 | (1 << 0x0F) // planespeed
7928 | (0 << 0x10) // moreindustriesperclimate - obsolete
7929 | (0 << 0x11) // moretoylandfeatures
7930 | (1 << 0x12) // newstations
7931 | (1 << 0x13) // tracktypecostdiff
7932 | (1 << 0x14) // manualconvert
7933 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
7934 | (1 << 0x16) // canals
7935 | (1 << 0x17) // newstartyear
7936 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
7937 | (1 << 0x19) // newhouses
7938 | (1 << 0x1A) // newbridges
7939 | (1 << 0x1B) // newtownnames
7940 | (1 << 0x1C) // moreanimation
7941 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
7942 | (1 << 0x1E) // newshistory
7943 | (0 << 0x1F); // custombridgeheads
7945 _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
7946 | (1 << 0x01) // windowsnap
7947 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
7948 | (1 << 0x03) // pathbasedsignalling
7949 | (0 << 0x04) // aichoosechance
7950 | (1 << 0x05) // resolutionwidth
7951 | (1 << 0x06) // resolutionheight
7952 | (1 << 0x07) // newindustries
7953 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
7954 | (0 << 0x09) // townroadbranchprob
7955 | (0 << 0x0A) // tempsnowline
7956 | (1 << 0x0B) // newcargo
7957 | (1 << 0x0C) // enhancemultiplayer
7958 | (1 << 0x0D) // onewayroads
7959 | (1 << 0x0E) // irregularstations
7960 | (1 << 0x0F) // statistics
7961 | (1 << 0x10) // newsounds
7962 | (1 << 0x11) // autoreplace
7963 | (1 << 0x12) // autoslope
7964 | (0 << 0x13) // followvehicle
7965 | (1 << 0x14) // trams
7966 | (0 << 0x15) // enhancetunnels
7967 | (1 << 0x16) // shortrvs
7968 | (1 << 0x17) // articulatedrvs
7969 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
7970 | (1 << 0x1E) // variablerunningcosts
7971 | (1 << 0x1F); // any switch is on
7974 /** Reset and clear all NewGRF stations */
7975 static void ResetCustomStations()
7977 const GRFFile * const *end = _grf_files.End();
7978 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7979 StationSpec **&stations = (*file)->stations;
7980 if (stations == NULL) continue;
7981 for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
7982 if (stations[i] == NULL) continue;
7983 StationSpec *statspec = stations[i];
7985 /* Release this station */
7986 delete statspec;
7989 /* Free and reset the station data */
7990 free(stations);
7991 stations = NULL;
7995 /** Reset and clear all NewGRF houses */
7996 static void ResetCustomHouses()
7998 const GRFFile * const *end = _grf_files.End();
7999 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8000 HouseSpec **&housespec = (*file)->housespec;
8001 if (housespec == NULL) continue;
8002 for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8003 free(housespec[i]);
8006 free(housespec);
8007 housespec = NULL;
8011 /** Reset and clear all NewGRF airports */
8012 static void ResetCustomAirports()
8014 const GRFFile * const *end = _grf_files.End();
8015 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8016 AirportSpec **aslist = (*file)->airportspec;
8017 if (aslist != NULL) {
8018 for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8019 AirportSpec *as = aslist[i];
8021 if (as != NULL) {
8022 /* We need to remove the tiles layouts */
8023 for (int j = 0; j < as->num_table; j++) {
8024 /* remove the individual layouts */
8025 free(as->table[j]);
8027 free(as->table);
8029 free(as);
8032 free(aslist);
8033 (*file)->airportspec = NULL;
8036 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8037 if (airporttilespec != NULL) {
8038 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8039 free(airporttilespec[i]);
8041 free(airporttilespec);
8042 airporttilespec = NULL;
8047 /** Reset and clear all NewGRF industries */
8048 static void ResetCustomIndustries()
8050 const GRFFile * const *end = _grf_files.End();
8051 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8052 IndustrySpec **&industryspec = (*file)->industryspec;
8053 IndustryTileSpec **&indtspec = (*file)->indtspec;
8055 /* We are verifiying both tiles and industries specs loaded from the grf file
8056 * First, let's deal with industryspec */
8057 if (industryspec != NULL) {
8058 for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8059 IndustrySpec *ind = industryspec[i];
8060 if (ind == NULL) continue;
8062 /* We need to remove the sounds array */
8063 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
8064 free(ind->random_sounds);
8067 /* We need to remove the tiles layouts */
8068 CleanIndustryTileTable(ind);
8070 free(ind);
8073 free(industryspec);
8074 industryspec = NULL;
8077 if (indtspec == NULL) continue;
8078 for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8079 free(indtspec[i]);
8082 free(indtspec);
8083 indtspec = NULL;
8087 /** Reset and clear all NewObjects */
8088 static void ResetCustomObjects()
8090 const GRFFile * const *end = _grf_files.End();
8091 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8092 ObjectSpec **&objectspec = (*file)->objectspec;
8093 if (objectspec == NULL) continue;
8094 for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8095 free(objectspec[i]);
8098 free(objectspec);
8099 objectspec = NULL;
8103 /** Reset and clear all NewGRFs */
8104 static void ResetNewGRF()
8106 const GRFFile * const *end = _grf_files.End();
8107 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8108 delete *file;
8111 _grf_files.Clear();
8112 _cur.grffile = NULL;
8115 /** Clear all NewGRF errors */
8116 static void ResetNewGRFErrors()
8118 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
8119 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
8120 delete c->error;
8121 c->error = NULL;
8127 * Reset all NewGRF loaded data
8128 * TODO
8130 void ResetNewGRFData()
8132 CleanUpStrings();
8133 CleanUpGRFTownNames();
8135 /* Copy/reset original engine info data */
8136 SetupEngines();
8138 /* Copy/reset original bridge info data */
8139 ResetBridges();
8141 /* Reset rail type information */
8142 ResetRailTypes();
8144 /* Allocate temporary refit/cargo class data */
8145 _gted = xcalloct<GRFTempEngineData>(Engine::GetPoolSize());
8147 /* Fill rail type label temporary data for default trains */
8148 Engine *e;
8149 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
8150 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
8153 /* Reset GRM reservations */
8154 memset(&_grm_engines, 0, sizeof(_grm_engines));
8155 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
8157 /* Reset generic feature callback lists */
8158 ResetGenericCallbacks();
8160 /* Reset price base data */
8161 ResetPriceBaseMultipliers();
8163 /* Reset the curencies array */
8164 ResetCurrencies();
8166 /* Reset the house array */
8167 ResetCustomHouses();
8168 ResetHouses();
8170 /* Reset the industries structures*/
8171 ResetCustomIndustries();
8172 ResetIndustries();
8174 /* Reset the objects. */
8175 ObjectClass::Reset();
8176 ResetCustomObjects();
8177 ResetObjects();
8179 /* Reset station classes */
8180 StationClass::Reset();
8181 ResetCustomStations();
8183 /* Reset airport-related structures */
8184 AirportClass::Reset();
8185 ResetCustomAirports();
8186 AirportSpec::ResetAirports();
8187 AirportTileSpec::ResetAirportTiles();
8189 /* Reset canal sprite groups and flags */
8190 memset(_water_feature, 0, sizeof(_water_feature));
8192 /* Reset the snowline table. */
8193 ClearSnowLine();
8195 /* Reset NewGRF files */
8196 ResetNewGRF();
8198 /* Reset NewGRF errors. */
8199 ResetNewGRFErrors();
8201 /* Set up the default cargo types */
8202 SetupCargoForClimate(_settings_game.game_creation.landscape);
8204 /* Reset misc GRF features and train list display variables */
8205 _misc_grf_features = 0;
8207 _loaded_newgrf_features.has_2CC = false;
8208 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8209 _loaded_newgrf_features.has_newhouses = false;
8210 _loaded_newgrf_features.has_newindustries = false;
8211 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
8213 /* Clear all GRF overrides */
8214 _grf_id_overrides.clear();
8216 InitializeSoundPool();
8217 SpriteGroup::clear();
8221 * Reset NewGRF data which is stored persistently in savegames.
8223 void ResetPersistentNewGRFData()
8225 /* Reset override managers */
8226 _engine_mngr.ResetToDefaultMapping();
8227 _house_mngr.ResetMapping();
8228 _industry_mngr.ResetMapping();
8229 _industile_mngr.ResetMapping();
8230 _airport_mngr.ResetMapping();
8231 _airporttile_mngr.ResetMapping();
8235 * Construct the Cargo Mapping
8236 * @note This is the reverse of a cargo translation table
8238 static void BuildCargoTranslationMap()
8240 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8242 for (CargoID c = 0; c < NUM_CARGO; c++) {
8243 const CargoSpec *cs = CargoSpec::Get(c);
8244 if (!cs->IsValid()) continue;
8246 if (_cur.grffile->cargo_list.Length() == 0) {
8247 /* Default translation table, so just a straight mapping to bitnum */
8248 _cur.grffile->cargo_map[c] = cs->bitnum;
8249 } else {
8250 /* Check the translation table for this cargo's label */
8251 int index = _cur.grffile->cargo_list.FindIndex(cs->label);
8252 if (index >= 0) _cur.grffile->cargo_map[c] = index;
8258 * Constructor for GRFFile
8259 * @param config GRFConfig to copy name, grfid and parameters from.
8261 GRFFile::GRFFile(const GRFConfig *config)
8263 this->filename = xstrdup(config->filename);
8264 this->grfid = config->ident.grfid;
8266 /* Initialise local settings to defaults */
8267 this->traininfo_vehicle_pitch = 0;
8268 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8270 /* Mark price_base_multipliers as 'not set' */
8271 for (Price i = PR_BEGIN; i < PR_END; i++) {
8272 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8275 /* Initialise rail type map with default rail types */
8276 memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
8277 this->railtype_map[0] = RAILTYPE_RAIL;
8278 this->railtype_map[1] = RAILTYPE_ELECTRIC;
8279 this->railtype_map[2] = RAILTYPE_MONO;
8280 this->railtype_map[3] = RAILTYPE_MAGLEV;
8282 /* Copy the initial parameter list
8283 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8284 assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8286 assert(config->num_params <= lengthof(config->param));
8287 this->param_end = config->num_params;
8288 if (this->param_end > 0) {
8289 MemCpyT(this->param, config->param, this->param_end);
8293 GRFFile::~GRFFile()
8295 free(this->filename);
8296 delete[] this->language_map;
8301 * List of what cargo labels are refittable for the given the vehicle-type.
8302 * Only currently active labels are applied.
8304 static const CargoLabel _default_refitmasks_rail[] = {
8305 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8306 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8307 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8308 'PLST', 'FZDR',
8309 0 };
8311 static const CargoLabel _default_refitmasks_road[] = {
8312 0 };
8314 static const CargoLabel _default_refitmasks_ships[] = {
8315 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8316 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8317 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8318 'PLST', 'FZDR',
8319 0 };
8321 static const CargoLabel _default_refitmasks_aircraft[] = {
8322 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8323 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8324 0 };
8326 static const CargoLabel * const _default_refitmasks[] = {
8327 _default_refitmasks_rail,
8328 _default_refitmasks_road,
8329 _default_refitmasks_ships,
8330 _default_refitmasks_aircraft,
8335 * Precalculate refit masks from cargo classes for all vehicles.
8337 static void CalculateRefitMasks()
8339 Engine *e;
8341 FOR_ALL_ENGINES(e) {
8342 EngineID engine = e->index;
8343 EngineInfo *ei = &e->info;
8344 bool only_defaultcargo; ///< Set if the vehicle shall carry only the default cargo
8346 /* Did the newgrf specify any refitting? If not, use defaults. */
8347 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8348 uint32 mask = 0;
8349 uint32 not_mask = 0;
8350 uint32 xor_mask = ei->refit_mask;
8352 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8353 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8354 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8356 if (_gted[engine].cargo_allowed != 0) {
8357 /* Build up the list of cargo types from the set cargo classes. */
8358 const CargoSpec *cs;
8359 FOR_ALL_CARGOSPECS(cs) {
8360 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8361 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8365 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8367 /* Apply explicit refit includes/excludes. */
8368 ei->refit_mask |= _gted[engine].ctt_include_mask;
8369 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8370 } else {
8371 uint32 xor_mask = 0;
8373 /* Don't apply default refit mask to wagons nor engines with no capacity */
8374 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8375 const CargoLabel *cl = _default_refitmasks[e->type];
8376 for (uint i = 0;; i++) {
8377 if (cl[i] == 0) break;
8379 CargoID cargo = GetCargoIDByLabel(cl[i]);
8380 if (cargo == CT_INVALID) continue;
8382 SetBit(xor_mask, cargo);
8386 ei->refit_mask = xor_mask & _cargo_mask;
8388 /* If the mask is zero, the vehicle shall only carry the default cargo */
8389 only_defaultcargo = (ei->refit_mask == 0);
8392 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8393 if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8395 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8396 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8397 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8398 ei->cargo_type = CT_INVALID;
8401 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8402 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8403 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8404 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8405 const uint8 *cargo_map_for_first_refittable = NULL;
8407 const GRFFile *file = _gted[engine].defaultcargo_grf;
8408 if (file == NULL) file = e->GetGRF();
8409 if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
8410 cargo_map_for_first_refittable = file->cargo_map;
8414 if (cargo_map_for_first_refittable != NULL) {
8415 /* Use first refittable cargo from cargo translation table */
8416 byte best_local_slot = 0xFF;
8417 CargoID cargo_type;
8418 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8419 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8420 if (local_slot < best_local_slot) {
8421 best_local_slot = local_slot;
8422 ei->cargo_type = cargo_type;
8427 if (ei->cargo_type == CT_INVALID) {
8428 /* Use first refittable cargo slot */
8429 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8432 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8434 /* Clear refit_mask for not refittable ships */
8435 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8436 ei->refit_mask = 0;
8441 /** Set to use the correct action0 properties for each canal feature */
8442 static void FinaliseCanals()
8444 for (uint i = 0; i < CF_END; i++) {
8445 if (_water_feature[i].grffile != NULL) {
8446 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
8447 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
8452 /** Check for invalid engines */
8453 static void FinaliseEngineArray()
8455 Engine *e;
8457 FOR_ALL_ENGINES(e) {
8458 if (e->GetGRF() == NULL) {
8459 const EngineIDMapping &eid = _engine_mngr[e->index];
8460 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8461 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8465 /* When the train does not set property 27 (misc flags), but it
8466 * is overridden by a NewGRF graphically we want to disable the
8467 * flipping possibility. */
8468 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
8469 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8472 /* Skip wagons, there livery is defined via the engine */
8473 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8474 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
8475 SetBit(_loaded_newgrf_features.used_liveries, ls);
8476 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8478 if (e->type == VEH_TRAIN) {
8479 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8480 switch (ls) {
8481 case LS_STEAM:
8482 case LS_DIESEL:
8483 case LS_ELECTRIC:
8484 case LS_MONORAIL:
8485 case LS_MAGLEV:
8486 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8487 break;
8489 case LS_DMU:
8490 case LS_EMU:
8491 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8492 break;
8494 default: NOT_REACHED();
8501 /** Check for invalid cargoes */
8502 static void FinaliseCargoArray()
8504 for (CargoID c = 0; c < NUM_CARGO; c++) {
8505 CargoSpec *cs = CargoSpec::Get(c);
8506 if (!cs->IsValid()) {
8507 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8508 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8509 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8515 * Check if a given housespec is valid and disable it if it's not.
8516 * The housespecs that follow it are used to check the validity of
8517 * multitile houses.
8518 * @param hs The housespec to check.
8519 * @param next1 The housespec that follows \c hs.
8520 * @param next2 The housespec that follows \c next1.
8521 * @param next3 The housespec that follows \c next2.
8522 * @param filename The filename of the newgrf this house was defined in.
8523 * @return Whether the given housespec is valid.
8525 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8527 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8528 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8529 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8530 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8531 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8532 hs->enabled = false;
8533 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);
8534 return false;
8537 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8538 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8539 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8540 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8541 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8542 hs->enabled = false;
8543 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);
8544 return false;
8547 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8548 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8549 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8550 hs->enabled = false;
8551 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);
8552 return false;
8555 /* Make sure that additional parts of multitile houses are not available. */
8556 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
8557 hs->enabled = false;
8558 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);
8559 return false;
8562 return true;
8566 * Make sure there is at least one house available in the year 0 for the given
8567 * climate.
8568 * @param bitmask The climate to check for. Exactly one climate bit should be
8569 * set.
8571 static void EnsureEarlyHouses (HouseZones climate_mask)
8573 for (uint z = 0; z < HZB_END; z++) {
8574 HouseZones bitmask = (HouseZones)(1U << z) | climate_mask;
8575 Year min_year = MAX_YEAR;
8577 for (int i = 0; i < NUM_HOUSES; i++) {
8578 const HouseSpec *hs = HouseSpec::Get(i);
8579 if (hs == NULL || !hs->enabled) continue;
8580 if ((hs->building_availability & bitmask) != bitmask) continue;
8581 if (hs->min_year < min_year) min_year = hs->min_year;
8584 if (min_year == 0) continue;
8586 for (int i = 0; i < NUM_HOUSES; i++) {
8587 HouseSpec *hs = HouseSpec::Get(i);
8588 if (hs == NULL || !hs->enabled) continue;
8589 if ((hs->building_availability & bitmask) != bitmask) continue;
8590 if (hs->min_year == min_year) hs->min_year = 0;
8596 * Add all new houses to the house array. House properties can be set at any
8597 * time in the GRF file, so we can only add a house spec to the house array
8598 * after the file has finished loading. We also need to check the dates, due to
8599 * the TTDPatch behaviour described below that we need to emulate.
8601 static void FinaliseHouseArray()
8603 /* If there are no houses with start dates before 1930, then all houses
8604 * with start dates of 1930 have them reset to 0. This is in order to be
8605 * compatible with TTDPatch, where if no houses have start dates before
8606 * 1930 and the date is before 1930, the game pretends that this is 1930.
8607 * If there have been any houses defined with start dates before 1930 then
8608 * the dates are left alone.
8609 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8610 * minimum introduction date to 0.
8612 const GRFFile * const *end = _grf_files.End();
8613 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8614 HouseSpec **&housespec = (*file)->housespec;
8615 if (housespec == NULL) continue;
8617 for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8618 HouseSpec *hs = housespec[i];
8620 if (hs == NULL) continue;
8622 const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : NULL);
8623 const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : NULL);
8624 const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : NULL);
8626 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
8628 _house_mngr.SetEntitySpec(hs);
8632 for (int i = 0; i < NUM_HOUSES; i++) {
8633 HouseSpec *hs = HouseSpec::Get(i);
8634 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : NULL);
8635 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : NULL);
8636 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : NULL);
8638 /* We need to check all houses again to we are sure that multitile houses
8639 * did get consecutive IDs and none of the parts are missing. */
8640 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
8641 /* GetHouseNorthPart checks 3 houses that are directly before
8642 * it in the house pool. If any of those houses have multi-tile
8643 * flags set it assumes it's part of a multitile house. Since
8644 * we can have invalid houses in the pool marked as disabled, we
8645 * don't want to have them influencing valid tiles. As such set
8646 * building_flags to zero here to make sure any house following
8647 * this one in the pool is properly handled as 1x1 house. */
8648 hs->building_flags = TILE_NO_FLAG;
8652 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
8653 EnsureEarlyHouses (climate_mask);
8655 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
8656 EnsureEarlyHouses (HZ_SUBARTC_ABOVE);
8661 * Add all new industries to the industry array. Industry properties can be set at any
8662 * time in the GRF file, so we can only add a industry spec to the industry array
8663 * after the file has finished loading.
8665 static void FinaliseIndustriesArray()
8667 const GRFFile * const *end = _grf_files.End();
8668 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8669 IndustrySpec **&industryspec = (*file)->industryspec;
8670 IndustryTileSpec **&indtspec = (*file)->indtspec;
8671 if (industryspec != NULL) {
8672 for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8673 IndustrySpec *indsp = industryspec[i];
8675 if (indsp != NULL && indsp->enabled) {
8676 StringID strid;
8677 /* process the conversion of text at the end, so to be sure everything will be fine
8678 * and available. Check if it does not return undefind marker, which is a very good sign of a
8679 * substitute industry who has not changed the string been examined, thus using it as such */
8680 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
8681 if (strid != STR_UNDEFINED) indsp->name = strid;
8683 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
8684 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
8686 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
8687 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
8689 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
8690 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
8692 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
8693 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
8695 if (indsp->station_name != STR_NULL) {
8696 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8697 * station's name. Don't want to lose the value, therefore, do not process. */
8698 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
8699 if (strid != STR_UNDEFINED) indsp->station_name = strid;
8702 _industry_mngr.SetEntitySpec(indsp);
8703 _loaded_newgrf_features.has_newindustries = true;
8708 if (indtspec != NULL) {
8709 for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8710 IndustryTileSpec *indtsp = indtspec[i];
8711 if (indtsp != NULL) {
8712 _industile_mngr.SetEntitySpec(indtsp);
8718 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
8719 IndustrySpec *indsp = &_industry_specs[j];
8720 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
8721 for (uint i = 0; i < 3; i++) {
8722 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
8725 if (!indsp->enabled) {
8726 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
8732 * Add all new objects to the object array. Object properties can be set at any
8733 * time in the GRF file, so we can only add an object spec to the object array
8734 * after the file has finished loading.
8736 static void FinaliseObjectsArray()
8738 const GRFFile * const *end = _grf_files.End();
8739 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8740 ObjectSpec **&objectspec = (*file)->objectspec;
8741 if (objectspec != NULL) {
8742 for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8743 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
8744 _object_mngr.SetEntitySpec(objectspec[i]);
8752 * Add all new airports to the airport array. Airport properties can be set at any
8753 * time in the GRF file, so we can only add a airport spec to the airport array
8754 * after the file has finished loading.
8756 static void FinaliseAirportsArray()
8758 const GRFFile * const *end = _grf_files.End();
8759 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8760 AirportSpec **&airportspec = (*file)->airportspec;
8761 if (airportspec != NULL) {
8762 for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8763 if (airportspec[i] != NULL && airportspec[i]->enabled) {
8764 _airport_mngr.SetEntitySpec(airportspec[i]);
8769 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8770 if (airporttilespec != NULL) {
8771 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8772 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
8773 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
8780 /* Here we perform initial decoding of some special sprites (as are they
8781 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8782 * partial implementation yet).
8783 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8784 * a crafted invalid GRF file. We should tell that to the user somehow, or
8785 * better make this more robust in the future. */
8786 static int DecodeSpecialSprite (byte *buf, uint num, GrfLoadingStage stage)
8788 /* XXX: There is a difference between staged loading in TTDPatch and
8789 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8790 * during stage 1, whilst action 3 is carried out during stage 2 (to
8791 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8792 * IDs are valid only within a given set (action 1) block, and may be
8793 * overwritten after action 3 associates them. But overwriting happens
8794 * in an earlier stage than associating, so... We just process actions
8795 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8796 * --pasky
8797 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8798 * is not in memory and scanning the file every time would be too expensive.
8799 * In other stages we skip action 0x10 since it's already dealt with. */
8800 static const SpecialSpriteHandler handlers[][GLS_END] = {
8801 /* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
8802 /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
8803 /* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
8804 /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
8805 /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
8806 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
8807 /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
8808 /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
8809 /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
8810 /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
8811 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
8812 /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
8813 /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
8814 /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
8815 /* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
8816 /* 0x0F */ { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
8817 /* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
8818 /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
8819 /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
8820 /* 0x13 */ { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
8821 /* 0x14 */ { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
8824 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
8826 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
8827 if (it == _grf_line_to_action6_sprite_override.end()) {
8828 /* No preloaded sprite to work with; read the
8829 * pseudo sprite content. */
8830 FioReadBlock(buf, num);
8831 } else {
8832 /* Use the preloaded sprite data. */
8833 buf = it->second.get();
8834 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8836 /* Skip the real (original) content of this action. */
8837 FioSeekTo(num, SEEK_CUR);
8840 ByteReader br(buf, buf + num);
8841 ByteReader *bufp = &br;
8843 try {
8844 byte action = bufp->ReadByte();
8846 if (action == 0xFF) {
8847 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8848 } else if (action == 0xFE) {
8849 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8850 } else if (action >= lengthof(handlers)) {
8851 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
8852 } else if (handlers[action][stage] == NULL) {
8853 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
8854 } else {
8855 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
8856 return handlers[action][stage](bufp);
8858 } catch (...) {
8859 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8860 DisableCur (STR_NEWGRF_ERROR_READ_BOUNDS);
8861 return -1;
8864 return 0;
8868 /** Signature of a container version 2 GRF. */
8869 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8872 * Read the header of a GRF header.
8873 * @param header Struct to fill with data.
8874 * @return Whether the header is valid.
8876 bool ReadGRFHeader (GRFHeader *header)
8878 size_t pos = FioGetPos();
8880 if (FioReadWord() != 0) {
8881 /* Container version 1 has no header, rewind to start. */
8882 FioSeekTo (pos, SEEK_SET);
8884 header->version = 1;
8885 header->sprite_offset = 0;
8886 } else {
8887 /* Check for GRF container version 2, which is identified by the
8888 * bytes '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8889 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
8890 if (FioReadByte() != _grf_cont_v2_sig[i]) return false;
8893 header->version = 2;
8894 uint32 offset = FioReadDword();
8895 header->sprite_offset = offset + FioGetPos();
8897 /* Read compression value. */
8898 if (FioReadByte() != 0) return false;
8901 return true;
8905 * Load a particular NewGRF.
8906 * @param config The configuration of the to be loaded NewGRF.
8907 * @param file_index The Fio index of the first NewGRF to load.
8908 * @param stage The loading stage of the NewGRF.
8909 * @param subdir The sub directory to find the NewGRF in.
8911 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
8913 assert (file_index < MAX_FILE_SLOTS);
8915 const char *filename = config->filename;
8917 FioOpenFile(file_index, filename, subdir);
8918 _cur.file_index = file_index; // XXX
8919 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
8921 _cur.grfconfig = config;
8923 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
8925 GRFHeader header;
8926 if (!ReadGRFHeader (&header)) {
8927 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8928 return;
8931 _cur.grf_container_ver = header.version;
8933 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
8934 /* We need the sprite offsets in the init stage for NewGRF sounds
8935 * and in the activation stage for real sprites. */
8936 ReadGRFSpriteOffsets (&header);
8939 /* Skip the first sprite; we don't care about how many sprites this
8940 * does contain; newest TTDPatches and George's longvehicles don't
8941 * neither, apparently. */
8942 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
8943 if (num == 4 && FioReadByte() == 0xFF) {
8944 FioReadDword();
8945 } else {
8946 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8947 return;
8950 _cur.ClearDataForNextFile();
8952 ReusableBuffer<byte> buf;
8953 int skip_sprites = 0;
8955 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
8956 byte type = FioReadByte();
8957 _cur.nfo_line++;
8959 if (skip_sprites != 0) {
8960 bool skip_real;
8961 switch (type) {
8962 case 0xFF:
8963 skip_real = false;
8964 break;
8965 case 0xFD:
8966 /* Reference to data section. Container version >= 2 only. */
8967 skip_real = (_cur.grf_container_ver < 2);
8968 break;
8969 default:
8970 skip_real = true;
8971 break;
8974 if (skip_real) {
8975 SkipSpriteData (type, num);
8976 } else {
8977 FioSkipBytes (num);
8980 skip_sprites--;
8982 } else if (type == 0xFF) {
8983 skip_sprites = DecodeSpecialSprite (buf.Allocate(num), num, stage);
8985 /* Stop all processing if we are to skip the remaining sprites */
8986 if (skip_sprites == -1) break;
8988 } else {
8989 grfmsg (0, "LoadNewGRFFile: Unexpected sprite, disabling");
8990 DisableCur (STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
8991 break;
8997 * Relocates the old shore sprites at new positions.
8999 * 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)
9000 * 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)
9001 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
9003 static void ActivateOldShore()
9005 /* Use default graphics, if no shore sprites were loaded.
9006 * Should not happen, as the base set's extra grf should include some. */
9007 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
9009 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
9010 for (uint i = 0; i < lengthof(shore_sprites_1); i++) {
9011 DupSprite (shore_sprites_1[i].old, shore_sprites_1[i].spr);
9015 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
9016 for (uint i = 0; i < lengthof(shore_sprites_2); i++) {
9017 DupSprite (shore_sprites_2[i].old, shore_sprites_2[i].spr);
9023 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
9025 static void FinalisePriceBaseMultipliers()
9027 extern const PriceBaseSpec _price_base_specs[];
9028 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
9029 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9031 /* Evaluate grf overrides */
9032 int num_grfs = _grf_files.Length();
9033 int *grf_overrides = AllocaM(int, num_grfs);
9034 for (int i = 0; i < num_grfs; i++) {
9035 grf_overrides[i] = -1;
9037 GRFFile *source = _grf_files[i];
9038 uint32 override = _grf_id_overrides[source->grfid];
9039 if (override == 0) continue;
9041 GRFFile *dest = GetFileByGRFID(override);
9042 if (dest == NULL) continue;
9044 grf_overrides[i] = _grf_files.FindIndex(dest);
9045 assert(grf_overrides[i] >= 0);
9048 /* Override features and price base multipliers of earlier loaded grfs */
9049 for (int i = 0; i < num_grfs; i++) {
9050 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
9051 GRFFile *source = _grf_files[i];
9052 GRFFile *dest = _grf_files[grf_overrides[i]];
9054 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9055 source->grf_features |= features;
9056 dest->grf_features |= features;
9058 for (Price p = PR_BEGIN; p < PR_END; p++) {
9059 /* No price defined -> nothing to do */
9060 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
9061 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9062 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9066 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9067 for (int i = num_grfs - 1; i >= 0; i--) {
9068 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
9069 GRFFile *source = _grf_files[i];
9070 GRFFile *dest = _grf_files[grf_overrides[i]];
9072 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9073 source->grf_features |= features;
9074 dest->grf_features |= features;
9076 for (Price p = PR_BEGIN; p < PR_END; p++) {
9077 /* Already a price defined -> nothing to do */
9078 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
9079 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9080 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9084 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9085 for (int i = 0; i < num_grfs; i++) {
9086 if (grf_overrides[i] < 0) continue;
9087 GRFFile *source = _grf_files[i];
9088 GRFFile *dest = _grf_files[grf_overrides[i]];
9090 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9091 source->grf_features |= features;
9092 dest->grf_features |= features;
9094 for (Price p = PR_BEGIN; p < PR_END; p++) {
9095 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
9096 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
9097 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9099 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
9103 /* Apply fallback prices for grf version < 8 */
9104 const GRFFile * const *end = _grf_files.End();
9105 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9106 if ((*file)->grf_version >= 8) continue;
9107 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9108 for (Price p = PR_BEGIN; p < PR_END; p++) {
9109 Price fallback_price = _price_base_specs[p].fallback_price;
9110 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9111 /* No price multiplier has been set.
9112 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9113 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9118 /* Decide local/global scope of price base multipliers */
9119 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9120 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9121 for (Price p = PR_BEGIN; p < PR_END; p++) {
9122 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9123 /* No multiplier was set; set it to a neutral value */
9124 price_base_multipliers[p] = 0;
9125 } else {
9126 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
9127 /* The grf does not define any objects of the feature,
9128 * so it must be a difficulty setting. Apply it globally */
9129 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
9130 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9131 price_base_multipliers[p] = 0;
9132 } else {
9133 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
9140 extern void InitGRFTownGeneratorNames();
9142 /** Finish loading NewGRFs and execute needed post-processing */
9143 static void AfterLoadGRFs()
9145 for (StringIDMapping *it = _string_to_grf_mapping.Begin(); it != _string_to_grf_mapping.End(); it++) {
9146 *it->target = MapGRFStringID(it->grfid, it->source);
9148 _string_to_grf_mapping.Clear();
9150 /* Free the action 6 override sprites. */
9151 _grf_line_to_action6_sprite_override.clear();
9153 /* Polish cargoes */
9154 FinaliseCargoArray();
9156 /* Pre-calculate all refit masks after loading GRF files. */
9157 CalculateRefitMasks();
9159 /* Polish engines */
9160 FinaliseEngineArray();
9162 /* Set the actually used Canal properties */
9163 FinaliseCanals();
9165 /* Add all new houses to the house array. */
9166 FinaliseHouseArray();
9168 /* Add all new industries to the industry array. */
9169 FinaliseIndustriesArray();
9171 /* Add all new objects to the object array. */
9172 FinaliseObjectsArray();
9174 InitializeSortedCargoSpecs();
9176 /* Sort the list of industry types. */
9177 SortIndustryTypes();
9179 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9180 BuildIndustriesLegend();
9182 /* Build the routemap legend, based on the available cargos */
9183 BuildLinkStatsLegend();
9185 /* Add all new airports to the airports array. */
9186 FinaliseAirportsArray();
9187 BindAirportSpecs();
9189 /* Update the townname generators list */
9190 InitGRFTownGeneratorNames();
9192 /* Run all queued vehicle list order changes */
9193 CommitVehicleListOrderChanges();
9195 /* Load old shore sprites in new position, if they were replaced by ActionA */
9196 ActivateOldShore();
9198 /* Set up custom rail types */
9199 InitRailTypes();
9201 Engine *e;
9202 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
9203 if (_gted[e->index].rv_max_speed != 0) {
9204 /* Set RV maximum speed from the mph/0.8 unit value */
9205 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9209 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
9210 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9211 if (railtype == INVALID_RAILTYPE) {
9212 /* Rail type is not available, so disable this engine */
9213 e->info.climates = 0;
9214 } else {
9215 e->u.rail.railtype = railtype;
9219 SetYearEngineAgingStops();
9221 FinalisePriceBaseMultipliers();
9223 /* Deallocate temporary loading data */
9224 free(_gted);
9225 _grm_sprites.clear();
9229 * Load all the NewGRFs.
9230 * @param load_index The offset for the first sprite to add.
9231 * @param file_index The Fio index of the first NewGRF to load.
9232 * @param num_baseset Number of NewGRFs at the front of the list to look up in the baseset dir instead of the newgrf dir.
9234 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9236 /* In case of networking we need to "sync" the start values
9237 * so all NewGRFs are loaded equally. For this we use the
9238 * start date of the game and we set the counters, etc. to
9239 * 0 so they're the same too. */
9240 Date date = _date;
9241 Year year = _cur_year;
9242 DateFract date_fract = _date_fract;
9243 uint16 tick_counter = _tick_counter;
9244 byte display_opt = _display_opt;
9246 if (_networking) {
9247 _cur_year = _settings_game.game_creation.starting_year;
9248 _date = ConvertYMDToDate(_cur_year, 0, 1);
9249 _date_fract = 0;
9250 _tick_counter = 0;
9251 _display_opt = 0;
9254 InitializeGRFSpecial();
9256 ResetNewGRFData();
9259 * Reset the status of all files, so we can 'retry' to load them.
9260 * This is needed when one for example rearranges the NewGRFs in-game
9261 * and a previously disabled NewGRF becomes useable. If it would not
9262 * be reset, the NewGRF would remain disabled even though it should
9263 * have been enabled.
9265 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9266 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9269 _cur.spriteid = load_index;
9271 /* Load newgrf sprites
9272 * in each loading stage, (try to) open each file specified in the config
9273 * and load information from it. */
9274 uint num_non_static = 0;
9275 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9276 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9277 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9278 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9279 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9282 if (stage == GLS_RESERVE) {
9283 static const uint32 overrides[][2] = {
9284 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9285 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9286 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9288 for (size_t i = 0; i < lengthof(overrides); i++) {
9289 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9293 uint slot = file_index;
9295 _cur.stage = stage;
9296 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9297 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9298 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9300 Subdirectory subdir = slot < file_index + num_baseset ? BASESET_DIR : NEWGRF_DIR;
9301 if (!FioCheckFileExists(c->filename, subdir)) {
9302 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9303 c->status = GCS_NOT_FOUND;
9304 continue;
9307 /* A .grf file is activated only if it was active
9308 * when the game was started. If a game is loaded,
9309 * only its active .grfs will be reactivated, unless
9310 * "loadallgraphics on" is used. A .grf file is
9311 * considered active if its action 8 has been
9312 * processed, i.e. its action 8 hasn't been skipped
9313 * using an action 7.
9315 * During activation, only actions 0, 1, 2, 3, 4, 5,
9316 * 7, 8, 9, 0A and 0B are carried out. All others
9317 * are ignored, because they only need to be
9318 * processed once at initialization. */
9320 _cur.grffile = GetFileByFilename (c->filename);
9321 if (stage == GLS_LABELSCAN) {
9322 if (_cur.grffile == NULL) {
9323 _cur.grffile = new GRFFile (c);
9324 *_grf_files.Append() = _cur.grffile;
9327 bool disable = false;
9328 if (slot == MAX_FILE_SLOTS) {
9329 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of file slots has been reached", c->filename);
9330 disable = true;
9331 } else if (!HasBit(c->flags, GCF_STATIC) && !HasBit(c->flags, GCF_SYSTEM)) {
9332 if (num_non_static == NETWORK_MAX_GRF_COUNT) {
9333 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
9334 disable = true;
9335 } else {
9336 num_non_static++;
9339 if (disable) {
9340 c->status = GCS_DISABLED;
9341 c->error = new GRFError (STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9342 continue;
9344 } else {
9345 if (_cur.grffile == NULL) usererror ("File '%s' lost in cache.\n", c->filename);
9346 if (stage == GLS_RESERVE && c->status != GCS_INITIALISED) return;
9347 if (stage == GLS_ACTIVATION && !HasBit(c->flags, GCF_RESERVED)) return;
9350 assert (slot < MAX_FILE_SLOTS);
9352 LoadNewGRFFile(c, slot++, stage, subdir);
9353 if (stage == GLS_RESERVE) {
9354 SetBit(c->flags, GCF_RESERVED);
9355 } else if (stage == GLS_ACTIVATION) {
9356 ClrBit(c->flags, GCF_RESERVED);
9357 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9358 ClearTemporaryNewGRFData(_cur.grffile);
9359 BuildCargoTranslationMap();
9360 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9361 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9362 /* We're not going to activate this, so free whatever data we allocated */
9363 ClearTemporaryNewGRFData(_cur.grffile);
9368 /* Pseudo sprite processing is finished; free temporary stuff */
9369 _cur.ClearDataForNextFile();
9371 /* Call any functions that should be run after GRFs have been loaded. */
9372 AfterLoadGRFs();
9374 /* Now revert back to the original situation */
9375 _cur_year = year;
9376 _date = date;
9377 _date_fract = date_fract;
9378 _tick_counter = tick_counter;
9379 _display_opt = display_opt;