Fix ICU iterators on leading/trailing whitespace
[openttd/fttd.git] / src / newgrf.cpp
blob4e64ce95a21a2d4281aaed77dba0e0f639eb3c95
1 /* $Id$ */
3 /*
4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 */
10 /** @file newgrf.cpp Base of all NewGRF support. */
12 #include "stdafx.h"
14 #include <stdarg.h>
16 #include "debug.h"
17 #include "fileio_func.h"
18 #include "engine_func.h"
19 #include "engine_base.h"
20 #include "bridge.h"
21 #include "town.h"
22 #include "newgrf_engine.h"
23 #include "newgrf_text.h"
24 #include "fontcache.h"
25 #include "currency.h"
26 #include "landscape.h"
27 #include "newgrf_cargo.h"
28 #include "newgrf_house.h"
29 #include "newgrf_sound.h"
30 #include "newgrf_station.h"
31 #include "industrytype.h"
32 #include "newgrf_canal.h"
33 #include "newgrf_townname.h"
34 #include "newgrf_industries.h"
35 #include "newgrf_airporttiles.h"
36 #include "newgrf_airport.h"
37 #include "newgrf_object.h"
38 #include "rev.h"
39 #include "fios.h"
40 #include "strings_func.h"
41 #include "date_func.h"
42 #include "string_func.h"
43 #include "network/network.h"
44 #include <map>
45 #include "smallmap_gui.h"
46 #include "genworld.h"
47 #include "error.h"
48 #include "vehicle_func.h"
49 #include "language.h"
50 #include "vehicle_base.h"
51 #include "rail.h"
53 #include "table/strings.h"
54 #include "table/build_industry.h"
56 /* TTDPatch extended GRF format codec
57 * (c) Petr Baudis 2004 (GPL'd)
58 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
60 * Contains portions of documentation by TTDPatch team.
61 * Thanks especially to Josef Drexler for the documentation as well as a lot
62 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
63 * served as subject to the initial testing of this codec. */
65 /** List of all loaded GRF files */
66 static SmallVector<GRFFile *, 16> _grf_files;
68 /** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
69 byte _misc_grf_features = 0;
71 /** 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
72 static uint32 _ttdpatch_flags[8];
74 /** Indicates which are the newgrf features currently loaded ingame */
75 GRFLoadedFeatures _loaded_newgrf_features;
77 static const uint MAX_SPRITEGROUP = UINT8_MAX; ///< Maximum GRF-local ID for a spritegroup.
79 /** Temporary data during loading of GRFs */
80 struct GrfProcessingState {
81 private:
82 /** Definition of a single Action1 spriteset */
83 struct SpriteSet {
84 SpriteID sprite; ///< SpriteID of the first sprite of the set.
85 uint num_sprites; ///< Number of sprites in the set.
88 /** Currently referenceable spritesets */
89 std::map<uint, SpriteSet> spritesets[GSF_END];
91 public:
92 /* Global state */
93 GrfLoadingStage stage; ///< Current loading stage
94 SpriteID spriteid; ///< First available SpriteID for loading realsprites.
96 /* Local state in the file */
97 uint file_index; ///< File index of currently processed GRF file.
98 GRFFile *grffile; ///< Currently processed GRF file.
99 GRFConfig *grfconfig; ///< Config of the currently processed GRF file.
100 uint32 nfo_line; ///< Currently processed pseudo sprite number in the GRF.
101 byte grf_container_ver; ///< Container format of the current GRF file.
103 /* Kind of return values when processing certain actions */
104 int skip_sprites; ///< Number of psuedo sprites to skip before processing the next one. (-1 to skip to end of file)
106 /* Currently referenceable spritegroups */
107 SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
109 /** Clear temporary data before processing the next file in the current loading stage */
110 void ClearDataForNextFile()
112 this->nfo_line = 0;
113 this->skip_sprites = 0;
115 for (uint i = 0; i < GSF_END; i++) {
116 this->spritesets[i].clear();
119 memset(this->spritegroups, 0, sizeof(this->spritegroups));
123 * Records new spritesets.
124 * @param feature GrfSpecFeature the set is defined for.
125 * @param first_sprite SpriteID of the first sprite in the set.
126 * @param first_set First spriteset to define.
127 * @param numsets Number of sets to define.
128 * @param numents Number of sprites per set to define.
130 void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
132 assert(feature < GSF_END);
133 for (uint i = 0; i < numsets; i++) {
134 SpriteSet &set = this->spritesets[feature][first_set + i];
135 set.sprite = first_sprite + i * numents;
136 set.num_sprites = numents;
141 * Check whether there are any valid spritesets for a feature.
142 * @param feature GrfSpecFeature to check.
143 * @return true if there are any valid sets.
144 * @note Spritesets with zero sprites are valid to allow callback-failures.
146 bool HasValidSpriteSets(byte feature) const
148 assert(feature < GSF_END);
149 return !this->spritesets[feature].empty();
153 * Check whether a specific set is defined.
154 * @param feature GrfSpecFeature to check.
155 * @param set Set to check.
156 * @return true if the set is valid.
157 * @note Spritesets with zero sprites are valid to allow callback-failures.
159 bool IsValidSpriteSet(byte feature, uint set) const
161 assert(feature < GSF_END);
162 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
166 * Returns the first sprite of a spriteset.
167 * @param feature GrfSpecFeature to query.
168 * @param set Set to query.
169 * @return First sprite of the set.
171 SpriteID GetSprite(byte feature, uint set) const
173 assert(IsValidSpriteSet(feature, set));
174 return this->spritesets[feature].find(set)->second.sprite;
178 * Returns the number of sprites in a spriteset
179 * @param feature GrfSpecFeature to query.
180 * @param set Set to query.
181 * @return Number of sprites in the set.
183 uint GetNumEnts(byte feature, uint set) const
185 assert(IsValidSpriteSet(feature, set));
186 return this->spritesets[feature].find(set)->second.num_sprites;
190 static GrfProcessingState _cur;
194 * Helper to check whether an image index is valid for a particular NewGRF vehicle.
195 * @param <T> The type of vehicle.
196 * @param image_index The image index to check.
197 * @return True iff the image index is valid, or 0xFD (use new graphics).
199 template <VehicleType T>
200 static inline bool IsValidNewGRFImageIndex(uint8 image_index)
202 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
205 class OTTDByteReaderSignal { };
207 /** Class to read from a NewGRF file */
208 class ByteReader {
209 protected:
210 byte *data;
211 byte *end;
213 public:
214 ByteReader(byte *data, byte *end) : data(data), end(end) { }
216 inline byte ReadByte()
218 if (data < end) return *(data)++;
219 throw OTTDByteReaderSignal();
222 uint16 ReadWord()
224 uint16 val = ReadByte();
225 return val | (ReadByte() << 8);
228 uint16 ReadExtendedByte()
230 uint16 val = ReadByte();
231 return val == 0xFF ? ReadWord() : val;
234 uint32 ReadDWord()
236 uint32 val = ReadWord();
237 return val | (ReadWord() << 16);
240 uint32 ReadVarSize(byte size)
242 switch (size) {
243 case 1: return ReadByte();
244 case 2: return ReadWord();
245 case 4: return ReadDWord();
246 default:
247 NOT_REACHED();
248 return 0;
252 const char *ReadString()
254 char *string = reinterpret_cast<char *>(data);
255 size_t string_length = ttd_strnlen(string, Remaining());
257 if (string_length == Remaining()) {
258 /* String was not NUL terminated, so make sure it is now. */
259 string[string_length - 1] = '\0';
260 grfmsg(7, "String was not terminated with a zero byte.");
261 } else {
262 /* Increase the string length to include the NUL byte. */
263 string_length++;
265 Skip(string_length);
267 return string;
270 inline size_t Remaining() const
272 return end - data;
275 inline bool HasData(size_t count = 1) const
277 return data + count <= end;
280 inline byte *Data()
282 return data;
285 inline void Skip(size_t len)
287 data += len;
288 /* It is valid to move the buffer to exactly the end of the data,
289 * as there may not be any more data read. */
290 if (data > end) throw OTTDByteReaderSignal();
294 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
296 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.
298 /** Temporary engine data used when loading only */
299 struct GRFTempEngineData {
300 /** Summary state of refittability properties */
301 enum Refittability {
302 UNSET = 0, ///< No properties assigned. Default refit masks shall be activated.
303 EMPTY, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
304 NONEMPTY, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
307 uint16 cargo_allowed;
308 uint16 cargo_disallowed;
309 RailTypeLabel railtypelabel;
310 const GRFFile *defaultcargo_grf; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
311 Refittability refittability; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
312 bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)?
313 uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
314 uint32 ctt_include_mask; ///< Cargo types always included in the refit mask.
315 uint32 ctt_exclude_mask; ///< Cargo types always excluded from the refit mask.
318 * Update the summary refittability on setting a refittability property.
319 * @param non_empty true if the GRF sets the vehicle to be refittable.
321 void UpdateRefittability(bool non_empty)
323 if (non_empty) {
324 this->refittability = NONEMPTY;
325 } else if (this->refittability == UNSET) {
326 this->refittability = EMPTY;
331 static GRFTempEngineData *_gted; ///< Temporary engine data used during NewGRF loading
334 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
335 * GRM for vehicles is only used if dynamic engine allocation is disabled,
336 * so 256 is the number of original engines. */
337 static uint32 _grm_engines[256];
339 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
340 static uint32 _grm_cargoes[NUM_CARGO * 2];
342 struct GRFLocation {
343 uint32 grfid;
344 uint32 nfoline;
346 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
348 bool operator<(const GRFLocation &other) const
350 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
353 bool operator == (const GRFLocation &other) const
355 return this->grfid == other.grfid && this->nfoline == other.nfoline;
359 static std::map<GRFLocation, SpriteID> _grm_sprites;
360 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
361 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
364 * DEBUG() function dedicated to newGRF debugging messages
365 * Function is essentially the same as DEBUG(grf, severity, ...) with the
366 * addition of file:line information when parsing grf files.
367 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
368 * loading/parsing grf files, not for runtime debug messages as there
369 * is no file information available during that time.
370 * @param severity debugging severity level, see debug.h
371 * @param str message in printf() format
373 void CDECL grfmsg(int severity, const char *str, ...)
375 char buf[1024];
376 va_list va;
378 va_start(va, str);
379 vsnprintf(buf, sizeof(buf), str, va);
380 va_end(va);
382 DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
386 * Obtain a NewGRF file by its grfID
387 * @param grfid The grfID to obtain the file for
388 * @return The file.
390 static GRFFile *GetFileByGRFID(uint32 grfid)
392 const GRFFile * const *end = _grf_files.End();
393 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
394 if ((*file)->grfid == grfid) return *file;
396 return NULL;
400 * Obtain a NewGRF file by its filename
401 * @param filename The filename to obtain the file for.
402 * @return The file.
404 static GRFFile *GetFileByFilename(const char *filename)
406 const GRFFile * const *end = _grf_files.End();
407 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
408 if (strcmp((*file)->filename, filename) == 0) return *file;
410 return NULL;
413 /** Reset all NewGRFData that was used only while processing data */
414 static void ClearTemporaryNewGRFData(GRFFile *gf)
416 /* Clear the GOTO labels used for GRF processing */
417 for (GRFLabel *l = gf->label; l != NULL;) {
418 GRFLabel *l2 = l->next;
419 free(l);
420 l = l2;
422 gf->label = NULL;
426 * Disable a GRF
427 * @param message Error message or STR_NULL.
428 * @param config GRFConfig to disable, NULL for current.
429 * @return Error message of the GRF for further customisation.
431 static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = NULL)
433 GRFFile *file;
434 if (config != NULL) {
435 file = GetFileByGRFID(config->ident.grfid);
436 } else {
437 config = _cur.grfconfig;
438 file = _cur.grffile;
441 config->status = GCS_DISABLED;
442 if (file != NULL) ClearTemporaryNewGRFData(file);
443 if (config == _cur.grfconfig) _cur.skip_sprites = -1;
445 if (message != STR_NULL) {
446 delete config->error;
447 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
448 if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
451 return config->error;
455 * Information for mapping static StringIDs.
457 struct StringIDMapping {
458 uint32 grfid; ///< Source NewGRF.
459 StringID source; ///< Source StringID (GRF local).
460 StringID *target; ///< Destination for mapping result.
462 typedef SmallVector<StringIDMapping, 16> StringIDMappingVector;
463 static StringIDMappingVector _string_to_grf_mapping;
466 * Record a static StringID for getting translated later.
467 * @param source Source StringID (GRF local).
468 * @param target Destination for the mapping result.
470 static void AddStringForMapping(StringID source, StringID *target)
472 *target = STR_UNDEFINED;
473 StringIDMapping *item = _string_to_grf_mapping.Append();
474 item->grfid = _cur.grffile->grfid;
475 item->source = source;
476 item->target = target;
480 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
481 * string IDs, but only for the ones we are aware off; the rest
482 * like likely unused and will show a warning.
483 * @param str the string ID to convert
484 * @return the converted string ID
486 static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
488 /* StringID table for TextIDs 0x4E->0x6D */
489 static const StringID units_volume[] = {
490 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
491 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
492 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
493 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
494 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
495 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
496 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
497 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
500 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
501 assert(!IsInsideMM(str, 0xD000, 0xD7FF));
503 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
504 assert_compile(stringend - stringid == end - begin); \
505 if (str >= begin && str <= end) return str + (stringid - begin)
507 /* We have some changes in our cargo strings, resulting in some missing. */
508 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
509 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
510 if (str >= 0x004E && str <= 0x006D) return units_volume[str - 0x004E];
511 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
512 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
513 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
515 /* Map building names according to our lang file changes. There are several
516 * ranges of house ids, all of which need to be remapped to allow newgrfs
517 * to use original house names. */
518 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
519 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
520 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
522 /* Same thing for industries */
523 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
524 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
525 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
526 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
527 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
529 switch (str) {
530 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
531 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
532 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
534 #undef TEXTID_TO_STRINGID
536 if (str == STR_NULL) return STR_EMPTY;
538 DEBUG(grf, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
540 return STR_EMPTY;
544 * Used when setting an object's property to map to the GRF's strings
545 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
546 * @param grfid Id of the grf file.
547 * @param str StringID that we want to have the equivalent in OoenTTD.
548 * @return The properly adjusted StringID.
550 StringID MapGRFStringID(uint32 grfid, StringID str)
552 /* 0xD0 and 0xDC stand for all the TextIDs in the range
553 * of 0xD000 (misc graphics texts) and 0xDC00 (misc persistent texts).
554 * These strings are unique to each grf file, and thus require to be used with the
555 * grfid in which they are declared */
556 switch (GB(str, 8, 8)) {
557 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
558 case 0xDC:
559 return GetGRFStringID(grfid, str);
561 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
562 /* Strings embedded via 0x81 have 0x400 added to them (no real
563 * explanation why...) */
564 return GetGRFStringID(grfid, str - 0x400);
566 default: break;
569 return TTDPStringIDToOTTDStringIDMapping(str);
572 static std::map<uint32, uint32> _grf_id_overrides;
575 * Set the override for a NewGRF
576 * @param source_grfid The grfID which wants to override another NewGRF.
577 * @param target_grfid The grfID which is being overridden.
579 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
581 _grf_id_overrides[source_grfid] = target_grfid;
582 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
586 * Returns the engine associated to a certain internal_id, resp. allocates it.
587 * @param file NewGRF that wants to change the engine.
588 * @param type Vehicle type.
589 * @param internal_id Engine ID inside the NewGRF.
590 * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04).
591 * @return The requested engine.
593 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
595 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
596 * them use the same engine slots. */
597 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
598 if (_settings_game.vehicle.dynamic_engines) {
599 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
600 scope_grfid = file->grfid;
601 uint32 override = _grf_id_overrides[file->grfid];
602 if (override != 0) {
603 scope_grfid = override;
604 const GRFFile *grf_match = GetFileByGRFID(override);
605 if (grf_match == NULL) {
606 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
607 } else {
608 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
612 /* Check if the engine is registered in the override manager */
613 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
614 if (engine != INVALID_ENGINE) {
615 Engine *e = Engine::Get(engine);
616 if (e->grf_prop.grffile == NULL) e->grf_prop.grffile = file;
617 return e;
621 /* Check if there is an unreserved slot */
622 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
623 if (engine != INVALID_ENGINE) {
624 Engine *e = Engine::Get(engine);
626 if (e->grf_prop.grffile == NULL) {
627 e->grf_prop.grffile = file;
628 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
631 /* Reserve the engine slot */
632 if (!static_access) {
633 EngineIDMapping *eid = _engine_mngr.Get(engine);
634 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
637 return e;
640 if (static_access) return NULL;
642 if (!Engine::CanAllocateItem()) {
643 grfmsg(0, "Can't allocate any more engines");
644 return NULL;
647 size_t engine_pool_size = Engine::GetPoolSize();
649 /* ... it's not, so create a new one based off an existing engine */
650 Engine *e = new Engine(type, internal_id);
651 e->grf_prop.grffile = file;
653 /* Reserve the engine slot */
654 assert(_engine_mngr.Length() == e->index);
655 EngineIDMapping *eid = _engine_mngr.Append();
656 eid->type = type;
657 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
658 eid->internal_id = internal_id;
659 eid->substitute_id = min(internal_id, _engine_counts[type]); // substitute_id == _engine_counts[subtype] means "no substitute"
661 if (engine_pool_size != Engine::GetPoolSize()) {
662 /* Resize temporary engine data ... */
663 _gted = ReallocT(_gted, Engine::GetPoolSize());
665 /* and blank the new block. */
666 size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
667 memset(_gted + engine_pool_size, 0, len);
669 if (type == VEH_TRAIN) {
670 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
673 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
675 return e;
679 * Return the ID of a new engine
680 * @param file The NewGRF file providing the engine.
681 * @param type The Vehicle type.
682 * @param internal_id NewGRF-internal ID of the engine.
683 * @return The new EngineID.
684 * @note depending on the dynamic_engine setting and a possible override
685 * property the grfID may be unique or overwriting or partially re-defining
686 * properties of an existing engine.
688 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
690 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
691 if (_settings_game.vehicle.dynamic_engines) {
692 scope_grfid = file->grfid;
693 uint32 override = _grf_id_overrides[file->grfid];
694 if (override != 0) scope_grfid = override;
697 return _engine_mngr.GetID(type, internal_id, scope_grfid);
701 * Map the colour modifiers of TTDPatch to those that Open is using.
702 * @param grf_sprite Pointer to the structure been modified.
704 static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
706 if (HasBit(grf_sprite->pal, 14)) {
707 ClrBit(grf_sprite->pal, 14);
708 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_OPAQUE);
711 if (HasBit(grf_sprite->sprite, 14)) {
712 ClrBit(grf_sprite->sprite, 14);
713 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_TRANSPARENT);
716 if (HasBit(grf_sprite->sprite, 15)) {
717 ClrBit(grf_sprite->sprite, 15);
718 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOUR);
723 * Read a sprite and a palette from the GRF and convert them into a format
724 * suitable to OpenTTD.
725 * @param buf Input stream.
726 * @param read_flags Whether to read TileLayoutFlags.
727 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
728 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
729 * @param feature GrfSpecFeature to use spritesets from.
730 * @param [out] grf_sprite Read sprite and palette.
731 * @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
732 * @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
733 * @return Read TileLayoutFlags.
735 static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags, bool invert_action1_flag, bool use_cur_spritesets, int feature, PalSpriteID *grf_sprite, uint16 *max_sprite_offset = NULL, uint16 *max_palette_offset = NULL)
737 grf_sprite->sprite = buf->ReadWord();
738 grf_sprite->pal = buf->ReadWord();
739 TileLayoutFlags flags = read_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
741 MapSpriteMappingRecolour(grf_sprite);
743 bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
744 ClrBit(grf_sprite->pal, 15);
745 if (custom_sprite) {
746 /* Use sprite from Action 1 */
747 uint index = GB(grf_sprite->sprite, 0, 14);
748 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
749 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
750 grf_sprite->sprite = SPR_IMG_QUERY;
751 grf_sprite->pal = PAL_NONE;
752 } else {
753 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
754 if (max_sprite_offset != NULL) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
755 SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
756 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
758 } else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
759 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
760 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
761 return flags;
764 if (flags & TLF_CUSTOM_PALETTE) {
765 /* Use palette from Action 1 */
766 uint index = GB(grf_sprite->pal, 0, 14);
767 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
768 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
769 grf_sprite->pal = PAL_NONE;
770 } else {
771 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
772 if (max_palette_offset != NULL) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
773 SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
774 SetBit(grf_sprite->pal, SPRITE_MODIFIER_CUSTOM_SPRITE);
776 } else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
777 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
778 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
779 return flags;
782 return flags;
786 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
787 * @param buf Input stream.
788 * @param flags TileLayoutFlags to process.
789 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
790 * @param dts Sprite layout to insert data into.
791 * @param index Sprite index to process; 0 for ground sprite.
793 static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bool is_parent, NewGRFSpriteLayout *dts, uint index)
795 if (!(flags & TLF_DRAWING_FLAGS)) return;
797 if (dts->registers == NULL) dts->AllocateRegisters();
798 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[index]);
799 regs.flags = flags & TLF_DRAWING_FLAGS;
801 if (flags & TLF_DODRAW) regs.dodraw = buf->ReadByte();
802 if (flags & TLF_SPRITE) regs.sprite = buf->ReadByte();
803 if (flags & TLF_PALETTE) regs.palette = buf->ReadByte();
805 if (is_parent) {
806 if (flags & TLF_BB_XY_OFFSET) {
807 regs.delta.parent[0] = buf->ReadByte();
808 regs.delta.parent[1] = buf->ReadByte();
810 if (flags & TLF_BB_Z_OFFSET) regs.delta.parent[2] = buf->ReadByte();
811 } else {
812 if (flags & TLF_CHILD_X_OFFSET) regs.delta.child[0] = buf->ReadByte();
813 if (flags & TLF_CHILD_Y_OFFSET) regs.delta.child[1] = buf->ReadByte();
816 if (flags & TLF_SPRITE_VAR10) {
817 regs.sprite_var10 = buf->ReadByte();
818 if (regs.sprite_var10 > TLR_MAX_VAR10) {
819 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
820 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
821 return;
825 if (flags & TLF_PALETTE_VAR10) {
826 regs.palette_var10 = buf->ReadByte();
827 if (regs.palette_var10 > TLR_MAX_VAR10) {
828 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
829 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
830 return;
836 * Read a spritelayout from the GRF.
837 * @param buf Input
838 * @param num_building_sprites Number of building sprites to read
839 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
840 * @param feature GrfSpecFeature to use spritesets from.
841 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
842 * @param no_z_position Whether bounding boxes have no Z offset
843 * @param dts Layout container to output into
844 * @return True on error (GRF was disabled).
846 static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
848 bool has_flags = HasBit(num_building_sprites, 6);
849 ClrBit(num_building_sprites, 6);
850 TileLayoutFlags valid_flags = TLF_KNOWN_FLAGS;
851 if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
852 dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags
854 uint16 *max_sprite_offset = AllocaM(uint16, num_building_sprites + 1);
855 uint16 *max_palette_offset = AllocaM(uint16, num_building_sprites + 1);
856 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
857 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
859 /* Groundsprite */
860 TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground, max_sprite_offset, max_palette_offset);
861 if (_cur.skip_sprites < 0) return true;
863 if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
864 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
865 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
866 return true;
869 ReadSpriteLayoutRegisters(buf, flags, false, dts, 0);
870 if (_cur.skip_sprites < 0) return true;
872 for (uint i = 0; i < num_building_sprites; i++) {
873 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&dts->seq[i]);
875 flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
876 if (_cur.skip_sprites < 0) return true;
878 if (flags & ~valid_flags) {
879 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
880 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
881 return true;
884 seq->delta_x = buf->ReadByte();
885 seq->delta_y = buf->ReadByte();
887 if (!no_z_position) seq->delta_z = buf->ReadByte();
889 if (seq->IsParentSprite()) {
890 seq->size_x = buf->ReadByte();
891 seq->size_y = buf->ReadByte();
892 seq->size_z = buf->ReadByte();
895 ReadSpriteLayoutRegisters(buf, flags, seq->IsParentSprite(), dts, i + 1);
896 if (_cur.skip_sprites < 0) return true;
899 /* Check if the number of sprites per spriteset is consistent */
900 bool is_consistent = true;
901 dts->consistent_max_offset = 0;
902 for (uint i = 0; i < num_building_sprites + 1; i++) {
903 if (max_sprite_offset[i] > 0) {
904 if (dts->consistent_max_offset == 0) {
905 dts->consistent_max_offset = max_sprite_offset[i];
906 } else if (dts->consistent_max_offset != max_sprite_offset[i]) {
907 is_consistent = false;
908 break;
911 if (max_palette_offset[i] > 0) {
912 if (dts->consistent_max_offset == 0) {
913 dts->consistent_max_offset = max_palette_offset[i];
914 } else if (dts->consistent_max_offset != max_palette_offset[i]) {
915 is_consistent = false;
916 break;
921 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
922 assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX)));
924 if (!is_consistent || dts->registers != NULL) {
925 dts->consistent_max_offset = 0;
926 if (dts->registers == NULL) dts->AllocateRegisters();
928 for (uint i = 0; i < num_building_sprites + 1; i++) {
929 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[i]);
930 regs.max_sprite_offset = max_sprite_offset[i];
931 regs.max_palette_offset = max_palette_offset[i];
935 return false;
939 * Translate the refit mask.
941 static uint32 TranslateRefitMask(uint32 refit_mask)
943 uint32 result = 0;
944 uint8 bit;
945 FOR_EACH_SET_BIT(bit, refit_mask) {
946 CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true);
947 if (cargo != CT_INVALID) SetBit(result, cargo);
949 return result;
953 * Converts TTD(P) Base Price pointers into the enum used by OTTD
954 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
955 * @param base_pointer TTD(P) Base Price Pointer
956 * @param error_location Function name for grf error messages
957 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
959 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
961 /* Special value for 'none' */
962 if (base_pointer == 0) {
963 *index = INVALID_PRICE;
964 return;
967 static const uint32 start = 0x4B34; ///< Position of first base price
968 static const uint32 size = 6; ///< Size of each base price record
970 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
971 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
972 return;
975 *index = (Price)((base_pointer - start) / size);
978 /** Possible return values for the FeatureChangeInfo functions */
979 enum ChangeInfoResult {
980 CIR_SUCCESS, ///< Variable was parsed and read
981 CIR_DISABLED, ///< GRF was disabled due to error
982 CIR_UNHANDLED, ///< Variable was parsed but unread
983 CIR_UNKNOWN, ///< Variable is unknown
984 CIR_INVALID_ID, ///< Attempt to modify an invalid ID
987 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
990 * Define properties common to all vehicles
991 * @param ei Engine info.
992 * @param prop The property to change.
993 * @param buf The property value.
994 * @return ChangeInfoResult.
996 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
998 switch (prop) {
999 case 0x00: // Introduction date
1000 ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
1001 break;
1003 case 0x02: // Decay speed
1004 ei->decay_speed = buf->ReadByte();
1005 break;
1007 case 0x03: // Vehicle life
1008 ei->lifelength = buf->ReadByte();
1009 break;
1011 case 0x04: // Model life
1012 ei->base_life = buf->ReadByte();
1013 break;
1015 case 0x06: // Climates available
1016 ei->climates = buf->ReadByte();
1017 break;
1019 case PROP_VEHICLE_LOAD_AMOUNT: // 0x07 Loading speed
1020 /* Amount of cargo loaded during a vehicle's "loading tick" */
1021 ei->load_amount = buf->ReadByte();
1022 break;
1024 default:
1025 return CIR_UNKNOWN;
1028 return CIR_SUCCESS;
1032 * Define properties for rail vehicles
1033 * @param engine :ocal ID of the first vehicle.
1034 * @param numinfo Number of subsequent IDs to change the property for.
1035 * @param prop The property to change.
1036 * @param buf The property value.
1037 * @return ChangeInfoResult.
1039 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1041 ChangeInfoResult ret = CIR_SUCCESS;
1043 for (int i = 0; i < numinfo; i++) {
1044 Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i);
1045 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1047 EngineInfo *ei = &e->info;
1048 RailVehicleInfo *rvi = &e->u.rail;
1050 switch (prop) {
1051 case 0x05: { // Track type
1052 uint8 tracktype = buf->ReadByte();
1054 if (tracktype < _cur.grffile->railtype_list.Length()) {
1055 _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype];
1056 break;
1059 switch (tracktype) {
1060 case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
1061 case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
1062 case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
1063 default:
1064 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1065 break;
1067 break;
1070 case 0x08: // AI passenger service
1071 /* Tells the AI that this engine is designed for
1072 * passenger services and shouldn't be used for freight. */
1073 rvi->ai_passenger_only = buf->ReadByte();
1074 break;
1076 case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
1077 uint16 speed = buf->ReadWord();
1078 if (speed == 0xFFFF) speed = 0;
1080 rvi->max_speed = speed;
1081 break;
1084 case PROP_TRAIN_POWER: // 0x0B Power
1085 rvi->power = buf->ReadWord();
1087 /* Set engine / wagon state based on power */
1088 if (rvi->power != 0) {
1089 if (rvi->railveh_type == RAILVEH_WAGON) {
1090 rvi->railveh_type = RAILVEH_SINGLEHEAD;
1092 } else {
1093 rvi->railveh_type = RAILVEH_WAGON;
1095 break;
1097 case PROP_TRAIN_RUNNING_COST_FACTOR: // 0x0D Running cost factor
1098 rvi->running_cost = buf->ReadByte();
1099 break;
1101 case 0x0E: // Running cost base
1102 ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
1103 break;
1105 case 0x12: { // Sprite ID
1106 uint8 spriteid = buf->ReadByte();
1107 uint8 orig_spriteid = spriteid;
1109 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1110 * as an array index, so we need it to be half the original value. */
1111 if (spriteid < 0xFD) spriteid >>= 1;
1113 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1114 rvi->image_index = spriteid;
1115 } else {
1116 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1117 rvi->image_index = 0;
1119 break;
1122 case 0x13: { // Dual-headed
1123 uint8 dual = buf->ReadByte();
1125 if (dual != 0) {
1126 rvi->railveh_type = RAILVEH_MULTIHEAD;
1127 } else {
1128 rvi->railveh_type = rvi->power == 0 ?
1129 RAILVEH_WAGON : RAILVEH_SINGLEHEAD;
1131 break;
1134 case PROP_TRAIN_CARGO_CAPACITY: // 0x14 Cargo capacity
1135 rvi->capacity = buf->ReadByte();
1136 break;
1138 case 0x15: { // Cargo type
1139 _gted[e->index].defaultcargo_grf = _cur.grffile;
1140 uint8 ctype = buf->ReadByte();
1142 if (ctype == 0xFF) {
1143 /* 0xFF is specified as 'use first refittable' */
1144 ei->cargo_type = CT_INVALID;
1145 } else if (_cur.grffile->grf_version >= 8) {
1146 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1147 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1148 } else if (ctype < NUM_CARGO) {
1149 /* Use untranslated cargo. */
1150 ei->cargo_type = ctype;
1151 } else {
1152 ei->cargo_type = CT_INVALID;
1153 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1155 break;
1158 case PROP_TRAIN_WEIGHT: // 0x16 Weight
1159 SB(rvi->weight, 0, 8, buf->ReadByte());
1160 break;
1162 case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
1163 rvi->cost_factor = buf->ReadByte();
1164 break;
1166 case 0x18: // AI rank
1167 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1168 buf->ReadByte();
1169 break;
1171 case 0x19: { // Engine traction type
1172 /* What do the individual numbers mean?
1173 * 0x00 .. 0x07: Steam
1174 * 0x08 .. 0x27: Diesel
1175 * 0x28 .. 0x31: Electric
1176 * 0x32 .. 0x37: Monorail
1177 * 0x38 .. 0x41: Maglev
1179 uint8 traction = buf->ReadByte();
1180 EngineClass engclass;
1182 if (traction <= 0x07) {
1183 engclass = EC_STEAM;
1184 } else if (traction <= 0x27) {
1185 engclass = EC_DIESEL;
1186 } else if (traction <= 0x31) {
1187 engclass = EC_ELECTRIC;
1188 } else if (traction <= 0x37) {
1189 engclass = EC_MONORAIL;
1190 } else if (traction <= 0x41) {
1191 engclass = EC_MAGLEV;
1192 } else {
1193 break;
1196 if (_cur.grffile->railtype_list.Length() == 0) {
1197 /* Use traction type to select between normal and electrified
1198 * rail only when no translation list is in place. */
1199 if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1200 if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
1203 rvi->engclass = engclass;
1204 break;
1207 case 0x1A: // Alter purchase list sort order
1208 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1209 break;
1211 case 0x1B: // Powered wagons power bonus
1212 rvi->pow_wag_power = buf->ReadWord();
1213 break;
1215 case 0x1C: // Refit cost
1216 ei->refit_cost = buf->ReadByte();
1217 break;
1219 case 0x1D: { // Refit cargo
1220 uint32 mask = buf->ReadDWord();
1221 _gted[e->index].UpdateRefittability(mask != 0);
1222 ei->refit_mask = TranslateRefitMask(mask);
1223 _gted[e->index].defaultcargo_grf = _cur.grffile;
1224 break;
1227 case 0x1E: // Callback
1228 ei->callback_mask = buf->ReadByte();
1229 break;
1231 case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
1232 rvi->tractive_effort = buf->ReadByte();
1233 break;
1235 case 0x20: // Air drag
1236 rvi->air_drag = buf->ReadByte();
1237 break;
1239 case PROP_TRAIN_SHORTEN_FACTOR: // 0x21 Shorter vehicle
1240 rvi->shorten_factor = buf->ReadByte();
1241 break;
1243 case 0x22: // Visual effect
1244 rvi->visual_effect = buf->ReadByte();
1245 /* Avoid accidentally setting visual_effect to the default value
1246 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1247 if (rvi->visual_effect == VE_DEFAULT) {
1248 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1249 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1251 break;
1253 case 0x23: // Powered wagons weight bonus
1254 rvi->pow_wag_weight = buf->ReadByte();
1255 break;
1257 case 0x24: { // High byte of vehicle weight
1258 byte weight = buf->ReadByte();
1260 if (weight > 4) {
1261 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1262 } else {
1263 SB(rvi->weight, 8, 8, weight);
1265 break;
1268 case PROP_TRAIN_USER_DATA: // 0x25 User-defined bit mask to set when checking veh. var. 42
1269 rvi->user_def_data = buf->ReadByte();
1270 break;
1272 case 0x26: // Retire vehicle early
1273 ei->retire_early = buf->ReadByte();
1274 break;
1276 case 0x27: // Miscellaneous flags
1277 ei->misc_flags = buf->ReadByte();
1278 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1279 _gted[e->index].prop27_set = true;
1280 break;
1282 case 0x28: // Cargo classes allowed
1283 _gted[e->index].cargo_allowed = buf->ReadWord();
1284 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1285 _gted[e->index].defaultcargo_grf = _cur.grffile;
1286 break;
1288 case 0x29: // Cargo classes disallowed
1289 _gted[e->index].cargo_disallowed = buf->ReadWord();
1290 _gted[e->index].UpdateRefittability(false);
1291 break;
1293 case 0x2A: // Long format introduction date (days since year 0)
1294 ei->base_intro = buf->ReadDWord();
1295 break;
1297 case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
1298 ei->cargo_age_period = buf->ReadWord();
1299 break;
1301 case 0x2C: // CTT refit include list
1302 case 0x2D: { // CTT refit exclude list
1303 uint8 count = buf->ReadByte();
1304 _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
1305 if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile;
1306 uint32 &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1307 ctt = 0;
1308 while (count--) {
1309 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1310 if (ctype == CT_INVALID) continue;
1311 SetBit(ctt, ctype);
1313 break;
1316 default:
1317 ret = CommonVehicleChangeInfo(ei, prop, buf);
1318 break;
1322 return ret;
1326 * Define properties for road vehicles
1327 * @param engine Local ID of the first vehicle.
1328 * @param numinfo Number of subsequent IDs to change the property for.
1329 * @param prop The property to change.
1330 * @param buf The property value.
1331 * @return ChangeInfoResult.
1333 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1335 ChangeInfoResult ret = CIR_SUCCESS;
1337 for (int i = 0; i < numinfo; i++) {
1338 Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i);
1339 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1341 EngineInfo *ei = &e->info;
1342 RoadVehicleInfo *rvi = &e->u.road;
1344 switch (prop) {
1345 case 0x08: // Speed (1 unit is 0.5 kmh)
1346 rvi->max_speed = buf->ReadByte();
1347 break;
1349 case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1350 rvi->running_cost = buf->ReadByte();
1351 break;
1353 case 0x0A: // Running cost base
1354 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1355 break;
1357 case 0x0E: { // Sprite ID
1358 uint8 spriteid = buf->ReadByte();
1359 uint8 orig_spriteid = spriteid;
1361 /* cars have different custom id in the GRF file */
1362 if (spriteid == 0xFF) spriteid = 0xFD;
1364 if (spriteid < 0xFD) spriteid >>= 1;
1366 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1367 rvi->image_index = spriteid;
1368 } else {
1369 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1370 rvi->image_index = 0;
1372 break;
1375 case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1376 rvi->capacity = buf->ReadByte();
1377 break;
1379 case 0x10: { // Cargo type
1380 _gted[e->index].defaultcargo_grf = _cur.grffile;
1381 uint8 ctype = buf->ReadByte();
1383 if (ctype == 0xFF) {
1384 /* 0xFF is specified as 'use first refittable' */
1385 ei->cargo_type = CT_INVALID;
1386 } else if (_cur.grffile->grf_version >= 8) {
1387 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1388 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1389 } else if (ctype < NUM_CARGO) {
1390 /* Use untranslated cargo. */
1391 ei->cargo_type = ctype;
1392 } else {
1393 ei->cargo_type = CT_INVALID;
1394 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1396 break;
1399 case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1400 rvi->cost_factor = buf->ReadByte();
1401 break;
1403 case 0x12: // SFX
1404 rvi->sfx = buf->ReadByte();
1405 break;
1407 case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1408 rvi->power = buf->ReadByte();
1409 break;
1411 case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1412 rvi->weight = buf->ReadByte();
1413 break;
1415 case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1416 _gted[e->index].rv_max_speed = buf->ReadByte();
1417 break;
1419 case 0x16: { // Cargoes available for refitting
1420 uint32 mask = buf->ReadDWord();
1421 _gted[e->index].UpdateRefittability(mask != 0);
1422 ei->refit_mask = TranslateRefitMask(mask);
1423 _gted[e->index].defaultcargo_grf = _cur.grffile;
1424 break;
1427 case 0x17: // Callback mask
1428 ei->callback_mask = buf->ReadByte();
1429 break;
1431 case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1432 rvi->tractive_effort = buf->ReadByte();
1433 break;
1435 case 0x19: // Air drag
1436 rvi->air_drag = buf->ReadByte();
1437 break;
1439 case 0x1A: // Refit cost
1440 ei->refit_cost = buf->ReadByte();
1441 break;
1443 case 0x1B: // Retire vehicle early
1444 ei->retire_early = buf->ReadByte();
1445 break;
1447 case 0x1C: // Miscellaneous flags
1448 ei->misc_flags = buf->ReadByte();
1449 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1450 break;
1452 case 0x1D: // Cargo classes allowed
1453 _gted[e->index].cargo_allowed = buf->ReadWord();
1454 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1455 _gted[e->index].defaultcargo_grf = _cur.grffile;
1456 break;
1458 case 0x1E: // Cargo classes disallowed
1459 _gted[e->index].cargo_disallowed = buf->ReadWord();
1460 _gted[e->index].UpdateRefittability(false);
1461 break;
1463 case 0x1F: // Long format introduction date (days since year 0)
1464 ei->base_intro = buf->ReadDWord();
1465 break;
1467 case 0x20: // Alter purchase list sort order
1468 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1469 break;
1471 case 0x21: // Visual effect
1472 rvi->visual_effect = buf->ReadByte();
1473 /* Avoid accidentally setting visual_effect to the default value
1474 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1475 if (rvi->visual_effect == VE_DEFAULT) {
1476 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1477 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1479 break;
1481 case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1482 ei->cargo_age_period = buf->ReadWord();
1483 break;
1485 case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
1486 rvi->shorten_factor = buf->ReadByte();
1487 break;
1489 case 0x24: // CTT refit include list
1490 case 0x25: { // CTT refit exclude list
1491 uint8 count = buf->ReadByte();
1492 _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
1493 if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
1494 uint32 &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1495 ctt = 0;
1496 while (count--) {
1497 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1498 if (ctype == CT_INVALID) continue;
1499 SetBit(ctt, ctype);
1501 break;
1504 default:
1505 ret = CommonVehicleChangeInfo(ei, prop, buf);
1506 break;
1510 return ret;
1514 * Define properties for ships
1515 * @param engine Local ID of the first vehicle.
1516 * @param numinfo Number of subsequent IDs to change the property for.
1517 * @param prop The property to change.
1518 * @param buf The property value.
1519 * @return ChangeInfoResult.
1521 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1523 ChangeInfoResult ret = CIR_SUCCESS;
1525 for (int i = 0; i < numinfo; i++) {
1526 Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1527 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1529 EngineInfo *ei = &e->info;
1530 ShipVehicleInfo *svi = &e->u.ship;
1532 switch (prop) {
1533 case 0x08: { // Sprite ID
1534 uint8 spriteid = buf->ReadByte();
1535 uint8 orig_spriteid = spriteid;
1537 /* ships have different custom id in the GRF file */
1538 if (spriteid == 0xFF) spriteid = 0xFD;
1540 if (spriteid < 0xFD) spriteid >>= 1;
1542 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1543 svi->image_index = spriteid;
1544 } else {
1545 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1546 svi->image_index = 0;
1548 break;
1551 case 0x09: // Refittable
1552 svi->old_refittable = (buf->ReadByte() != 0);
1553 break;
1555 case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1556 svi->cost_factor = buf->ReadByte();
1557 break;
1559 case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1560 svi->max_speed = buf->ReadByte();
1561 break;
1563 case 0x0C: { // Cargo type
1564 _gted[e->index].defaultcargo_grf = _cur.grffile;
1565 uint8 ctype = buf->ReadByte();
1567 if (ctype == 0xFF) {
1568 /* 0xFF is specified as 'use first refittable' */
1569 ei->cargo_type = CT_INVALID;
1570 } else if (_cur.grffile->grf_version >= 8) {
1571 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1572 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1573 } else if (ctype < NUM_CARGO) {
1574 /* Use untranslated cargo. */
1575 ei->cargo_type = ctype;
1576 } else {
1577 ei->cargo_type = CT_INVALID;
1578 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1580 break;
1583 case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1584 svi->capacity = buf->ReadWord();
1585 break;
1587 case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1588 svi->running_cost = buf->ReadByte();
1589 break;
1591 case 0x10: // SFX
1592 svi->sfx = buf->ReadByte();
1593 break;
1595 case 0x11: { // Cargoes available for refitting
1596 uint32 mask = buf->ReadDWord();
1597 _gted[e->index].UpdateRefittability(mask != 0);
1598 ei->refit_mask = TranslateRefitMask(mask);
1599 _gted[e->index].defaultcargo_grf = _cur.grffile;
1600 break;
1603 case 0x12: // Callback mask
1604 ei->callback_mask = buf->ReadByte();
1605 break;
1607 case 0x13: // Refit cost
1608 ei->refit_cost = buf->ReadByte();
1609 break;
1611 case 0x14: // Ocean speed fraction
1612 svi->ocean_speed_frac = buf->ReadByte();
1613 break;
1615 case 0x15: // Canal speed fraction
1616 svi->canal_speed_frac = buf->ReadByte();
1617 break;
1619 case 0x16: // Retire vehicle early
1620 ei->retire_early = buf->ReadByte();
1621 break;
1623 case 0x17: // Miscellaneous flags
1624 ei->misc_flags = buf->ReadByte();
1625 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1626 break;
1628 case 0x18: // Cargo classes allowed
1629 _gted[e->index].cargo_allowed = buf->ReadWord();
1630 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1631 _gted[e->index].defaultcargo_grf = _cur.grffile;
1632 break;
1634 case 0x19: // Cargo classes disallowed
1635 _gted[e->index].cargo_disallowed = buf->ReadWord();
1636 _gted[e->index].UpdateRefittability(false);
1637 break;
1639 case 0x1A: // Long format introduction date (days since year 0)
1640 ei->base_intro = buf->ReadDWord();
1641 break;
1643 case 0x1B: // Alter purchase list sort order
1644 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1645 break;
1647 case 0x1C: // Visual effect
1648 svi->visual_effect = buf->ReadByte();
1649 /* Avoid accidentally setting visual_effect to the default value
1650 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1651 if (svi->visual_effect == VE_DEFAULT) {
1652 assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1653 SB(svi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1655 break;
1657 case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1658 ei->cargo_age_period = buf->ReadWord();
1659 break;
1661 case 0x1E: // CTT refit include list
1662 case 0x1F: { // CTT refit exclude list
1663 uint8 count = buf->ReadByte();
1664 _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
1665 if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
1666 uint32 &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1667 ctt = 0;
1668 while (count--) {
1669 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1670 if (ctype == CT_INVALID) continue;
1671 SetBit(ctt, ctype);
1673 break;
1676 default:
1677 ret = CommonVehicleChangeInfo(ei, prop, buf);
1678 break;
1682 return ret;
1686 * Define properties for aircraft
1687 * @param engine Local ID of the aircraft.
1688 * @param numinfo Number of subsequent IDs to change the property for.
1689 * @param prop The property to change.
1690 * @param buf The property value.
1691 * @return ChangeInfoResult.
1693 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1695 ChangeInfoResult ret = CIR_SUCCESS;
1697 for (int i = 0; i < numinfo; i++) {
1698 Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1699 if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1701 EngineInfo *ei = &e->info;
1702 AircraftVehicleInfo *avi = &e->u.air;
1704 switch (prop) {
1705 case 0x08: { // Sprite ID
1706 uint8 spriteid = buf->ReadByte();
1707 uint8 orig_spriteid = spriteid;
1709 /* aircraft have different custom id in the GRF file */
1710 if (spriteid == 0xFF) spriteid = 0xFD;
1712 if (spriteid < 0xFD) spriteid >>= 1;
1714 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1715 avi->image_index = spriteid;
1716 } else {
1717 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1718 avi->image_index = 0;
1720 break;
1723 case 0x09: // Helicopter
1724 if (buf->ReadByte() == 0) {
1725 avi->subtype = AIR_HELI;
1726 } else {
1727 SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1729 break;
1731 case 0x0A: // Large
1732 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1733 break;
1735 case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1736 avi->cost_factor = buf->ReadByte();
1737 break;
1739 case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1740 avi->max_speed = (buf->ReadByte() * 128) / 10;
1741 break;
1743 case 0x0D: // Acceleration
1744 avi->acceleration = buf->ReadByte();
1745 break;
1747 case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1748 avi->running_cost = buf->ReadByte();
1749 break;
1751 case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1752 avi->passenger_capacity = buf->ReadWord();
1753 break;
1755 case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1756 avi->mail_capacity = buf->ReadByte();
1757 break;
1759 case 0x12: // SFX
1760 avi->sfx = buf->ReadByte();
1761 break;
1763 case 0x13: { // Cargoes available for refitting
1764 uint32 mask = buf->ReadDWord();
1765 _gted[e->index].UpdateRefittability(mask != 0);
1766 ei->refit_mask = TranslateRefitMask(mask);
1767 _gted[e->index].defaultcargo_grf = _cur.grffile;
1768 break;
1771 case 0x14: // Callback mask
1772 ei->callback_mask = buf->ReadByte();
1773 break;
1775 case 0x15: // Refit cost
1776 ei->refit_cost = buf->ReadByte();
1777 break;
1779 case 0x16: // Retire vehicle early
1780 ei->retire_early = buf->ReadByte();
1781 break;
1783 case 0x17: // Miscellaneous flags
1784 ei->misc_flags = buf->ReadByte();
1785 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1786 break;
1788 case 0x18: // Cargo classes allowed
1789 _gted[e->index].cargo_allowed = buf->ReadWord();
1790 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1791 _gted[e->index].defaultcargo_grf = _cur.grffile;
1792 break;
1794 case 0x19: // Cargo classes disallowed
1795 _gted[e->index].cargo_disallowed = buf->ReadWord();
1796 _gted[e->index].UpdateRefittability(false);
1797 break;
1799 case 0x1A: // Long format introduction date (days since year 0)
1800 ei->base_intro = buf->ReadDWord();
1801 break;
1803 case 0x1B: // Alter purchase list sort order
1804 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1805 break;
1807 case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1808 ei->cargo_age_period = buf->ReadWord();
1809 break;
1811 case 0x1D: // CTT refit include list
1812 case 0x1E: { // CTT refit exclude list
1813 uint8 count = buf->ReadByte();
1814 _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
1815 if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
1816 uint32 &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1817 ctt = 0;
1818 while (count--) {
1819 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1820 if (ctype == CT_INVALID) continue;
1821 SetBit(ctt, ctype);
1823 break;
1826 case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
1827 avi->max_range = buf->ReadWord();
1828 break;
1830 default:
1831 ret = CommonVehicleChangeInfo(ei, prop, buf);
1832 break;
1836 return ret;
1840 * Define properties for stations
1841 * @param stdid StationID of the first station tile.
1842 * @param numinfo Number of subsequent station tiles to change the property for.
1843 * @param prop The property to change.
1844 * @param buf The property value.
1845 * @return ChangeInfoResult.
1847 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
1849 ChangeInfoResult ret = CIR_SUCCESS;
1851 if (stid + numinfo > NUM_STATIONS_PER_GRF) {
1852 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
1853 return CIR_INVALID_ID;
1856 /* Allocate station specs if necessary */
1857 if (_cur.grffile->stations == NULL) _cur.grffile->stations = CallocT<StationSpec*>(NUM_STATIONS_PER_GRF);
1859 for (int i = 0; i < numinfo; i++) {
1860 StationSpec *statspec = _cur.grffile->stations[stid + i];
1862 /* Check that the station we are modifying is defined. */
1863 if (statspec == NULL && prop != 0x08) {
1864 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1865 return CIR_INVALID_ID;
1868 switch (prop) {
1869 case 0x08: { // Class ID
1870 StationSpec **spec = &_cur.grffile->stations[stid + i];
1872 /* Property 0x08 is special; it is where the station is allocated */
1873 if (*spec == NULL) *spec = CallocT<StationSpec>(1);
1875 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1876 uint32 classid = buf->ReadDWord();
1877 (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
1878 break;
1881 case 0x09: // Define sprite layout
1882 statspec->tiles = buf->ReadExtendedByte();
1883 delete[] statspec->renderdata; // delete earlier loaded stuff
1884 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1886 for (uint t = 0; t < statspec->tiles; t++) {
1887 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1888 dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
1890 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1891 buf->Skip(4);
1892 extern const DrawTileSprites _station_display_datas_rail[8];
1893 dts->Clone(&_station_display_datas_rail[t % 8]);
1894 continue;
1897 ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
1898 /* On error, bail out immediately. Temporary GRF data was already freed */
1899 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1901 static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
1902 tmp_layout.Clear();
1903 for (;;) {
1904 /* no relative bounding box support */
1905 DrawTileSeqStruct *dtss = tmp_layout.Append();
1906 MemSetT(dtss, 0);
1908 dtss->delta_x = buf->ReadByte();
1909 if (dtss->IsTerminator()) break;
1910 dtss->delta_y = buf->ReadByte();
1911 dtss->delta_z = buf->ReadByte();
1912 dtss->size_x = buf->ReadByte();
1913 dtss->size_y = buf->ReadByte();
1914 dtss->size_z = buf->ReadByte();
1916 ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss->image);
1917 /* On error, bail out immediately. Temporary GRF data was already freed */
1918 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1920 dts->Clone(tmp_layout.Begin());
1922 break;
1924 case 0x0A: { // Copy sprite layout
1925 byte srcid = buf->ReadByte();
1926 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1928 if (srcstatspec == NULL) {
1929 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1930 continue;
1933 delete[] statspec->renderdata; // delete earlier loaded stuff
1935 statspec->tiles = srcstatspec->tiles;
1936 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1937 for (uint t = 0; t < statspec->tiles; t++) {
1938 statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
1940 break;
1943 case 0x0B: // Callback mask
1944 statspec->callback_mask = buf->ReadByte();
1945 break;
1947 case 0x0C: // Disallowed number of platforms
1948 statspec->disallowed_platforms = buf->ReadByte();
1949 break;
1951 case 0x0D: // Disallowed platform lengths
1952 statspec->disallowed_lengths = buf->ReadByte();
1953 break;
1955 case 0x0E: // Define custom layout
1956 statspec->copied_layouts = false;
1958 while (buf->HasData()) {
1959 byte length = buf->ReadByte();
1960 byte number = buf->ReadByte();
1961 StationLayout layout;
1962 uint l, p;
1964 if (length == 0 || number == 0) break;
1966 if (length > statspec->lengths) {
1967 statspec->platforms = ReallocT(statspec->platforms, length);
1968 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
1970 statspec->layouts = ReallocT(statspec->layouts, length);
1971 memset(statspec->layouts + statspec->lengths, 0,
1972 (length - statspec->lengths) * sizeof(*statspec->layouts));
1974 statspec->lengths = length;
1976 l = length - 1; // index is zero-based
1978 if (number > statspec->platforms[l]) {
1979 statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
1980 /* We expect NULL being 0 here, but C99 guarantees that. */
1981 memset(statspec->layouts[l] + statspec->platforms[l], 0,
1982 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
1984 statspec->platforms[l] = number;
1987 p = 0;
1988 layout = MallocT<byte>(length * number);
1989 try {
1990 for (l = 0; l < length; l++) {
1991 for (p = 0; p < number; p++) {
1992 layout[l * number + p] = buf->ReadByte();
1995 } catch (...) {
1996 free(layout);
1997 throw;
2000 l--;
2001 p--;
2002 free(statspec->layouts[l][p]);
2003 statspec->layouts[l][p] = layout;
2005 break;
2007 case 0x0F: { // Copy custom layout
2008 byte srcid = buf->ReadByte();
2009 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
2011 if (srcstatspec == NULL) {
2012 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2013 continue;
2016 statspec->lengths = srcstatspec->lengths;
2017 statspec->platforms = srcstatspec->platforms;
2018 statspec->layouts = srcstatspec->layouts;
2019 statspec->copied_layouts = true;
2020 break;
2023 case 0x10: // Little/lots cargo threshold
2024 statspec->cargo_threshold = buf->ReadWord();
2025 break;
2027 case 0x11: // Pylon placement
2028 statspec->pylons = buf->ReadByte();
2029 break;
2031 case 0x12: // Cargo types for random triggers
2032 statspec->cargo_triggers = buf->ReadDWord();
2033 if (_cur.grffile->grf_version >= 7) {
2034 statspec->cargo_triggers = TranslateRefitMask(statspec->cargo_triggers);
2036 break;
2038 case 0x13: // General flags
2039 statspec->flags = buf->ReadByte();
2040 break;
2042 case 0x14: // Overhead wire placement
2043 statspec->wires = buf->ReadByte();
2044 break;
2046 case 0x15: // Blocked tiles
2047 statspec->blocked = buf->ReadByte();
2048 break;
2050 case 0x16: // Animation info
2051 statspec->animation.frames = buf->ReadByte();
2052 statspec->animation.status = buf->ReadByte();
2053 break;
2055 case 0x17: // Animation speed
2056 statspec->animation.speed = buf->ReadByte();
2057 break;
2059 case 0x18: // Animation triggers
2060 statspec->animation.triggers = buf->ReadWord();
2061 break;
2063 case 0x1A: // Advanced sprite layout
2064 statspec->tiles = buf->ReadExtendedByte();
2065 delete[] statspec->renderdata; // delete earlier loaded stuff
2066 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
2068 for (uint t = 0; t < statspec->tiles; t++) {
2069 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
2070 uint num_building_sprites = buf->ReadByte();
2071 /* On error, bail out immediately. Temporary GRF data was already freed */
2072 if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED;
2074 break;
2076 default:
2077 ret = CIR_UNKNOWN;
2078 break;
2082 return ret;
2086 * Define properties for water features
2087 * @param id Type of the first water feature.
2088 * @param numinfo Number of subsequent water feature ids to change the property for.
2089 * @param prop The property to change.
2090 * @param buf The property value.
2091 * @return ChangeInfoResult.
2093 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
2095 ChangeInfoResult ret = CIR_SUCCESS;
2097 if (id + numinfo > CF_END) {
2098 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id + numinfo, CF_END);
2099 return CIR_INVALID_ID;
2102 for (int i = 0; i < numinfo; i++) {
2103 CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
2105 switch (prop) {
2106 case 0x08:
2107 cp->callback_mask = buf->ReadByte();
2108 break;
2110 case 0x09:
2111 cp->flags = buf->ReadByte();
2112 break;
2114 default:
2115 ret = CIR_UNKNOWN;
2116 break;
2120 return ret;
2124 * Define properties for bridges
2125 * @param brid BridgeID of the bridge.
2126 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2127 * @param prop The property to change.
2128 * @param buf The property value.
2129 * @return ChangeInfoResult.
2131 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
2133 ChangeInfoResult ret = CIR_SUCCESS;
2135 if (brid + numinfo > MAX_BRIDGES) {
2136 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
2137 return CIR_INVALID_ID;
2140 for (int i = 0; i < numinfo; i++) {
2141 BridgeSpec *bridge = &_bridge[brid + i];
2143 switch (prop) {
2144 case 0x08: { // Year of availability
2145 /* We treat '0' as always available */
2146 byte year = buf->ReadByte();
2147 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
2148 break;
2151 case 0x09: // Minimum length
2152 bridge->min_length = buf->ReadByte();
2153 break;
2155 case 0x0A: // Maximum length
2156 bridge->max_length = buf->ReadByte();
2157 if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
2158 break;
2160 case 0x0B: // Cost factor
2161 bridge->price = buf->ReadByte();
2162 break;
2164 case 0x0C: // Maximum speed
2165 bridge->speed = buf->ReadWord();
2166 break;
2168 case 0x0D: { // Bridge sprite tables
2169 byte tableid = buf->ReadByte();
2170 byte numtables = buf->ReadByte();
2172 if (bridge->sprite_table == NULL) {
2173 /* Allocate memory for sprite table pointers and zero out */
2174 bridge->sprite_table = CallocT<PalSpriteID*>(7);
2177 for (; numtables-- != 0; tableid++) {
2178 if (tableid >= 7) { // skip invalid data
2179 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2180 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2181 continue;
2184 if (bridge->sprite_table[tableid] == NULL) {
2185 bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
2188 for (byte sprite = 0; sprite < 32; sprite++) {
2189 SpriteID image = buf->ReadWord();
2190 PaletteID pal = buf->ReadWord();
2192 bridge->sprite_table[tableid][sprite].sprite = image;
2193 bridge->sprite_table[tableid][sprite].pal = pal;
2195 MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
2198 break;
2201 case 0x0E: // Flags; bit 0 - disable far pillars
2202 bridge->flags = buf->ReadByte();
2203 break;
2205 case 0x0F: // Long format year of availability (year since year 0)
2206 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
2207 break;
2209 case 0x10: { // purchase string
2210 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2211 if (newone != STR_UNDEFINED) bridge->material = newone;
2212 break;
2215 case 0x11: // description of bridge with rails or roads
2216 case 0x12: {
2217 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2218 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
2219 break;
2222 case 0x13: // 16 bits cost multiplier
2223 bridge->price = buf->ReadWord();
2224 break;
2226 default:
2227 ret = CIR_UNKNOWN;
2228 break;
2232 return ret;
2236 * Ignore a house property
2237 * @param prop Property to read.
2238 * @param buf Property value.
2239 * @return ChangeInfoResult.
2241 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
2243 ChangeInfoResult ret = CIR_SUCCESS;
2245 switch (prop) {
2246 case 0x09:
2247 case 0x0B:
2248 case 0x0C:
2249 case 0x0D:
2250 case 0x0E:
2251 case 0x0F:
2252 case 0x11:
2253 case 0x14:
2254 case 0x15:
2255 case 0x16:
2256 case 0x18:
2257 case 0x19:
2258 case 0x1A:
2259 case 0x1B:
2260 case 0x1C:
2261 case 0x1D:
2262 case 0x1F:
2263 buf->ReadByte();
2264 break;
2266 case 0x0A:
2267 case 0x10:
2268 case 0x12:
2269 case 0x13:
2270 case 0x21:
2271 case 0x22:
2272 buf->ReadWord();
2273 break;
2275 case 0x1E:
2276 buf->ReadDWord();
2277 break;
2279 case 0x17:
2280 for (uint j = 0; j < 4; j++) buf->ReadByte();
2281 break;
2283 case 0x20: {
2284 byte count = buf->ReadByte();
2285 for (byte j = 0; j < count; j++) buf->ReadByte();
2286 break;
2289 default:
2290 ret = CIR_UNKNOWN;
2291 break;
2293 return ret;
2297 * Define properties for houses
2298 * @param hid HouseID of the house.
2299 * @param numinfo Number of subsequent houseIDs to change the property for.
2300 * @param prop The property to change.
2301 * @param buf The property value.
2302 * @return ChangeInfoResult.
2304 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2306 ChangeInfoResult ret = CIR_SUCCESS;
2308 if (hid + numinfo > NUM_HOUSES_PER_GRF) {
2309 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
2310 return CIR_INVALID_ID;
2313 /* Allocate house specs if they haven't been allocated already. */
2314 if (_cur.grffile->housespec == NULL) {
2315 _cur.grffile->housespec = CallocT<HouseSpec*>(NUM_HOUSES_PER_GRF);
2318 for (int i = 0; i < numinfo; i++) {
2319 HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2321 if (prop != 0x08 && housespec == NULL) {
2322 /* If the house property 08 is not yet set, ignore this property */
2323 ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2324 if (cir > ret) ret = cir;
2325 continue;
2328 switch (prop) {
2329 case 0x08: { // Substitute building type, and definition of a new house
2330 HouseSpec **house = &_cur.grffile->housespec[hid + i];
2331 byte subs_id = buf->ReadByte();
2333 if (subs_id == 0xFF) {
2334 /* Instead of defining a new house, a substitute house id
2335 * of 0xFF disables the old house with the current id. */
2336 HouseSpec::Get(hid + i)->enabled = false;
2337 continue;
2338 } else if (subs_id >= NEW_HOUSE_OFFSET) {
2339 /* The substitute id must be one of the original houses. */
2340 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2341 continue;
2344 /* Allocate space for this house. */
2345 if (*house == NULL) *house = CallocT<HouseSpec>(1);
2347 housespec = *house;
2349 MemCpyT(housespec, HouseSpec::Get(subs_id));
2351 housespec->enabled = true;
2352 housespec->grf_prop.local_id = hid + i;
2353 housespec->grf_prop.subst_id = subs_id;
2354 housespec->grf_prop.grffile = _cur.grffile;
2355 housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2356 housespec->random_colour[1] = 0x08; // for all new houses
2357 housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2358 housespec->random_colour[3] = 0x06;
2360 /* Make sure that the third cargo type is valid in this
2361 * climate. This can cause problems when copying the properties
2362 * of a house that accepts food, where the new house is valid
2363 * in the temperate climate. */
2364 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2365 housespec->cargo_acceptance[2] = 0;
2368 _loaded_newgrf_features.has_newhouses = true;
2369 break;
2372 case 0x09: // Building flags
2373 housespec->building_flags = (BuildingFlags)buf->ReadByte();
2374 break;
2376 case 0x0A: { // Availability years
2377 uint16 years = buf->ReadWord();
2378 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2379 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2380 break;
2383 case 0x0B: // Population
2384 housespec->population = buf->ReadByte();
2385 break;
2387 case 0x0C: // Mail generation multiplier
2388 housespec->mail_generation = buf->ReadByte();
2389 break;
2391 case 0x0D: // Passenger acceptance
2392 case 0x0E: // Mail acceptance
2393 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2394 break;
2396 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2397 int8 goods = buf->ReadByte();
2399 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2400 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2401 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2402 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2404 /* Make sure the cargo type is valid in this climate. */
2405 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2407 housespec->accepts_cargo[2] = cid;
2408 housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2409 break;
2412 case 0x10: // Local authority rating decrease on removal
2413 housespec->remove_rating_decrease = buf->ReadWord();
2414 break;
2416 case 0x11: // Removal cost multiplier
2417 housespec->removal_cost = buf->ReadByte();
2418 break;
2420 case 0x12: // Building name ID
2421 AddStringForMapping(buf->ReadWord(), &housespec->building_name);
2422 break;
2424 case 0x13: // Building availability mask
2425 housespec->building_availability = (HouseZones)buf->ReadWord();
2426 break;
2428 case 0x14: // House callback mask
2429 housespec->callback_mask |= buf->ReadByte();
2430 break;
2432 case 0x15: { // House override byte
2433 byte override = buf->ReadByte();
2435 /* The house being overridden must be an original house. */
2436 if (override >= NEW_HOUSE_OFFSET) {
2437 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2438 continue;
2441 _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2442 break;
2445 case 0x16: // Periodic refresh multiplier
2446 housespec->processing_time = min(buf->ReadByte(), 63);
2447 break;
2449 case 0x17: // Four random colours to use
2450 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2451 break;
2453 case 0x18: // Relative probability of appearing
2454 housespec->probability = buf->ReadByte();
2455 break;
2457 case 0x19: // Extra flags
2458 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2459 break;
2461 case 0x1A: // Animation frames
2462 housespec->animation.frames = buf->ReadByte();
2463 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2464 SB(housespec->animation.frames, 7, 1, 0);
2465 break;
2467 case 0x1B: // Animation speed
2468 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2469 break;
2471 case 0x1C: // Class of the building type
2472 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2473 break;
2475 case 0x1D: // Callback mask part 2
2476 housespec->callback_mask |= (buf->ReadByte() << 8);
2477 break;
2479 case 0x1E: { // Accepted cargo types
2480 uint32 cargotypes = buf->ReadDWord();
2482 /* Check if the cargo types should not be changed */
2483 if (cargotypes == 0xFFFFFFFF) break;
2485 for (uint j = 0; j < 3; j++) {
2486 /* Get the cargo number from the 'list' */
2487 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2488 CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2490 if (cargo == CT_INVALID) {
2491 /* Disable acceptance of invalid cargo type */
2492 housespec->cargo_acceptance[j] = 0;
2493 } else {
2494 housespec->accepts_cargo[j] = cargo;
2497 break;
2500 case 0x1F: // Minimum life span
2501 housespec->minimum_life = buf->ReadByte();
2502 break;
2504 case 0x20: { // Cargo acceptance watch list
2505 byte count = buf->ReadByte();
2506 for (byte j = 0; j < count; j++) {
2507 CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2508 if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
2510 break;
2513 case 0x21: // long introduction year
2514 housespec->min_year = buf->ReadWord();
2515 break;
2517 case 0x22: // long maximum year
2518 housespec->max_year = buf->ReadWord();
2519 break;
2521 default:
2522 ret = CIR_UNKNOWN;
2523 break;
2527 return ret;
2531 * Get the language map associated with a given NewGRF and language.
2532 * @param grfid The NewGRF to get the map for.
2533 * @param language_id The (NewGRF) language ID to get the map for.
2534 * @return The LanguageMap, or NULL if it couldn't be found.
2536 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2538 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2539 const GRFFile *grffile = GetFileByGRFID(grfid);
2540 return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL;
2544 * Load a cargo- or railtype-translation table.
2545 * @param gvid ID of the global variable. This is basically only checked for zerones.
2546 * @param numinfo Number of subsequent IDs to change the property for.
2547 * @param buf The property value.
2548 * @param [in,out] translation_table Storage location for the translation table.
2549 * @param name Name of the table for debug output.
2550 * @return ChangeInfoResult.
2552 template <typename T>
2553 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
2555 if (gvid != 0) {
2556 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
2557 return CIR_INVALID_ID;
2560 translation_table.Clear();
2561 for (int i = 0; i < numinfo; i++) {
2562 uint32 item = buf->ReadDWord();
2563 *translation_table.Append() = BSWAP32(item);
2566 return CIR_SUCCESS;
2570 * Define properties for global variables
2571 * @param gvid ID of the global variable.
2572 * @param numinfo Number of subsequent IDs to change the property for.
2573 * @param prop The property to change.
2574 * @param buf The property value.
2575 * @return ChangeInfoResult.
2577 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2579 /* Properties which are handled as a whole */
2580 switch (prop) {
2581 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2582 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2584 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2585 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2587 default:
2588 break;
2591 /* Properties which are handled per item */
2592 ChangeInfoResult ret = CIR_SUCCESS;
2593 for (int i = 0; i < numinfo; i++) {
2594 switch (prop) {
2595 case 0x08: { // Cost base factor
2596 int factor = buf->ReadByte();
2597 uint price = gvid + i;
2599 if (price < PR_END) {
2600 _cur.grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
2601 } else {
2602 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2604 break;
2607 case 0x0A: { // Currency display names
2608 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2609 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2611 if ((newone != STR_UNDEFINED) && (curidx < CURRENCY_END)) {
2612 _currency_specs[curidx].name = newone;
2614 break;
2617 case 0x0B: { // Currency multipliers
2618 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2619 uint32 rate = buf->ReadDWord();
2621 if (curidx < CURRENCY_END) {
2622 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2623 * which OTTD does not. For this reason, divide grf value by 1000,
2624 * to be compatible */
2625 _currency_specs[curidx].rate = rate / 1000;
2626 } else {
2627 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2629 break;
2632 case 0x0C: { // Currency options
2633 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2634 uint16 options = buf->ReadWord();
2636 if (curidx < CURRENCY_END) {
2637 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
2638 _currency_specs[curidx].separator[1] = '\0';
2639 /* By specifying only one bit, we prevent errors,
2640 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2641 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
2642 } else {
2643 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2645 break;
2648 case 0x0D: { // Currency prefix symbol
2649 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2650 uint32 tempfix = buf->ReadDWord();
2652 if (curidx < CURRENCY_END) {
2653 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
2654 _currency_specs[curidx].prefix[4] = 0;
2655 } else {
2656 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2658 break;
2661 case 0x0E: { // Currency suffix symbol
2662 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2663 uint32 tempfix = buf->ReadDWord();
2665 if (curidx < CURRENCY_END) {
2666 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
2667 _currency_specs[curidx].suffix[4] = 0;
2668 } else {
2669 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2671 break;
2674 case 0x0F: { // Euro introduction dates
2675 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2676 Year year_euro = buf->ReadWord();
2678 if (curidx < CURRENCY_END) {
2679 _currency_specs[curidx].to_euro = year_euro;
2680 } else {
2681 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2683 break;
2686 case 0x10: // Snow line height table
2687 if (numinfo > 1 || IsSnowLineSet()) {
2688 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2689 } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
2690 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2691 } else {
2692 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2694 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2695 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2696 table[i][j] = buf->ReadByte();
2697 if (_cur.grffile->grf_version >= 8) {
2698 if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + MAX_TILE_HEIGHT) / 256;
2699 } else {
2700 if (table[i][j] >= 128) {
2701 /* no snow */
2702 table[i][j] = 0xFF;
2703 } else {
2704 table[i][j] = table[i][j] * (1 + MAX_TILE_HEIGHT) / 128;
2709 SetSnowLine(table);
2711 break;
2713 case 0x11: // GRF match for engine allocation
2714 /* This is loaded during the reservation stage, so just skip it here. */
2715 /* Each entry is 8 bytes. */
2716 buf->Skip(8);
2717 break;
2719 case 0x13: // Gender translation table
2720 case 0x14: // Case translation table
2721 case 0x15: { // Plural form translation
2722 uint curidx = gvid + i; // The current index, i.e. language.
2723 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL;
2724 if (lang == NULL) {
2725 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2726 /* Skip over the data. */
2727 if (prop == 0x15) {
2728 buf->ReadByte();
2729 } else {
2730 while (buf->ReadByte() != 0) {
2731 buf->ReadString();
2734 break;
2737 if (_cur.grffile->language_map == NULL) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2739 if (prop == 0x15) {
2740 uint plural_form = buf->ReadByte();
2741 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2742 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2743 } else {
2744 _cur.grffile->language_map[curidx].plural_form = plural_form;
2746 break;
2749 byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2750 while (newgrf_id != 0) {
2751 const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2753 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2754 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2755 * is just a subset of UTF8, or they need the bigger UTF8 characters
2756 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2757 WChar c;
2758 size_t len = Utf8Decode(&c, name);
2759 if (c == NFO_UTF8_IDENTIFIER) name += len;
2761 LanguageMap::Mapping map;
2762 map.newgrf_id = newgrf_id;
2763 if (prop == 0x13) {
2764 map.openttd_id = lang->GetGenderIndex(name);
2765 if (map.openttd_id >= MAX_NUM_GENDERS) {
2766 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2767 } else {
2768 *_cur.grffile->language_map[curidx].gender_map.Append() = map;
2770 } else {
2771 map.openttd_id = lang->GetCaseIndex(name);
2772 if (map.openttd_id >= MAX_NUM_CASES) {
2773 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2774 } else {
2775 *_cur.grffile->language_map[curidx].case_map.Append() = map;
2778 newgrf_id = buf->ReadByte();
2780 break;
2783 default:
2784 ret = CIR_UNKNOWN;
2785 break;
2789 return ret;
2792 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2794 /* Properties which are handled as a whole */
2795 switch (prop) {
2796 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2797 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2799 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2800 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2802 default:
2803 break;
2806 /* Properties which are handled per item */
2807 ChangeInfoResult ret = CIR_SUCCESS;
2808 for (int i = 0; i < numinfo; i++) {
2809 switch (prop) {
2810 case 0x08: // Cost base factor
2811 case 0x15: // Plural form translation
2812 buf->ReadByte();
2813 break;
2815 case 0x0A: // Currency display names
2816 case 0x0C: // Currency options
2817 case 0x0F: // Euro introduction dates
2818 buf->ReadWord();
2819 break;
2821 case 0x0B: // Currency multipliers
2822 case 0x0D: // Currency prefix symbol
2823 case 0x0E: // Currency suffix symbol
2824 buf->ReadDWord();
2825 break;
2827 case 0x10: // Snow line height table
2828 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
2829 break;
2831 case 0x11: { // GRF match for engine allocation
2832 uint32 s = buf->ReadDWord();
2833 uint32 t = buf->ReadDWord();
2834 SetNewGRFOverride(s, t);
2835 break;
2838 case 0x13: // Gender translation table
2839 case 0x14: // Case translation table
2840 while (buf->ReadByte() != 0) {
2841 buf->ReadString();
2843 break;
2845 default:
2846 ret = CIR_UNKNOWN;
2847 break;
2851 return ret;
2856 * Define properties for cargoes
2857 * @param cid Local ID of the cargo.
2858 * @param numinfo Number of subsequent IDs to change the property for.
2859 * @param prop The property to change.
2860 * @param buf The property value.
2861 * @return ChangeInfoResult.
2863 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
2865 ChangeInfoResult ret = CIR_SUCCESS;
2867 if (cid + numinfo > NUM_CARGO) {
2868 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
2869 return CIR_INVALID_ID;
2872 for (int i = 0; i < numinfo; i++) {
2873 CargoSpec *cs = CargoSpec::Get(cid + i);
2875 switch (prop) {
2876 case 0x08: // Bit number of cargo
2877 cs->bitnum = buf->ReadByte();
2878 if (cs->IsValid()) {
2879 cs->grffile = _cur.grffile;
2880 SetBit(_cargo_mask, cid + i);
2881 } else {
2882 ClrBit(_cargo_mask, cid + i);
2884 break;
2886 case 0x09: // String ID for cargo type name
2887 AddStringForMapping(buf->ReadWord(), &cs->name);
2888 break;
2890 case 0x0A: // String for 1 unit of cargo
2891 AddStringForMapping(buf->ReadWord(), &cs->name_single);
2892 break;
2894 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2895 case 0x1B: // String for cargo units
2896 /* String for units of cargo. This is different in OpenTTD
2897 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2898 * Property 1B is used to set OpenTTD's behaviour. */
2899 AddStringForMapping(buf->ReadWord(), &cs->units_volume);
2900 break;
2902 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2903 case 0x1C: // String for any amount of cargo
2904 /* Strings for an amount of cargo. This is different in OpenTTD
2905 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2906 * Property 1C is used to set OpenTTD's behaviour. */
2907 AddStringForMapping(buf->ReadWord(), &cs->quantifier);
2908 break;
2910 case 0x0D: // String for two letter cargo abbreviation
2911 AddStringForMapping(buf->ReadWord(), &cs->abbrev);
2912 break;
2914 case 0x0E: // Sprite ID for cargo icon
2915 cs->sprite = buf->ReadWord();
2916 break;
2918 case 0x0F: // Weight of one unit of cargo
2919 cs->weight = buf->ReadByte();
2920 break;
2922 case 0x10: // Used for payment calculation
2923 cs->transit_days[0] = buf->ReadByte();
2924 break;
2926 case 0x11: // Used for payment calculation
2927 cs->transit_days[1] = buf->ReadByte();
2928 break;
2930 case 0x12: // Base cargo price
2931 cs->initial_payment = buf->ReadDWord();
2932 break;
2934 case 0x13: // Colour for station rating bars
2935 cs->rating_colour = buf->ReadByte();
2936 break;
2938 case 0x14: // Colour for cargo graph
2939 cs->legend_colour = buf->ReadByte();
2940 break;
2942 case 0x15: // Freight status
2943 cs->is_freight = (buf->ReadByte() != 0);
2944 break;
2946 case 0x16: // Cargo classes
2947 cs->classes = buf->ReadWord();
2948 break;
2950 case 0x17: // Cargo label
2951 cs->label = buf->ReadDWord();
2952 cs->label = BSWAP32(cs->label);
2953 break;
2955 case 0x18: { // Town growth substitute type
2956 uint8 substitute_type = buf->ReadByte();
2958 switch (substitute_type) {
2959 case 0x00: cs->town_effect = TE_PASSENGERS; break;
2960 case 0x02: cs->town_effect = TE_MAIL; break;
2961 case 0x05: cs->town_effect = TE_GOODS; break;
2962 case 0x09: cs->town_effect = TE_WATER; break;
2963 case 0x0B: cs->town_effect = TE_FOOD; break;
2964 default:
2965 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
2966 /* FALL THROUGH */
2967 case 0xFF: cs->town_effect = TE_NONE; break;
2969 break;
2972 case 0x19: // Town growth coefficient
2973 cs->multipliertowngrowth = buf->ReadWord();
2974 break;
2976 case 0x1A: // Bitmask of callbacks to use
2977 cs->callback_mask = buf->ReadByte();
2978 break;
2980 case 0x1D: // Vehicle capacity muliplier
2981 cs->multiplier = max<uint16>(1u, buf->ReadWord());
2982 break;
2984 default:
2985 ret = CIR_UNKNOWN;
2986 break;
2990 return ret;
2995 * Define properties for sound effects
2996 * @param sid Local ID of the sound.
2997 * @param numinfo Number of subsequent IDs to change the property for.
2998 * @param prop The property to change.
2999 * @param buf The property value.
3000 * @return ChangeInfoResult.
3002 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
3004 ChangeInfoResult ret = CIR_SUCCESS;
3006 if (_cur.grffile->sound_offset == 0) {
3007 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3008 return CIR_INVALID_ID;
3011 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
3012 grfmsg(1, "SoundEffectChangeInfo: Attemting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
3013 return CIR_INVALID_ID;
3016 for (int i = 0; i < numinfo; i++) {
3017 SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
3019 switch (prop) {
3020 case 0x08: // Relative volume
3021 sound->volume = buf->ReadByte();
3022 break;
3024 case 0x09: // Priority
3025 sound->priority = buf->ReadByte();
3026 break;
3028 case 0x0A: { // Override old sound
3029 SoundID orig_sound = buf->ReadByte();
3031 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
3032 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
3033 } else {
3034 SoundEntry *old_sound = GetSound(orig_sound);
3036 /* Literally copy the data of the new sound over the original */
3037 *old_sound = *sound;
3039 break;
3042 default:
3043 ret = CIR_UNKNOWN;
3044 break;
3048 return ret;
3052 * Ignore an industry tile property
3053 * @param prop The property to ignore.
3054 * @param buf The property value.
3055 * @return ChangeInfoResult.
3057 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
3059 ChangeInfoResult ret = CIR_SUCCESS;
3061 switch (prop) {
3062 case 0x09:
3063 case 0x0D:
3064 case 0x0E:
3065 case 0x10:
3066 case 0x11:
3067 case 0x12:
3068 buf->ReadByte();
3069 break;
3071 case 0x0A:
3072 case 0x0B:
3073 case 0x0C:
3074 case 0x0F:
3075 buf->ReadWord();
3076 break;
3078 default:
3079 ret = CIR_UNKNOWN;
3080 break;
3082 return ret;
3086 * Define properties for industry tiles
3087 * @param indtid Local ID of the industry tile.
3088 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3089 * @param prop The property to change.
3090 * @param buf The property value.
3091 * @return ChangeInfoResult.
3093 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
3095 ChangeInfoResult ret = CIR_SUCCESS;
3097 if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
3098 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
3099 return CIR_INVALID_ID;
3102 /* Allocate industry tile specs if they haven't been allocated already. */
3103 if (_cur.grffile->indtspec == NULL) {
3104 _cur.grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES_PER_GRF);
3107 for (int i = 0; i < numinfo; i++) {
3108 IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
3110 if (prop != 0x08 && tsp == NULL) {
3111 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
3112 if (cir > ret) ret = cir;
3113 continue;
3116 switch (prop) {
3117 case 0x08: { // Substitute industry tile type
3118 IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i];
3119 byte subs_id = buf->ReadByte();
3121 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
3122 /* The substitute id must be one of the original industry tile. */
3123 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3124 continue;
3127 /* Allocate space for this industry. */
3128 if (*tilespec == NULL) {
3129 *tilespec = CallocT<IndustryTileSpec>(1);
3130 tsp = *tilespec;
3132 memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
3133 tsp->enabled = true;
3135 /* A copied tile should not have the animation infos copied too.
3136 * The anim_state should be left untouched, though
3137 * It is up to the author to animate them himself */
3138 tsp->anim_production = INDUSTRYTILE_NOANIM;
3139 tsp->anim_next = INDUSTRYTILE_NOANIM;
3141 tsp->grf_prop.local_id = indtid + i;
3142 tsp->grf_prop.subst_id = subs_id;
3143 tsp->grf_prop.grffile = _cur.grffile;
3144 _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3146 break;
3149 case 0x09: { // Industry tile override
3150 byte ovrid = buf->ReadByte();
3152 /* The industry being overridden must be an original industry. */
3153 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
3154 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3155 continue;
3158 _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
3159 break;
3162 case 0x0A: // Tile acceptance
3163 case 0x0B:
3164 case 0x0C: {
3165 uint16 acctp = buf->ReadWord();
3166 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
3167 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
3168 break;
3171 case 0x0D: // Land shape flags
3172 tsp->slopes_refused = (Slope)buf->ReadByte();
3173 break;
3175 case 0x0E: // Callback mask
3176 tsp->callback_mask = buf->ReadByte();
3177 break;
3179 case 0x0F: // Animation information
3180 tsp->animation.frames = buf->ReadByte();
3181 tsp->animation.status = buf->ReadByte();
3182 break;
3184 case 0x10: // Animation speed
3185 tsp->animation.speed = buf->ReadByte();
3186 break;
3188 case 0x11: // Triggers for callback 25
3189 tsp->animation.triggers = buf->ReadByte();
3190 break;
3192 case 0x12: // Special flags
3193 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
3194 break;
3196 default:
3197 ret = CIR_UNKNOWN;
3198 break;
3202 return ret;
3206 * Ignore an industry property
3207 * @param prop The property to ignore.
3208 * @param buf The property value.
3209 * @return ChangeInfoResult.
3211 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
3213 ChangeInfoResult ret = CIR_SUCCESS;
3215 switch (prop) {
3216 case 0x09:
3217 case 0x0B:
3218 case 0x0F:
3219 case 0x12:
3220 case 0x13:
3221 case 0x14:
3222 case 0x17:
3223 case 0x18:
3224 case 0x19:
3225 case 0x21:
3226 case 0x22:
3227 buf->ReadByte();
3228 break;
3230 case 0x0C:
3231 case 0x0D:
3232 case 0x0E:
3233 case 0x10:
3234 case 0x1B:
3235 case 0x1F:
3236 case 0x24:
3237 buf->ReadWord();
3238 break;
3240 case 0x11:
3241 case 0x1A:
3242 case 0x1C:
3243 case 0x1D:
3244 case 0x1E:
3245 case 0x20:
3246 case 0x23:
3247 buf->ReadDWord();
3248 break;
3250 case 0x0A: {
3251 byte num_table = buf->ReadByte();
3252 for (byte j = 0; j < num_table; j++) {
3253 for (uint k = 0;; k++) {
3254 byte x = buf->ReadByte();
3255 if (x == 0xFE && k == 0) {
3256 buf->ReadByte();
3257 buf->ReadByte();
3258 break;
3261 byte y = buf->ReadByte();
3262 if (x == 0 && y == 0x80) break;
3264 byte gfx = buf->ReadByte();
3265 if (gfx == 0xFE) buf->ReadWord();
3268 break;
3271 case 0x16:
3272 for (byte j = 0; j < 3; j++) buf->ReadByte();
3273 break;
3275 case 0x15: {
3276 byte number_of_sounds = buf->ReadByte();
3277 for (uint8 j = 0; j < number_of_sounds; j++) {
3278 buf->ReadByte();
3280 break;
3283 default:
3284 ret = CIR_UNKNOWN;
3285 break;
3287 return ret;
3291 * Validate the industry layout; e.g. to prevent duplicate tiles.
3292 * @param layout The layout to check.
3293 * @param size The size of the layout.
3294 * @return True if the layout is deemed valid.
3296 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
3298 for (int i = 0; i < size - 1; i++) {
3299 for (int j = i + 1; j < size; j++) {
3300 if (layout[i].ti.x == layout[j].ti.x &&
3301 layout[i].ti.y == layout[j].ti.y) {
3302 return false;
3306 return true;
3309 /** Clean the tile table of the IndustrySpec if it's needed. */
3310 static void CleanIndustryTileTable(IndustrySpec *ind)
3312 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) {
3313 for (int j = 0; j < ind->num_table; j++) {
3314 /* remove the individual layouts */
3315 free(ind->table[j]);
3317 /* remove the layouts pointers */
3318 free(ind->table);
3319 ind->table = NULL;
3324 * Define properties for industries
3325 * @param indid Local ID of the industry.
3326 * @param numinfo Number of subsequent industry IDs to change the property for.
3327 * @param prop The property to change.
3328 * @param buf The property value.
3329 * @return ChangeInfoResult.
3331 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3333 ChangeInfoResult ret = CIR_SUCCESS;
3335 if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
3336 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
3337 return CIR_INVALID_ID;
3340 /* Allocate industry specs if they haven't been allocated already. */
3341 if (_cur.grffile->industryspec == NULL) {
3342 _cur.grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES_PER_GRF);
3345 for (int i = 0; i < numinfo; i++) {
3346 IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3348 if (prop != 0x08 && indsp == NULL) {
3349 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3350 if (cir > ret) ret = cir;
3351 continue;
3354 switch (prop) {
3355 case 0x08: { // Substitute industry type
3356 IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i];
3357 byte subs_id = buf->ReadByte();
3359 if (subs_id == 0xFF) {
3360 /* Instead of defining a new industry, a substitute industry id
3361 * of 0xFF disables the old industry with the current id. */
3362 _industry_specs[indid + i].enabled = false;
3363 continue;
3364 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3365 /* The substitute id must be one of the original industry. */
3366 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3367 continue;
3370 /* Allocate space for this industry.
3371 * Only need to do it once. If ever it is called again, it should not
3372 * do anything */
3373 if (*indspec == NULL) {
3374 *indspec = CallocT<IndustrySpec>(1);
3375 indsp = *indspec;
3377 memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
3378 indsp->enabled = true;
3379 indsp->grf_prop.local_id = indid + i;
3380 indsp->grf_prop.subst_id = subs_id;
3381 indsp->grf_prop.grffile = _cur.grffile;
3382 /* If the grf industry needs to check its surounding upon creation, it should
3383 * rely on callbacks, not on the original placement functions */
3384 indsp->check_proc = CHECK_NOTHING;
3386 break;
3389 case 0x09: { // Industry type override
3390 byte ovrid = buf->ReadByte();
3392 /* The industry being overridden must be an original industry. */
3393 if (ovrid >= NEW_INDUSTRYOFFSET) {
3394 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3395 continue;
3397 indsp->grf_prop.override = ovrid;
3398 _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3399 break;
3402 case 0x0A: { // Set industry layout(s)
3403 byte new_num_layouts = buf->ReadByte(); // Number of layaouts
3404 /* We read the total size in bytes, but we can't rely on the
3405 * newgrf to provide a sane value. First assume the value is
3406 * sane but later on we make sure we enlarge the array if the
3407 * newgrf contains more data. Each tile uses either 3 or 5
3408 * bytes, so to play it safe we assume 3. */
3409 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
3410 IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(new_num_layouts); // Table with tiles to compose an industry
3411 IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles); // Temporary array to read the tile layouts from the GRF
3412 uint size;
3413 const IndustryTileTable *copy_from;
3415 try {
3416 for (byte j = 0; j < new_num_layouts; j++) {
3417 for (uint k = 0;; k++) {
3418 if (k >= def_num_tiles) {
3419 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3420 /* Size reported by newgrf was not big enough so enlarge the array. */
3421 def_num_tiles *= 2;
3422 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
3425 itt[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3427 if (itt[k].ti.x == 0xFE && k == 0) {
3428 /* This means we have to borrow the layout from an old industry */
3429 IndustryType type = buf->ReadByte(); // industry holding required layout
3430 byte laynbr = buf->ReadByte(); // layout number to borrow
3432 copy_from = _origin_industry_specs[type].table[laynbr];
3433 for (size = 1;; size++) {
3434 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
3436 break;
3439 itt[k].ti.y = buf->ReadByte(); // Or table definition finalisation
3441 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
3442 /* Not the same terminator. The one we are using is rather
3443 x = -80, y = x . So, adjust it. */
3444 itt[k].ti.x = -0x80;
3445 itt[k].ti.y = 0;
3446 itt[k].gfx = 0;
3448 size = k + 1;
3449 copy_from = itt;
3450 break;
3453 itt[k].gfx = buf->ReadByte();
3455 if (itt[k].gfx == 0xFE) {
3456 /* Use a new tile from this GRF */
3457 int local_tile_id = buf->ReadWord();
3459 /* Read the ID from the _industile_mngr. */
3460 int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3462 if (tempid == INVALID_INDUSTRYTILE) {
3463 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3464 } else {
3465 /* Declared as been valid, can be used */
3466 itt[k].gfx = tempid;
3467 size = k + 1;
3468 copy_from = itt;
3470 } else if (itt[k].gfx == 0xFF) {
3471 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
3472 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
3476 if (!ValidateIndustryLayout(copy_from, size)) {
3477 /* The industry layout was not valid, so skip this one. */
3478 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3479 new_num_layouts--;
3480 j--;
3481 } else {
3482 tile_table[j] = CallocT<IndustryTileTable>(size);
3483 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3486 } catch (...) {
3487 for (int i = 0; i < new_num_layouts; i++) {
3488 free(tile_table[i]);
3490 free(tile_table);
3491 free(itt);
3492 throw;
3495 /* Clean the tile table if it was already set by a previous prop A. */
3496 CleanIndustryTileTable(indsp);
3497 /* Install final layout construction in the industry spec */
3498 indsp->num_table = new_num_layouts;
3499 indsp->table = tile_table;
3500 SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
3501 free(itt);
3502 break;
3505 case 0x0B: // Industry production flags
3506 indsp->life_type = (IndustryLifeType)buf->ReadByte();
3507 break;
3509 case 0x0C: // Industry closure message
3510 AddStringForMapping(buf->ReadWord(), &indsp->closure_text);
3511 break;
3513 case 0x0D: // Production increase message
3514 AddStringForMapping(buf->ReadWord(), &indsp->production_up_text);
3515 break;
3517 case 0x0E: // Production decrease message
3518 AddStringForMapping(buf->ReadWord(), &indsp->production_down_text);
3519 break;
3521 case 0x0F: // Fund cost multiplier
3522 indsp->cost_multiplier = buf->ReadByte();
3523 break;
3525 case 0x10: // Production cargo types
3526 for (byte j = 0; j < 2; j++) {
3527 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3529 break;
3531 case 0x11: // Acceptance cargo types
3532 for (byte j = 0; j < 3; j++) {
3533 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3535 buf->ReadByte(); // Unnused, eat it up
3536 break;
3538 case 0x12: // Production multipliers
3539 case 0x13:
3540 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3541 break;
3543 case 0x14: // Minimal amount of cargo distributed
3544 indsp->minimal_cargo = buf->ReadByte();
3545 break;
3547 case 0x15: { // Random sound effects
3548 indsp->number_of_sounds = buf->ReadByte();
3549 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
3551 try {
3552 for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
3553 sounds[j] = buf->ReadByte();
3555 } catch (...) {
3556 free(sounds);
3557 throw;
3560 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3561 free(indsp->random_sounds);
3563 indsp->random_sounds = sounds;
3564 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
3565 break;
3568 case 0x16: // Conflicting industry types
3569 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3570 break;
3572 case 0x17: // Probability in random game
3573 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3574 break;
3576 case 0x18: // Probability during gameplay
3577 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3578 break;
3580 case 0x19: // Map colour
3581 indsp->map_colour = buf->ReadByte();
3582 break;
3584 case 0x1A: // Special industry flags to define special behavior
3585 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3586 break;
3588 case 0x1B: // New industry text ID
3589 AddStringForMapping(buf->ReadWord(), &indsp->new_industry_text);
3590 break;
3592 case 0x1C: // Input cargo multipliers for the three input cargo types
3593 case 0x1D:
3594 case 0x1E: {
3595 uint32 multiples = buf->ReadDWord();
3596 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3597 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3598 break;
3601 case 0x1F: // Industry name
3602 AddStringForMapping(buf->ReadWord(), &indsp->name);
3603 break;
3605 case 0x20: // Prospecting success chance
3606 indsp->prospecting_chance = buf->ReadDWord();
3607 break;
3609 case 0x21: // Callback mask
3610 case 0x22: { // Callback additional mask
3611 byte aflag = buf->ReadByte();
3612 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3613 break;
3616 case 0x23: // removal cost multiplier
3617 indsp->removal_cost_multiplier = buf->ReadDWord();
3618 break;
3620 case 0x24: { // name for nearby station
3621 uint16 str = buf->ReadWord();
3622 if (str == 0) {
3623 indsp->station_name = STR_NULL;
3624 } else {
3625 AddStringForMapping(str, &indsp->station_name);
3627 break;
3630 default:
3631 ret = CIR_UNKNOWN;
3632 break;
3636 return ret;
3640 * Create a copy of the tile table so it can be freed later
3641 * without problems.
3642 * @param as The AirportSpec to copy the arrays of.
3644 static void DuplicateTileTable(AirportSpec *as)
3646 AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
3647 for (int i = 0; i < as->num_table; i++) {
3648 uint num_tiles = 1;
3649 const AirportTileTable *it = as->table[0];
3650 do {
3651 num_tiles++;
3652 } while ((++it)->ti.x != -0x80);
3653 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3654 MemCpyT(table_list[i], as->table[i], num_tiles);
3656 as->table = table_list;
3657 HangarTileTable *depot_table = MallocT<HangarTileTable>(as->nof_depots);
3658 MemCpyT(depot_table, as->depot_table, as->nof_depots);
3659 as->depot_table = depot_table;
3663 * Define properties for airports
3664 * @param airport Local ID of the airport.
3665 * @param numinfo Number of subsequent airport IDs to change the property for.
3666 * @param prop The property to change.
3667 * @param buf The property value.
3668 * @return ChangeInfoResult.
3670 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3672 ChangeInfoResult ret = CIR_SUCCESS;
3674 if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
3675 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
3676 return CIR_INVALID_ID;
3679 /* Allocate industry specs if they haven't been allocated already. */
3680 if (_cur.grffile->airportspec == NULL) {
3681 _cur.grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS_PER_GRF);
3684 for (int i = 0; i < numinfo; i++) {
3685 AirportSpec *as = _cur.grffile->airportspec[airport + i];
3687 if (as == NULL && prop != 0x08 && prop != 0x09) {
3688 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3689 return CIR_INVALID_ID;
3692 switch (prop) {
3693 case 0x08: { // Modify original airport
3694 byte subs_id = buf->ReadByte();
3696 if (subs_id == 0xFF) {
3697 /* Instead of defining a new airport, an airport id
3698 * of 0xFF disables the old airport with the current id. */
3699 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3700 continue;
3701 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3702 /* The substitute id must be one of the original airports. */
3703 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3704 continue;
3707 AirportSpec **spec = &_cur.grffile->airportspec[airport + i];
3708 /* Allocate space for this airport.
3709 * Only need to do it once. If ever it is called again, it should not
3710 * do anything */
3711 if (*spec == NULL) {
3712 *spec = MallocT<AirportSpec>(1);
3713 as = *spec;
3715 memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
3716 as->enabled = true;
3717 as->grf_prop.local_id = airport + i;
3718 as->grf_prop.subst_id = subs_id;
3719 as->grf_prop.grffile = _cur.grffile;
3720 /* override the default airport */
3721 _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3722 /* Create a copy of the original tiletable so it can be freed later. */
3723 DuplicateTileTable(as);
3725 break;
3728 case 0x0A: { // Set airport layout
3729 as->num_table = buf->ReadByte(); // Number of layaouts
3730 as->rotation = MallocT<Direction>(as->num_table);
3731 uint32 defsize = buf->ReadDWord(); // Total size of the definition
3732 AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3733 AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
3734 int size;
3735 const AirportTileTable *copy_from;
3736 try {
3737 for (byte j = 0; j < as->num_table; j++) {
3738 as->rotation[j] = (Direction)buf->ReadByte();
3739 for (int k = 0;; k++) {
3740 att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3741 att[k].ti.y = buf->ReadByte();
3743 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3744 /* Not the same terminator. The one we are using is rather
3745 * x = -80, y = 0 . So, adjust it. */
3746 att[k].ti.x = -0x80;
3747 att[k].ti.y = 0;
3748 att[k].gfx = 0;
3750 size = k + 1;
3751 copy_from = att;
3752 break;
3755 att[k].gfx = buf->ReadByte();
3757 if (att[k].gfx == 0xFE) {
3758 /* Use a new tile from this GRF */
3759 int local_tile_id = buf->ReadWord();
3761 /* Read the ID from the _airporttile_mngr. */
3762 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3764 if (tempid == INVALID_AIRPORTTILE) {
3765 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3766 } else {
3767 /* Declared as been valid, can be used */
3768 att[k].gfx = tempid;
3769 size = k + 1;
3770 copy_from = att;
3772 } else if (att[k].gfx == 0xFF) {
3773 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3774 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3777 if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
3778 as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
3779 as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
3780 } else {
3781 as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
3782 as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
3785 tile_table[j] = CallocT<AirportTileTable>(size);
3786 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3788 /* Install final layout construction in the airport spec */
3789 as->table = tile_table;
3790 free(att);
3791 } catch (...) {
3792 for (int i = 0; i < as->num_table; i++) {
3793 free(tile_table[i]);
3795 free(tile_table);
3796 free(att);
3797 throw;
3799 break;
3802 case 0x0C:
3803 as->min_year = buf->ReadWord();
3804 as->max_year = buf->ReadWord();
3805 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3806 break;
3808 case 0x0D:
3809 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3810 break;
3812 case 0x0E:
3813 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3814 break;
3816 case 0x0F:
3817 as->noise_level = buf->ReadByte();
3818 break;
3820 case 0x10:
3821 AddStringForMapping(buf->ReadWord(), &as->name);
3822 break;
3824 case 0x11: // Maintenance cost factor
3825 as->maintenance_cost = buf->ReadWord();
3826 break;
3828 default:
3829 ret = CIR_UNKNOWN;
3830 break;
3834 return ret;
3838 * Ignore properties for objects
3839 * @param prop The property to ignore.
3840 * @param buf The property value.
3841 * @return ChangeInfoResult.
3843 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
3845 ChangeInfoResult ret = CIR_SUCCESS;
3847 switch (prop) {
3848 case 0x0B:
3849 case 0x0C:
3850 case 0x0D:
3851 case 0x12:
3852 case 0x14:
3853 case 0x16:
3854 case 0x17:
3855 buf->ReadByte();
3856 break;
3858 case 0x09:
3859 case 0x0A:
3860 case 0x10:
3861 case 0x11:
3862 case 0x13:
3863 case 0x15:
3864 buf->ReadWord();
3865 break;
3867 case 0x08:
3868 case 0x0E:
3869 case 0x0F:
3870 buf->ReadDWord();
3871 break;
3873 default:
3874 ret = CIR_UNKNOWN;
3875 break;
3878 return ret;
3882 * Define properties for objects
3883 * @param id Local ID of the object.
3884 * @param numinfo Number of subsequent objectIDs to change the property for.
3885 * @param prop The property to change.
3886 * @param buf The property value.
3887 * @return ChangeInfoResult.
3889 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
3891 ChangeInfoResult ret = CIR_SUCCESS;
3893 if (id + numinfo > NUM_OBJECTS_PER_GRF) {
3894 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
3895 return CIR_INVALID_ID;
3898 /* Allocate object specs if they haven't been allocated already. */
3899 if (_cur.grffile->objectspec == NULL) {
3900 _cur.grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS_PER_GRF);
3903 for (int i = 0; i < numinfo; i++) {
3904 ObjectSpec *spec = _cur.grffile->objectspec[id + i];
3906 if (prop != 0x08 && spec == NULL) {
3907 /* If the object property 08 is not yet set, ignore this property */
3908 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
3909 if (cir > ret) ret = cir;
3910 continue;
3913 switch (prop) {
3914 case 0x08: { // Class ID
3915 ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
3917 /* Allocate space for this object. */
3918 if (*ospec == NULL) {
3919 *ospec = CallocT<ObjectSpec>(1);
3920 (*ospec)->views = 1; // Default for NewGRFs that don't set it.
3923 /* Swap classid because we read it in BE. */
3924 uint32 classid = buf->ReadDWord();
3925 (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
3926 (*ospec)->enabled = true;
3927 break;
3930 case 0x09: { // Class name
3931 ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
3932 AddStringForMapping(buf->ReadWord(), &objclass->name);
3933 break;
3936 case 0x0A: // Object name
3937 AddStringForMapping(buf->ReadWord(), &spec->name);
3938 break;
3940 case 0x0B: // Climate mask
3941 spec->climate = buf->ReadByte();
3942 break;
3944 case 0x0C: // Size
3945 spec->size = buf->ReadByte();
3946 break;
3948 case 0x0D: // Build cost multipler
3949 spec->build_cost_multiplier = buf->ReadByte();
3950 spec->clear_cost_multiplier = spec->build_cost_multiplier;
3951 break;
3953 case 0x0E: // Introduction date
3954 spec->introduction_date = buf->ReadDWord();
3955 break;
3957 case 0x0F: // End of life
3958 spec->end_of_life_date = buf->ReadDWord();
3959 break;
3961 case 0x10: // Flags
3962 spec->flags = (ObjectFlags)buf->ReadWord();
3963 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
3964 break;
3966 case 0x11: // Animation info
3967 spec->animation.frames = buf->ReadByte();
3968 spec->animation.status = buf->ReadByte();
3969 break;
3971 case 0x12: // Animation speed
3972 spec->animation.speed = buf->ReadByte();
3973 break;
3975 case 0x13: // Animation triggers
3976 spec->animation.triggers = buf->ReadWord();
3977 break;
3979 case 0x14: // Removal cost multiplier
3980 spec->clear_cost_multiplier = buf->ReadByte();
3981 break;
3983 case 0x15: // Callback mask
3984 spec->callback_mask = buf->ReadWord();
3985 break;
3987 case 0x16: // Building height
3988 spec->height = buf->ReadByte();
3989 break;
3991 case 0x17: // Views
3992 spec->views = buf->ReadByte();
3993 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
3994 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
3995 spec->views = 1;
3997 break;
3999 case 0x18: // Amount placed on 256^2 map on map creation
4000 spec->generate_amount = buf->ReadByte();
4001 break;
4003 default:
4004 ret = CIR_UNKNOWN;
4005 break;
4009 return ret;
4013 * Define properties for railtypes
4014 * @param id ID of the railtype.
4015 * @param numinfo Number of subsequent IDs to change the property for.
4016 * @param prop The property to change.
4017 * @param buf The property value.
4018 * @return ChangeInfoResult.
4020 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4022 ChangeInfoResult ret = CIR_SUCCESS;
4024 extern RailtypeInfo _railtypes[RAILTYPE_END];
4026 if (id + numinfo > RAILTYPE_END) {
4027 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4028 return CIR_INVALID_ID;
4031 for (int i = 0; i < numinfo; i++) {
4032 RailType rt = _cur.grffile->railtype_map[id + i];
4033 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
4035 RailtypeInfo *rti = &_railtypes[rt];
4037 switch (prop) {
4038 case 0x08: // Label of rail type
4039 /* Skipped here as this is loaded during reservation stage. */
4040 buf->ReadDWord();
4041 break;
4043 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4044 uint16 str = buf->ReadWord();
4045 AddStringForMapping(str, &rti->strings.toolbar_caption);
4046 if (_cur.grffile->grf_version < 8) {
4047 AddStringForMapping(str, &rti->strings.name);
4049 break;
4052 case 0x0A: // Menu text of railtype
4053 AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4054 break;
4056 case 0x0B: // Build window caption
4057 AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4058 break;
4060 case 0x0C: // Autoreplace text
4061 AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4062 break;
4064 case 0x0D: // New locomotive text
4065 AddStringForMapping(buf->ReadWord(), &rti->strings.new_loco);
4066 break;
4068 case 0x0E: // Compatible railtype list
4069 case 0x0F: // Powered railtype list
4070 case 0x18: // Railtype list required for date introduction
4071 case 0x19: // Introduced railtype list
4073 /* Rail type compatibility bits are added to the existing bits
4074 * to allow multiple GRFs to modify compatibility with the
4075 * default rail types. */
4076 int n = buf->ReadByte();
4077 for (int j = 0; j != n; j++) {
4078 RailTypeLabel label = buf->ReadDWord();
4079 RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
4080 if (rt != INVALID_RAILTYPE) {
4081 switch (prop) {
4082 case 0x0F: SetBit(rti->powered_railtypes, rt); // Powered implies compatible.
4083 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
4084 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
4085 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
4089 break;
4092 case 0x10: // Rail Type flags
4093 rti->flags = (RailTypeFlags)buf->ReadByte();
4094 break;
4096 case 0x11: // Curve speed advantage
4097 rti->curve_speed = buf->ReadByte();
4098 break;
4100 case 0x12: // Station graphic
4101 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
4102 break;
4104 case 0x13: // Construction cost factor
4105 rti->cost_multiplier = buf->ReadWord();
4106 break;
4108 case 0x14: // Speed limit
4109 rti->max_speed = buf->ReadWord();
4110 break;
4112 case 0x15: // Acceleration model
4113 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
4114 break;
4116 case 0x16: // Map colour
4117 rti->map_colour = buf->ReadByte();
4118 break;
4120 case 0x17: // Introduction date
4121 rti->introduction_date = buf->ReadDWord();
4122 break;
4124 case 0x1A: // Sort order
4125 rti->sorting_order = buf->ReadByte();
4126 break;
4128 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4129 AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4130 break;
4132 case 0x1C: // Maintenance cost factor
4133 rti->maintenance_multiplier = buf->ReadWord();
4134 break;
4136 case 0x1D: // Alternate rail type label list
4137 /* Skipped here as this is loaded during reservation stage. */
4138 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4139 break;
4141 default:
4142 ret = CIR_UNKNOWN;
4143 break;
4147 return ret;
4150 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4152 ChangeInfoResult ret = CIR_SUCCESS;
4154 extern RailtypeInfo _railtypes[RAILTYPE_END];
4156 if (id + numinfo > RAILTYPE_END) {
4157 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4158 return CIR_INVALID_ID;
4161 for (int i = 0; i < numinfo; i++) {
4162 switch (prop) {
4163 case 0x08: // Label of rail type
4165 RailTypeLabel rtl = buf->ReadDWord();
4166 rtl = BSWAP32(rtl);
4168 RailType rt = GetRailTypeByLabel(rtl, false);
4169 if (rt == INVALID_RAILTYPE) {
4170 /* Set up new rail type */
4171 rt = AllocateRailType(rtl);
4174 _cur.grffile->railtype_map[id + i] = rt;
4175 break;
4178 case 0x09: // Toolbar caption of railtype
4179 case 0x0A: // Menu text
4180 case 0x0B: // Build window caption
4181 case 0x0C: // Autoreplace text
4182 case 0x0D: // New loco
4183 case 0x13: // Construction cost
4184 case 0x14: // Speed limit
4185 case 0x1B: // Name of railtype
4186 case 0x1C: // Maintenance cost factor
4187 buf->ReadWord();
4188 break;
4190 case 0x1D: // Alternate rail type label list
4191 if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
4192 int n = buf->ReadByte();
4193 for (int j = 0; j != n; j++) {
4194 *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord());
4196 break;
4198 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
4199 /* FALL THROUGH */
4201 case 0x0E: // Compatible railtype list
4202 case 0x0F: // Powered railtype list
4203 case 0x18: // Railtype list required for date introduction
4204 case 0x19: // Introduced railtype list
4205 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4206 break;
4208 case 0x10: // Rail Type flags
4209 case 0x11: // Curve speed advantage
4210 case 0x12: // Station graphic
4211 case 0x15: // Acceleration model
4212 case 0x16: // Map colour
4213 case 0x1A: // Sort order
4214 buf->ReadByte();
4215 break;
4217 case 0x17: // Introduction date
4218 buf->ReadDWord();
4219 break;
4221 default:
4222 ret = CIR_UNKNOWN;
4223 break;
4227 return ret;
4230 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
4232 ChangeInfoResult ret = CIR_SUCCESS;
4234 if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
4235 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
4236 return CIR_INVALID_ID;
4239 /* Allocate airport tile specs if they haven't been allocated already. */
4240 if (_cur.grffile->airtspec == NULL) {
4241 _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES_PER_GRF);
4244 for (int i = 0; i < numinfo; i++) {
4245 AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
4247 if (prop != 0x08 && tsp == NULL) {
4248 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4249 return CIR_INVALID_ID;
4252 switch (prop) {
4253 case 0x08: { // Substitute airport tile type
4254 AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
4255 byte subs_id = buf->ReadByte();
4257 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
4258 /* The substitute id must be one of the original airport tiles. */
4259 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4260 continue;
4263 /* Allocate space for this airport tile. */
4264 if (*tilespec == NULL) {
4265 *tilespec = CallocT<AirportTileSpec>(1);
4266 tsp = *tilespec;
4268 memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
4269 tsp->enabled = true;
4271 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
4273 tsp->grf_prop.local_id = airtid + i;
4274 tsp->grf_prop.subst_id = subs_id;
4275 tsp->grf_prop.grffile = _cur.grffile;
4276 _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
4278 break;
4281 case 0x09: { // Airport tile override
4282 byte override = buf->ReadByte();
4284 /* The airport tile being overridden must be an original airport tile. */
4285 if (override >= NEW_AIRPORTTILE_OFFSET) {
4286 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
4287 continue;
4290 _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
4291 break;
4294 case 0x0E: // Callback mask
4295 tsp->callback_mask = buf->ReadByte();
4296 break;
4298 case 0x0F: // Animation information
4299 tsp->animation.frames = buf->ReadByte();
4300 tsp->animation.status = buf->ReadByte();
4301 break;
4303 case 0x10: // Animation speed
4304 tsp->animation.speed = buf->ReadByte();
4305 break;
4307 case 0x11: // Animation triggers
4308 tsp->animation.triggers = buf->ReadByte();
4309 break;
4311 default:
4312 ret = CIR_UNKNOWN;
4313 break;
4317 return ret;
4320 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4322 switch (cir) {
4323 default: NOT_REACHED();
4325 case CIR_DISABLED:
4326 /* Error has already been printed; just stop parsing */
4327 return true;
4329 case CIR_SUCCESS:
4330 return false;
4332 case CIR_UNHANDLED:
4333 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4334 return false;
4336 case CIR_UNKNOWN:
4337 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4338 /* FALL THROUGH */
4340 case CIR_INVALID_ID: {
4341 /* No debug message for an invalid ID, as it has already been output */
4342 GRFError *error = DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4343 if (cir != CIR_INVALID_ID) error->param_value[1] = property;
4344 return true;
4349 /* Action 0x00 */
4350 static void FeatureChangeInfo(ByteReader *buf)
4352 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4354 * B feature
4355 * B num-props how many properties to change per vehicle/station
4356 * B num-info how many vehicles/stations to change
4357 * E id ID of first vehicle/station to change, if num-info is
4358 * greater than one, this one and the following
4359 * vehicles/stations will be changed
4360 * B property what property to change, depends on the feature
4361 * V new-info new bytes of info (variable size; depends on properties) */
4363 static const VCI_Handler handler[] = {
4364 /* GSF_TRAINS */ RailVehicleChangeInfo,
4365 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4366 /* GSF_SHIPS */ ShipVehicleChangeInfo,
4367 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4368 /* GSF_STATIONS */ StationChangeInfo,
4369 /* GSF_CANALS */ CanalChangeInfo,
4370 /* GSF_BRIDGES */ BridgeChangeInfo,
4371 /* GSF_HOUSES */ TownHouseChangeInfo,
4372 /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4373 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4374 /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4375 /* GSF_CARGOES */ NULL, // Cargo is handled during reservation
4376 /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4377 /* GSF_AIRPORTS */ AirportChangeInfo,
4378 /* GSF_SIGNALS */ NULL,
4379 /* GSF_OBJECTS */ ObjectChangeInfo,
4380 /* GSF_RAILTYPES */ RailTypeChangeInfo,
4381 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4384 uint8 feature = buf->ReadByte();
4385 uint8 numprops = buf->ReadByte();
4386 uint numinfo = buf->ReadByte();
4387 uint engine = buf->ReadExtendedByte();
4389 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4390 feature, numprops, engine, numinfo);
4392 if (feature >= lengthof(handler) || handler[feature] == NULL) {
4393 if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
4394 return;
4397 /* Mark the feature as used by the grf */
4398 SetBit(_cur.grffile->grf_features, feature);
4400 while (numprops-- && buf->HasData()) {
4401 uint8 prop = buf->ReadByte();
4403 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4404 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
4408 /* Action 0x00 (GLS_SAFETYSCAN) */
4409 static void SafeChangeInfo(ByteReader *buf)
4411 uint8 feature = buf->ReadByte();
4412 uint8 numprops = buf->ReadByte();
4413 uint numinfo = buf->ReadByte();
4414 buf->ReadExtendedByte(); // id
4416 if (feature == GSF_BRIDGES && numprops == 1) {
4417 uint8 prop = buf->ReadByte();
4418 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4419 * is considered safe. */
4420 if (prop == 0x0D) return;
4421 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4422 uint8 prop = buf->ReadByte();
4423 /* Engine ID Mappings are safe, if the source is static */
4424 if (prop == 0x11) {
4425 bool is_safe = true;
4426 for (uint i = 0; i < numinfo; i++) {
4427 uint32 s = buf->ReadDWord();
4428 buf->ReadDWord(); // dest
4429 const GRFConfig *grfconfig = GetGRFConfig(s);
4430 if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) {
4431 is_safe = false;
4432 break;
4435 if (is_safe) return;
4439 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4441 /* Skip remainder of GRF */
4442 _cur.skip_sprites = -1;
4445 /* Action 0x00 (GLS_RESERVE) */
4446 static void ReserveChangeInfo(ByteReader *buf)
4448 uint8 feature = buf->ReadByte();
4450 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return;
4452 uint8 numprops = buf->ReadByte();
4453 uint8 numinfo = buf->ReadByte();
4454 uint8 index = buf->ReadExtendedByte();
4456 while (numprops-- && buf->HasData()) {
4457 uint8 prop = buf->ReadByte();
4458 ChangeInfoResult cir = CIR_SUCCESS;
4460 switch (feature) {
4461 default: NOT_REACHED();
4462 case GSF_CARGOES:
4463 cir = CargoChangeInfo(index, numinfo, prop, buf);
4464 break;
4466 case GSF_GLOBALVAR:
4467 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4468 break;
4470 case GSF_RAILTYPES:
4471 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4472 break;
4475 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
4479 /* Action 0x01 */
4480 static void NewSpriteSet(ByteReader *buf)
4482 /* Basic format: <01> <feature> <num-sets> <num-ent>
4483 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4485 * B feature feature to define sprites for
4486 * 0, 1, 2, 3: veh-type, 4: train stations
4487 * E first-set first sprite set to define
4488 * B num-sets number of sprite sets (extended byte in extended format)
4489 * E num-ent how many entries per sprite set
4490 * For vehicles, this is the number of different
4491 * vehicle directions in each sprite set
4492 * Set num-dirs=8, unless your sprites are symmetric.
4493 * In that case, use num-dirs=4.
4496 uint8 feature = buf->ReadByte();
4497 uint16 num_sets = buf->ReadByte();
4498 uint16 first_set = 0;
4500 if (num_sets == 0 && buf->HasData(3)) {
4501 /* Extended Action1 format.
4502 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4503 first_set = buf->ReadExtendedByte();
4504 num_sets = buf->ReadExtendedByte();
4506 uint16 num_ents = buf->ReadExtendedByte();
4508 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4510 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4511 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4514 for (int i = 0; i < num_sets * num_ents; i++) {
4515 _cur.nfo_line++;
4516 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
4520 /* Action 0x01 (SKIP) */
4521 static void SkipAct1(ByteReader *buf)
4523 buf->ReadByte();
4524 uint16 num_sets = buf->ReadByte();
4526 if (num_sets == 0 && buf->HasData(3)) {
4527 /* Extended Action1 format.
4528 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4529 buf->ReadExtendedByte(); // first_set
4530 num_sets = buf->ReadExtendedByte();
4532 uint16 num_ents = buf->ReadExtendedByte();
4534 _cur.skip_sprites = num_sets * num_ents;
4536 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
4539 /* Helper function to either create a callback or link to a previously
4540 * defined spritegroup. */
4541 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4543 if (HasBit(groupid, 15)) {
4544 assert(CallbackResultSpriteGroup::CanAllocateItem());
4545 return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
4548 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4549 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4550 return NULL;
4553 return _cur.spritegroups[groupid];
4557 * Helper function to either create a callback or a result sprite group.
4558 * @param feature GrfSpecFeature to define spritegroup for.
4559 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4560 * @param type Type of the currently being parsed Action2. (only for debug output)
4561 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4562 * @return Created spritegroup.
4564 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4566 if (HasBit(spriteid, 15)) {
4567 assert(CallbackResultSpriteGroup::CanAllocateItem());
4568 return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
4571 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4572 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4573 return NULL;
4576 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4577 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4579 /* Ensure that the sprites are loeded */
4580 assert(spriteset_start + num_sprites <= _cur.spriteid);
4582 assert(ResultSpriteGroup::CanAllocateItem());
4583 return new ResultSpriteGroup(spriteset_start, num_sprites);
4586 /* Action 0x02 */
4587 static void NewSpriteGroup(ByteReader *buf)
4589 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4591 * B feature see action 1
4592 * B set-id ID of this particular definition
4593 * B type/num-entries
4594 * if 80 or greater, this is a randomized or variational
4595 * list definition, see below
4596 * otherwise it specifies a number of entries, the exact
4597 * meaning depends on the feature
4598 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4599 SpriteGroup *act_group = NULL;
4601 uint8 feature = buf->ReadByte();
4602 uint8 setid = buf->ReadByte();
4603 uint8 type = buf->ReadByte();
4605 /* Sprite Groups are created here but they are allocated from a pool, so
4606 * we do not need to delete anything if there is an exception from the
4607 * ByteReader. */
4609 switch (type) {
4610 /* Deterministic Sprite Group */
4611 case 0x81: // Self scope, byte
4612 case 0x82: // Parent scope, byte
4613 case 0x85: // Self scope, word
4614 case 0x86: // Parent scope, word
4615 case 0x89: // Self scope, dword
4616 case 0x8A: // Parent scope, dword
4618 byte varadjust;
4619 byte varsize;
4621 assert(DeterministicSpriteGroup::CanAllocateItem());
4622 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
4623 act_group = group;
4624 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4626 switch (GB(type, 2, 2)) {
4627 default: NOT_REACHED();
4628 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
4629 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
4630 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
4633 static SmallVector<DeterministicSpriteGroupAdjust, 16> adjusts;
4634 adjusts.Clear();
4636 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4637 * from the outset, so we shall have to keep reallocing. */
4638 do {
4639 DeterministicSpriteGroupAdjust *adjust = adjusts.Append();
4641 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4642 adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
4643 adjust->variable = buf->ReadByte();
4644 if (adjust->variable == 0x7E) {
4645 /* Link subroutine group */
4646 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
4647 } else {
4648 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
4651 varadjust = buf->ReadByte();
4652 adjust->shift_num = GB(varadjust, 0, 5);
4653 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
4654 adjust->and_mask = buf->ReadVarSize(varsize);
4656 if (adjust->type != DSGA_TYPE_NONE) {
4657 adjust->add_val = buf->ReadVarSize(varsize);
4658 adjust->divmod_val = buf->ReadVarSize(varsize);
4659 } else {
4660 adjust->add_val = 0;
4661 adjust->divmod_val = 0;
4664 /* Continue reading var adjusts while bit 5 is set. */
4665 } while (HasBit(varadjust, 5));
4667 group->num_adjusts = adjusts.Length();
4668 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
4669 MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts);
4671 group->num_ranges = buf->ReadByte();
4672 if (group->num_ranges > 0) group->ranges = CallocT<DeterministicSpriteGroupRange>(group->num_ranges);
4674 for (uint i = 0; i < group->num_ranges; i++) {
4675 group->ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4676 group->ranges[i].low = buf->ReadVarSize(varsize);
4677 group->ranges[i].high = buf->ReadVarSize(varsize);
4680 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4681 break;
4684 /* Randomized Sprite Group */
4685 case 0x80: // Self scope
4686 case 0x83: // Parent scope
4687 case 0x84: // Relative scope
4689 assert(RandomizedSpriteGroup::CanAllocateItem());
4690 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
4691 act_group = group;
4692 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4694 if (HasBit(type, 2)) {
4695 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
4696 group->count = buf->ReadByte();
4699 uint8 triggers = buf->ReadByte();
4700 group->triggers = GB(triggers, 0, 7);
4701 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
4702 group->lowest_randbit = buf->ReadByte();
4703 group->num_groups = buf->ReadByte();
4704 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
4706 for (uint i = 0; i < group->num_groups; i++) {
4707 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
4710 break;
4713 /* Neither a variable or randomized sprite group... must be a real group */
4714 default:
4716 switch (feature) {
4717 case GSF_TRAINS:
4718 case GSF_ROADVEHICLES:
4719 case GSF_SHIPS:
4720 case GSF_AIRCRAFT:
4721 case GSF_STATIONS:
4722 case GSF_CANALS:
4723 case GSF_CARGOES:
4724 case GSF_AIRPORTS:
4725 case GSF_RAILTYPES:
4727 byte num_loaded = type;
4728 byte num_loading = buf->ReadByte();
4730 if (!_cur.HasValidSpriteSets(feature)) {
4731 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4732 return;
4735 assert(RealSpriteGroup::CanAllocateItem());
4736 RealSpriteGroup *group = new RealSpriteGroup();
4737 act_group = group;
4739 group->num_loaded = num_loaded;
4740 group->num_loading = num_loading;
4741 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
4742 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
4744 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4745 setid, num_loaded, num_loading);
4747 for (uint i = 0; i < num_loaded; i++) {
4748 uint16 spriteid = buf->ReadWord();
4749 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4750 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
4753 for (uint i = 0; i < num_loading; i++) {
4754 uint16 spriteid = buf->ReadWord();
4755 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
4756 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
4759 break;
4762 case GSF_HOUSES:
4763 case GSF_AIRPORTTILES:
4764 case GSF_OBJECTS:
4765 case GSF_INDUSTRYTILES: {
4766 byte num_building_sprites = max((uint8)1, type);
4768 assert(TileLayoutSpriteGroup::CanAllocateItem());
4769 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
4770 act_group = group;
4772 /* On error, bail out immediately. Temporary GRF data was already freed */
4773 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
4774 break;
4777 case GSF_INDUSTRIES: {
4778 if (type > 1) {
4779 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
4780 break;
4783 assert(IndustryProductionSpriteGroup::CanAllocateItem());
4784 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
4785 act_group = group;
4786 group->version = type;
4787 if (type == 0) {
4788 for (uint i = 0; i < 3; i++) {
4789 group->subtract_input[i] = (int16)buf->ReadWord(); // signed
4791 for (uint i = 0; i < 2; i++) {
4792 group->add_output[i] = buf->ReadWord(); // unsigned
4794 group->again = buf->ReadByte();
4795 } else {
4796 for (uint i = 0; i < 3; i++) {
4797 group->subtract_input[i] = buf->ReadByte();
4799 for (uint i = 0; i < 2; i++) {
4800 group->add_output[i] = buf->ReadByte();
4802 group->again = buf->ReadByte();
4804 break;
4807 /* Loading of Tile Layout and Production Callback groups would happen here */
4808 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
4813 _cur.spritegroups[setid] = act_group;
4816 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
4818 if (feature == GSF_OBJECTS) {
4819 switch (ctype) {
4820 case 0: return 0;
4821 case 0xFF: return CT_PURCHASE_OBJECT;
4822 default:
4823 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
4824 return CT_INVALID;
4827 /* Special cargo types for purchase list and stations */
4828 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
4829 if (ctype == 0xFF) return CT_PURCHASE;
4831 if (_cur.grffile->cargo_list.Length() == 0) {
4832 /* No cargo table, so use bitnum values */
4833 if (ctype >= 32) {
4834 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
4835 return CT_INVALID;
4838 const CargoSpec *cs;
4839 FOR_ALL_CARGOSPECS(cs) {
4840 if (cs->bitnum == ctype) {
4841 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
4842 return cs->Index();
4846 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
4847 return CT_INVALID;
4850 /* Check if the cargo type is out of bounds of the cargo translation table */
4851 if (ctype >= _cur.grffile->cargo_list.Length()) {
4852 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1);
4853 return CT_INVALID;
4856 /* Look up the cargo label from the translation table */
4857 CargoLabel cl = _cur.grffile->cargo_list[ctype];
4858 if (cl == 0) {
4859 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
4860 return CT_INVALID;
4863 ctype = GetCargoIDByLabel(cl);
4864 if (ctype == CT_INVALID) {
4865 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));
4866 return CT_INVALID;
4869 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);
4870 return ctype;
4874 static bool IsValidGroupID(uint16 groupid, const char *function)
4876 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4877 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
4878 return false;
4881 return true;
4884 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
4886 static EngineID *last_engines;
4887 static uint last_engines_count;
4888 bool wagover = false;
4890 /* Test for 'wagon override' flag */
4891 if (HasBit(idcount, 7)) {
4892 wagover = true;
4893 /* Strip off the flag */
4894 idcount = GB(idcount, 0, 7);
4896 if (last_engines_count == 0) {
4897 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4898 return;
4901 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4902 last_engines_count, idcount);
4903 } else {
4904 if (last_engines_count != idcount) {
4905 last_engines = ReallocT(last_engines, idcount);
4906 last_engines_count = idcount;
4910 EngineID *engines = AllocaM(EngineID, idcount);
4911 for (uint i = 0; i < idcount; i++) {
4912 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
4913 if (e == NULL) {
4914 /* No engine could be allocated?!? Deal with it. Okay,
4915 * this might look bad. Also make sure this NewGRF
4916 * gets disabled, as a half loaded one is bad. */
4917 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
4918 return;
4921 engines[i] = e->index;
4922 if (!wagover) last_engines[i] = engines[i];
4925 uint8 cidcount = buf->ReadByte();
4926 for (uint c = 0; c < cidcount; c++) {
4927 uint8 ctype = buf->ReadByte();
4928 uint16 groupid = buf->ReadWord();
4929 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
4931 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
4933 ctype = TranslateCargo(feature, ctype);
4934 if (ctype == CT_INVALID) continue;
4936 for (uint i = 0; i < idcount; i++) {
4937 EngineID engine = engines[i];
4939 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
4941 if (wagover) {
4942 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
4943 } else {
4944 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
4949 uint16 groupid = buf->ReadWord();
4950 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
4952 grfmsg(8, "-- Default group id 0x%04X", groupid);
4954 for (uint i = 0; i < idcount; i++) {
4955 EngineID engine = engines[i];
4957 if (wagover) {
4958 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
4959 } else {
4960 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
4961 SetEngineGRF(engine, _cur.grffile);
4967 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
4969 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
4970 for (uint i = 0; i < idcount; i++) {
4971 cfs[i] = (CanalFeature)buf->ReadByte();
4974 uint8 cidcount = buf->ReadByte();
4975 buf->Skip(cidcount * 3);
4977 uint16 groupid = buf->ReadWord();
4978 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
4980 for (uint i = 0; i < idcount; i++) {
4981 CanalFeature cf = cfs[i];
4983 if (cf >= CF_END) {
4984 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
4985 continue;
4988 _water_feature[cf].grffile = _cur.grffile;
4989 _water_feature[cf].group = _cur.spritegroups[groupid];
4994 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
4996 uint8 *stations = AllocaM(uint8, idcount);
4997 for (uint i = 0; i < idcount; i++) {
4998 stations[i] = buf->ReadByte();
5001 uint8 cidcount = buf->ReadByte();
5002 for (uint c = 0; c < cidcount; c++) {
5003 uint8 ctype = buf->ReadByte();
5004 uint16 groupid = buf->ReadWord();
5005 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
5007 ctype = TranslateCargo(GSF_STATIONS, ctype);
5008 if (ctype == CT_INVALID) continue;
5010 for (uint i = 0; i < idcount; i++) {
5011 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5013 if (statspec == NULL) {
5014 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5015 continue;
5018 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5022 uint16 groupid = buf->ReadWord();
5023 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
5025 for (uint i = 0; i < idcount; i++) {
5026 StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]];
5028 if (statspec == NULL) {
5029 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5030 continue;
5033 if (statspec->grf_prop.grffile != NULL) {
5034 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5035 continue;
5038 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
5039 statspec->grf_prop.grffile = _cur.grffile;
5040 statspec->grf_prop.local_id = stations[i];
5041 StationClass::Assign(statspec);
5046 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
5048 uint8 *houses = AllocaM(uint8, idcount);
5049 for (uint i = 0; i < idcount; i++) {
5050 houses[i] = buf->ReadByte();
5053 /* Skip the cargo type section, we only care about the default group */
5054 uint8 cidcount = buf->ReadByte();
5055 buf->Skip(cidcount * 3);
5057 uint16 groupid = buf->ReadWord();
5058 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
5060 if (_cur.grffile->housespec == NULL) {
5061 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5062 return;
5065 for (uint i = 0; i < idcount; i++) {
5066 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
5068 if (hs == NULL) {
5069 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5070 continue;
5073 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5077 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5079 uint8 *industries = AllocaM(uint8, idcount);
5080 for (uint i = 0; i < idcount; i++) {
5081 industries[i] = buf->ReadByte();
5084 /* Skip the cargo type section, we only care about the default group */
5085 uint8 cidcount = buf->ReadByte();
5086 buf->Skip(cidcount * 3);
5088 uint16 groupid = buf->ReadWord();
5089 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5091 if (_cur.grffile->industryspec == NULL) {
5092 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5093 return;
5096 for (uint i = 0; i < idcount; i++) {
5097 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5099 if (indsp == NULL) {
5100 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5101 continue;
5104 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5108 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5110 uint8 *indtiles = AllocaM(uint8, idcount);
5111 for (uint i = 0; i < idcount; i++) {
5112 indtiles[i] = buf->ReadByte();
5115 /* Skip the cargo type section, we only care about the default group */
5116 uint8 cidcount = buf->ReadByte();
5117 buf->Skip(cidcount * 3);
5119 uint16 groupid = buf->ReadWord();
5120 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5122 if (_cur.grffile->indtspec == NULL) {
5123 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5124 return;
5127 for (uint i = 0; i < idcount; i++) {
5128 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5130 if (indtsp == NULL) {
5131 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5132 continue;
5135 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5139 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5141 CargoID *cargoes = AllocaM(CargoID, idcount);
5142 for (uint i = 0; i < idcount; i++) {
5143 cargoes[i] = buf->ReadByte();
5146 /* Skip the cargo type section, we only care about the default group */
5147 uint8 cidcount = buf->ReadByte();
5148 buf->Skip(cidcount * 3);
5150 uint16 groupid = buf->ReadWord();
5151 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5153 for (uint i = 0; i < idcount; i++) {
5154 CargoID cid = cargoes[i];
5156 if (cid >= NUM_CARGO) {
5157 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5158 continue;
5161 CargoSpec *cs = CargoSpec::Get(cid);
5162 cs->grffile = _cur.grffile;
5163 cs->group = _cur.spritegroups[groupid];
5167 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5169 if (_cur.grffile->objectspec == NULL) {
5170 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5171 return;
5174 uint8 *objects = AllocaM(uint8, idcount);
5175 for (uint i = 0; i < idcount; i++) {
5176 objects[i] = buf->ReadByte();
5179 uint8 cidcount = buf->ReadByte();
5180 for (uint c = 0; c < cidcount; c++) {
5181 uint8 ctype = buf->ReadByte();
5182 uint16 groupid = buf->ReadWord();
5183 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5185 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5186 if (ctype == CT_INVALID) continue;
5188 for (uint i = 0; i < idcount; i++) {
5189 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5191 if (spec == NULL) {
5192 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5193 continue;
5196 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5200 uint16 groupid = buf->ReadWord();
5201 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5203 for (uint i = 0; i < idcount; i++) {
5204 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5206 if (spec == NULL) {
5207 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5208 continue;
5211 if (spec->grf_prop.grffile != NULL) {
5212 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5213 continue;
5216 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5217 spec->grf_prop.grffile = _cur.grffile;
5218 spec->grf_prop.local_id = objects[i];
5222 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5224 uint8 *railtypes = AllocaM(uint8, idcount);
5225 for (uint i = 0; i < idcount; i++) {
5226 railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
5229 uint8 cidcount = buf->ReadByte();
5230 for (uint c = 0; c < cidcount; c++) {
5231 uint8 ctype = buf->ReadByte();
5232 uint16 groupid = buf->ReadWord();
5233 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5235 if (ctype >= RTSG_END) continue;
5237 extern RailtypeInfo _railtypes[RAILTYPE_END];
5238 for (uint i = 0; i < idcount; i++) {
5239 if (railtypes[i] != INVALID_RAILTYPE) {
5240 RailtypeInfo *rti = &_railtypes[railtypes[i]];
5242 rti->grffile[ctype] = _cur.grffile;
5243 rti->group[ctype] = _cur.spritegroups[groupid];
5248 /* Railtypes do not use the default group. */
5249 buf->ReadWord();
5252 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5254 uint8 *airports = AllocaM(uint8, idcount);
5255 for (uint i = 0; i < idcount; i++) {
5256 airports[i] = buf->ReadByte();
5259 /* Skip the cargo type section, we only care about the default group */
5260 uint8 cidcount = buf->ReadByte();
5261 buf->Skip(cidcount * 3);
5263 uint16 groupid = buf->ReadWord();
5264 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5266 if (_cur.grffile->airportspec == NULL) {
5267 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5268 return;
5271 for (uint i = 0; i < idcount; i++) {
5272 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5274 if (as == NULL) {
5275 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5276 continue;
5279 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5283 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5285 uint8 *airptiles = AllocaM(uint8, idcount);
5286 for (uint i = 0; i < idcount; i++) {
5287 airptiles[i] = buf->ReadByte();
5290 /* Skip the cargo type section, we only care about the default group */
5291 uint8 cidcount = buf->ReadByte();
5292 buf->Skip(cidcount * 3);
5294 uint16 groupid = buf->ReadWord();
5295 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5297 if (_cur.grffile->airtspec == NULL) {
5298 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5299 return;
5302 for (uint i = 0; i < idcount; i++) {
5303 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5305 if (airtsp == NULL) {
5306 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5307 continue;
5310 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5315 /* Action 0x03 */
5316 static void FeatureMapSpriteGroup(ByteReader *buf)
5318 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5319 * id-list := [<id>] [id-list]
5320 * cargo-list := <cargo-type> <cid> [cargo-list]
5322 * B feature see action 0
5323 * B n-id bits 0-6: how many IDs this definition applies to
5324 * bit 7: if set, this is a wagon override definition (see below)
5325 * B ids the IDs for which this definition applies
5326 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5327 * can be zero, in that case the def-cid is used always
5328 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5329 * W cid cargo ID (sprite group ID) for this type of cargo
5330 * W def-cid default cargo ID (sprite group ID) */
5332 uint8 feature = buf->ReadByte();
5333 uint8 idcount = buf->ReadByte();
5335 /* If idcount is zero, this is a feature callback */
5336 if (idcount == 0) {
5337 /* Skip number of cargo ids? */
5338 buf->ReadByte();
5339 uint16 groupid = buf->ReadWord();
5340 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
5342 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
5344 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5345 return;
5348 /* Mark the feature as used by the grf (generic callbacks do not count) */
5349 SetBit(_cur.grffile->grf_features, feature);
5351 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
5353 switch (feature) {
5354 case GSF_TRAINS:
5355 case GSF_ROADVEHICLES:
5356 case GSF_SHIPS:
5357 case GSF_AIRCRAFT:
5358 VehicleMapSpriteGroup(buf, feature, idcount);
5359 return;
5361 case GSF_CANALS:
5362 CanalMapSpriteGroup(buf, idcount);
5363 return;
5365 case GSF_STATIONS:
5366 StationMapSpriteGroup(buf, idcount);
5367 return;
5369 case GSF_HOUSES:
5370 TownHouseMapSpriteGroup(buf, idcount);
5371 return;
5373 case GSF_INDUSTRIES:
5374 IndustryMapSpriteGroup(buf, idcount);
5375 return;
5377 case GSF_INDUSTRYTILES:
5378 IndustrytileMapSpriteGroup(buf, idcount);
5379 return;
5381 case GSF_CARGOES:
5382 CargoMapSpriteGroup(buf, idcount);
5383 return;
5385 case GSF_AIRPORTS:
5386 AirportMapSpriteGroup(buf, idcount);
5387 return;
5389 case GSF_OBJECTS:
5390 ObjectMapSpriteGroup(buf, idcount);
5391 break;
5393 case GSF_RAILTYPES:
5394 RailTypeMapSpriteGroup(buf, idcount);
5395 break;
5397 case GSF_AIRPORTTILES:
5398 AirportTileMapSpriteGroup(buf, idcount);
5399 return;
5401 default:
5402 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
5403 return;
5407 /* Action 0x04 */
5408 static void FeatureNewName(ByteReader *buf)
5410 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5412 * B veh-type see action 0 (as 00..07, + 0A
5413 * But IF veh-type = 48, then generic text
5414 * B language-id If bit 6 is set, This is the extended language scheme,
5415 * with up to 64 language.
5416 * Otherwise, it is a mapping where set bits have meaning
5417 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5418 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5419 * B num-veh number of vehicles which are getting a new name
5420 * B/W offset number of the first vehicle that gets a new name
5421 * Byte : ID of vehicle to change
5422 * Word : ID of string to change/add
5423 * S data new texts, each of them zero-terminated, after
5424 * which the next name begins. */
5426 bool new_scheme = _cur.grffile->grf_version >= 7;
5428 uint8 feature = buf->ReadByte();
5429 uint8 lang = buf->ReadByte();
5430 uint8 num = buf->ReadByte();
5431 bool generic = HasBit(lang, 7);
5432 uint16 id;
5433 if (generic) {
5434 id = buf->ReadWord();
5435 } else if (feature <= GSF_AIRCRAFT) {
5436 id = buf->ReadExtendedByte();
5437 } else {
5438 id = buf->ReadByte();
5441 ClrBit(lang, 7);
5443 uint16 endid = id + num;
5445 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5446 id, endid, feature, lang);
5448 for (; id < endid && buf->HasData(); id++) {
5449 const char *name = buf->ReadString();
5450 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5452 switch (feature) {
5453 case GSF_TRAINS:
5454 case GSF_ROADVEHICLES:
5455 case GSF_SHIPS:
5456 case GSF_AIRCRAFT:
5457 if (!generic) {
5458 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
5459 if (e == NULL) break;
5460 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
5461 e->info.string_id = string;
5462 } else {
5463 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5465 break;
5467 case GSF_INDUSTRIES: {
5468 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5469 break;
5472 case GSF_HOUSES:
5473 default:
5474 switch (GB(id, 8, 8)) {
5475 case 0xC4: // Station class name
5476 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5477 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5478 } else {
5479 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
5480 StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5482 break;
5484 case 0xC5: // Station name
5485 if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) {
5486 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5487 } else {
5488 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5490 break;
5492 case 0xC7: // Airporttile name
5493 if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) {
5494 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
5495 } else {
5496 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5498 break;
5500 case 0xC9: // House name
5501 if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) {
5502 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
5503 } else {
5504 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5506 break;
5508 case 0xD0:
5509 case 0xD1:
5510 case 0xD2:
5511 case 0xD3:
5512 case 0xDC:
5513 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5514 break;
5516 default:
5517 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
5518 break;
5520 break;
5526 * Sanitize incoming sprite offsets for Action 5 graphics replacements.
5527 * @param num The number of sprites to load.
5528 * @param offset Offset from the base.
5529 * @param max_sprites The maximum number of sprites that can be loaded in this action 5.
5530 * @param name Used for error warnings.
5531 * @return The number of sprites that is going to be skipped.
5533 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
5536 if (offset >= max_sprites) {
5537 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
5538 uint orig_num = num;
5539 num = 0;
5540 return orig_num;
5543 if (offset + num > max_sprites) {
5544 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
5545 uint orig_num = num;
5546 num = max(max_sprites - offset, 0);
5547 return orig_num - num;
5550 return 0;
5554 /** The type of action 5 type. */
5555 enum Action5BlockType {
5556 A5BLOCK_FIXED, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5557 A5BLOCK_ALLOW_OFFSET, ///< Allow replacing any subset by specifiing an offset.
5558 A5BLOCK_INVALID, ///< unknown/not-implemented type
5560 /** Information about a single action 5 type. */
5561 struct Action5Type {
5562 Action5BlockType block_type; ///< How is this Action5 type processed?
5563 SpriteID sprite_base; ///< Load the sprites starting from this sprite.
5564 uint16 min_sprites; ///< If the Action5 contains less sprites, the whole block will be ignored.
5565 uint16 max_sprites; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5566 const char *name; ///< Name for error messages.
5569 /** The information about action 5 types. */
5570 static const Action5Type _action5_types[] = {
5571 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5572 /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
5573 /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
5574 /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
5575 /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
5576 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
5577 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Catenary graphics" },
5578 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
5579 /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5580 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
5581 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
5582 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
5583 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
5584 /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5585 /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
5586 /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5587 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
5588 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
5589 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
5590 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
5591 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
5592 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
5593 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
5594 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
5595 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
5598 /* Action 0x05 */
5599 static void GraphicsNew(ByteReader *buf)
5601 /* <05> <graphics-type> <num-sprites> <other data...>
5603 * B graphics-type What set of graphics the sprites define.
5604 * E num-sprites How many sprites are in this set?
5605 * V other data Graphics type specific data. Currently unused. */
5606 /* TODO */
5608 uint8 type = buf->ReadByte();
5609 uint16 num = buf->ReadExtendedByte();
5610 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
5611 ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
5613 if ((type == 0x0D) && (num == 10) && _cur.grffile->is_ottdfile) {
5614 /* Special not-TTDP-compatible case used in openttd.grf
5615 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5616 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5617 LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_S
5618 LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_W
5619 LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_WSE
5620 LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_N
5621 LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NWS
5622 LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_ENW
5623 LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_SEN
5624 LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_E
5625 LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_EW
5626 LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NS
5627 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
5628 return;
5631 /* Supported type? */
5632 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
5633 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
5634 _cur.skip_sprites = num;
5635 return;
5638 const Action5Type *action5_type = &_action5_types[type];
5640 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5641 * except for the long version of the shore type:
5642 * Ignore offset if not allowed */
5643 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
5644 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
5645 offset = 0;
5648 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5649 * This does not make sense, if <offset> is allowed */
5650 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
5651 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);
5652 _cur.skip_sprites = num;
5653 return;
5656 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5657 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
5658 SpriteID replace = action5_type->sprite_base + offset;
5660 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5661 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);
5663 for (; num > 0; num--) {
5664 _cur.nfo_line++;
5665 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
5668 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
5670 _cur.skip_sprites = skip_num;
5673 /* Action 0x05 (SKIP) */
5674 static void SkipAct5(ByteReader *buf)
5676 /* Ignore type byte */
5677 buf->ReadByte();
5679 /* Skip the sprites of this action */
5680 _cur.skip_sprites = buf->ReadExtendedByte();
5682 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
5686 * Check whether we are (obviously) missing some of the extra
5687 * (Action 0x05) sprites that we like to use.
5688 * When missing sprites are found a warning will be shown.
5690 void CheckForMissingSprites()
5692 /* Don't break out quickly, but allow to check the other
5693 * sprites as well, so we can give the best information. */
5694 bool missing = false;
5695 for (uint8 i = 0; i < lengthof(_action5_types); i++) {
5696 const Action5Type *type = &_action5_types[i];
5697 if (type->block_type == A5BLOCK_INVALID) continue;
5699 for (uint j = 0; j < type->max_sprites; j++) {
5700 if (!SpriteExists(type->sprite_base + j)) {
5701 DEBUG(grf, 0, "%s sprites are missing", type->name);
5702 missing = true;
5703 /* No need to log more of the same. */
5704 break;
5709 if (missing) {
5710 ShowErrorMessage(IsReleasedVersion() ? STR_NEWGRF_ERROR_MISSING_SPRITES : STR_NEWGRF_ERROR_MISSING_SPRITES_UNSTABLE, INVALID_STRING_ID, WL_CRITICAL);
5715 * Reads a variable common to VarAction2 and Action7/9/D.
5717 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5718 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5720 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5721 * @param value returns the value of the variable.
5722 * @param grffile NewGRF querying the variable
5723 * @return true iff the variable is known and the value is returned in 'value'.
5725 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
5727 switch (param) {
5728 case 0x00: // current date
5729 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
5730 return true;
5732 case 0x01: // current year
5733 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
5734 return true;
5736 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)
5737 YearMonthDay ymd;
5738 ConvertDateToYMD(_date, &ymd);
5739 Date start_of_year = ConvertYMDToDate(ymd.year, 0, 1);
5740 *value = ymd.month | (ymd.day - 1) << 8 | (IsLeapYear(ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
5741 return true;
5744 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5745 *value = _settings_game.game_creation.landscape;
5746 return true;
5748 case 0x06: // road traffic side, bit 4 clear=left, set=right
5749 *value = _settings_game.vehicle.road_side << 4;
5750 return true;
5752 case 0x09: // date fraction
5753 *value = _date_fract * 885;
5754 return true;
5756 case 0x0A: // animation counter
5757 *value = _tick_counter;
5758 return true;
5760 case 0x0B: { // TTDPatch version
5761 uint major = 2;
5762 uint minor = 6;
5763 uint revision = 1; // special case: 2.0.1 is 2.0.10
5764 uint build = 1382;
5765 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
5766 return true;
5769 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5770 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
5771 return true;
5773 case 0x0E: // Y-offset for train sprites
5774 *value = _cur.grffile->traininfo_vehicle_pitch;
5775 return true;
5777 case 0x0F: // Rail track type cost factors
5778 *value = 0;
5779 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
5780 if (_settings_game.vehicle.disable_elrails) {
5781 /* skip elrail multiplier - disabled */
5782 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
5783 } else {
5784 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
5785 /* Skip monorail multiplier - no space in result */
5787 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
5788 return true;
5790 case 0x11: // current rail tool type
5791 *value = 0; // constant fake value to avoid desync
5792 return true;
5794 case 0x12: // Game mode
5795 *value = _game_mode;
5796 return true;
5798 /* case 0x13: // Tile refresh offset to left not implemented */
5799 /* case 0x14: // Tile refresh offset to right not implemented */
5800 /* case 0x15: // Tile refresh offset upwards not implemented */
5801 /* case 0x16: // Tile refresh offset downwards not implemented */
5802 /* case 0x17: // temperate snow line not implemented */
5804 case 0x1A: // Always -1
5805 *value = UINT_MAX;
5806 return true;
5808 case 0x1B: // Display options
5809 *value = 0x3F; // constant fake value to avoid desync
5810 return true;
5812 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5813 *value = 1;
5814 return true;
5816 case 0x1E: // Miscellaneous GRF features
5817 *value = _misc_grf_features;
5819 /* Add the local flags */
5820 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
5821 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
5822 return true;
5824 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5826 case 0x20: { // snow line height
5827 byte snowline = GetSnowLine();
5828 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= MAX_TILE_HEIGHT) {
5829 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
5830 } else {
5831 /* No snow */
5832 *value = 0xFF;
5834 return true;
5837 case 0x21: // OpenTTD version
5838 *value = _openttd_newgrf_version;
5839 return true;
5841 case 0x22: // difficulty level
5842 *value = SP_CUSTOM;
5843 return true;
5845 case 0x23: // long format date
5846 *value = _date;
5847 return true;
5849 case 0x24: // long format year
5850 *value = _cur_year;
5851 return true;
5853 default: return false;
5857 static uint32 GetParamVal(byte param, uint32 *cond_val)
5859 /* First handle variable common with VarAction2 */
5860 uint32 value;
5861 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
5863 /* Non-common variable */
5864 switch (param) {
5865 case 0x84: { // GRF loading stage
5866 uint32 res = 0;
5868 if (_cur.stage > GLS_INIT) SetBit(res, 0);
5869 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
5870 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
5871 return res;
5874 case 0x85: // TTDPatch flags, only for bit tests
5875 if (cond_val == NULL) {
5876 /* Supported in Action 0x07 and 0x09, not 0x0D */
5877 return 0;
5878 } else {
5879 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
5880 *cond_val %= 0x20;
5881 return param_val;
5884 case 0x88: // GRF ID check
5885 return 0;
5887 /* case 0x99: Global ID offset not implemented */
5889 default:
5890 /* GRF Parameter */
5891 if (param < 0x80) return _cur.grffile->GetParam(param);
5893 /* In-game variable. */
5894 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
5895 return UINT_MAX;
5899 /* Action 0x06 */
5900 static void CfgApply(ByteReader *buf)
5902 /* <06> <param-num> <param-size> <offset> ... <FF>
5904 * B param-num Number of parameter to substitute (First = "zero")
5905 * Ignored if that parameter was not specified in newgrf.cfg
5906 * B param-size How many bytes to replace. If larger than 4, the
5907 * bytes of the following parameter are used. In that
5908 * case, nothing is applied unless *all* parameters
5909 * were specified.
5910 * B offset Offset into data from beginning of next sprite
5911 * to place where parameter is to be stored. */
5913 /* Preload the next sprite */
5914 size_t pos = FioGetPos();
5915 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
5916 uint8 type = FioReadByte();
5917 byte *preload_sprite = NULL;
5919 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5920 if (type == 0xFF) {
5921 preload_sprite = MallocT<byte>(num);
5922 FioReadBlock(preload_sprite, num);
5925 /* Reset the file position to the start of the next sprite */
5926 FioSeekTo(pos, SEEK_SET);
5928 if (type != 0xFF) {
5929 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5930 free(preload_sprite);
5931 return;
5934 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
5935 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
5936 if (it != _grf_line_to_action6_sprite_override.end()) {
5937 free(preload_sprite);
5938 preload_sprite = _grf_line_to_action6_sprite_override[location];
5939 } else {
5940 _grf_line_to_action6_sprite_override[location] = preload_sprite;
5943 /* Now perform the Action 0x06 on our data. */
5945 for (;;) {
5946 uint i;
5947 uint param_num;
5948 uint param_size;
5949 uint offset;
5950 bool add_value;
5952 /* Read the parameter to apply. 0xFF indicates no more data to change. */
5953 param_num = buf->ReadByte();
5954 if (param_num == 0xFF) break;
5956 /* Get the size of the parameter to use. If the size covers multiple
5957 * double words, sequential parameter values are used. */
5958 param_size = buf->ReadByte();
5960 /* Bit 7 of param_size indicates we should add to the original value
5961 * instead of replacing it. */
5962 add_value = HasBit(param_size, 7);
5963 param_size = GB(param_size, 0, 7);
5965 /* Where to apply the data to within the pseudo sprite data. */
5966 offset = buf->ReadExtendedByte();
5968 /* If the parameter is a GRF parameter (not an internal variable) check
5969 * if it (and all further sequential parameters) has been defined. */
5970 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
5971 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
5972 break;
5975 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
5977 bool carry = false;
5978 for (i = 0; i < param_size && offset + i < num; i++) {
5979 uint32 value = GetParamVal(param_num + i / 4, NULL);
5980 /* Reset carry flag for each iteration of the variable (only really
5981 * matters if param_size is greater than 4) */
5982 if (i % 4 == 0) carry = false;
5984 if (add_value) {
5985 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
5986 preload_sprite[offset + i] = GB(new_value, 0, 8);
5987 /* Check if the addition overflowed */
5988 carry = new_value >= 256;
5989 } else {
5990 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
5997 * Disable a static NewGRF when it is influencing another (non-static)
5998 * NewGRF as this could cause desyncs.
6000 * We could just tell the NewGRF querying that the file doesn't exist,
6001 * but that might give unwanted results. Disabling the NewGRF gives the
6002 * best result as no NewGRF author can complain about that.
6003 * @param c The NewGRF to disable.
6005 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
6007 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
6008 error->data = strdup(_cur.grfconfig->GetName());
6011 /* Action 0x07
6012 * Action 0x09 */
6013 static void SkipIf(ByteReader *buf)
6015 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6017 * B param-num
6018 * B param-size
6019 * B condition-type
6020 * V value
6021 * B num-sprites */
6022 /* TODO: More params. More condition types. */
6023 uint32 cond_val = 0;
6024 uint32 mask = 0;
6025 bool result;
6027 uint8 param = buf->ReadByte();
6028 uint8 paramsize = buf->ReadByte();
6029 uint8 condtype = buf->ReadByte();
6031 if (condtype < 2) {
6032 /* Always 1 for bit tests, the given value should be ignored. */
6033 paramsize = 1;
6036 switch (paramsize) {
6037 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6038 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6039 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6040 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6041 default: break;
6044 if (param < 0x80 && _cur.grffile->param_end <= param) {
6045 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6046 return;
6049 uint32 param_val = GetParamVal(param, &cond_val);
6051 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
6054 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6055 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6056 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6057 * So, when the condition type is one of those, the specific variable
6058 * 0x88 code is skipped, so the "general" code for the cargo
6059 * availability conditions kicks in.
6061 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
6062 /* GRF ID checks */
6064 GRFConfig *c = GetGRFConfig(cond_val, mask);
6066 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6067 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6068 c = NULL;
6071 if (condtype != 10 && c == NULL) {
6072 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6073 return;
6076 switch (condtype) {
6077 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6078 case 0x06: // Is GRFID active?
6079 result = c->status == GCS_ACTIVATED;
6080 break;
6082 case 0x07: // Is GRFID non-active?
6083 result = c->status != GCS_ACTIVATED;
6084 break;
6086 case 0x08: // GRFID is not but will be active?
6087 result = c->status == GCS_INITIALISED;
6088 break;
6090 case 0x09: // GRFID is or will be active?
6091 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6092 break;
6094 case 0x0A: // GRFID is not nor will be active
6095 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6096 result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6097 break;
6099 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
6101 } else {
6102 /* Parameter or variable tests */
6103 switch (condtype) {
6104 case 0x00: result = !!(param_val & (1 << cond_val));
6105 break;
6106 case 0x01: result = !(param_val & (1 << cond_val));
6107 break;
6108 case 0x02: result = (param_val & mask) == cond_val;
6109 break;
6110 case 0x03: result = (param_val & mask) != cond_val;
6111 break;
6112 case 0x04: result = (param_val & mask) < cond_val;
6113 break;
6114 case 0x05: result = (param_val & mask) > cond_val;
6115 break;
6116 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6117 break;
6118 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6119 break;
6120 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6121 break;
6122 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6123 break;
6125 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
6129 if (!result) {
6130 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6131 return;
6134 uint8 numsprites = buf->ReadByte();
6136 /* numsprites can be a GOTO label if it has been defined in the GRF
6137 * file. The jump will always be the first matching label that follows
6138 * the current nfo_line. If no matching label is found, the first matching
6139 * label in the file is used. */
6140 GRFLabel *choice = NULL;
6141 for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) {
6142 if (label->label != numsprites) continue;
6144 /* Remember a goto before the current line */
6145 if (choice == NULL) choice = label;
6146 /* If we find a label here, this is definitely good */
6147 if (label->nfo_line > _cur.nfo_line) {
6148 choice = label;
6149 break;
6153 if (choice != NULL) {
6154 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6155 FioSeekTo(choice->pos, SEEK_SET);
6156 _cur.nfo_line = choice->nfo_line;
6157 return;
6160 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6161 _cur.skip_sprites = numsprites;
6162 if (_cur.skip_sprites == 0) {
6163 /* Zero means there are no sprites to skip, so
6164 * we use -1 to indicate that all further
6165 * sprites should be skipped. */
6166 _cur.skip_sprites = -1;
6168 /* If an action 8 hasn't been encountered yet, disable the grf. */
6169 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6170 DisableGrf();
6176 /* Action 0x08 (GLS_FILESCAN) */
6177 static void ScanInfo(ByteReader *buf)
6179 uint8 grf_version = buf->ReadByte();
6180 uint32 grfid = buf->ReadDWord();
6181 const char *name = buf->ReadString();
6183 _cur.grfconfig->ident.grfid = grfid;
6185 if (grf_version < 2 || grf_version > 8) {
6186 SetBit(_cur.grfconfig->flags, GCF_INVALID);
6187 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);
6190 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6191 if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6193 AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
6195 if (buf->HasData()) {
6196 const char *info = buf->ReadString();
6197 AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
6200 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6201 _cur.skip_sprites = -1;
6204 /* Action 0x08 */
6205 static void GRFInfo(ByteReader *buf)
6207 /* <08> <version> <grf-id> <name> <info>
6209 * B version newgrf version, currently 06
6210 * 4*B grf-id globally unique ID of this .grf file
6211 * S name name of this .grf set
6212 * S info string describing the set, and e.g. author and copyright */
6214 uint8 version = buf->ReadByte();
6215 uint32 grfid = buf->ReadDWord();
6216 const char *name = buf->ReadString();
6218 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6219 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6220 return;
6223 if (_cur.grffile->grfid != grfid) {
6224 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));
6225 _cur.grffile->grfid = grfid;
6228 _cur.grffile->grf_version = version;
6229 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6231 /* Do swap the GRFID for displaying purposes since people expect that */
6232 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);
6235 /* Action 0x0A */
6236 static void SpriteReplace(ByteReader *buf)
6238 /* <0A> <num-sets> <set1> [<set2> ...]
6239 * <set>: <num-sprites> <first-sprite>
6241 * B num-sets How many sets of sprites to replace.
6242 * Each set:
6243 * B num-sprites How many sprites are in this set
6244 * W first-sprite First sprite number to replace */
6246 uint8 num_sets = buf->ReadByte();
6248 for (uint i = 0; i < num_sets; i++) {
6249 uint8 num_sprites = buf->ReadByte();
6250 uint16 first_sprite = buf->ReadWord();
6252 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6253 i, num_sprites, first_sprite
6256 for (uint j = 0; j < num_sprites; j++) {
6257 int load_index = first_sprite + j;
6258 _cur.nfo_line++;
6259 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6261 /* Shore sprites now located at different addresses.
6262 * So detect when the old ones get replaced. */
6263 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6264 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
6270 /* Action 0x0A (SKIP) */
6271 static void SkipActA(ByteReader *buf)
6273 uint8 num_sets = buf->ReadByte();
6275 for (uint i = 0; i < num_sets; i++) {
6276 /* Skip the sprites this replaces */
6277 _cur.skip_sprites += buf->ReadByte();
6278 /* But ignore where they go */
6279 buf->ReadWord();
6282 grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
6285 /* Action 0x0B */
6286 static void GRFLoadError(ByteReader *buf)
6288 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6290 * B severity 00: notice, contine loading grf file
6291 * 01: warning, continue loading grf file
6292 * 02: error, but continue loading grf file, and attempt
6293 * loading grf again when loading or starting next game
6294 * 03: error, abort loading and prevent loading again in
6295 * the future (only when restarting the patch)
6296 * B language-id see action 4, use 1F for built-in error messages
6297 * B message-id message to show, see below
6298 * S message for custom messages (message-id FF), text of the message
6299 * not present for built-in messages.
6300 * V data additional data for built-in (or custom) messages
6301 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6303 static const StringID msgstr[] = {
6304 STR_NEWGRF_ERROR_VERSION_NUMBER,
6305 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6306 STR_NEWGRF_ERROR_UNSET_SWITCH,
6307 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6308 STR_NEWGRF_ERROR_LOAD_BEFORE,
6309 STR_NEWGRF_ERROR_LOAD_AFTER,
6310 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6313 static const StringID sevstr[] = {
6314 STR_NEWGRF_ERROR_MSG_INFO,
6315 STR_NEWGRF_ERROR_MSG_WARNING,
6316 STR_NEWGRF_ERROR_MSG_ERROR,
6317 STR_NEWGRF_ERROR_MSG_FATAL
6320 byte severity = buf->ReadByte();
6321 byte lang = buf->ReadByte();
6322 byte message_id = buf->ReadByte();
6324 /* Skip the error if it isn't valid for the current language. */
6325 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
6327 /* Skip the error until the activation stage unless bit 7 of the severity
6328 * is set. */
6329 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6330 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6331 return;
6333 ClrBit(severity, 7);
6335 if (severity >= lengthof(sevstr)) {
6336 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6337 severity = 2;
6338 } else if (severity == 3) {
6339 /* This is a fatal error, so make sure the GRF is deactivated and no
6340 * more of it gets loaded. */
6341 DisableGrf();
6343 /* Make sure we show fatal errors, instead of silly infos from before */
6344 delete _cur.grfconfig->error;
6345 _cur.grfconfig->error = NULL;
6348 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6349 grfmsg(7, "GRFLoadError: Invalid message id.");
6350 return;
6353 if (buf->Remaining() <= 1) {
6354 grfmsg(7, "GRFLoadError: No message data supplied.");
6355 return;
6358 /* For now we can only show one message per newgrf file. */
6359 if (_cur.grfconfig->error != NULL) return;
6361 GRFError *error = new GRFError(sevstr[severity]);
6363 if (message_id == 0xFF) {
6364 /* This is a custom error message. */
6365 if (buf->HasData()) {
6366 const char *message = buf->ReadString();
6368 error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, NULL, SCC_RAW_STRING_POINTER);
6369 } else {
6370 grfmsg(7, "GRFLoadError: No custom message supplied.");
6371 error->custom_message = strdup("");
6373 } else {
6374 error->message = msgstr[message_id];
6377 if (buf->HasData()) {
6378 const char *data = buf->ReadString();
6380 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6381 } else {
6382 grfmsg(7, "GRFLoadError: No message data supplied.");
6383 error->data = strdup("");
6386 /* Only two parameter numbers can be used in the string. */
6387 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6388 uint param_number = buf->ReadByte();
6389 error->param_value[i] = _cur.grffile->GetParam(param_number);
6392 _cur.grfconfig->error = error;
6395 /* Action 0x0C */
6396 static void GRFComment(ByteReader *buf)
6398 /* <0C> [<ignored...>]
6400 * V ignored Anything following the 0C is ignored */
6402 if (!buf->HasData()) return;
6404 const char *text = buf->ReadString();
6405 grfmsg(2, "GRFComment: %s", text);
6408 /* Action 0x0D (GLS_SAFETYSCAN) */
6409 static void SafeParamSet(ByteReader *buf)
6411 uint8 target = buf->ReadByte();
6413 /* Only writing GRF parameters is considered safe */
6414 if (target < 0x80) return;
6416 /* GRM could be unsafe, but as here it can only happen after other GRFs
6417 * are loaded, it should be okay. If the GRF tried to use the slots it
6418 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6419 * sprites is considered safe. */
6421 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6423 /* Skip remainder of GRF */
6424 _cur.skip_sprites = -1;
6428 static uint32 GetPatchVariable(uint8 param)
6430 switch (param) {
6431 /* start year - 1920 */
6432 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
6434 /* freight trains weight factor */
6435 case 0x0E: return _settings_game.vehicle.freight_trains;
6437 /* empty wagon speed increase */
6438 case 0x0F: return 0;
6440 /* plane speed factor; our patch option is reversed from TTDPatch's,
6441 * the following is good for 1x, 2x and 4x (most common?) and...
6442 * well not really for 3x. */
6443 case 0x10:
6444 switch (_settings_game.vehicle.plane_speed) {
6445 default:
6446 case 4: return 1;
6447 case 3: return 2;
6448 case 2: return 2;
6449 case 1: return 4;
6453 /* 2CC colourmap base sprite */
6454 case 0x11: return SPR_2CCMAP_BASE;
6456 /* map size: format = -MABXYSS
6457 * M : the type of map
6458 * bit 0 : set : squared map. Bit 1 is now not relevant
6459 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6460 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6461 * clear : X is the bigger edge.
6462 * A : minimum edge(log2) of the map
6463 * B : maximum edge(log2) of the map
6464 * XY : edges(log2) of each side of the map.
6465 * SS : combination of both X and Y, thus giving the size(log2) of the map
6467 case 0x13: {
6468 byte map_bits = 0;
6469 byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6470 byte log_Y = MapLogY() - 6;
6471 byte max_edge = max(log_X, log_Y);
6473 if (log_X == log_Y) { // we have a squared map, since both edges are identical
6474 SetBit(map_bits, 0);
6475 } else {
6476 if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
6479 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
6480 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
6483 /* The maximum height of the map. */
6484 case 0x14:
6485 return MAX_TILE_HEIGHT;
6487 /* Extra foundations base sprite */
6488 case 0x15:
6489 return SPR_SLOPES_BASE;
6491 /* Shore base sprite */
6492 case 0x16:
6493 return SPR_SHORE_BASE;
6495 default:
6496 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
6497 return 0;
6502 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
6504 uint start = 0;
6505 uint size = 0;
6507 if (op == 6) {
6508 /* Return GRFID of set that reserved ID */
6509 return grm[_cur.grffile->GetParam(target)];
6512 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6513 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
6515 for (uint i = start; i < num_ids; i++) {
6516 if (grm[i] == 0) {
6517 size++;
6518 } else {
6519 if (op == 2 || op == 3) break;
6520 start = i + 1;
6521 size = 0;
6524 if (size == count) break;
6527 if (size == count) {
6528 /* Got the slot... */
6529 if (op == 0 || op == 3) {
6530 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
6531 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
6533 return start;
6536 /* Unable to allocate */
6537 if (op != 4 && op != 5) {
6538 /* Deactivate GRF */
6539 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
6540 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6541 return UINT_MAX;
6544 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
6545 return UINT_MAX;
6549 /** Action 0x0D: Set parameter */
6550 static void ParamSet(ByteReader *buf)
6552 /* <0D> <target> <operation> <source1> <source2> [<data>]
6554 * B target parameter number where result is stored
6555 * B operation operation to perform, see below
6556 * B source1 first source operand
6557 * B source2 second source operand
6558 * D data data to use in the calculation, not necessary
6559 * if both source1 and source2 refer to actual parameters
6561 * Operations
6562 * 00 Set parameter equal to source1
6563 * 01 Addition, source1 + source2
6564 * 02 Subtraction, source1 - source2
6565 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6566 * 04 Signed multiplication, source1 * source2 (both signed)
6567 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6568 * signed quantity; left shift if positive and right shift if
6569 * negative, source1 is unsigned)
6570 * 06 Signed bit shift, source1 by source2
6571 * (source2 like in 05, and source1 as well)
6574 uint8 target = buf->ReadByte();
6575 uint8 oper = buf->ReadByte();
6576 uint32 src1 = buf->ReadByte();
6577 uint32 src2 = buf->ReadByte();
6579 uint32 data = 0;
6580 if (buf->Remaining() >= 4) data = buf->ReadDWord();
6582 /* You can add 80 to the operation to make it apply only if the target
6583 * is not defined yet. In this respect, a parameter is taken to be
6584 * defined if any of the following applies:
6585 * - it has been set to any value in the newgrf(w).cfg parameter list
6586 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6587 * an earlier action D */
6588 if (HasBit(oper, 7)) {
6589 if (target < 0x80 && target < _cur.grffile->param_end) {
6590 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
6591 return;
6594 oper = GB(oper, 0, 7);
6597 if (src2 == 0xFE) {
6598 if (GB(data, 0, 8) == 0xFF) {
6599 if (data == 0x0000FFFF) {
6600 /* Patch variables */
6601 src1 = GetPatchVariable(src1);
6602 } else {
6603 /* GRF Resource Management */
6604 uint8 op = src1;
6605 uint8 feature = GB(data, 8, 8);
6606 uint16 count = GB(data, 16, 16);
6608 if (_cur.stage == GLS_RESERVE) {
6609 if (feature == 0x08) {
6610 /* General sprites */
6611 if (op == 0) {
6612 /* Check if the allocated sprites will fit below the original sprite limit */
6613 if (_cur.spriteid + count >= 16384) {
6614 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
6615 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6616 return;
6619 /* Reserve space at the current sprite ID */
6620 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
6621 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
6622 _cur.spriteid += count;
6625 /* Ignore GRM result during reservation */
6626 src1 = 0;
6627 } else if (_cur.stage == GLS_ACTIVATION) {
6628 switch (feature) {
6629 case 0x00: // Trains
6630 case 0x01: // Road Vehicles
6631 case 0x02: // Ships
6632 case 0x03: // Aircraft
6633 if (!_settings_game.vehicle.dynamic_engines) {
6634 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
6635 if (_cur.skip_sprites == -1) return;
6636 } else {
6637 /* GRM does not apply for dynamic engine allocation. */
6638 switch (op) {
6639 case 2:
6640 case 3:
6641 src1 = _cur.grffile->GetParam(target);
6642 break;
6644 default:
6645 src1 = 0;
6646 break;
6649 break;
6651 case 0x08: // General sprites
6652 switch (op) {
6653 case 0:
6654 /* Return space reserved during reservation stage */
6655 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
6656 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
6657 break;
6659 case 1:
6660 src1 = _cur.spriteid;
6661 break;
6663 default:
6664 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
6665 return;
6667 break;
6669 case 0x0B: // Cargo
6670 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6671 src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
6672 if (_cur.skip_sprites == -1) return;
6673 break;
6675 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
6677 } else {
6678 /* Ignore GRM during initialization */
6679 src1 = 0;
6682 } else {
6683 /* Read another GRF File's parameter */
6684 const GRFFile *file = GetFileByGRFID(data);
6685 GRFConfig *c = GetGRFConfig(data);
6686 if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6687 /* Disable the read GRF if it is a static NewGRF. */
6688 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6689 src1 = 0;
6690 } else if (file == NULL || c == NULL || c->status == GCS_DISABLED) {
6691 src1 = 0;
6692 } else if (src1 == 0xFE) {
6693 src1 = c->version;
6694 } else {
6695 src1 = file->GetParam(src1);
6698 } else {
6699 /* The source1 and source2 operands refer to the grf parameter number
6700 * like in action 6 and 7. In addition, they can refer to the special
6701 * variables available in action 7, or they can be FF to use the value
6702 * of <data>. If referring to parameters that are undefined, a value
6703 * of 0 is used instead. */
6704 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
6705 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
6708 /* TODO: You can access the parameters of another GRF file by using
6709 * source2=FE, source1=the other GRF's parameter number and data=GRF
6710 * ID. This is only valid with operation 00 (set). If the GRF ID
6711 * cannot be found, a value of 0 is used for the parameter value
6712 * instead. */
6714 uint32 res;
6715 switch (oper) {
6716 case 0x00:
6717 res = src1;
6718 break;
6720 case 0x01:
6721 res = src1 + src2;
6722 break;
6724 case 0x02:
6725 res = src1 - src2;
6726 break;
6728 case 0x03:
6729 res = src1 * src2;
6730 break;
6732 case 0x04:
6733 res = (int32)src1 * (int32)src2;
6734 break;
6736 case 0x05:
6737 if ((int32)src2 < 0) {
6738 res = src1 >> -(int32)src2;
6739 } else {
6740 res = src1 << src2;
6742 break;
6744 case 0x06:
6745 if ((int32)src2 < 0) {
6746 res = (int32)src1 >> -(int32)src2;
6747 } else {
6748 res = (int32)src1 << src2;
6750 break;
6752 case 0x07: // Bitwise AND
6753 res = src1 & src2;
6754 break;
6756 case 0x08: // Bitwise OR
6757 res = src1 | src2;
6758 break;
6760 case 0x09: // Unsigned division
6761 if (src2 == 0) {
6762 res = src1;
6763 } else {
6764 res = src1 / src2;
6766 break;
6768 case 0x0A: // Signed divison
6769 if (src2 == 0) {
6770 res = src1;
6771 } else {
6772 res = (int32)src1 / (int32)src2;
6774 break;
6776 case 0x0B: // Unsigned modulo
6777 if (src2 == 0) {
6778 res = src1;
6779 } else {
6780 res = src1 % src2;
6782 break;
6784 case 0x0C: // Signed modulo
6785 if (src2 == 0) {
6786 res = src1;
6787 } else {
6788 res = (int32)src1 % (int32)src2;
6790 break;
6792 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
6795 switch (target) {
6796 case 0x8E: // Y-Offset for train sprites
6797 _cur.grffile->traininfo_vehicle_pitch = res;
6798 break;
6800 case 0x8F: { // Rail track type cost factors
6801 extern RailtypeInfo _railtypes[RAILTYPE_END];
6802 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
6803 if (_settings_game.vehicle.disable_elrails) {
6804 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
6805 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
6806 } else {
6807 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
6808 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
6810 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
6811 break;
6814 /* @todo implement */
6815 case 0x93: // Tile refresh offset to left
6816 case 0x94: // Tile refresh offset to right
6817 case 0x95: // Tile refresh offset upwards
6818 case 0x96: // Tile refresh offset downwards
6819 case 0x97: // Snow line height
6820 case 0x99: // Global ID offset
6821 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6822 break;
6824 case 0x9E: // Miscellaneous GRF features
6825 /* Set train list engine width */
6826 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
6827 /* Remove the local flags from the global flags */
6828 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
6830 _misc_grf_features = res;
6831 break;
6833 case 0x9F: // locale-dependent settings
6834 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
6835 break;
6837 default:
6838 if (target < 0x80) {
6839 _cur.grffile->param[target] = res;
6840 /* param is zeroed by default */
6841 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
6842 } else {
6843 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
6845 break;
6849 /* Action 0x0E (GLS_SAFETYSCAN) */
6850 static void SafeGRFInhibit(ByteReader *buf)
6852 /* <0E> <num> <grfids...>
6854 * B num Number of GRFIDs that follow
6855 * D grfids GRFIDs of the files to deactivate */
6857 uint8 num = buf->ReadByte();
6859 for (uint i = 0; i < num; i++) {
6860 uint32 grfid = buf->ReadDWord();
6862 /* GRF is unsafe it if tries to deactivate other GRFs */
6863 if (grfid != _cur.grfconfig->ident.grfid) {
6864 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6866 /* Skip remainder of GRF */
6867 _cur.skip_sprites = -1;
6869 return;
6874 /* Action 0x0E */
6875 static void GRFInhibit(ByteReader *buf)
6877 /* <0E> <num> <grfids...>
6879 * B num Number of GRFIDs that follow
6880 * D grfids GRFIDs of the files to deactivate */
6882 uint8 num = buf->ReadByte();
6884 for (uint i = 0; i < num; i++) {
6885 uint32 grfid = buf->ReadDWord();
6886 GRFConfig *file = GetGRFConfig(grfid);
6888 /* Unset activation flag */
6889 if (file != NULL && file != _cur.grfconfig) {
6890 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
6891 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
6892 error->data = strdup(_cur.grfconfig->GetName());
6897 /** Action 0x0F - Define Town names */
6898 static void FeatureTownName(ByteReader *buf)
6900 /* <0F> <id> <style-name> <num-parts> <parts>
6902 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6903 * V style-name Name of the style (only for final definition)
6904 * B num-parts Number of parts in this definition
6905 * V parts The parts */
6907 uint32 grfid = _cur.grffile->grfid;
6909 GRFTownName *townname = AddGRFTownName(grfid);
6911 byte id = buf->ReadByte();
6912 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
6914 if (HasBit(id, 7)) {
6915 /* Final definition */
6916 ClrBit(id, 7);
6917 bool new_scheme = _cur.grffile->grf_version >= 7;
6919 byte lang = buf->ReadByte();
6921 byte nb_gen = townname->nb_gen;
6922 do {
6923 ClrBit(lang, 7);
6925 const char *name = buf->ReadString();
6927 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
6928 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
6929 free(lang_name);
6931 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
6933 lang = buf->ReadByte();
6934 } while (lang != 0);
6935 townname->id[nb_gen] = id;
6936 townname->nb_gen++;
6939 byte nb = buf->ReadByte();
6940 grfmsg(6, "FeatureTownName: %u parts", nb);
6942 townname->nbparts[id] = nb;
6943 townname->partlist[id] = CallocT<NamePartList>(nb);
6945 for (int i = 0; i < nb; i++) {
6946 byte nbtext = buf->ReadByte();
6947 townname->partlist[id][i].bitstart = buf->ReadByte();
6948 townname->partlist[id][i].bitcount = buf->ReadByte();
6949 townname->partlist[id][i].maxprob = 0;
6950 townname->partlist[id][i].partcount = nbtext;
6951 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
6952 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);
6954 for (int j = 0; j < nbtext; j++) {
6955 byte prob = buf->ReadByte();
6957 if (HasBit(prob, 7)) {
6958 byte ref_id = buf->ReadByte();
6960 if (townname->nbparts[ref_id] == 0) {
6961 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
6962 DelGRFTownName(grfid);
6963 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
6964 return;
6967 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
6968 townname->partlist[id][i].parts[j].data.id = ref_id;
6969 } else {
6970 const char *text = buf->ReadString();
6971 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
6972 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
6974 townname->partlist[id][i].parts[j].prob = prob;
6975 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
6977 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
6981 /** Action 0x10 - Define goto label */
6982 static void DefineGotoLabel(ByteReader *buf)
6984 /* <10> <label> [<comment>]
6986 * B label The label to define
6987 * V comment Optional comment - ignored */
6989 byte nfo_label = buf->ReadByte();
6991 GRFLabel *label = MallocT<GRFLabel>(1);
6992 label->label = nfo_label;
6993 label->nfo_line = _cur.nfo_line;
6994 label->pos = FioGetPos();
6995 label->next = NULL;
6997 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
6998 if (_cur.grffile->label == NULL) {
6999 _cur.grffile->label = label;
7000 } else {
7001 /* Attach the label to the end of the list */
7002 GRFLabel *l;
7003 for (l = _cur.grffile->label; l->next != NULL; l = l->next) {}
7004 l->next = label;
7007 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7011 * Process a sound import from another GRF file.
7012 * @param sound Destination for sound.
7014 static void ImportGRFSound(SoundEntry *sound)
7016 const GRFFile *file;
7017 uint32 grfid = FioReadDword();
7018 SoundID sound_id = FioReadWord();
7020 file = GetFileByGRFID(grfid);
7021 if (file == NULL || file->sound_offset == 0) {
7022 grfmsg(1, "ImportGRFSound: Source file not available");
7023 return;
7026 if (sound_id >= file->num_sounds) {
7027 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
7028 return;
7031 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7033 *sound = *GetSound(file->sound_offset + sound_id);
7035 /* Reset volume and priority, which TTDPatch doesn't copy */
7036 sound->volume = 128;
7037 sound->priority = 0;
7041 * Load a sound from a file.
7042 * @param offs File offset to read sound from.
7043 * @param sound Destination for sound.
7045 static void LoadGRFSound(size_t offs, SoundEntry *sound)
7047 /* Set default volume and priority */
7048 sound->volume = 0x80;
7049 sound->priority = 0;
7051 if (offs != SIZE_MAX) {
7052 /* Sound is present in the NewGRF. */
7053 sound->file_slot = _cur.file_index;
7054 sound->file_offset = offs;
7055 sound->grf_container_ver = _cur.grf_container_ver;
7059 /* Action 0x11 */
7060 static void GRFSound(ByteReader *buf)
7062 /* <11> <num>
7064 * W num Number of sound files that follow */
7066 uint16 num = buf->ReadWord();
7067 if (num == 0) return;
7069 SoundEntry *sound;
7070 if (_cur.grffile->sound_offset == 0) {
7071 _cur.grffile->sound_offset = GetNumSounds();
7072 _cur.grffile->num_sounds = num;
7073 sound = AllocateSound(num);
7074 } else {
7075 sound = GetSound(_cur.grffile->sound_offset);
7078 for (int i = 0; i < num; i++) {
7079 _cur.nfo_line++;
7081 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7082 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7083 bool invalid = i >= _cur.grffile->num_sounds;
7085 size_t offs = FioGetPos();
7087 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7088 byte type = FioReadByte();
7090 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7091 /* Reference to sprite section. */
7092 if (invalid) {
7093 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7094 FioSkipBytes(len);
7095 } else if (len != 4) {
7096 grfmsg(1, "GRFSound: Invalid sprite section import");
7097 FioSkipBytes(len);
7098 } else {
7099 uint32 id = FioReadDword();
7100 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7102 continue;
7105 if (type != 0xFF) {
7106 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7107 FioSkipBytes(7);
7108 SkipSpriteData(type, len - 8);
7109 continue;
7112 if (invalid) {
7113 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7114 FioSkipBytes(len);
7117 byte action = FioReadByte();
7118 switch (action) {
7119 case 0xFF:
7120 /* Allocate sound only in init stage. */
7121 if (_cur.stage == GLS_INIT) {
7122 if (_cur.grf_container_ver >= 2) {
7123 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7124 } else {
7125 LoadGRFSound(offs, sound + i);
7128 FioSkipBytes(len - 1); // already read <action>
7129 break;
7131 case 0xFE:
7132 if (_cur.stage == GLS_ACTIVATION) {
7133 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7134 * importing sounds, so this is probably all wrong... */
7135 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7136 ImportGRFSound(sound + i);
7137 } else {
7138 FioSkipBytes(len - 1); // already read <action>
7140 break;
7142 default:
7143 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7144 FioSkipBytes(len - 1); // already read <action>
7145 break;
7150 /* Action 0x11 (SKIP) */
7151 static void SkipAct11(ByteReader *buf)
7153 /* <11> <num>
7155 * W num Number of sound files that follow */
7157 _cur.skip_sprites = buf->ReadWord();
7159 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
7162 /** Action 0x12 */
7163 static void LoadFontGlyph(ByteReader *buf)
7165 /* <12> <num_def> <font_size> <num_char> <base_char>
7167 * B num_def Number of definitions
7168 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7169 * B num_char Number of consecutive glyphs
7170 * W base_char First character index */
7172 uint8 num_def = buf->ReadByte();
7174 for (uint i = 0; i < num_def; i++) {
7175 FontSize size = (FontSize)buf->ReadByte();
7176 uint8 num_char = buf->ReadByte();
7177 uint16 base_char = buf->ReadWord();
7179 if (size >= FS_END) {
7180 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7183 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7185 for (uint c = 0; c < num_char; c++) {
7186 if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
7187 _cur.nfo_line++;
7188 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7193 /** Action 0x12 (SKIP) */
7194 static void SkipAct12(ByteReader *buf)
7196 /* <12> <num_def> <font_size> <num_char> <base_char>
7198 * B num_def Number of definitions
7199 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7200 * B num_char Number of consecutive glyphs
7201 * W base_char First character index */
7203 uint8 num_def = buf->ReadByte();
7205 for (uint i = 0; i < num_def; i++) {
7206 /* Ignore 'size' byte */
7207 buf->ReadByte();
7209 /* Sum up number of characters */
7210 _cur.skip_sprites += buf->ReadByte();
7212 /* Ignore 'base_char' word */
7213 buf->ReadWord();
7216 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
7219 /** Action 0x13 */
7220 static void TranslateGRFStrings(ByteReader *buf)
7222 /* <13> <grfid> <num-ent> <offset> <text...>
7224 * 4*B grfid The GRFID of the file whose texts are to be translated
7225 * B num-ent Number of strings
7226 * W offset First text ID
7227 * S text... Zero-terminated strings */
7229 uint32 grfid = buf->ReadDWord();
7230 const GRFConfig *c = GetGRFConfig(grfid);
7231 if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7232 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7233 return;
7236 if (c->status == GCS_INITIALISED) {
7237 /* If the file is not active but will be activated later, give an error
7238 * and disable this file. */
7239 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
7241 char tmp[256];
7242 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
7243 error->data = strdup(tmp);
7245 return;
7248 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7249 * to be added as a generic string, thus the language id of 0x7F. For this to work
7250 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7251 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7252 * not change anything if a string has been provided specifically for this language. */
7253 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7254 byte num_strings = buf->ReadByte();
7255 uint16 first_id = buf->ReadWord();
7257 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD3FF) || (first_id >= 0xDC00 && first_id + num_strings <= 0xDCFF))) {
7258 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7259 return;
7262 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7263 const char *string = buf->ReadString();
7265 if (StrEmpty(string)) {
7266 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7267 continue;
7270 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7274 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7275 static bool ChangeGRFName(byte langid, const char *str)
7277 AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
7278 return true;
7281 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7282 static bool ChangeGRFDescription(byte langid, const char *str)
7284 AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
7285 return true;
7288 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7289 static bool ChangeGRFURL(byte langid, const char *str)
7291 AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str);
7292 return true;
7295 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7296 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7298 if (len != 1) {
7299 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7300 buf->Skip(len);
7301 } else {
7302 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7304 return true;
7307 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7308 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7310 if (len != 1) {
7311 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7312 buf->Skip(len);
7313 } else {
7314 char data = buf->ReadByte();
7315 GRFPalette pal = GRFP_GRF_UNSET;
7316 switch (data) {
7317 case '*':
7318 case 'A': pal = GRFP_GRF_ANY; break;
7319 case 'W': pal = GRFP_GRF_WINDOWS; break;
7320 case 'D': pal = GRFP_GRF_DOS; break;
7321 default:
7322 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7323 break;
7325 if (pal != GRFP_GRF_UNSET) {
7326 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7327 _cur.grfconfig->palette |= pal;
7330 return true;
7333 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7334 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7336 if (len != 1) {
7337 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7338 buf->Skip(len);
7339 } else {
7340 char data = buf->ReadByte();
7341 GRFPalette pal = GRFP_BLT_UNSET;
7342 switch (data) {
7343 case '8': pal = GRFP_BLT_UNSET; break;
7344 case '3': pal = GRFP_BLT_32BPP; break;
7345 default:
7346 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7347 return true;
7349 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7350 _cur.grfconfig->palette |= pal;
7352 return true;
7355 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7356 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7358 if (len != 4) {
7359 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7360 buf->Skip(len);
7361 } else {
7362 /* Set min_loadable_version as well (default to minimal compatibility) */
7363 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7365 return true;
7368 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7369 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7371 if (len != 4) {
7372 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7373 buf->Skip(len);
7374 } else {
7375 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7376 if (_cur.grfconfig->version == 0) {
7377 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7378 _cur.grfconfig->min_loadable_version = 0;
7380 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7381 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7382 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
7385 return true;
7388 static GRFParameterInfo *_cur_parameter; ///< The parameter which info is currently changed by the newgrf.
7390 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7391 static bool ChangeGRFParamName(byte langid, const char *str)
7393 AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
7394 return true;
7397 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7398 static bool ChangeGRFParamDescription(byte langid, const char *str)
7400 AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
7401 return true;
7404 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7405 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7407 if (len != 1) {
7408 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7409 buf->Skip(len);
7410 } else {
7411 GRFParameterType type = (GRFParameterType)buf->ReadByte();
7412 if (type < PTYPE_END) {
7413 _cur_parameter->type = type;
7414 } else {
7415 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7418 return true;
7421 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7422 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7424 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7425 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7426 buf->Skip(len);
7427 } else if (len != 8) {
7428 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7429 buf->Skip(len);
7430 } else {
7431 _cur_parameter->min_value = buf->ReadDWord();
7432 _cur_parameter->max_value = buf->ReadDWord();
7434 return true;
7437 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7438 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7440 if (len < 1 || len > 3) {
7441 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7442 buf->Skip(len);
7443 } else {
7444 byte param_nr = buf->ReadByte();
7445 if (param_nr >= lengthof(_cur.grfconfig->param)) {
7446 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7447 buf->Skip(len - 1);
7448 } else {
7449 _cur_parameter->param_nr = param_nr;
7450 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
7451 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7455 return true;
7458 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7459 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7461 if (len != 4) {
7462 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7463 buf->Skip(len);
7464 } else {
7465 _cur_parameter->def_value = buf->ReadDWord();
7467 _cur.grfconfig->has_param_defaults = true;
7468 return true;
7471 typedef bool (*DataHandler)(size_t, ByteReader *); ///< Type of callback function for binary nodes
7472 typedef bool (*TextHandler)(byte, const char *str); ///< Type of callback function for text nodes
7473 typedef bool (*BranchHandler)(ByteReader *); ///< Type of callback function for branch nodes
7476 * Data structure to store the allowed id/type combinations for action 14. The
7477 * data can be represented as a tree with 3 types of nodes:
7478 * 1. Branch nodes (identified by 'C' for choice).
7479 * 2. Binary leaf nodes (identified by 'B').
7480 * 3. Text leaf nodes (identified by 'T').
7482 struct AllowedSubtags {
7483 /** Create empty subtags object used to identify the end of a list. */
7484 AllowedSubtags() :
7485 id(0),
7486 type(0)
7490 * Create a binary leaf node.
7491 * @param id The id for this node.
7492 * @param handler The callback function to call.
7494 AllowedSubtags(uint32 id, DataHandler handler) :
7495 id(id),
7496 type('B')
7498 this->handler.data = handler;
7502 * Create a text leaf node.
7503 * @param id The id for this node.
7504 * @param handler The callback function to call.
7506 AllowedSubtags(uint32 id, TextHandler handler) :
7507 id(id),
7508 type('T')
7510 this->handler.text = handler;
7514 * Create a branch node with a callback handler
7515 * @param id The id for this node.
7516 * @param handler The callback function to call.
7518 AllowedSubtags(uint32 id, BranchHandler handler) :
7519 id(id),
7520 type('C')
7522 this->handler.call_handler = true;
7523 this->handler.u.branch = handler;
7527 * Create a branch node with a list of sub-nodes.
7528 * @param id The id for this node.
7529 * @param subtags Array with all valid subtags.
7531 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
7532 id(id),
7533 type('C')
7535 this->handler.call_handler = false;
7536 this->handler.u.subtags = subtags;
7539 uint32 id; ///< The identifier for this node
7540 byte type; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7541 union {
7542 DataHandler data; ///< Callback function for a binary node, only valid if type == 'B'.
7543 TextHandler text; ///< Callback function for a text node, only valid if type == 'T'.
7544 struct {
7545 union {
7546 BranchHandler branch; ///< Callback function for a branch node, only valid if type == 'C' && call_handler.
7547 AllowedSubtags *subtags; ///< Pointer to a list of subtags, only valid if type == 'C' && !call_handler.
7548 } u;
7549 bool call_handler; ///< True if there is a callback function for this node, false if there is a list of subnodes.
7551 } handler;
7554 static bool SkipUnknownInfo(ByteReader *buf, byte type);
7555 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
7558 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7559 * of some parameter values (type uint/enum) or the names of some bits
7560 * (type bitmask). In both cases the format is the same:
7561 * Each subnode should be a text node with the value/bit number as id.
7563 static bool ChangeGRFParamValueNames(ByteReader *buf)
7565 byte type = buf->ReadByte();
7566 while (type != 0) {
7567 uint32 id = buf->ReadDWord();
7568 if (type != 'T' || id > _cur_parameter->max_value) {
7569 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7570 if (!SkipUnknownInfo(buf, type)) return false;
7571 type = buf->ReadByte();
7572 continue;
7575 byte langid = buf->ReadByte();
7576 const char *name_string = buf->ReadString();
7578 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
7579 if (val_name != _cur_parameter->value_names.End()) {
7580 AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
7581 } else {
7582 GRFText *list = NULL;
7583 AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
7584 _cur_parameter->value_names.Insert(id, list);
7587 type = buf->ReadByte();
7589 return true;
7592 /** Action14 parameter tags */
7593 AllowedSubtags _tags_parameters[] = {
7594 AllowedSubtags('NAME', ChangeGRFParamName),
7595 AllowedSubtags('DESC', ChangeGRFParamDescription),
7596 AllowedSubtags('TYPE', ChangeGRFParamType),
7597 AllowedSubtags('LIMI', ChangeGRFParamLimits),
7598 AllowedSubtags('MASK', ChangeGRFParamMask),
7599 AllowedSubtags('VALU', ChangeGRFParamValueNames),
7600 AllowedSubtags('DFLT', ChangeGRFParamDefault),
7601 AllowedSubtags()
7605 * Callback function for 'INFO'->'PARA' to set extra information about the
7606 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7607 * the parameter number as id. The first parameter has id 0. The maximum
7608 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7610 static bool HandleParameterInfo(ByteReader *buf)
7612 byte type = buf->ReadByte();
7613 while (type != 0) {
7614 uint32 id = buf->ReadDWord();
7615 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
7616 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7617 if (!SkipUnknownInfo(buf, type)) return false;
7618 type = buf->ReadByte();
7619 continue;
7622 if (id >= _cur.grfconfig->param_info.Length()) {
7623 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
7624 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
7625 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
7627 if (_cur.grfconfig->param_info[id] == NULL) {
7628 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
7630 _cur_parameter = _cur.grfconfig->param_info[id];
7631 /* Read all parameter-data and process each node. */
7632 if (!HandleNodes(buf, _tags_parameters)) return false;
7633 type = buf->ReadByte();
7635 return true;
7638 /** Action14 tags for the INFO node */
7639 AllowedSubtags _tags_info[] = {
7640 AllowedSubtags('NAME', ChangeGRFName),
7641 AllowedSubtags('DESC', ChangeGRFDescription),
7642 AllowedSubtags('URL_', ChangeGRFURL),
7643 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
7644 AllowedSubtags('PALS', ChangeGRFPalette),
7645 AllowedSubtags('BLTR', ChangeGRFBlitter),
7646 AllowedSubtags('VRSN', ChangeGRFVersion),
7647 AllowedSubtags('MINV', ChangeGRFMinVersion),
7648 AllowedSubtags('PARA', HandleParameterInfo),
7649 AllowedSubtags()
7652 /** Action14 root tags */
7653 AllowedSubtags _tags_root[] = {
7654 AllowedSubtags('INFO', _tags_info),
7655 AllowedSubtags()
7660 * Try to skip the current node and all subnodes (if it's a branch node).
7661 * @param buf Buffer.
7662 * @param type The node type to skip.
7663 * @return True if we could skip the node, false if an error occured.
7665 static bool SkipUnknownInfo(ByteReader *buf, byte type)
7667 /* type and id are already read */
7668 switch (type) {
7669 case 'C': {
7670 byte new_type = buf->ReadByte();
7671 while (new_type != 0) {
7672 buf->ReadDWord(); // skip the id
7673 if (!SkipUnknownInfo(buf, new_type)) return false;
7674 new_type = buf->ReadByte();
7676 break;
7679 case 'T':
7680 buf->ReadByte(); // lang
7681 buf->ReadString(); // actual text
7682 break;
7684 case 'B': {
7685 uint16 size = buf->ReadWord();
7686 buf->Skip(size);
7687 break;
7690 default:
7691 return false;
7694 return true;
7698 * Handle the nodes of an Action14
7699 * @param type Type of node.
7700 * @param id ID.
7701 * @param buf Buffer.
7702 * @param subtags Allowed subtags.
7703 * @return Whether all tags could be handled.
7705 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
7707 uint i = 0;
7708 AllowedSubtags *tag;
7709 while ((tag = &subtags[i++])->type != 0) {
7710 if (tag->id != BSWAP32(id) || tag->type != type) continue;
7711 switch (type) {
7712 default: NOT_REACHED();
7714 case 'T': {
7715 byte langid = buf->ReadByte();
7716 return tag->handler.text(langid, buf->ReadString());
7719 case 'B': {
7720 size_t len = buf->ReadWord();
7721 if (buf->Remaining() < len) return false;
7722 return tag->handler.data(len, buf);
7725 case 'C': {
7726 if (tag->handler.call_handler) {
7727 return tag->handler.u.branch(buf);
7729 return HandleNodes(buf, tag->handler.u.subtags);
7733 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
7734 return SkipUnknownInfo(buf, type);
7738 * Handle the contents of a 'C' choice of an Action14
7739 * @param buf Buffer.
7740 * @param subtags List of subtags.
7741 * @return Whether the nodes could all be handled.
7743 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
7745 byte type = buf->ReadByte();
7746 while (type != 0) {
7747 uint32 id = buf->ReadDWord();
7748 if (!HandleNode(type, id, buf, subtags)) return false;
7749 type = buf->ReadByte();
7751 return true;
7755 * Handle Action 0x14
7756 * @param buf Buffer.
7758 static void StaticGRFInfo(ByteReader *buf)
7760 /* <14> <type> <id> <text/data...> */
7761 HandleNodes(buf, _tags_root);
7765 * Set the current NewGRF as unsafe for static use
7766 * @param buf Unused.
7767 * @note Used during safety scan on unsafe actions.
7769 static void GRFUnsafe(ByteReader *buf)
7771 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7773 /* Skip remainder of GRF */
7774 _cur.skip_sprites = -1;
7778 /** Initialize the TTDPatch flags */
7779 static void InitializeGRFSpecial()
7781 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
7782 | (1 << 0x0D) // newairports
7783 | (1 << 0x0E) // largestations
7784 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
7785 | (0 << 0x10) // loadtime
7786 | (1 << 0x12) // presignals
7787 | (1 << 0x13) // extpresignals
7788 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
7789 | (1 << 0x1B) // multihead
7790 | (1 << 0x1D) // lowmemory
7791 | (1 << 0x1E); // generalfixes
7793 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
7794 | (1 << 0x08) // mammothtrains
7795 | (1 << 0x09) // trainrefit
7796 | (0 << 0x0B) // subsidiaries
7797 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
7798 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7799 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7800 | (1 << 0x14) // bridgespeedlimits
7801 | (1 << 0x16) // eternalgame
7802 | (1 << 0x17) // newtrains
7803 | (1 << 0x18) // newrvs
7804 | (1 << 0x19) // newships
7805 | (1 << 0x1A) // newplanes
7806 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7807 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
7809 _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
7810 | (1 << 0x03) // semaphores
7811 | (1 << 0x0A) // newobjects
7812 | (0 << 0x0B) // enhancedgui
7813 | (0 << 0x0C) // newagerating
7814 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
7815 | (1 << 0x0E) // fullloadany
7816 | (1 << 0x0F) // planespeed
7817 | (0 << 0x10) // moreindustriesperclimate - obsolete
7818 | (0 << 0x11) // moretoylandfeatures
7819 | (1 << 0x12) // newstations
7820 | (1 << 0x13) // tracktypecostdiff
7821 | (1 << 0x14) // manualconvert
7822 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
7823 | (1 << 0x16) // canals
7824 | (1 << 0x17) // newstartyear
7825 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
7826 | (1 << 0x19) // newhouses
7827 | (1 << 0x1A) // newbridges
7828 | (1 << 0x1B) // newtownnames
7829 | (1 << 0x1C) // moreanimation
7830 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
7831 | (1 << 0x1E) // newshistory
7832 | (0 << 0x1F); // custombridgeheads
7834 _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
7835 | (1 << 0x01) // windowsnap
7836 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
7837 | (1 << 0x03) // pathbasedsignalling
7838 | (0 << 0x04) // aichoosechance
7839 | (1 << 0x05) // resolutionwidth
7840 | (1 << 0x06) // resolutionheight
7841 | (1 << 0x07) // newindustries
7842 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
7843 | (0 << 0x09) // townroadbranchprob
7844 | (0 << 0x0A) // tempsnowline
7845 | (1 << 0x0B) // newcargo
7846 | (1 << 0x0C) // enhancemultiplayer
7847 | (1 << 0x0D) // onewayroads
7848 | (1 << 0x0E) // irregularstations
7849 | (1 << 0x0F) // statistics
7850 | (1 << 0x10) // newsounds
7851 | (1 << 0x11) // autoreplace
7852 | (1 << 0x12) // autoslope
7853 | (0 << 0x13) // followvehicle
7854 | (1 << 0x14) // trams
7855 | (0 << 0x15) // enhancetunnels
7856 | (1 << 0x16) // shortrvs
7857 | (1 << 0x17) // articulatedrvs
7858 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
7859 | (1 << 0x1E) // variablerunningcosts
7860 | (1 << 0x1F); // any switch is on
7863 /** Reset and clear all NewGRF stations */
7864 static void ResetCustomStations()
7866 const GRFFile * const *end = _grf_files.End();
7867 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7868 StationSpec **&stations = (*file)->stations;
7869 if (stations == NULL) continue;
7870 for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
7871 if (stations[i] == NULL) continue;
7872 StationSpec *statspec = stations[i];
7874 delete[] statspec->renderdata;
7876 /* Release platforms and layouts */
7877 if (!statspec->copied_layouts) {
7878 for (uint l = 0; l < statspec->lengths; l++) {
7879 for (uint p = 0; p < statspec->platforms[l]; p++) {
7880 free(statspec->layouts[l][p]);
7882 free(statspec->layouts[l]);
7884 free(statspec->layouts);
7885 free(statspec->platforms);
7888 /* Release this station */
7889 free(statspec);
7892 /* Free and reset the station data */
7893 free(stations);
7894 stations = NULL;
7898 /** Reset and clear all NewGRF houses */
7899 static void ResetCustomHouses()
7901 const GRFFile * const *end = _grf_files.End();
7902 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7903 HouseSpec **&housespec = (*file)->housespec;
7904 if (housespec == NULL) continue;
7905 for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
7906 free(housespec[i]);
7909 free(housespec);
7910 housespec = NULL;
7914 /** Reset and clear all NewGRF airports */
7915 static void ResetCustomAirports()
7917 const GRFFile * const *end = _grf_files.End();
7918 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7919 AirportSpec **aslist = (*file)->airportspec;
7920 if (aslist != NULL) {
7921 for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
7922 AirportSpec *as = aslist[i];
7924 if (as != NULL) {
7925 /* We need to remove the tiles layouts */
7926 for (int j = 0; j < as->num_table; j++) {
7927 /* remove the individual layouts */
7928 free(as->table[j]);
7930 free(as->table);
7931 free(as->depot_table);
7933 free(as);
7936 free(aslist);
7937 (*file)->airportspec = NULL;
7940 AirportTileSpec **&airporttilespec = (*file)->airtspec;
7941 if (airporttilespec != NULL) {
7942 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
7943 free(airporttilespec[i]);
7945 free(airporttilespec);
7946 airporttilespec = NULL;
7951 /** Reset and clear all NewGRF industries */
7952 static void ResetCustomIndustries()
7954 const GRFFile * const *end = _grf_files.End();
7955 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7956 IndustrySpec **&industryspec = (*file)->industryspec;
7957 IndustryTileSpec **&indtspec = (*file)->indtspec;
7959 /* We are verifiying both tiles and industries specs loaded from the grf file
7960 * First, let's deal with industryspec */
7961 if (industryspec != NULL) {
7962 for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
7963 IndustrySpec *ind = industryspec[i];
7964 if (ind == NULL) continue;
7966 /* We need to remove the sounds array */
7967 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
7968 free(ind->random_sounds);
7971 /* We need to remove the tiles layouts */
7972 CleanIndustryTileTable(ind);
7974 free(ind);
7977 free(industryspec);
7978 industryspec = NULL;
7981 if (indtspec == NULL) continue;
7982 for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
7983 free(indtspec[i]);
7986 free(indtspec);
7987 indtspec = NULL;
7991 /** Reset and clear all NewObjects */
7992 static void ResetCustomObjects()
7994 const GRFFile * const *end = _grf_files.End();
7995 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
7996 ObjectSpec **&objectspec = (*file)->objectspec;
7997 if (objectspec == NULL) continue;
7998 for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
7999 free(objectspec[i]);
8002 free(objectspec);
8003 objectspec = NULL;
8007 /** Reset and clear all NewGRFs */
8008 static void ResetNewGRF()
8010 const GRFFile * const *end = _grf_files.End();
8011 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8012 delete *file;
8015 _grf_files.Clear();
8016 _cur.grffile = NULL;
8019 /** Clear all NewGRF errors */
8020 static void ResetNewGRFErrors()
8022 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
8023 if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
8024 delete c->error;
8025 c->error = NULL;
8031 * Reset all NewGRF loaded data
8032 * TODO
8034 void ResetNewGRFData()
8036 CleanUpStrings();
8037 CleanUpGRFTownNames();
8039 /* Copy/reset original engine info data */
8040 SetupEngines();
8042 /* Copy/reset original bridge info data */
8043 ResetBridges();
8045 /* Reset rail type information */
8046 ResetRailTypes();
8048 /* Allocate temporary refit/cargo class data */
8049 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
8051 /* Fill rail type label temporary data for default trains */
8052 Engine *e;
8053 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
8054 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
8057 /* Reset GRM reservations */
8058 memset(&_grm_engines, 0, sizeof(_grm_engines));
8059 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
8061 /* Reset generic feature callback lists */
8062 ResetGenericCallbacks();
8064 /* Reset price base data */
8065 ResetPriceBaseMultipliers();
8067 /* Reset the curencies array */
8068 ResetCurrencies();
8070 /* Reset the house array */
8071 ResetCustomHouses();
8072 ResetHouses();
8074 /* Reset the industries structures*/
8075 ResetCustomIndustries();
8076 ResetIndustries();
8078 /* Reset the objects. */
8079 ObjectClass::Reset();
8080 ResetCustomObjects();
8081 ResetObjects();
8083 /* Reset station classes */
8084 StationClass::Reset();
8085 ResetCustomStations();
8087 /* Reset airport-related structures */
8088 AirportClass::Reset();
8089 ResetCustomAirports();
8090 AirportSpec::ResetAirports();
8091 AirportTileSpec::ResetAirportTiles();
8093 /* Reset canal sprite groups and flags */
8094 memset(_water_feature, 0, sizeof(_water_feature));
8096 /* Reset the snowline table. */
8097 ClearSnowLine();
8099 /* Reset NewGRF files */
8100 ResetNewGRF();
8102 /* Reset NewGRF errors. */
8103 ResetNewGRFErrors();
8105 /* Set up the default cargo types */
8106 SetupCargoForClimate(_settings_game.game_creation.landscape);
8108 /* Reset misc GRF features and train list display variables */
8109 _misc_grf_features = 0;
8111 _loaded_newgrf_features.has_2CC = false;
8112 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8113 _loaded_newgrf_features.has_newhouses = false;
8114 _loaded_newgrf_features.has_newindustries = false;
8115 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
8117 /* Clear all GRF overrides */
8118 _grf_id_overrides.clear();
8120 InitializeSoundPool();
8121 SpriteGroup::pool.CleanPool();
8125 * Reset NewGRF data which is stored persistently in savegames.
8127 void ResetPersistentNewGRFData()
8129 /* Reset override managers */
8130 _engine_mngr.ResetToDefaultMapping();
8131 _house_mngr.ResetMapping();
8132 _industry_mngr.ResetMapping();
8133 _industile_mngr.ResetMapping();
8134 _airport_mngr.ResetMapping();
8135 _airporttile_mngr.ResetMapping();
8139 * Construct the Cargo Mapping
8140 * @note This is the reverse of a cargo translation table
8142 static void BuildCargoTranslationMap()
8144 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8146 for (CargoID c = 0; c < NUM_CARGO; c++) {
8147 const CargoSpec *cs = CargoSpec::Get(c);
8148 if (!cs->IsValid()) continue;
8150 if (_cur.grffile->cargo_list.Length() == 0) {
8151 /* Default translation table, so just a straight mapping to bitnum */
8152 _cur.grffile->cargo_map[c] = cs->bitnum;
8153 } else {
8154 /* Check the translation table for this cargo's label */
8155 int index = _cur.grffile->cargo_list.FindIndex(cs->label);
8156 if (index >= 0) _cur.grffile->cargo_map[c] = index;
8162 * Prepare loading a NewGRF file with its config
8163 * @param config The NewGRF configuration struct with name, id, parameters and alike.
8165 static void InitNewGRFFile(const GRFConfig *config)
8167 GRFFile *newfile = GetFileByFilename(config->filename);
8168 if (newfile != NULL) {
8169 /* We already loaded it once. */
8170 _cur.grffile = newfile;
8171 return;
8174 newfile = new GRFFile(config);
8175 *_grf_files.Append() = _cur.grffile = newfile;
8179 * Constructor for GRFFile
8180 * @param config GRFConfig to copy name, grfid and parameters from.
8182 GRFFile::GRFFile(const GRFConfig *config)
8184 this->filename = strdup(config->filename);
8185 this->grfid = config->ident.grfid;
8187 /* Initialise local settings to defaults */
8188 this->traininfo_vehicle_pitch = 0;
8189 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8191 /* Mark price_base_multipliers as 'not set' */
8192 for (Price i = PR_BEGIN; i < PR_END; i++) {
8193 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8196 /* Initialise rail type map with default rail types */
8197 memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
8198 this->railtype_map[0] = RAILTYPE_RAIL;
8199 this->railtype_map[1] = RAILTYPE_ELECTRIC;
8200 this->railtype_map[2] = RAILTYPE_MONO;
8201 this->railtype_map[3] = RAILTYPE_MAGLEV;
8203 /* Copy the initial parameter list
8204 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8205 assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8207 assert(config->num_params <= lengthof(config->param));
8208 this->param_end = config->num_params;
8209 if (this->param_end > 0) {
8210 MemCpyT(this->param, config->param, this->param_end);
8214 GRFFile::~GRFFile()
8216 free(this->filename);
8217 delete[] this->language_map;
8222 * List of what cargo labels are refittable for the given the vehicle-type.
8223 * Only currently active labels are applied.
8225 static const CargoLabel _default_refitmasks_rail[] = {
8226 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8227 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8228 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8229 'PLST', 'FZDR',
8230 0 };
8232 static const CargoLabel _default_refitmasks_road[] = {
8233 0 };
8235 static const CargoLabel _default_refitmasks_ships[] = {
8236 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8237 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8238 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8239 'PLST', 'FZDR',
8240 0 };
8242 static const CargoLabel _default_refitmasks_aircraft[] = {
8243 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8244 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8245 0 };
8247 static const CargoLabel * const _default_refitmasks[] = {
8248 _default_refitmasks_rail,
8249 _default_refitmasks_road,
8250 _default_refitmasks_ships,
8251 _default_refitmasks_aircraft,
8256 * Precalculate refit masks from cargo classes for all vehicles.
8258 static void CalculateRefitMasks()
8260 Engine *e;
8262 FOR_ALL_ENGINES(e) {
8263 EngineID engine = e->index;
8264 EngineInfo *ei = &e->info;
8265 bool only_defaultcargo; ///< Set if the vehicle shall carry only the default cargo
8267 /* Did the newgrf specify any refitting? If not, use defaults. */
8268 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8269 uint32 mask = 0;
8270 uint32 not_mask = 0;
8271 uint32 xor_mask = ei->refit_mask;
8273 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8274 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8275 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8277 if (_gted[engine].cargo_allowed != 0) {
8278 /* Build up the list of cargo types from the set cargo classes. */
8279 const CargoSpec *cs;
8280 FOR_ALL_CARGOSPECS(cs) {
8281 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8282 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8286 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8288 /* Apply explicit refit includes/excludes. */
8289 ei->refit_mask |= _gted[engine].ctt_include_mask;
8290 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8291 } else {
8292 uint32 xor_mask = 0;
8294 /* Don't apply default refit mask to wagons nor engines with no capacity */
8295 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8296 const CargoLabel *cl = _default_refitmasks[e->type];
8297 for (uint i = 0;; i++) {
8298 if (cl[i] == 0) break;
8300 CargoID cargo = GetCargoIDByLabel(cl[i]);
8301 if (cargo == CT_INVALID) continue;
8303 SetBit(xor_mask, cargo);
8307 ei->refit_mask = xor_mask & _cargo_mask;
8309 /* If the mask is zero, the vehicle shall only carry the default cargo */
8310 only_defaultcargo = (ei->refit_mask == 0);
8313 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8314 if (!HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8316 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8317 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8318 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8319 ei->cargo_type = CT_INVALID;
8322 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8323 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8324 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8325 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8326 const uint8 *cargo_map_for_first_refittable = NULL;
8328 const GRFFile *file = _gted[engine].defaultcargo_grf;
8329 if (file == NULL) file = e->GetGRF();
8330 if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
8331 cargo_map_for_first_refittable = file->cargo_map;
8335 if (cargo_map_for_first_refittable != NULL) {
8336 /* Use first refittable cargo from cargo translation table */
8337 byte best_local_slot = 0xFF;
8338 CargoID cargo_type;
8339 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8340 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8341 if (local_slot < best_local_slot) {
8342 best_local_slot = local_slot;
8343 ei->cargo_type = cargo_type;
8348 if (ei->cargo_type == CT_INVALID) {
8349 /* Use first refittable cargo slot */
8350 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8353 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8355 /* Clear refit_mask for not refittable ships */
8356 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8357 ei->refit_mask = 0;
8362 /** Set to use the correct action0 properties for each canal feature */
8363 static void FinaliseCanals()
8365 for (uint i = 0; i < CF_END; i++) {
8366 if (_water_feature[i].grffile != NULL) {
8367 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
8368 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
8373 /** Check for invalid engines */
8374 static void FinaliseEngineArray()
8376 Engine *e;
8378 FOR_ALL_ENGINES(e) {
8379 if (e->GetGRF() == NULL) {
8380 const EngineIDMapping &eid = _engine_mngr[e->index];
8381 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8382 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8386 /* When the train does not set property 27 (misc flags), but it
8387 * is overridden by a NewGRF graphically we want to disable the
8388 * flipping possibility. */
8389 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) {
8390 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8393 /* Skip wagons, there livery is defined via the engine */
8394 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8395 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, NULL);
8396 SetBit(_loaded_newgrf_features.used_liveries, ls);
8397 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8399 if (e->type == VEH_TRAIN) {
8400 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8401 switch (ls) {
8402 case LS_STEAM:
8403 case LS_DIESEL:
8404 case LS_ELECTRIC:
8405 case LS_MONORAIL:
8406 case LS_MAGLEV:
8407 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8408 break;
8410 case LS_DMU:
8411 case LS_EMU:
8412 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8413 break;
8415 default: NOT_REACHED();
8422 /** Check for invalid cargoes */
8423 static void FinaliseCargoArray()
8425 for (CargoID c = 0; c < NUM_CARGO; c++) {
8426 CargoSpec *cs = CargoSpec::Get(c);
8427 if (!cs->IsValid()) {
8428 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8429 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8430 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8436 * Check if a given housespec is valid and disable it if it's not.
8437 * The housespecs that follow it are used to check the validity of
8438 * multitile houses.
8439 * @param hs The housespec to check.
8440 * @param next1 The housespec that follows \c hs.
8441 * @param next2 The housespec that follows \c next1.
8442 * @param next3 The housespec that follows \c next2.
8443 * @param filename The filename of the newgrf this house was defined in.
8444 * @return Whether the given housespec is valid.
8446 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8448 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8449 (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8450 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8451 (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8452 next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8453 hs->enabled = false;
8454 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);
8455 return false;
8458 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8459 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8460 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8461 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8462 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8463 hs->enabled = false;
8464 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);
8465 return false;
8468 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8469 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8470 if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8471 hs->enabled = false;
8472 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);
8473 return false;
8476 /* Make sure that additional parts of multitile houses are not available. */
8477 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
8478 hs->enabled = false;
8479 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);
8480 return false;
8483 return true;
8487 * Make sure there is at least one house available in the year 0 for the given
8488 * climate / housezone combination.
8489 * @param bitmask The climate and housezone to check for. Exactly one climate
8490 * bit and one housezone bit should be set.
8492 static void EnsureEarlyHouse(HouseZones bitmask)
8494 Year min_year = MAX_YEAR;
8496 for (int i = 0; i < NUM_HOUSES; i++) {
8497 HouseSpec *hs = HouseSpec::Get(i);
8498 if (hs == NULL || !hs->enabled) continue;
8499 if ((hs->building_availability & bitmask) != bitmask) continue;
8500 if (hs->min_year < min_year) min_year = hs->min_year;
8503 if (min_year == 0) return;
8505 for (int i = 0; i < NUM_HOUSES; i++) {
8506 HouseSpec *hs = HouseSpec::Get(i);
8507 if (hs == NULL || !hs->enabled) continue;
8508 if ((hs->building_availability & bitmask) != bitmask) continue;
8509 if (hs->min_year == min_year) hs->min_year = 0;
8514 * Add all new houses to the house array. House properties can be set at any
8515 * time in the GRF file, so we can only add a house spec to the house array
8516 * after the file has finished loading. We also need to check the dates, due to
8517 * the TTDPatch behaviour described below that we need to emulate.
8519 static void FinaliseHouseArray()
8521 /* If there are no houses with start dates before 1930, then all houses
8522 * with start dates of 1930 have them reset to 0. This is in order to be
8523 * compatible with TTDPatch, where if no houses have start dates before
8524 * 1930 and the date is before 1930, the game pretends that this is 1930.
8525 * If there have been any houses defined with start dates before 1930 then
8526 * the dates are left alone.
8527 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8528 * minimum introduction date to 0.
8530 const GRFFile * const *end = _grf_files.End();
8531 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8532 HouseSpec **&housespec = (*file)->housespec;
8533 if (housespec == NULL) continue;
8535 for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8536 HouseSpec *hs = housespec[i];
8538 if (hs == NULL) continue;
8540 const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : NULL);
8541 const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : NULL);
8542 const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : NULL);
8544 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
8546 _house_mngr.SetEntitySpec(hs);
8550 for (int i = 0; i < NUM_HOUSES; i++) {
8551 HouseSpec *hs = HouseSpec::Get(i);
8552 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : NULL);
8553 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : NULL);
8554 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : NULL);
8556 /* We need to check all houses again to we are sure that multitile houses
8557 * did get consecutive IDs and none of the parts are missing. */
8558 if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) {
8559 /* GetHouseNorthPart checks 3 houses that are directly before
8560 * it in the house pool. If any of those houses have multi-tile
8561 * flags set it assumes it's part of a multitile house. Since
8562 * we can have invalid houses in the pool marked as disabled, we
8563 * don't want to have them influencing valid tiles. As such set
8564 * building_flags to zero here to make sure any house following
8565 * this one in the pool is properly handled as 1x1 house. */
8566 hs->building_flags = TILE_NO_FLAG;
8570 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
8571 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
8572 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
8573 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
8574 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
8575 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
8577 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
8578 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
8579 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
8580 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
8581 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
8582 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
8587 * Add all new industries to the industry array. Industry properties can be set at any
8588 * time in the GRF file, so we can only add a industry spec to the industry array
8589 * after the file has finished loading.
8591 static void FinaliseIndustriesArray()
8593 const GRFFile * const *end = _grf_files.End();
8594 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8595 IndustrySpec **&industryspec = (*file)->industryspec;
8596 IndustryTileSpec **&indtspec = (*file)->indtspec;
8597 if (industryspec != NULL) {
8598 for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8599 IndustrySpec *indsp = industryspec[i];
8601 if (indsp != NULL && indsp->enabled) {
8602 StringID strid;
8603 /* process the conversion of text at the end, so to be sure everything will be fine
8604 * and available. Check if it does not return undefind marker, which is a very good sign of a
8605 * substitute industry who has not changed the string been examined, thus using it as such */
8606 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
8607 if (strid != STR_UNDEFINED) indsp->name = strid;
8609 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
8610 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
8612 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
8613 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
8615 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
8616 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
8618 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
8619 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
8621 if (indsp->station_name != STR_NULL) {
8622 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8623 * station's name. Don't want to lose the value, therefore, do not process. */
8624 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
8625 if (strid != STR_UNDEFINED) indsp->station_name = strid;
8628 _industry_mngr.SetEntitySpec(indsp);
8629 _loaded_newgrf_features.has_newindustries = true;
8634 if (indtspec != NULL) {
8635 for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8636 IndustryTileSpec *indtsp = indtspec[i];
8637 if (indtsp != NULL) {
8638 _industile_mngr.SetEntitySpec(indtsp);
8644 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
8645 IndustrySpec *indsp = &_industry_specs[j];
8646 if (indsp->enabled && indsp->grf_prop.grffile != NULL) {
8647 for (uint i = 0; i < 3; i++) {
8648 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
8651 if (!indsp->enabled) {
8652 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
8658 * Add all new objects to the object array. Object properties can be set at any
8659 * time in the GRF file, so we can only add an object spec to the object array
8660 * after the file has finished loading.
8662 static void FinaliseObjectsArray()
8664 const GRFFile * const *end = _grf_files.End();
8665 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8666 ObjectSpec **&objectspec = (*file)->objectspec;
8667 if (objectspec != NULL) {
8668 for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8669 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) {
8670 _object_mngr.SetEntitySpec(objectspec[i]);
8678 * Add all new airports to the airport array. Airport properties can be set at any
8679 * time in the GRF file, so we can only add a airport spec to the airport array
8680 * after the file has finished loading.
8682 static void FinaliseAirportsArray()
8684 const GRFFile * const *end = _grf_files.End();
8685 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8686 AirportSpec **&airportspec = (*file)->airportspec;
8687 if (airportspec != NULL) {
8688 for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8689 if (airportspec[i] != NULL && airportspec[i]->enabled) {
8690 _airport_mngr.SetEntitySpec(airportspec[i]);
8695 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8696 if (airporttilespec != NULL) {
8697 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8698 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
8699 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
8706 /* Here we perform initial decoding of some special sprites (as are they
8707 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8708 * partial implementation yet).
8709 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8710 * a crafted invalid GRF file. We should tell that to the user somehow, or
8711 * better make this more robust in the future. */
8712 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
8714 /* XXX: There is a difference between staged loading in TTDPatch and
8715 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8716 * during stage 1, whilst action 3 is carried out during stage 2 (to
8717 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8718 * IDs are valid only within a given set (action 1) block, and may be
8719 * overwritten after action 3 associates them. But overwriting happens
8720 * in an earlier stage than associating, so... We just process actions
8721 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8722 * --pasky
8723 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8724 * is not in memory and scanning the file every time would be too expensive.
8725 * In other stages we skip action 0x10 since it's already dealt with. */
8726 static const SpecialSpriteHandler handlers[][GLS_END] = {
8727 /* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
8728 /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
8729 /* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
8730 /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
8731 /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
8732 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
8733 /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
8734 /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
8735 /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
8736 /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
8737 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
8738 /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
8739 /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
8740 /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, },
8741 /* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
8742 /* 0x0F */ { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, },
8743 /* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, },
8744 /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
8745 /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
8746 /* 0x13 */ { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, },
8747 /* 0x14 */ { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, },
8750 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
8752 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
8753 if (it == _grf_line_to_action6_sprite_override.end()) {
8754 /* No preloaded sprite to work with; read the
8755 * pseudo sprite content. */
8756 FioReadBlock(buf, num);
8757 } else {
8758 /* Use the preloaded sprite data. */
8759 buf = _grf_line_to_action6_sprite_override[location];
8760 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8762 /* Skip the real (original) content of this action. */
8763 FioSeekTo(num, SEEK_CUR);
8766 ByteReader br(buf, buf + num);
8767 ByteReader *bufp = &br;
8769 try {
8770 byte action = bufp->ReadByte();
8772 if (action == 0xFF) {
8773 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8774 } else if (action == 0xFE) {
8775 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8776 } else if (action >= lengthof(handlers)) {
8777 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
8778 } else if (handlers[action][stage] == NULL) {
8779 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
8780 } else {
8781 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
8782 handlers[action][stage](bufp);
8784 } catch (...) {
8785 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8786 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
8791 /** Signature of a container version 2 GRF. */
8792 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8795 * Get the container version of the currently opened GRF file.
8796 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
8798 byte GetGRFContainerVersion()
8800 size_t pos = FioGetPos();
8802 if (FioReadWord() == 0) {
8803 /* Check for GRF container version 2, which is identified by the bytes
8804 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8805 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
8806 if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
8809 return 2;
8812 /* Container version 1 has no header, rewind to start. */
8813 FioSeekTo(pos, SEEK_SET);
8814 return 1;
8818 * Load a particular NewGRF.
8819 * @param config The configuration of the to be loaded NewGRF.
8820 * @param file_index The Fio index of the first NewGRF to load.
8821 * @param stage The loading stage of the NewGRF.
8822 * @param subdir The sub directory to find the NewGRF in.
8824 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
8826 const char *filename = config->filename;
8828 /* A .grf file is activated only if it was active when the game was
8829 * started. If a game is loaded, only its active .grfs will be
8830 * reactivated, unless "loadallgraphics on" is used. A .grf file is
8831 * considered active if its action 8 has been processed, i.e. its
8832 * action 8 hasn't been skipped using an action 7.
8834 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
8835 * carried out. All others are ignored, because they only need to be
8836 * processed once at initialization. */
8837 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
8838 _cur.grffile = GetFileByFilename(filename);
8839 if (_cur.grffile == NULL) usererror("File '%s' lost in cache.\n", filename);
8840 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
8841 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
8842 _cur.grffile->is_ottdfile = config->IsOpenTTDBaseGRF();
8845 if (file_index > LAST_GRF_SLOT) {
8846 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
8847 config->status = GCS_DISABLED;
8848 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
8849 return;
8852 FioOpenFile(file_index, filename, subdir);
8853 _cur.file_index = file_index; // XXX
8854 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
8856 _cur.grfconfig = config;
8858 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
8860 _cur.grf_container_ver = GetGRFContainerVersion();
8861 if (_cur.grf_container_ver == 0) {
8862 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8863 return;
8866 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
8867 /* We need the sprite offsets in the init stage for NewGRF sounds
8868 * and in the activation stage for real sprites. */
8869 ReadGRFSpriteOffsets(_cur.grf_container_ver);
8870 } else {
8871 /* Skip sprite section offset if present. */
8872 if (_cur.grf_container_ver >= 2) FioReadDword();
8875 if (_cur.grf_container_ver >= 2) {
8876 /* Read compression value. */
8877 byte compression = FioReadByte();
8878 if (compression != 0) {
8879 DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
8880 return;
8884 /* Skip the first sprite; we don't care about how many sprites this
8885 * does contain; newest TTDPatches and George's longvehicles don't
8886 * neither, apparently. */
8887 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
8888 if (num == 4 && FioReadByte() == 0xFF) {
8889 FioReadDword();
8890 } else {
8891 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8892 return;
8895 _cur.ClearDataForNextFile();
8897 ReusableBuffer<byte> buf;
8899 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
8900 byte type = FioReadByte();
8901 _cur.nfo_line++;
8903 if (type == 0xFF) {
8904 if (_cur.skip_sprites == 0) {
8905 DecodeSpecialSprite(buf.Allocate(num), num, stage);
8907 /* Stop all processing if we are to skip the remaining sprites */
8908 if (_cur.skip_sprites == -1) break;
8910 continue;
8911 } else {
8912 FioSkipBytes(num);
8914 } else {
8915 if (_cur.skip_sprites == 0) {
8916 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8917 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
8918 break;
8921 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
8922 /* Reference to data section. Container version >= 2 only. */
8923 FioSkipBytes(num);
8924 } else {
8925 FioSkipBytes(7);
8926 SkipSpriteData(type, num - 8);
8930 if (_cur.skip_sprites > 0) _cur.skip_sprites--;
8935 * Relocates the old shore sprites at new positions.
8937 * 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)
8938 * 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)
8939 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
8941 static void ActivateOldShore()
8943 /* Use default graphics, if no shore sprites were loaded.
8944 * Should not happen, as the base set's extra grf should include some. */
8945 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
8947 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
8948 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
8949 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
8950 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
8951 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
8952 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
8953 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
8954 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
8955 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
8958 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
8959 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
8960 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
8961 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
8962 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
8963 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
8964 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
8965 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
8966 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
8968 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
8969 * If they would be used somewhen, then these grass tiles will most like not look as needed */
8970 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
8971 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
8976 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
8978 static void FinalisePriceBaseMultipliers()
8980 extern const PriceBaseSpec _price_base_specs[];
8981 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
8982 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
8984 /* Evaluate grf overrides */
8985 int num_grfs = _grf_files.Length();
8986 int *grf_overrides = AllocaM(int, num_grfs);
8987 for (int i = 0; i < num_grfs; i++) {
8988 grf_overrides[i] = -1;
8990 GRFFile *source = _grf_files[i];
8991 uint32 override = _grf_id_overrides[source->grfid];
8992 if (override == 0) continue;
8994 GRFFile *dest = GetFileByGRFID(override);
8995 if (dest == NULL) continue;
8997 grf_overrides[i] = _grf_files.FindIndex(dest);
8998 assert(grf_overrides[i] >= 0);
9001 /* Override features and price base multipliers of earlier loaded grfs */
9002 for (int i = 0; i < num_grfs; i++) {
9003 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
9004 GRFFile *source = _grf_files[i];
9005 GRFFile *dest = _grf_files[grf_overrides[i]];
9007 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9008 source->grf_features |= features;
9009 dest->grf_features |= features;
9011 for (Price p = PR_BEGIN; p < PR_END; p++) {
9012 /* No price defined -> nothing to do */
9013 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
9014 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9015 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9019 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9020 for (int i = num_grfs - 1; i >= 0; i--) {
9021 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
9022 GRFFile *source = _grf_files[i];
9023 GRFFile *dest = _grf_files[grf_overrides[i]];
9025 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9026 source->grf_features |= features;
9027 dest->grf_features |= features;
9029 for (Price p = PR_BEGIN; p < PR_END; p++) {
9030 /* Already a price defined -> nothing to do */
9031 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
9032 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9033 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9037 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9038 for (int i = 0; i < num_grfs; i++) {
9039 if (grf_overrides[i] < 0) continue;
9040 GRFFile *source = _grf_files[i];
9041 GRFFile *dest = _grf_files[grf_overrides[i]];
9043 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9044 source->grf_features |= features;
9045 dest->grf_features |= features;
9047 for (Price p = PR_BEGIN; p < PR_END; p++) {
9048 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
9049 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
9050 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9052 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
9056 /* Apply fallback prices for grf version < 8 */
9057 const GRFFile * const *end = _grf_files.End();
9058 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9059 if ((*file)->grf_version >= 8) continue;
9060 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9061 for (Price p = PR_BEGIN; p < PR_END; p++) {
9062 Price fallback_price = _price_base_specs[p].fallback_price;
9063 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9064 /* No price multiplier has been set.
9065 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9066 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9071 /* Decide local/global scope of price base multipliers */
9072 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9073 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9074 for (Price p = PR_BEGIN; p < PR_END; p++) {
9075 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9076 /* No multiplier was set; set it to a neutral value */
9077 price_base_multipliers[p] = 0;
9078 } else {
9079 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
9080 /* The grf does not define any objects of the feature,
9081 * so it must be a difficulty setting. Apply it globally */
9082 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
9083 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9084 price_base_multipliers[p] = 0;
9085 } else {
9086 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
9093 void InitDepotWindowBlockSizes();
9095 extern void InitGRFTownGeneratorNames();
9097 /** Finish loading NewGRFs and execute needed post-processing */
9098 static void AfterLoadGRFs()
9100 for (StringIDMapping *it = _string_to_grf_mapping.Begin(); it != _string_to_grf_mapping.End(); it++) {
9101 *it->target = MapGRFStringID(it->grfid, it->source);
9103 _string_to_grf_mapping.Clear();
9105 /* Free the action 6 override sprites. */
9106 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9107 free((*it).second);
9109 _grf_line_to_action6_sprite_override.clear();
9111 /* Polish cargoes */
9112 FinaliseCargoArray();
9114 /* Pre-calculate all refit masks after loading GRF files. */
9115 CalculateRefitMasks();
9117 /* Polish engines */
9118 FinaliseEngineArray();
9120 /* Set the actually used Canal properties */
9121 FinaliseCanals();
9123 /* Set the block size in the depot windows based on vehicle sprite sizes */
9124 InitDepotWindowBlockSizes();
9126 /* Add all new houses to the house array. */
9127 FinaliseHouseArray();
9129 /* Add all new industries to the industry array. */
9130 FinaliseIndustriesArray();
9132 /* Add all new objects to the object array. */
9133 FinaliseObjectsArray();
9135 InitializeSortedCargoSpecs();
9137 /* Sort the list of industry types. */
9138 SortIndustryTypes();
9140 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9141 BuildIndustriesLegend();
9143 /* Build the routemap legend, based on the available cargos */
9144 BuildLinkStatsLegend();
9146 /* Add all new airports to the airports array. */
9147 FinaliseAirportsArray();
9148 BindAirportSpecs();
9150 /* Update the townname generators list */
9151 InitGRFTownGeneratorNames();
9153 /* Run all queued vehicle list order changes */
9154 CommitVehicleListOrderChanges();
9156 /* Load old shore sprites in new position, if they were replaced by ActionA */
9157 ActivateOldShore();
9159 /* Set up custom rail types */
9160 InitRailTypes();
9162 Engine *e;
9163 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
9164 if (_gted[e->index].rv_max_speed != 0) {
9165 /* Set RV maximum speed from the mph/0.8 unit value */
9166 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9170 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
9171 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9172 if (railtype == INVALID_RAILTYPE) {
9173 /* Rail type is not available, so disable this engine */
9174 e->info.climates = 0;
9175 } else {
9176 e->u.rail.railtype = railtype;
9180 SetYearEngineAgingStops();
9182 FinalisePriceBaseMultipliers();
9184 /* Deallocate temporary loading data */
9185 free(_gted);
9186 _grm_sprites.clear();
9190 * Load all the NewGRFs.
9191 * @param load_index The offset for the first sprite to add.
9192 * @param file_index The Fio index of the first NewGRF to load.
9194 void LoadNewGRF(uint load_index, uint file_index)
9196 /* In case of networking we need to "sync" the start values
9197 * so all NewGRFs are loaded equally. For this we use the
9198 * start date of the game and we set the counters, etc. to
9199 * 0 so they're the same too. */
9200 Date date = _date;
9201 Year year = _cur_year;
9202 DateFract date_fract = _date_fract;
9203 uint16 tick_counter = _tick_counter;
9204 byte display_opt = _display_opt;
9206 if (_networking) {
9207 _cur_year = _settings_game.game_creation.starting_year;
9208 _date = ConvertYMDToDate(_cur_year, 0, 1);
9209 _date_fract = 0;
9210 _tick_counter = 0;
9211 _display_opt = 0;
9214 InitializeGRFSpecial();
9216 ResetNewGRFData();
9219 * Reset the status of all files, so we can 'retry' to load them.
9220 * This is needed when one for example rearranges the NewGRFs in-game
9221 * and a previously disabled NewGRF becomes useable. If it would not
9222 * be reset, the NewGRF would remain disabled even though it should
9223 * have been enabled.
9225 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9226 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9229 _cur.spriteid = load_index;
9231 /* Load newgrf sprites
9232 * in each loading stage, (try to) open each file specified in the config
9233 * and load information from it. */
9234 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9235 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9236 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9237 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9238 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9241 if (stage == GLS_RESERVE) {
9242 static const uint32 overrides[][2] = {
9243 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9244 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9245 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9247 for (size_t i = 0; i < lengthof(overrides); i++) {
9248 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9252 uint slot = file_index;
9254 _cur.stage = stage;
9255 for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
9256 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9257 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9259 Subdirectory subdir = slot == file_index ? BASESET_DIR : NEWGRF_DIR;
9260 if (!FioCheckFileExists(c->filename, subdir)) {
9261 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9262 c->status = GCS_NOT_FOUND;
9263 continue;
9266 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
9267 LoadNewGRFFile(c, slot++, stage, subdir);
9268 if (stage == GLS_RESERVE) {
9269 SetBit(c->flags, GCF_RESERVED);
9270 } else if (stage == GLS_ACTIVATION) {
9271 ClrBit(c->flags, GCF_RESERVED);
9272 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9273 ClearTemporaryNewGRFData(_cur.grffile);
9274 BuildCargoTranslationMap();
9275 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9276 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9277 /* We're not going to activate this, so free whatever data we allocated */
9278 ClearTemporaryNewGRFData(_cur.grffile);
9283 /* Pseudo sprite processing is finished; free temporary stuff */
9284 _cur.ClearDataForNextFile();
9286 /* Call any functions that should be run after GRFs have been loaded. */
9287 AfterLoadGRFs();
9289 /* Now revert back to the original situation */
9290 _cur_year = year;
9291 _date = date;
9292 _date_fract = date_fract;
9293 _tick_counter = tick_counter;
9294 _display_opt = display_opt;