Increase the number of road and tram subtypes to 32.
[openttd-joker.git] / src / newgrf.cpp
blob95591c3553ce1716f31822d98942b485aa3ef2c4
1 /* $Id: newgrf.cpp 26245 2014-01-12 18:01:50Z frosch $ */
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>
15 #include <algorithm>
17 #include "debug.h"
18 #include "fileio_func.h"
19 #include "engine_func.h"
20 #include "engine_base.h"
21 #include "bridge.h"
22 #include "town.h"
23 #include "newgrf_engine.h"
24 #include "newgrf_text.h"
25 #include "fontcache.h"
26 #include "currency.h"
27 #include "landscape.h"
28 #include "newgrf_cargo.h"
29 #include "newgrf_house.h"
30 #include "newgrf_sound.h"
31 #include "newgrf_station.h"
32 #include "industrytype.h"
33 #include "newgrf_canal.h"
34 #include "newgrf_townname.h"
35 #include "newgrf_industries.h"
36 #include "newgrf_airporttiles.h"
37 #include "newgrf_airport.h"
38 #include "newgrf_object.h"
39 #include "rev.h"
40 #include "fios.h"
41 #include "strings_func.h"
42 #include "date_func.h"
43 #include "string_func.h"
44 #include "network/network.h"
45 #include <map>
46 #include "smallmap_gui.h"
47 #include "genworld.h"
48 #include "error.h"
49 #include "vehicle_func.h"
50 #include "language.h"
51 #include "vehicle_base.h"
53 #include "table/strings.h"
54 #include "table/build_industry.h"
56 #include "3rdparty/cpp-btree/btree_map.h"
58 #include "safeguards.h"
60 /* TTDPatch extended GRF format codec
61 * (c) Petr Baudis 2004 (GPL'd)
62 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
64 * Contains portions of documentation by TTDPatch team.
65 * Thanks especially to Josef Drexler for the documentation as well as a lot
66 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
67 * served as subject to the initial testing of this codec. */
69 /** List of all loaded GRF files */
70 static SmallVector<GRFFile *, 16> _grf_files;
72 /** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
73 byte _misc_grf_features = 0;
75 /** 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
76 static uint32 _ttdpatch_flags[8];
78 /** Indicates which are the newgrf features currently loaded ingame */
79 GRFLoadedFeatures _loaded_newgrf_features;
81 static const uint MAX_SPRITEGROUP = UINT8_MAX; ///< Maximum GRF-local ID for a spritegroup.
83 /** Temporary data during loading of GRFs */
84 struct GrfProcessingState {
85 private:
86 /** Definition of a single Action1 spriteset */
87 struct SpriteSet {
88 SpriteID sprite; ///< SpriteID of the first sprite of the set.
89 uint num_sprites; ///< Number of sprites in the set.
92 /** Currently referenceable spritesets */
93 btree::btree_map<uint, SpriteSet> spritesets[GSF_END];
95 public:
96 /* Global state */
97 GrfLoadingStage stage; ///< Current loading stage
98 SpriteID spriteid; ///< First available SpriteID for loading realsprites.
100 /* Local state in the file */
101 uint file_index; ///< File index of currently processed GRF file.
102 GRFFile *grffile; ///< Currently processed GRF file.
103 GRFConfig *grfconfig; ///< Config of the currently processed GRF file.
104 uint32 nfo_line; ///< Currently processed pseudo sprite number in the GRF.
105 byte grf_container_ver; ///< Container format of the current GRF file.
107 /* Kind of return values when processing certain actions */
108 int skip_sprites; ///< Number of psuedo sprites to skip before processing the next one. (-1 to skip to end of file)
110 /* Currently referenceable spritegroups */
111 SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1];
113 /** Clear temporary data before processing the next file in the current loading stage */
114 void ClearDataForNextFile()
116 this->nfo_line = 0;
117 this->skip_sprites = 0;
119 for (uint i = 0; i < GSF_END; i++) {
120 this->spritesets[i].clear();
123 memset(this->spritegroups, 0, sizeof(this->spritegroups));
127 * Records new spritesets.
128 * @param feature GrfSpecFeature the set is defined for.
129 * @param first_sprite SpriteID of the first sprite in the set.
130 * @param first_set First spriteset to define.
131 * @param numsets Number of sets to define.
132 * @param numents Number of sprites per set to define.
134 void AddSpriteSets(byte feature, SpriteID first_sprite, uint first_set, uint numsets, uint numents)
136 assert(feature < GSF_END);
137 for (uint i = 0; i < numsets; i++) {
138 SpriteSet &set = this->spritesets[feature][first_set + i];
139 set.sprite = first_sprite + i * numents;
140 set.num_sprites = numents;
145 * Check whether there are any valid spritesets for a feature.
146 * @param feature GrfSpecFeature to check.
147 * @return true if there are any valid sets.
148 * @note Spritesets with zero sprites are valid to allow callback-failures.
150 bool HasValidSpriteSets(byte feature) const
152 assert(feature < GSF_END);
153 return !this->spritesets[feature].empty();
157 * Check whether a specific set is defined.
158 * @param feature GrfSpecFeature to check.
159 * @param set Set to check.
160 * @return true if the set is valid.
161 * @note Spritesets with zero sprites are valid to allow callback-failures.
163 bool IsValidSpriteSet(byte feature, uint set) const
165 assert(feature < GSF_END);
166 return this->spritesets[feature].find(set) != this->spritesets[feature].end();
170 * Returns the first sprite of a spriteset.
171 * @param feature GrfSpecFeature to query.
172 * @param set Set to query.
173 * @return First sprite of the set.
175 SpriteID GetSprite(byte feature, uint set) const
177 assert(IsValidSpriteSet(feature, set));
178 return this->spritesets[feature].find(set)->second.sprite;
182 * Returns the number of sprites in a spriteset
183 * @param feature GrfSpecFeature to query.
184 * @param set Set to query.
185 * @return Number of sprites in the set.
187 uint GetNumEnts(byte feature, uint set) const
189 assert(IsValidSpriteSet(feature, set));
190 return this->spritesets[feature].find(set)->second.num_sprites;
194 static GrfProcessingState _cur;
198 * Helper to check whether an image index is valid for a particular NewGRF vehicle.
199 * @param <T> The type of vehicle.
200 * @param image_index The image index to check.
201 * @return True iff the image index is valid, or 0xFD (use new graphics).
203 template <VehicleType T>
204 static inline bool IsValidNewGRFImageIndex(uint8 image_index)
206 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
209 class OTTDByteReaderSignal { };
211 /** Class to read from a NewGRF file */
212 class ByteReader {
213 protected:
214 byte *data;
215 byte *end;
217 public:
218 ByteReader(byte *data, byte *end) : data(data), end(end) { }
220 inline byte ReadByte()
222 if (data < end) return *(data)++;
223 throw OTTDByteReaderSignal();
226 uint16 ReadWord()
228 uint16 val = ReadByte();
229 return val | (ReadByte() << 8);
232 uint16 ReadExtendedByte()
234 uint16 val = ReadByte();
235 return val == 0xFF ? ReadWord() : val;
238 uint32 ReadDWord()
240 uint32 val = ReadWord();
241 return val | (ReadWord() << 16);
244 uint32 ReadVarSize(byte size)
246 switch (size) {
247 case 1: return ReadByte();
248 case 2: return ReadWord();
249 case 4: return ReadDWord();
250 default:
251 NOT_REACHED();
252 return 0;
256 const char *ReadString()
258 char *string = reinterpret_cast<char *>(data);
259 size_t string_length = ttd_strnlen(string, Remaining());
261 if (string_length == Remaining()) {
262 /* String was not NUL terminated, so make sure it is now. */
263 string[string_length - 1] = '\0';
264 grfmsg(7, "String was not terminated with a zero byte.");
265 } else {
266 /* Increase the string length to include the NUL byte. */
267 string_length++;
269 Skip(string_length);
271 return string;
274 inline size_t Remaining() const
276 return end - data;
279 inline bool HasData(size_t count = 1) const
281 return data + count <= end;
284 inline byte *Data()
286 return data;
289 inline void Skip(size_t len)
291 data += len;
292 /* It is valid to move the buffer to exactly the end of the data,
293 * as there may not be any more data read. */
294 if (data > end) throw OTTDByteReaderSignal();
298 typedef void (*SpecialSpriteHandler)(ByteReader *buf);
300 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.
302 /** Temporary engine data used when loading only */
303 struct GRFTempEngineData {
304 /** Summary state of refittability properties */
305 enum Refittability {
306 UNSET = 0, ///< No properties assigned. Default refit masks shall be activated.
307 EMPTY, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
308 NONEMPTY, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
311 uint16 cargo_allowed;
312 uint16 cargo_disallowed;
313 RailTypeLabel railtypelabel;
314 uint8 roadsubtype;
315 const GRFFile *defaultcargo_grf; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
316 Refittability refittability; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
317 bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)?
318 uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
319 uint32 ctt_include_mask; ///< Cargo types always included in the refit mask.
320 uint32 ctt_exclude_mask; ///< Cargo types always excluded from the refit mask.
323 * Update the summary refittability on setting a refittability property.
324 * @param non_empty true if the GRF sets the vehicle to be refittable.
326 void UpdateRefittability(bool non_empty)
328 if (non_empty) {
329 this->refittability = NONEMPTY;
330 } else if (this->refittability == UNSET) {
331 this->refittability = EMPTY;
336 static GRFTempEngineData *_gted; ///< Temporary engine data used during NewGRF loading
339 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
340 * GRM for vehicles is only used if dynamic engine allocation is disabled,
341 * so 256 is the number of original engines. */
342 static uint32 _grm_engines[256];
344 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
345 static uint32 _grm_cargoes[NUM_CARGO * 2];
347 struct GRFLocation {
348 uint32 grfid;
349 uint32 nfoline;
351 GRFLocation() { }
352 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
354 bool operator<(const GRFLocation &other) const
356 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
359 bool operator == (const GRFLocation &other) const
361 return this->grfid == other.grfid && this->nfoline == other.nfoline;
365 static btree::btree_map<GRFLocation, SpriteID> _grm_sprites;
366 typedef btree::btree_map<GRFLocation, byte*> GRFLineToSpriteOverride;
367 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
370 * DEBUG() function dedicated to newGRF debugging messages
371 * Function is essentially the same as DEBUG(grf, severity, ...) with the
372 * addition of file:line information when parsing grf files.
373 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
374 * loading/parsing grf files, not for runtime debug messages as there
375 * is no file information available during that time.
376 * @param severity debugging severity level, see debug.h
377 * @param str message in printf() format
379 void CDECL grfmsg(int severity, const char *str, ...)
381 char buf[1024];
382 va_list va;
384 va_start(va, str);
385 vseprintf(buf, lastof(buf), str, va);
386 va_end(va);
388 DEBUG(grf, severity, "[%s:%d] %s", _cur.grfconfig->filename, _cur.nfo_line, buf);
392 * Obtain a NewGRF file by its grfID
393 * @param grfid The grfID to obtain the file for
394 * @return The file.
396 static GRFFile *GetFileByGRFID(uint32 grfid)
398 const GRFFile * const *end = _grf_files.End();
399 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
400 if ((*file)->grfid == grfid) return *file;
402 return nullptr;
406 * Obtain a NewGRF file by its filename
407 * @param filename The filename to obtain the file for.
408 * @return The file.
410 static GRFFile *GetFileByFilename(const char *filename)
412 const GRFFile * const *end = _grf_files.End();
413 for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) {
414 if (strcmp((*file)->filename, filename) == 0) return *file;
416 return nullptr;
419 /** Reset all NewGRFData that was used only while processing data */
420 static void ClearTemporaryNewGRFData(GRFFile *gf)
422 /* Clear the GOTO labels used for GRF processing */
423 for (GRFLabel *l = gf->label; l != nullptr;) {
424 GRFLabel *l2 = l->next;
425 free(l);
426 l = l2;
428 gf->label = nullptr;
432 * Disable a GRF
433 * @param message Error message or STR_NULL.
434 * @param config GRFConfig to disable, nullptr for current.
435 * @return Error message of the GRF for further customisation.
437 static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = nullptr)
439 GRFFile *file;
440 if (config != nullptr) {
441 file = GetFileByGRFID(config->ident.grfid);
442 } else {
443 config = _cur.grfconfig;
444 file = _cur.grffile;
447 config->status = GCS_DISABLED;
448 if (file != nullptr) ClearTemporaryNewGRFData(file);
449 if (config == _cur.grfconfig) _cur.skip_sprites = -1;
451 if (message != STR_NULL) {
452 delete config->error;
453 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
454 if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
457 return config->error;
461 * Information for mapping static StringIDs.
463 struct StringIDMapping {
464 uint32 grfid; ///< Source NewGRF.
465 StringID source; ///< Source StringID (GRF local).
466 StringID *target; ///< Destination for mapping result.
468 typedef SmallVector<StringIDMapping, 16> StringIDMappingVector;
469 static StringIDMappingVector _string_to_grf_mapping;
472 * Record a static StringID for getting translated later.
473 * @param source Source StringID (GRF local).
474 * @param target Destination for the mapping result.
476 static void AddStringForMapping(StringID source, StringID *target)
478 *target = STR_UNDEFINED;
479 StringIDMapping *item = _string_to_grf_mapping.Append();
480 item->grfid = _cur.grffile->grfid;
481 item->source = source;
482 item->target = target;
486 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
487 * string IDs, but only for the ones we are aware off; the rest
488 * like likely unused and will show a warning.
489 * @param str the string ID to convert
490 * @return the converted string ID
492 static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
494 /* StringID table for TextIDs 0x4E->0x6D */
495 static const StringID units_volume[] = {
496 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
497 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
498 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
499 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
500 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
501 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
502 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
503 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
506 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
507 assert(!IsInsideMM(str, 0xD000, 0xD7FF));
509 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
510 assert_compile(stringend - stringid == end - begin); \
511 if (str >= begin && str <= end) return str + (stringid - begin)
513 /* We have some changes in our cargo strings, resulting in some missing. */
514 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
515 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
516 if (str >= 0x004E && str <= 0x006D) return units_volume[str - 0x004E];
517 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
518 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
519 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
521 /* Map building names according to our lang file changes. There are several
522 * ranges of house ids, all of which need to be remapped to allow newgrfs
523 * to use original house names. */
524 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
525 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
526 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
528 /* Same thing for industries */
529 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
530 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
531 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
532 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
533 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
535 switch (str) {
536 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
537 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
538 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
540 #undef TEXTID_TO_STRINGID
542 if (str == STR_NULL) return STR_EMPTY;
544 DEBUG(grf, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
546 return STR_EMPTY;
550 * Used when setting an object's property to map to the GRF's strings
551 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
552 * @param grfid Id of the grf file.
553 * @param str StringID that we want to have the equivalent in OoenTTD.
554 * @return The properly adjusted StringID.
556 StringID MapGRFStringID(uint32 grfid, StringID str)
558 if (IsInsideMM(str, 0xD800, 0xE000)) {
559 /* General text provided by NewGRF.
560 * In the specs this is called the 0xDCxx range (misc presistent texts),
561 * but we meanwhile extended the range to 0xD800-0xDFFF.
562 * Note: We are not involved in the "persistent" business, since we do not store
563 * any NewGRF strings in savegames. */
564 return GetGRFStringID(grfid, str);
565 } else if (IsInsideMM(str, 0xD000, 0xD800)) {
566 /* Callback text provided by NewGRF.
567 * In the specs this is called the 0xD0xx range (misc graphics texts).
568 * These texts can be returned by various callbacks.
570 * Due to how TTDP implements the GRF-local- to global-textid translation
571 * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
572 * We do not care about that difference and just mask out the 0x400 bit.
574 str &= ~0x400;
575 return GetGRFStringID(grfid, str);
576 } else {
577 /* The NewGRF wants to include/reference an original TTD string.
578 * Try our best to find an equivalent one. */
579 return TTDPStringIDToOTTDStringIDMapping(str);
583 static std::map<uint32, uint32> _grf_id_overrides;
586 * Set the override for a NewGRF
587 * @param source_grfid The grfID which wants to override another NewGRF.
588 * @param target_grfid The grfID which is being overridden.
590 static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid)
592 _grf_id_overrides[source_grfid] = target_grfid;
593 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid), BSWAP32(target_grfid));
597 * Returns the engine associated to a certain internal_id, resp. allocates it.
598 * @param file NewGRF that wants to change the engine.
599 * @param type Vehicle type.
600 * @param internal_id Engine ID inside the NewGRF.
601 * @param static_access If the engine is not present, return nullptr instead of allocating a new engine. (Used for static Action 0x04).
602 * @return The requested engine.
604 static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false)
606 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
607 * them use the same engine slots. */
608 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
609 if (_settings_game.vehicle.dynamic_engines) {
610 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
611 scope_grfid = file->grfid;
612 uint32 override = _grf_id_overrides[file->grfid];
613 if (override != 0) {
614 scope_grfid = override;
615 const GRFFile *grf_match = GetFileByGRFID(override);
616 if (grf_match == nullptr) {
617 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override));
618 } else {
619 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override));
623 /* Check if the engine is registered in the override manager */
624 EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid);
625 if (engine != INVALID_ENGINE) {
626 Engine *e = Engine::Get(engine);
627 if (e->grf_prop.grffile == nullptr) e->grf_prop.grffile = file;
628 return e;
632 /* Check if there is an unreserved slot */
633 EngineID engine = _engine_mngr.GetID(type, internal_id, INVALID_GRFID);
634 if (engine != INVALID_ENGINE) {
635 Engine *e = Engine::Get(engine);
637 if (e->grf_prop.grffile == nullptr) {
638 e->grf_prop.grffile = file;
639 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
642 /* Reserve the engine slot */
643 if (!static_access) {
644 EngineIDMapping *eid = _engine_mngr.Get(engine);
645 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
648 return e;
651 if (static_access) return nullptr;
653 if (!Engine::CanAllocateItem()) {
654 grfmsg(0, "Can't allocate any more engines");
655 return nullptr;
658 size_t engine_pool_size = Engine::GetPoolSize();
660 /* ... it's not, so create a new one based off an existing engine */
661 Engine *e = new Engine(type, internal_id);
662 e->grf_prop.grffile = file;
664 /* Reserve the engine slot */
665 assert(_engine_mngr.Length() == e->index);
666 EngineIDMapping *eid = _engine_mngr.Append();
667 eid->type = type;
668 eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
669 eid->internal_id = internal_id;
670 eid->substitute_id = min(internal_id, _engine_counts[type]); // substitute_id == _engine_counts[subtype] means "no substitute"
672 if (engine_pool_size != Engine::GetPoolSize()) {
673 /* Resize temporary engine data ... */
674 _gted = ReallocT(_gted, Engine::GetPoolSize());
676 /* and blank the new block. */
677 size_t len = (Engine::GetPoolSize() - engine_pool_size) * sizeof(*_gted);
678 memset(_gted + engine_pool_size, 0, len);
680 switch (type) {
681 case VEH_TRAIN:
682 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
683 break;
684 case VEH_ROAD:
685 _gted[e->index].roadsubtype = 0xFF;
686 break;
687 default:
688 break;
691 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id);
693 return e;
697 * Return the ID of a new engine
698 * @param file The NewGRF file providing the engine.
699 * @param type The Vehicle type.
700 * @param internal_id NewGRF-internal ID of the engine.
701 * @return The new EngineID.
702 * @note depending on the dynamic_engine setting and a possible override
703 * property the grfID may be unique or overwriting or partially re-defining
704 * properties of an existing engine.
706 EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16 internal_id)
708 uint32 scope_grfid = INVALID_GRFID; // If not using dynamic_engines, all newgrfs share their ID range
709 if (_settings_game.vehicle.dynamic_engines) {
710 scope_grfid = file->grfid;
711 uint32 override = _grf_id_overrides[file->grfid];
712 if (override != 0) scope_grfid = override;
715 return _engine_mngr.GetID(type, internal_id, scope_grfid);
719 * Map the colour modifiers of TTDPatch to those that Open is using.
720 * @param grf_sprite Pointer to the structure been modified.
722 static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite)
724 if (HasBit(grf_sprite->pal, 14)) {
725 ClrBit(grf_sprite->pal, 14);
726 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_OPAQUE);
729 if (HasBit(grf_sprite->sprite, 14)) {
730 ClrBit(grf_sprite->sprite, 14);
731 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_TRANSPARENT);
734 if (HasBit(grf_sprite->sprite, 15)) {
735 ClrBit(grf_sprite->sprite, 15);
736 SetBit(grf_sprite->sprite, PALETTE_MODIFIER_COLOUR);
741 * Read a sprite and a palette from the GRF and convert them into a format
742 * suitable to OpenTTD.
743 * @param buf Input stream.
744 * @param read_flags Whether to read TileLayoutFlags.
745 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
746 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
747 * @param feature GrfSpecFeature to use spritesets from.
748 * @param [out] grf_sprite Read sprite and palette.
749 * @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
750 * @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
751 * @return Read TileLayoutFlags.
753 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 = nullptr, uint16 *max_palette_offset = nullptr)
755 grf_sprite->sprite = buf->ReadWord();
756 grf_sprite->pal = buf->ReadWord();
757 TileLayoutFlags flags = read_flags ? (TileLayoutFlags)buf->ReadWord() : TLF_NOTHING;
759 MapSpriteMappingRecolour(grf_sprite);
761 bool custom_sprite = HasBit(grf_sprite->pal, 15) != invert_action1_flag;
762 ClrBit(grf_sprite->pal, 15);
763 if (custom_sprite) {
764 /* Use sprite from Action 1 */
765 uint index = GB(grf_sprite->sprite, 0, 14);
766 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
767 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
768 grf_sprite->sprite = SPR_IMG_QUERY;
769 grf_sprite->pal = PAL_NONE;
770 } else {
771 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
772 if (max_sprite_offset != nullptr) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
773 SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite);
774 SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE);
776 } else if ((flags & TLF_SPRITE_VAR10) && !(flags & TLF_SPRITE_REG_FLAGS)) {
777 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
778 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
779 return flags;
782 if (flags & TLF_CUSTOM_PALETTE) {
783 /* Use palette from Action 1 */
784 uint index = GB(grf_sprite->pal, 0, 14);
785 if (use_cur_spritesets && (!_cur.IsValidSpriteSet(feature, index) || _cur.GetNumEnts(feature, index) == 0)) {
786 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
787 grf_sprite->pal = PAL_NONE;
788 } else {
789 SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index;
790 if (max_palette_offset != nullptr) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX;
791 SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite);
792 SetBit(grf_sprite->pal, SPRITE_MODIFIER_CUSTOM_SPRITE);
794 } else if ((flags & TLF_PALETTE_VAR10) && !(flags & TLF_PALETTE_REG_FLAGS)) {
795 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
796 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
797 return flags;
800 return flags;
804 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
805 * @param buf Input stream.
806 * @param flags TileLayoutFlags to process.
807 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
808 * @param dts Sprite layout to insert data into.
809 * @param index Sprite index to process; 0 for ground sprite.
811 static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bool is_parent, NewGRFSpriteLayout *dts, uint index)
813 if (!(flags & TLF_DRAWING_FLAGS)) return;
815 if (dts->registers == nullptr) dts->AllocateRegisters();
816 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[index]);
817 regs.flags = flags & TLF_DRAWING_FLAGS;
819 if (flags & TLF_DODRAW) regs.dodraw = buf->ReadByte();
820 if (flags & TLF_SPRITE) regs.sprite = buf->ReadByte();
821 if (flags & TLF_PALETTE) regs.palette = buf->ReadByte();
823 if (is_parent) {
824 if (flags & TLF_BB_XY_OFFSET) {
825 regs.delta.parent[0] = buf->ReadByte();
826 regs.delta.parent[1] = buf->ReadByte();
828 if (flags & TLF_BB_Z_OFFSET) regs.delta.parent[2] = buf->ReadByte();
829 } else {
830 if (flags & TLF_CHILD_X_OFFSET) regs.delta.child[0] = buf->ReadByte();
831 if (flags & TLF_CHILD_Y_OFFSET) regs.delta.child[1] = buf->ReadByte();
834 if (flags & TLF_SPRITE_VAR10) {
835 regs.sprite_var10 = buf->ReadByte();
836 if (regs.sprite_var10 > TLR_MAX_VAR10) {
837 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.sprite_var10, TLR_MAX_VAR10);
838 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
839 return;
843 if (flags & TLF_PALETTE_VAR10) {
844 regs.palette_var10 = buf->ReadByte();
845 if (regs.palette_var10 > TLR_MAX_VAR10) {
846 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs.palette_var10, TLR_MAX_VAR10);
847 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
848 return;
854 * Read a spritelayout from the GRF.
855 * @param buf Input
856 * @param num_building_sprites Number of building sprites to read
857 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
858 * @param feature GrfSpecFeature to use spritesets from.
859 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
860 * @param no_z_position Whether bounding boxes have no Z offset
861 * @param dts Layout container to output into
862 * @return True on error (GRF was disabled).
864 static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool use_cur_spritesets, byte feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
866 bool has_flags = HasBit(num_building_sprites, 6);
867 ClrBit(num_building_sprites, 6);
868 TileLayoutFlags valid_flags = TLF_KNOWN_FLAGS;
869 if (!allow_var10) valid_flags &= ~TLF_VAR10_FLAGS;
870 dts->Allocate(num_building_sprites); // allocate before reading groundsprite flags
872 uint16 *max_sprite_offset = AllocaM(uint16, num_building_sprites + 1);
873 uint16 *max_palette_offset = AllocaM(uint16, num_building_sprites + 1);
874 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
875 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
877 /* Groundsprite */
878 TileLayoutFlags flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &dts->ground, max_sprite_offset, max_palette_offset);
879 if (_cur.skip_sprites < 0) return true;
881 if (flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS)) {
882 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~TLF_NON_GROUND_FLAGS));
883 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
884 return true;
887 ReadSpriteLayoutRegisters(buf, flags, false, dts, 0);
888 if (_cur.skip_sprites < 0) return true;
890 for (uint i = 0; i < num_building_sprites; i++) {
891 DrawTileSeqStruct *seq = const_cast<DrawTileSeqStruct*>(&dts->seq[i]);
893 flags = ReadSpriteLayoutSprite(buf, has_flags, false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
894 if (_cur.skip_sprites < 0) return true;
896 if (flags & ~valid_flags) {
897 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
898 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
899 return true;
902 seq->delta_x = buf->ReadByte();
903 seq->delta_y = buf->ReadByte();
905 if (!no_z_position) seq->delta_z = buf->ReadByte();
907 if (seq->IsParentSprite()) {
908 seq->size_x = buf->ReadByte();
909 seq->size_y = buf->ReadByte();
910 seq->size_z = buf->ReadByte();
913 ReadSpriteLayoutRegisters(buf, flags, seq->IsParentSprite(), dts, i + 1);
914 if (_cur.skip_sprites < 0) return true;
917 /* Check if the number of sprites per spriteset is consistent */
918 bool is_consistent = true;
919 dts->consistent_max_offset = 0;
920 for (uint i = 0; i < num_building_sprites + 1; i++) {
921 if (max_sprite_offset[i] > 0) {
922 if (dts->consistent_max_offset == 0) {
923 dts->consistent_max_offset = max_sprite_offset[i];
924 } else if (dts->consistent_max_offset != max_sprite_offset[i]) {
925 is_consistent = false;
926 break;
929 if (max_palette_offset[i] > 0) {
930 if (dts->consistent_max_offset == 0) {
931 dts->consistent_max_offset = max_palette_offset[i];
932 } else if (dts->consistent_max_offset != max_palette_offset[i]) {
933 is_consistent = false;
934 break;
939 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
940 assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX)));
942 if (!is_consistent || dts->registers != nullptr) {
943 dts->consistent_max_offset = 0;
944 if (dts->registers == nullptr) dts->AllocateRegisters();
946 for (uint i = 0; i < num_building_sprites + 1; i++) {
947 TileLayoutRegisters &regs = const_cast<TileLayoutRegisters&>(dts->registers[i]);
948 regs.max_sprite_offset = max_sprite_offset[i];
949 regs.max_palette_offset = max_palette_offset[i];
953 return false;
957 * Translate the refit mask.
959 static uint32 TranslateRefitMask(uint32 refit_mask)
961 uint32 result = 0;
962 uint8 bit;
963 FOR_EACH_SET_BIT(bit, refit_mask) {
964 CargoID cargo = GetCargoTranslation(bit, _cur.grffile, true);
965 if (cargo != CT_INVALID) SetBit(result, cargo);
967 return result;
971 * Converts TTD(P) Base Price pointers into the enum used by OTTD
972 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
973 * @param base_pointer TTD(P) Base Price Pointer
974 * @param error_location Function name for grf error messages
975 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
977 static void ConvertTTDBasePrice(uint32 base_pointer, const char *error_location, Price *index)
979 /* Special value for 'none' */
980 if (base_pointer == 0) {
981 *index = INVALID_PRICE;
982 return;
985 static const uint32 start = 0x4B34; ///< Position of first base price
986 static const uint32 size = 6; ///< Size of each base price record
988 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
989 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
990 return;
993 *index = (Price)((base_pointer - start) / size);
996 /** Possible return values for the FeatureChangeInfo functions */
997 enum ChangeInfoResult {
998 CIR_SUCCESS, ///< Variable was parsed and read
999 CIR_DISABLED, ///< GRF was disabled due to error
1000 CIR_UNHANDLED, ///< Variable was parsed but unread
1001 CIR_UNKNOWN, ///< Variable is unknown
1002 CIR_INVALID_ID, ///< Attempt to modify an invalid ID
1005 typedef ChangeInfoResult (*VCI_Handler)(uint engine, int numinfo, int prop, ByteReader *buf);
1008 * Define properties common to all vehicles
1009 * @param ei Engine info.
1010 * @param prop The property to change.
1011 * @param buf The property value.
1012 * @return ChangeInfoResult.
1014 static ChangeInfoResult CommonVehicleChangeInfo(EngineInfo *ei, int prop, ByteReader *buf)
1016 switch (prop) {
1017 case 0x00: // Introduction date
1018 ei->base_intro = buf->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR;
1019 break;
1021 case 0x02: // Decay speed
1022 ei->decay_speed = buf->ReadByte();
1023 break;
1025 case 0x03: // Vehicle life
1026 ei->lifelength = buf->ReadByte();
1027 break;
1029 case 0x04: // Model life
1030 ei->base_life = buf->ReadByte();
1031 break;
1033 case 0x06: // Climates available
1034 ei->climates = buf->ReadByte();
1035 break;
1037 case PROP_VEHICLE_LOAD_AMOUNT: // 0x07 Loading speed
1038 /* Amount of cargo loaded during a vehicle's "loading tick" */
1039 ei->load_amount = buf->ReadByte();
1040 break;
1042 default:
1043 return CIR_UNKNOWN;
1046 return CIR_SUCCESS;
1050 * Define properties for rail vehicles
1051 * @param engine :ocal ID of the first vehicle.
1052 * @param numinfo Number of subsequent IDs to change the property for.
1053 * @param prop The property to change.
1054 * @param buf The property value.
1055 * @return ChangeInfoResult.
1057 static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1059 ChangeInfoResult ret = CIR_SUCCESS;
1061 for (int i = 0; i < numinfo; i++) {
1062 Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i);
1063 if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1065 EngineInfo *ei = &e->info;
1066 RailVehicleInfo *rvi = &e->u.rail;
1068 switch (prop) {
1069 case 0x05: { // Track type
1070 uint8 tracktype = buf->ReadByte();
1072 if (tracktype < _cur.grffile->railtype_list.Length()) {
1073 _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype];
1074 break;
1077 switch (tracktype) {
1078 case 0: _gted[e->index].railtypelabel = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL; break;
1079 case 1: _gted[e->index].railtypelabel = RAILTYPE_MONO_LABEL; break;
1080 case 2: _gted[e->index].railtypelabel = RAILTYPE_MAGLEV_LABEL; break;
1081 default:
1082 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1083 break;
1085 break;
1088 case 0x08: // AI passenger service
1089 /* Tells the AI that this engine is designed for
1090 * passenger services and shouldn't be used for freight. */
1091 rvi->ai_passenger_only = buf->ReadByte();
1092 break;
1094 case PROP_TRAIN_SPEED: { // 0x09 Speed (1 unit is 1 km-ish/h)
1095 uint16 speed = buf->ReadWord();
1096 if (speed == 0xFFFF) speed = 0;
1098 rvi->max_speed = speed;
1099 break;
1102 case PROP_TRAIN_POWER: // 0x0B Power
1103 rvi->power = buf->ReadWord();
1105 /* Set engine / wagon state based on power */
1106 if (rvi->power != 0) {
1107 if (rvi->railveh_type == RAILVEH_WAGON) {
1108 rvi->railveh_type = RAILVEH_SINGLEHEAD;
1110 } else {
1111 rvi->railveh_type = RAILVEH_WAGON;
1113 break;
1115 case PROP_TRAIN_RUNNING_COST_FACTOR: // 0x0D Running cost factor
1116 rvi->running_cost = buf->ReadByte();
1117 break;
1119 case 0x0E: // Running cost base
1120 ConvertTTDBasePrice(buf->ReadDWord(), "RailVehicleChangeInfo", &rvi->running_cost_class);
1121 break;
1123 case 0x12: { // Sprite ID
1124 uint8 spriteid = buf->ReadByte();
1125 uint8 orig_spriteid = spriteid;
1127 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1128 * as an array index, so we need it to be half the original value. */
1129 if (spriteid < 0xFD) spriteid >>= 1;
1131 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1132 rvi->image_index = spriteid;
1133 } else {
1134 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1135 rvi->image_index = 0;
1137 break;
1140 case 0x13: { // Dual-headed
1141 uint8 dual = buf->ReadByte();
1143 if (dual != 0) {
1144 rvi->railveh_type = RAILVEH_MULTIHEAD;
1145 } else {
1146 rvi->railveh_type = rvi->power == 0 ?
1147 RAILVEH_WAGON : RAILVEH_SINGLEHEAD;
1149 break;
1152 case PROP_TRAIN_CARGO_CAPACITY: // 0x14 Cargo capacity
1153 rvi->capacity = buf->ReadByte();
1154 break;
1156 case 0x15: { // Cargo type
1157 _gted[e->index].defaultcargo_grf = _cur.grffile;
1158 uint8 ctype = buf->ReadByte();
1160 if (ctype == 0xFF) {
1161 /* 0xFF is specified as 'use first refittable' */
1162 ei->cargo_type = CT_INVALID;
1163 } else if (_cur.grffile->grf_version >= 8) {
1164 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1165 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1166 } else if (ctype < NUM_CARGO) {
1167 /* Use untranslated cargo. */
1168 ei->cargo_type = ctype;
1169 } else {
1170 ei->cargo_type = CT_INVALID;
1171 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1173 break;
1176 case PROP_TRAIN_WEIGHT: // 0x16 Weight
1177 SB(rvi->weight, 0, 8, buf->ReadByte());
1178 break;
1180 case PROP_TRAIN_COST_FACTOR: // 0x17 Cost factor
1181 rvi->cost_factor = buf->ReadByte();
1182 break;
1184 case 0x18: // AI rank
1185 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1186 buf->ReadByte();
1187 break;
1189 case 0x19: { // Engine traction type
1190 /* What do the individual numbers mean?
1191 * 0x00 .. 0x07: Steam
1192 * 0x08 .. 0x27: Diesel
1193 * 0x28 .. 0x31: Electric
1194 * 0x32 .. 0x37: Monorail
1195 * 0x38 .. 0x41: Maglev
1197 uint8 traction = buf->ReadByte();
1198 EngineClass engclass;
1200 if (traction <= 0x07) {
1201 engclass = EC_STEAM;
1202 } else if (traction <= 0x27) {
1203 engclass = EC_DIESEL;
1204 } else if (traction <= 0x31) {
1205 engclass = EC_ELECTRIC;
1206 } else if (traction <= 0x37) {
1207 engclass = EC_MONORAIL;
1208 } else if (traction <= 0x41) {
1209 engclass = EC_MAGLEV;
1210 } else {
1211 break;
1214 if (_cur.grffile->railtype_list.Length() == 0) {
1215 /* Use traction type to select between normal and electrified
1216 * rail only when no translation list is in place. */
1217 if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1218 if (_gted[e->index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass < EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_RAIL_LABEL;
1221 rvi->engclass = engclass;
1222 break;
1225 case 0x1A: // Alter purchase list sort order
1226 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1227 break;
1229 case 0x1B: // Powered wagons power bonus
1230 rvi->pow_wag_power = buf->ReadWord();
1231 break;
1233 case 0x1C: // Refit cost
1234 ei->refit_cost = buf->ReadByte();
1235 break;
1237 case 0x1D: { // Refit cargo
1238 uint32 mask = buf->ReadDWord();
1239 _gted[e->index].UpdateRefittability(mask != 0);
1240 ei->refit_mask = TranslateRefitMask(mask);
1241 _gted[e->index].defaultcargo_grf = _cur.grffile;
1242 break;
1245 case 0x1E: // Callback
1246 ei->callback_mask = buf->ReadByte();
1247 break;
1249 case PROP_TRAIN_TRACTIVE_EFFORT: // 0x1F Tractive effort coefficient
1250 rvi->tractive_effort = buf->ReadByte();
1251 break;
1253 case 0x20: // Air drag
1254 rvi->air_drag = buf->ReadByte();
1255 break;
1257 case PROP_TRAIN_SHORTEN_FACTOR: // 0x21 Shorter vehicle
1258 rvi->shorten_factor = buf->ReadByte();
1259 break;
1261 case 0x22: // Visual effect
1262 rvi->visual_effect = buf->ReadByte();
1263 /* Avoid accidentally setting visual_effect to the default value
1264 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1265 if (rvi->visual_effect == VE_DEFAULT) {
1266 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1267 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1269 break;
1271 case 0x23: // Powered wagons weight bonus
1272 rvi->pow_wag_weight = buf->ReadByte();
1273 break;
1275 case 0x24: { // High byte of vehicle weight
1276 byte weight = buf->ReadByte();
1278 if (weight > 4) {
1279 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1280 } else {
1281 SB(rvi->weight, 8, 8, weight);
1283 break;
1286 case PROP_TRAIN_USER_DATA: // 0x25 User-defined bit mask to set when checking veh. var. 42
1287 rvi->user_def_data = buf->ReadByte();
1288 break;
1290 case 0x26: // Retire vehicle early
1291 ei->retire_early = buf->ReadByte();
1292 break;
1294 case 0x27: // Miscellaneous flags
1295 ei->misc_flags = buf->ReadByte();
1296 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1297 _gted[e->index].prop27_set = true;
1298 break;
1300 case 0x28: // Cargo classes allowed
1301 _gted[e->index].cargo_allowed = buf->ReadWord();
1302 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1303 _gted[e->index].defaultcargo_grf = _cur.grffile;
1304 break;
1306 case 0x29: // Cargo classes disallowed
1307 _gted[e->index].cargo_disallowed = buf->ReadWord();
1308 _gted[e->index].UpdateRefittability(false);
1309 break;
1311 case 0x2A: // Long format introduction date (days since year 0)
1312 ei->base_intro = buf->ReadDWord();
1313 break;
1315 case PROP_TRAIN_CARGO_AGE_PERIOD: // 0x2B Cargo aging period
1316 ei->cargo_age_period = buf->ReadWord();
1317 break;
1319 case 0x2C: // CTT refit include list
1320 case 0x2D: { // CTT refit exclude list
1321 uint8 count = buf->ReadByte();
1322 _gted[e->index].UpdateRefittability(prop == 0x2C && count != 0);
1323 if (prop == 0x2C) _gted[e->index].defaultcargo_grf = _cur.grffile;
1324 uint32 &ctt = prop == 0x2C ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1325 ctt = 0;
1326 while (count--) {
1327 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1328 if (ctype == CT_INVALID) continue;
1329 SetBit(ctt, ctype);
1331 break;
1334 default:
1335 ret = CommonVehicleChangeInfo(ei, prop, buf);
1336 break;
1340 return ret;
1344 * Define properties for road vehicles
1345 * @param engine Local ID of the first vehicle.
1346 * @param numinfo Number of subsequent IDs to change the property for.
1347 * @param prop The property to change.
1348 * @param buf The property value.
1349 * @return ChangeInfoResult.
1351 static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1353 ChangeInfoResult ret = CIR_SUCCESS;
1355 for (int i = 0; i < numinfo; i++) {
1356 Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i);
1357 if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1359 EngineInfo *ei = &e->info;
1360 RoadVehicleInfo *rvi = &e->u.road;
1362 switch (prop) {
1363 case 0x05: // Road/tram subtype
1364 _gted[e->index].roadsubtype = buf->ReadByte();
1365 break;
1367 case 0x08: // Speed (1 unit is 0.5 kmh)
1368 rvi->max_speed = buf->ReadByte();
1369 break;
1371 case PROP_ROADVEH_RUNNING_COST_FACTOR: // 0x09 Running cost factor
1372 rvi->running_cost = buf->ReadByte();
1373 break;
1375 case 0x0A: // Running cost base
1376 ConvertTTDBasePrice(buf->ReadDWord(), "RoadVehicleChangeInfo", &rvi->running_cost_class);
1377 break;
1379 case 0x0E: { // Sprite ID
1380 uint8 spriteid = buf->ReadByte();
1381 uint8 orig_spriteid = spriteid;
1383 /* cars have different custom id in the GRF file */
1384 if (spriteid == 0xFF) spriteid = 0xFD;
1386 if (spriteid < 0xFD) spriteid >>= 1;
1388 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1389 rvi->image_index = spriteid;
1390 } else {
1391 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1392 rvi->image_index = 0;
1394 break;
1397 case PROP_ROADVEH_CARGO_CAPACITY: // 0x0F Cargo capacity
1398 rvi->capacity = buf->ReadByte();
1399 break;
1401 case 0x10: { // Cargo type
1402 _gted[e->index].defaultcargo_grf = _cur.grffile;
1403 uint8 ctype = buf->ReadByte();
1405 if (ctype == 0xFF) {
1406 /* 0xFF is specified as 'use first refittable' */
1407 ei->cargo_type = CT_INVALID;
1408 } else if (_cur.grffile->grf_version >= 8) {
1409 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1410 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1411 } else if (ctype < NUM_CARGO) {
1412 /* Use untranslated cargo. */
1413 ei->cargo_type = ctype;
1414 } else {
1415 ei->cargo_type = CT_INVALID;
1416 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1418 break;
1421 case PROP_ROADVEH_COST_FACTOR: // 0x11 Cost factor
1422 rvi->cost_factor = buf->ReadByte();
1423 break;
1425 case 0x12: // SFX
1426 rvi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1427 break;
1429 case PROP_ROADVEH_POWER: // Power in units of 10 HP.
1430 rvi->power = buf->ReadByte();
1431 break;
1433 case PROP_ROADVEH_WEIGHT: // Weight in units of 1/4 tons.
1434 rvi->weight = buf->ReadByte();
1435 break;
1437 case PROP_ROADVEH_SPEED: // Speed in mph/0.8
1438 _gted[e->index].rv_max_speed = buf->ReadByte();
1439 break;
1441 case 0x16: { // Cargoes available for refitting
1442 uint32 mask = buf->ReadDWord();
1443 _gted[e->index].UpdateRefittability(mask != 0);
1444 ei->refit_mask = TranslateRefitMask(mask);
1445 _gted[e->index].defaultcargo_grf = _cur.grffile;
1446 break;
1449 case 0x17: // Callback mask
1450 ei->callback_mask = buf->ReadByte();
1451 break;
1453 case PROP_ROADVEH_TRACTIVE_EFFORT: // Tractive effort coefficient in 1/256.
1454 rvi->tractive_effort = buf->ReadByte();
1455 break;
1457 case 0x19: // Air drag
1458 rvi->air_drag = buf->ReadByte();
1459 break;
1461 case 0x1A: // Refit cost
1462 ei->refit_cost = buf->ReadByte();
1463 break;
1465 case 0x1B: // Retire vehicle early
1466 ei->retire_early = buf->ReadByte();
1467 break;
1469 case 0x1C: // Miscellaneous flags
1470 ei->misc_flags = buf->ReadByte();
1471 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1472 break;
1474 case 0x1D: // Cargo classes allowed
1475 _gted[e->index].cargo_allowed = buf->ReadWord();
1476 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1477 _gted[e->index].defaultcargo_grf = _cur.grffile;
1478 break;
1480 case 0x1E: // Cargo classes disallowed
1481 _gted[e->index].cargo_disallowed = buf->ReadWord();
1482 _gted[e->index].UpdateRefittability(false);
1483 break;
1485 case 0x1F: // Long format introduction date (days since year 0)
1486 ei->base_intro = buf->ReadDWord();
1487 break;
1489 case 0x20: // Alter purchase list sort order
1490 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1491 break;
1493 case 0x21: // Visual effect
1494 rvi->visual_effect = buf->ReadByte();
1495 /* Avoid accidentally setting visual_effect to the default value
1496 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1497 if (rvi->visual_effect == VE_DEFAULT) {
1498 assert(HasBit(rvi->visual_effect, VE_DISABLE_EFFECT));
1499 SB(rvi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1501 break;
1503 case PROP_ROADVEH_CARGO_AGE_PERIOD: // 0x22 Cargo aging period
1504 ei->cargo_age_period = buf->ReadWord();
1505 break;
1507 case PROP_ROADVEH_SHORTEN_FACTOR: // 0x23 Shorter vehicle
1508 rvi->shorten_factor = buf->ReadByte();
1509 break;
1511 case 0x24: // CTT refit include list
1512 case 0x25: { // CTT refit exclude list
1513 uint8 count = buf->ReadByte();
1514 _gted[e->index].UpdateRefittability(prop == 0x24 && count != 0);
1515 if (prop == 0x24) _gted[e->index].defaultcargo_grf = _cur.grffile;
1516 uint32 &ctt = prop == 0x24 ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1517 ctt = 0;
1518 while (count--) {
1519 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1520 if (ctype == CT_INVALID) continue;
1521 SetBit(ctt, ctype);
1523 break;
1526 default:
1527 ret = CommonVehicleChangeInfo(ei, prop, buf);
1528 break;
1532 return ret;
1536 * Define properties for ships
1537 * @param engine Local ID of the first vehicle.
1538 * @param numinfo Number of subsequent IDs to change the property for.
1539 * @param prop The property to change.
1540 * @param buf The property value.
1541 * @return ChangeInfoResult.
1543 static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1545 ChangeInfoResult ret = CIR_SUCCESS;
1547 for (int i = 0; i < numinfo; i++) {
1548 Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i);
1549 if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1551 EngineInfo *ei = &e->info;
1552 ShipVehicleInfo *svi = &e->u.ship;
1554 switch (prop) {
1555 case 0x08: { // Sprite ID
1556 uint8 spriteid = buf->ReadByte();
1557 uint8 orig_spriteid = spriteid;
1559 /* ships have different custom id in the GRF file */
1560 if (spriteid == 0xFF) spriteid = 0xFD;
1562 if (spriteid < 0xFD) spriteid >>= 1;
1564 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1565 svi->image_index = spriteid;
1566 } else {
1567 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1568 svi->image_index = 0;
1570 break;
1573 case 0x09: // Refittable
1574 svi->old_refittable = (buf->ReadByte() != 0);
1575 break;
1577 case PROP_SHIP_COST_FACTOR: // 0x0A Cost factor
1578 svi->cost_factor = buf->ReadByte();
1579 break;
1581 case PROP_SHIP_SPEED: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1582 svi->max_speed = buf->ReadByte();
1583 break;
1585 case 0x0C: { // Cargo type
1586 _gted[e->index].defaultcargo_grf = _cur.grffile;
1587 uint8 ctype = buf->ReadByte();
1589 if (ctype == 0xFF) {
1590 /* 0xFF is specified as 'use first refittable' */
1591 ei->cargo_type = CT_INVALID;
1592 } else if (_cur.grffile->grf_version >= 8) {
1593 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1594 ei->cargo_type = GetCargoTranslation(ctype, _cur.grffile);
1595 } else if (ctype < NUM_CARGO) {
1596 /* Use untranslated cargo. */
1597 ei->cargo_type = ctype;
1598 } else {
1599 ei->cargo_type = CT_INVALID;
1600 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1602 break;
1605 case PROP_SHIP_CARGO_CAPACITY: // 0x0D Cargo capacity
1606 svi->capacity = buf->ReadWord();
1607 break;
1609 case PROP_SHIP_RUNNING_COST_FACTOR: // 0x0F Running cost factor
1610 svi->running_cost = buf->ReadByte();
1611 break;
1613 case 0x10: // SFX
1614 svi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1615 break;
1617 case 0x11: { // Cargoes available for refitting
1618 uint32 mask = buf->ReadDWord();
1619 _gted[e->index].UpdateRefittability(mask != 0);
1620 ei->refit_mask = TranslateRefitMask(mask);
1621 _gted[e->index].defaultcargo_grf = _cur.grffile;
1622 break;
1625 case 0x12: // Callback mask
1626 ei->callback_mask = buf->ReadByte();
1627 break;
1629 case 0x13: // Refit cost
1630 ei->refit_cost = buf->ReadByte();
1631 break;
1633 case 0x14: // Ocean speed fraction
1634 svi->ocean_speed_frac = buf->ReadByte();
1635 break;
1637 case 0x15: // Canal speed fraction
1638 svi->canal_speed_frac = buf->ReadByte();
1639 break;
1641 case 0x16: // Retire vehicle early
1642 ei->retire_early = buf->ReadByte();
1643 break;
1645 case 0x17: // Miscellaneous flags
1646 ei->misc_flags = buf->ReadByte();
1647 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1648 break;
1650 case 0x18: // Cargo classes allowed
1651 _gted[e->index].cargo_allowed = buf->ReadWord();
1652 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1653 _gted[e->index].defaultcargo_grf = _cur.grffile;
1654 break;
1656 case 0x19: // Cargo classes disallowed
1657 _gted[e->index].cargo_disallowed = buf->ReadWord();
1658 _gted[e->index].UpdateRefittability(false);
1659 break;
1661 case 0x1A: // Long format introduction date (days since year 0)
1662 ei->base_intro = buf->ReadDWord();
1663 break;
1665 case 0x1B: // Alter purchase list sort order
1666 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1667 break;
1669 case 0x1C: // Visual effect
1670 svi->visual_effect = buf->ReadByte();
1671 /* Avoid accidentally setting visual_effect to the default value
1672 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1673 if (svi->visual_effect == VE_DEFAULT) {
1674 assert(HasBit(svi->visual_effect, VE_DISABLE_EFFECT));
1675 SB(svi->visual_effect, VE_TYPE_START, VE_TYPE_COUNT, 0);
1677 break;
1679 case PROP_SHIP_CARGO_AGE_PERIOD: // 0x1D Cargo aging period
1680 ei->cargo_age_period = buf->ReadWord();
1681 break;
1683 case 0x1E: // CTT refit include list
1684 case 0x1F: { // CTT refit exclude list
1685 uint8 count = buf->ReadByte();
1686 _gted[e->index].UpdateRefittability(prop == 0x1E && count != 0);
1687 if (prop == 0x1E) _gted[e->index].defaultcargo_grf = _cur.grffile;
1688 uint32 &ctt = prop == 0x1E ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1689 ctt = 0;
1690 while (count--) {
1691 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1692 if (ctype == CT_INVALID) continue;
1693 SetBit(ctt, ctype);
1695 break;
1698 default:
1699 ret = CommonVehicleChangeInfo(ei, prop, buf);
1700 break;
1704 return ret;
1708 * Define properties for aircraft
1709 * @param engine Local ID of the aircraft.
1710 * @param numinfo Number of subsequent IDs to change the property for.
1711 * @param prop The property to change.
1712 * @param buf The property value.
1713 * @return ChangeInfoResult.
1715 static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int prop, ByteReader *buf)
1717 ChangeInfoResult ret = CIR_SUCCESS;
1719 for (int i = 0; i < numinfo; i++) {
1720 Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i);
1721 if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles
1723 EngineInfo *ei = &e->info;
1724 AircraftVehicleInfo *avi = &e->u.air;
1726 switch (prop) {
1727 case 0x08: { // Sprite ID
1728 uint8 spriteid = buf->ReadByte();
1729 uint8 orig_spriteid = spriteid;
1731 /* aircraft have different custom id in the GRF file */
1732 if (spriteid == 0xFF) spriteid = 0xFD;
1734 if (spriteid < 0xFD) spriteid >>= 1;
1736 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1737 avi->image_index = spriteid;
1738 } else {
1739 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1740 avi->image_index = 0;
1742 break;
1745 case 0x09: // Helicopter
1746 if (buf->ReadByte() == 0) {
1747 avi->subtype = AIR_HELI;
1748 } else {
1749 SB(avi->subtype, 0, 1, 1); // AIR_CTOL
1751 break;
1753 case 0x0A: // Large
1754 SB(avi->subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1755 break;
1757 case PROP_AIRCRAFT_COST_FACTOR: // 0x0B Cost factor
1758 avi->cost_factor = buf->ReadByte();
1759 break;
1761 case PROP_AIRCRAFT_SPEED: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1762 avi->max_speed = (buf->ReadByte() * 128) / 10;
1763 break;
1765 case 0x0D: // Acceleration
1766 avi->acceleration = buf->ReadByte();
1767 break;
1769 case PROP_AIRCRAFT_RUNNING_COST_FACTOR: // 0x0E Running cost factor
1770 avi->running_cost = buf->ReadByte();
1771 break;
1773 case PROP_AIRCRAFT_PASSENGER_CAPACITY: // 0x0F Passenger capacity
1774 avi->passenger_capacity = buf->ReadWord();
1775 break;
1777 case PROP_AIRCRAFT_MAIL_CAPACITY: // 0x11 Mail capacity
1778 avi->mail_capacity = buf->ReadByte();
1779 break;
1781 case 0x12: // SFX
1782 avi->sfx = GetNewGRFSoundID(_cur.grffile, buf->ReadByte());
1783 break;
1785 case 0x13: { // Cargoes available for refitting
1786 uint32 mask = buf->ReadDWord();
1787 _gted[e->index].UpdateRefittability(mask != 0);
1788 ei->refit_mask = TranslateRefitMask(mask);
1789 _gted[e->index].defaultcargo_grf = _cur.grffile;
1790 break;
1793 case 0x14: // Callback mask
1794 ei->callback_mask = buf->ReadByte();
1795 break;
1797 case 0x15: // Refit cost
1798 ei->refit_cost = buf->ReadByte();
1799 break;
1801 case 0x16: // Retire vehicle early
1802 ei->retire_early = buf->ReadByte();
1803 break;
1805 case 0x17: // Miscellaneous flags
1806 ei->misc_flags = buf->ReadByte();
1807 _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
1808 break;
1810 case 0x18: // Cargo classes allowed
1811 _gted[e->index].cargo_allowed = buf->ReadWord();
1812 _gted[e->index].UpdateRefittability(_gted[e->index].cargo_allowed != 0);
1813 _gted[e->index].defaultcargo_grf = _cur.grffile;
1814 break;
1816 case 0x19: // Cargo classes disallowed
1817 _gted[e->index].cargo_disallowed = buf->ReadWord();
1818 _gted[e->index].UpdateRefittability(false);
1819 break;
1821 case 0x1A: // Long format introduction date (days since year 0)
1822 ei->base_intro = buf->ReadDWord();
1823 break;
1825 case 0x1B: // Alter purchase list sort order
1826 AlterVehicleListOrder(e->index, buf->ReadExtendedByte());
1827 break;
1829 case PROP_AIRCRAFT_CARGO_AGE_PERIOD: // 0x1C Cargo aging period
1830 ei->cargo_age_period = buf->ReadWord();
1831 break;
1833 case 0x1D: // CTT refit include list
1834 case 0x1E: { // CTT refit exclude list
1835 uint8 count = buf->ReadByte();
1836 _gted[e->index].UpdateRefittability(prop == 0x1D && count != 0);
1837 if (prop == 0x1D) _gted[e->index].defaultcargo_grf = _cur.grffile;
1838 uint32 &ctt = prop == 0x1D ? _gted[e->index].ctt_include_mask : _gted[e->index].ctt_exclude_mask;
1839 ctt = 0;
1840 while (count--) {
1841 CargoID ctype = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
1842 if (ctype == CT_INVALID) continue;
1843 SetBit(ctt, ctype);
1845 break;
1848 case PROP_AIRCRAFT_RANGE: // 0x1F Max aircraft range
1849 avi->max_range = buf->ReadWord();
1850 break;
1852 default:
1853 ret = CommonVehicleChangeInfo(ei, prop, buf);
1854 break;
1858 return ret;
1862 * Define properties for stations
1863 * @param stdid StationID of the first station tile.
1864 * @param numinfo Number of subsequent station tiles to change the property for.
1865 * @param prop The property to change.
1866 * @param buf The property value.
1867 * @return ChangeInfoResult.
1869 static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, ByteReader *buf)
1871 ChangeInfoResult ret = CIR_SUCCESS;
1873 if (stid + numinfo > NUM_STATIONS_PER_GRF) {
1874 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid + numinfo, NUM_STATIONS_PER_GRF);
1875 return CIR_INVALID_ID;
1878 /* Allocate station specs if necessary */
1879 if (_cur.grffile->stations == nullptr) _cur.grffile->stations = CallocT<StationSpec*>(NUM_STATIONS_PER_GRF);
1881 for (int i = 0; i < numinfo; i++) {
1882 StationSpec *statspec = _cur.grffile->stations[stid + i];
1884 /* Check that the station we are modifying is defined. */
1885 if (statspec == nullptr && prop != 0x08) {
1886 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1887 return CIR_INVALID_ID;
1890 switch (prop) {
1891 case 0x08: { // Class ID
1892 StationSpec **spec = &_cur.grffile->stations[stid + i];
1894 /* Property 0x08 is special; it is where the station is allocated */
1895 if (*spec == nullptr) *spec = CallocT<StationSpec>(1);
1897 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1898 uint32 classid = buf->ReadDWord();
1899 (*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
1900 break;
1903 case 0x09: // Define sprite layout
1904 statspec->tiles = buf->ReadExtendedByte();
1905 delete[] statspec->renderdata; // delete earlier loaded stuff
1906 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1908 for (uint t = 0; t < statspec->tiles; t++) {
1909 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
1910 dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
1912 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1913 buf->Skip(4);
1914 extern const DrawTileSprites _station_display_datas_rail[8];
1915 dts->Clone(&_station_display_datas_rail[t % 8]);
1916 continue;
1919 ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
1920 /* On error, bail out immediately. Temporary GRF data was already freed */
1921 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1923 static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
1924 tmp_layout.Clear();
1925 for (;;) {
1926 /* no relative bounding box support */
1927 DrawTileSeqStruct *dtss = tmp_layout.Append();
1928 MemSetT(dtss, 0);
1930 dtss->delta_x = buf->ReadByte();
1931 if (dtss->IsTerminator()) break;
1932 dtss->delta_y = buf->ReadByte();
1933 dtss->delta_z = buf->ReadByte();
1934 dtss->size_x = buf->ReadByte();
1935 dtss->size_y = buf->ReadByte();
1936 dtss->size_z = buf->ReadByte();
1938 ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss->image);
1939 /* On error, bail out immediately. Temporary GRF data was already freed */
1940 if (_cur.skip_sprites < 0) return CIR_DISABLED;
1942 dts->Clone(tmp_layout.Begin());
1944 break;
1946 case 0x0A: { // Copy sprite layout
1947 byte srcid = buf->ReadByte();
1948 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
1950 if (srcstatspec == nullptr) {
1951 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1952 continue;
1955 delete[] statspec->renderdata; // delete earlier loaded stuff
1957 statspec->tiles = srcstatspec->tiles;
1958 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
1959 for (uint t = 0; t < statspec->tiles; t++) {
1960 statspec->renderdata[t].Clone(&srcstatspec->renderdata[t]);
1962 break;
1965 case 0x0B: // Callback mask
1966 statspec->callback_mask = buf->ReadByte();
1967 break;
1969 case 0x0C: // Disallowed number of platforms
1970 statspec->disallowed_platforms = buf->ReadByte();
1971 break;
1973 case 0x0D: // Disallowed platform lengths
1974 statspec->disallowed_lengths = buf->ReadByte();
1975 break;
1977 case 0x0E: // Define custom layout
1978 statspec->copied_layouts = false;
1980 while (buf->HasData()) {
1981 byte length = buf->ReadByte();
1982 byte number = buf->ReadByte();
1983 StationLayout layout;
1984 uint l, p;
1986 if (length == 0 || number == 0) break;
1988 if (length > statspec->lengths) {
1989 statspec->platforms = ReallocT(statspec->platforms, length);
1990 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
1992 statspec->layouts = ReallocT(statspec->layouts, length);
1993 memset(statspec->layouts + statspec->lengths, 0,
1994 (length - statspec->lengths) * sizeof(*statspec->layouts));
1996 statspec->lengths = length;
1998 l = length - 1; // index is zero-based
2000 if (number > statspec->platforms[l]) {
2001 statspec->layouts[l] = ReallocT(statspec->layouts[l], number);
2002 /* We expect nullptr being 0 here, but C99 guarantees that. */
2003 memset(statspec->layouts[l] + statspec->platforms[l], 0,
2004 (number - statspec->platforms[l]) * sizeof(**statspec->layouts));
2006 statspec->platforms[l] = number;
2009 p = 0;
2010 layout = MallocT<byte>(length * number);
2011 try {
2012 for (l = 0; l < length; l++) {
2013 for (p = 0; p < number; p++) {
2014 layout[l * number + p] = buf->ReadByte();
2017 } catch (...) {
2018 free(layout);
2019 throw;
2022 l--;
2023 p--;
2024 free(statspec->layouts[l][p]);
2025 statspec->layouts[l][p] = layout;
2027 break;
2029 case 0x0F: { // Copy custom layout
2030 byte srcid = buf->ReadByte();
2031 const StationSpec *srcstatspec = _cur.grffile->stations[srcid];
2033 if (srcstatspec == nullptr) {
2034 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2035 continue;
2038 statspec->lengths = srcstatspec->lengths;
2039 statspec->platforms = srcstatspec->platforms;
2040 statspec->layouts = srcstatspec->layouts;
2041 statspec->copied_layouts = true;
2042 break;
2045 case 0x10: // Little/lots cargo threshold
2046 statspec->cargo_threshold = buf->ReadWord();
2047 break;
2049 case 0x11: // Pylon placement
2050 statspec->pylons = buf->ReadByte();
2051 break;
2053 case 0x12: // Cargo types for random triggers
2054 statspec->cargo_triggers = buf->ReadDWord();
2055 if (_cur.grffile->grf_version >= 7) {
2056 statspec->cargo_triggers = TranslateRefitMask(statspec->cargo_triggers);
2058 break;
2060 case 0x13: // General flags
2061 statspec->flags = buf->ReadByte();
2062 break;
2064 case 0x14: // Overhead wire placement
2065 statspec->wires = buf->ReadByte();
2066 break;
2068 case 0x15: // Blocked tiles
2069 statspec->blocked = buf->ReadByte();
2070 break;
2072 case 0x16: // Animation info
2073 statspec->animation.frames = buf->ReadByte();
2074 statspec->animation.status = buf->ReadByte();
2075 break;
2077 case 0x17: // Animation speed
2078 statspec->animation.speed = buf->ReadByte();
2079 break;
2081 case 0x18: // Animation triggers
2082 statspec->animation.triggers = buf->ReadWord();
2083 break;
2085 case 0x1A: // Advanced sprite layout
2086 statspec->tiles = buf->ReadExtendedByte();
2087 delete[] statspec->renderdata; // delete earlier loaded stuff
2088 statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
2090 for (uint t = 0; t < statspec->tiles; t++) {
2091 NewGRFSpriteLayout *dts = &statspec->renderdata[t];
2092 uint num_building_sprites = buf->ReadByte();
2093 /* On error, bail out immediately. Temporary GRF data was already freed */
2094 if (ReadSpriteLayout(buf, num_building_sprites, false, GSF_STATIONS, true, false, dts)) return CIR_DISABLED;
2096 break;
2098 default:
2099 ret = CIR_UNKNOWN;
2100 break;
2104 return ret;
2108 * Define properties for water features
2109 * @param id Type of the first water feature.
2110 * @param numinfo Number of subsequent water feature ids to change the property for.
2111 * @param prop The property to change.
2112 * @param buf The property value.
2113 * @return ChangeInfoResult.
2115 static ChangeInfoResult CanalChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
2117 ChangeInfoResult ret = CIR_SUCCESS;
2119 if (id + numinfo > CF_END) {
2120 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id + numinfo, CF_END);
2121 return CIR_INVALID_ID;
2124 for (int i = 0; i < numinfo; i++) {
2125 CanalProperties *cp = &_cur.grffile->canal_local_properties[id + i];
2127 switch (prop) {
2128 case 0x08:
2129 cp->callback_mask = buf->ReadByte();
2130 break;
2132 case 0x09:
2133 cp->flags = buf->ReadByte();
2134 break;
2136 default:
2137 ret = CIR_UNKNOWN;
2138 break;
2142 return ret;
2146 * Define properties for bridges
2147 * @param brid BridgeID of the bridge.
2148 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2149 * @param prop The property to change.
2150 * @param buf The property value.
2151 * @return ChangeInfoResult.
2153 static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteReader *buf)
2155 ChangeInfoResult ret = CIR_SUCCESS;
2157 if (brid + numinfo > MAX_BRIDGES) {
2158 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo, MAX_BRIDGES);
2159 return CIR_INVALID_ID;
2162 for (int i = 0; i < numinfo; i++) {
2163 BridgeSpec *bridge = &_bridge[brid + i];
2165 switch (prop) {
2166 case 0x08: { // Year of availability
2167 /* We treat '0' as always available */
2168 byte year = buf->ReadByte();
2169 bridge->avail_year = (year > 0 ? ORIGINAL_BASE_YEAR + year : 0);
2170 break;
2173 case 0x09: // Minimum length
2174 bridge->min_length = buf->ReadByte();
2175 break;
2177 case 0x0A: // Maximum length
2178 bridge->max_length = buf->ReadByte();
2179 if (bridge->max_length > 16) bridge->max_length = 0xFFFF;
2180 break;
2182 case 0x0B: // Cost factor
2183 bridge->price = buf->ReadByte();
2184 break;
2186 case 0x0C: // Maximum speed
2187 bridge->speed = buf->ReadWord();
2188 break;
2190 case 0x0D: { // Bridge sprite tables
2191 byte tableid = buf->ReadByte();
2192 byte numtables = buf->ReadByte();
2194 if (bridge->sprite_table == nullptr) {
2195 /* Allocate memory for sprite table pointers and zero out */
2196 bridge->sprite_table = CallocT<PalSpriteID*>(7);
2199 for (; numtables-- != 0; tableid++) {
2200 if (tableid >= 7) { // skip invalid data
2201 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2202 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2203 continue;
2206 if (bridge->sprite_table[tableid] == nullptr) {
2207 bridge->sprite_table[tableid] = MallocT<PalSpriteID>(32);
2210 for (byte sprite = 0; sprite < 32; sprite++) {
2211 SpriteID image = buf->ReadWord();
2212 PaletteID pal = buf->ReadWord();
2214 bridge->sprite_table[tableid][sprite].sprite = image;
2215 bridge->sprite_table[tableid][sprite].pal = pal;
2217 MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]);
2220 break;
2223 case 0x0E: // Flags; bit 0 - disable far pillars
2224 bridge->flags = buf->ReadByte();
2225 break;
2227 case 0x0F: // Long format year of availability (year since year 0)
2228 bridge->avail_year = Clamp(buf->ReadDWord(), MIN_YEAR, MAX_YEAR);
2229 break;
2231 case 0x10: { // purchase string
2232 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2233 if (newone != STR_UNDEFINED) bridge->material = newone;
2234 break;
2237 case 0x11: // description of bridge with rails or roads
2238 case 0x12: {
2239 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2240 if (newone != STR_UNDEFINED) bridge->transport_name[prop - 0x11] = newone;
2241 break;
2244 case 0x13: // 16 bits cost multiplier
2245 bridge->price = buf->ReadWord();
2246 break;
2248 default:
2249 ret = CIR_UNKNOWN;
2250 break;
2254 return ret;
2258 * Ignore a house property
2259 * @param prop Property to read.
2260 * @param buf Property value.
2261 * @return ChangeInfoResult.
2263 static ChangeInfoResult IgnoreTownHouseProperty(int prop, ByteReader *buf)
2265 ChangeInfoResult ret = CIR_SUCCESS;
2267 switch (prop) {
2268 case 0x09:
2269 case 0x0B:
2270 case 0x0C:
2271 case 0x0D:
2272 case 0x0E:
2273 case 0x0F:
2274 case 0x11:
2275 case 0x14:
2276 case 0x15:
2277 case 0x16:
2278 case 0x18:
2279 case 0x19:
2280 case 0x1A:
2281 case 0x1B:
2282 case 0x1C:
2283 case 0x1D:
2284 case 0x1F:
2285 buf->ReadByte();
2286 break;
2288 case 0x0A:
2289 case 0x10:
2290 case 0x12:
2291 case 0x13:
2292 case 0x21:
2293 case 0x22:
2294 buf->ReadWord();
2295 break;
2297 case 0x1E:
2298 buf->ReadDWord();
2299 break;
2301 case 0x17:
2302 for (uint j = 0; j < 4; j++) buf->ReadByte();
2303 break;
2305 case 0x20: {
2306 byte count = buf->ReadByte();
2307 for (byte j = 0; j < count; j++) buf->ReadByte();
2308 break;
2311 default:
2312 ret = CIR_UNKNOWN;
2313 break;
2315 return ret;
2319 * Define properties for houses
2320 * @param hid HouseID of the house.
2321 * @param numinfo Number of subsequent houseIDs to change the property for.
2322 * @param prop The property to change.
2323 * @param buf The property value.
2324 * @return ChangeInfoResult.
2326 static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, ByteReader *buf)
2328 ChangeInfoResult ret = CIR_SUCCESS;
2330 if (hid + numinfo > NUM_HOUSES_PER_GRF) {
2331 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo, NUM_HOUSES_PER_GRF);
2332 return CIR_INVALID_ID;
2335 /* Allocate house specs if they haven't been allocated already. */
2336 if (_cur.grffile->housespec == nullptr) {
2337 _cur.grffile->housespec = CallocT<HouseSpec*>(NUM_HOUSES_PER_GRF);
2340 for (int i = 0; i < numinfo; i++) {
2341 HouseSpec *housespec = _cur.grffile->housespec[hid + i];
2343 if (prop != 0x08 && housespec == nullptr) {
2344 /* If the house property 08 is not yet set, ignore this property */
2345 ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf);
2346 if (cir > ret) ret = cir;
2347 continue;
2350 switch (prop) {
2351 case 0x08: { // Substitute building type, and definition of a new house
2352 HouseSpec **house = &_cur.grffile->housespec[hid + i];
2353 byte subs_id = buf->ReadByte();
2355 if (subs_id == 0xFF) {
2356 /* Instead of defining a new house, a substitute house id
2357 * of 0xFF disables the old house with the current id. */
2358 HouseSpec::Get(hid + i)->enabled = false;
2359 continue;
2360 } else if (subs_id >= NEW_HOUSE_OFFSET) {
2361 /* The substitute id must be one of the original houses. */
2362 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2363 continue;
2366 /* Allocate space for this house. */
2367 if (*house == nullptr) *house = CallocT<HouseSpec>(1);
2369 housespec = *house;
2371 MemCpyT(housespec, HouseSpec::Get(subs_id));
2373 housespec->enabled = true;
2374 housespec->grf_prop.local_id = hid + i;
2375 housespec->grf_prop.subst_id = subs_id;
2376 housespec->grf_prop.grffile = _cur.grffile;
2377 housespec->random_colour[0] = 0x04; // those 4 random colours are the base colour
2378 housespec->random_colour[1] = 0x08; // for all new houses
2379 housespec->random_colour[2] = 0x0C; // they stand for red, blue, orange and green
2380 housespec->random_colour[3] = 0x06;
2382 /* Make sure that the third cargo type is valid in this
2383 * climate. This can cause problems when copying the properties
2384 * of a house that accepts food, where the new house is valid
2385 * in the temperate climate. */
2386 if (!CargoSpec::Get(housespec->accepts_cargo[2])->IsValid()) {
2387 housespec->cargo_acceptance[2] = 0;
2390 _loaded_newgrf_features.has_newhouses = true;
2391 break;
2394 case 0x09: // Building flags
2395 housespec->building_flags = (BuildingFlags)buf->ReadByte();
2396 break;
2398 case 0x0A: { // Availability years
2399 uint16 years = buf->ReadWord();
2400 housespec->min_year = GB(years, 0, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 0, 8);
2401 housespec->max_year = GB(years, 8, 8) > 150 ? MAX_YEAR : ORIGINAL_BASE_YEAR + GB(years, 8, 8);
2402 break;
2405 case 0x0B: // Population
2406 housespec->population = buf->ReadByte();
2407 break;
2409 case 0x0C: // Mail generation multiplier
2410 housespec->mail_generation = buf->ReadByte();
2411 break;
2413 case 0x0D: // Passenger acceptance
2414 case 0x0E: // Mail acceptance
2415 housespec->cargo_acceptance[prop - 0x0D] = buf->ReadByte();
2416 break;
2418 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2419 int8 goods = buf->ReadByte();
2421 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2422 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2423 CargoID cid = (goods >= 0) ? ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_CANDY : CT_GOODS) :
2424 ((_settings_game.game_creation.landscape == LT_TOYLAND) ? CT_FIZZY_DRINKS : CT_FOOD);
2426 /* Make sure the cargo type is valid in this climate. */
2427 if (!CargoSpec::Get(cid)->IsValid()) goods = 0;
2429 housespec->accepts_cargo[2] = cid;
2430 housespec->cargo_acceptance[2] = abs(goods); // but we do need positive value here
2431 break;
2434 case 0x10: // Local authority rating decrease on removal
2435 housespec->remove_rating_decrease = buf->ReadWord();
2436 break;
2438 case 0x11: // Removal cost multiplier
2439 housespec->removal_cost = buf->ReadByte();
2440 break;
2442 case 0x12: // Building name ID
2443 AddStringForMapping(buf->ReadWord(), &housespec->building_name);
2444 break;
2446 case 0x13: // Building availability mask
2447 housespec->building_availability = (HouseZones)buf->ReadWord();
2448 break;
2450 case 0x14: // House callback mask
2451 housespec->callback_mask |= buf->ReadByte();
2452 break;
2454 case 0x15: { // House override byte
2455 byte override = buf->ReadByte();
2457 /* The house being overridden must be an original house. */
2458 if (override >= NEW_HOUSE_OFFSET) {
2459 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override, hid + i);
2460 continue;
2463 _house_mngr.Add(hid + i, _cur.grffile->grfid, override);
2464 break;
2467 case 0x16: // Periodic refresh multiplier
2468 housespec->processing_time = min(buf->ReadByte(), 63);
2469 break;
2471 case 0x17: // Four random colours to use
2472 for (uint j = 0; j < 4; j++) housespec->random_colour[j] = buf->ReadByte();
2473 break;
2475 case 0x18: // Relative probability of appearing
2476 housespec->probability = buf->ReadByte();
2477 break;
2479 case 0x19: // Extra flags
2480 housespec->extra_flags = (HouseExtraFlags)buf->ReadByte();
2481 break;
2483 case 0x1A: // Animation frames
2484 housespec->animation.frames = buf->ReadByte();
2485 housespec->animation.status = GB(housespec->animation.frames, 7, 1);
2486 SB(housespec->animation.frames, 7, 1, 0);
2487 break;
2489 case 0x1B: // Animation speed
2490 housespec->animation.speed = Clamp(buf->ReadByte(), 2, 16);
2491 break;
2493 case 0x1C: // Class of the building type
2494 housespec->class_id = AllocateHouseClassID(buf->ReadByte(), _cur.grffile->grfid);
2495 break;
2497 case 0x1D: // Callback mask part 2
2498 housespec->callback_mask |= (buf->ReadByte() << 8);
2499 break;
2501 case 0x1E: { // Accepted cargo types
2502 uint32 cargotypes = buf->ReadDWord();
2504 /* Check if the cargo types should not be changed */
2505 if (cargotypes == 0xFFFFFFFF) break;
2507 for (uint j = 0; j < 3; j++) {
2508 /* Get the cargo number from the 'list' */
2509 uint8 cargo_part = GB(cargotypes, 8 * j, 8);
2510 CargoID cargo = GetCargoTranslation(cargo_part, _cur.grffile);
2512 if (cargo == CT_INVALID) {
2513 /* Disable acceptance of invalid cargo type */
2514 housespec->cargo_acceptance[j] = 0;
2515 } else {
2516 housespec->accepts_cargo[j] = cargo;
2519 break;
2522 case 0x1F: // Minimum life span
2523 housespec->minimum_life = buf->ReadByte();
2524 break;
2526 case 0x20: { // Cargo acceptance watch list
2527 byte count = buf->ReadByte();
2528 for (byte j = 0; j < count; j++) {
2529 CargoID cargo = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
2530 if (cargo != CT_INVALID) SetBit(housespec->watched_cargoes, cargo);
2532 break;
2535 case 0x21: // long introduction year
2536 housespec->min_year = buf->ReadWord();
2537 break;
2539 case 0x22: // long maximum year
2540 housespec->max_year = buf->ReadWord();
2541 break;
2543 default:
2544 ret = CIR_UNKNOWN;
2545 break;
2549 return ret;
2553 * Get the language map associated with a given NewGRF and language.
2554 * @param grfid The NewGRF to get the map for.
2555 * @param language_id The (NewGRF) language ID to get the map for.
2556 * @return The LanguageMap, or nullptr if it couldn't be found.
2558 /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id)
2560 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2561 const GRFFile *grffile = GetFileByGRFID(grfid);
2562 return (grffile != nullptr && grffile->language_map != nullptr && language_id < MAX_LANG) ? &grffile->language_map[language_id] : nullptr;
2566 * Load a cargo- or railtype-translation table.
2567 * @param gvid ID of the global variable. This is basically only checked for zerones.
2568 * @param numinfo Number of subsequent IDs to change the property for.
2569 * @param buf The property value.
2570 * @param [in,out] translation_table Storage location for the translation table.
2571 * @param name Name of the table for debug output.
2572 * @return ChangeInfoResult.
2574 template <typename T>
2575 static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader *buf, T &translation_table, const char *name)
2577 if (gvid != 0) {
2578 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name);
2579 return CIR_INVALID_ID;
2582 translation_table.Clear();
2583 for (int i = 0; i < numinfo; i++) {
2584 uint32 item = buf->ReadDWord();
2585 *translation_table.Append() = BSWAP32(item);
2588 return CIR_SUCCESS;
2592 * Define properties for global variables
2593 * @param gvid ID of the global variable.
2594 * @param numinfo Number of subsequent IDs to change the property for.
2595 * @param prop The property to change.
2596 * @param buf The property value.
2597 * @return ChangeInfoResult.
2599 static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2601 /* Properties which are handled as a whole */
2602 switch (prop) {
2603 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2604 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2606 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2607 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2609 case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2610 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->roadtype_list[ROADTYPE_ROAD], "Road type");
2612 case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2613 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->roadtype_list[ROADTYPE_TRAM], "Tram type");
2615 default:
2616 break;
2619 /* Properties which are handled per item */
2620 ChangeInfoResult ret = CIR_SUCCESS;
2621 for (int i = 0; i < numinfo; i++) {
2622 switch (prop) {
2623 case 0x08: { // Cost base factor
2624 int factor = buf->ReadByte();
2625 uint price = gvid + i;
2627 if (price < PR_END) {
2628 _cur.grffile->price_base_multipliers[price] = min<int>(factor - 8, MAX_PRICE_MODIFIER);
2629 } else {
2630 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2632 break;
2635 case 0x0A: { // Currency display names
2636 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2637 StringID newone = GetGRFStringID(_cur.grffile->grfid, buf->ReadWord());
2639 if ((newone != STR_UNDEFINED) && (curidx < CURRENCY_END)) {
2640 _currency_specs[curidx].name = newone;
2642 break;
2645 case 0x0B: { // Currency multipliers
2646 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2647 uint32 rate = buf->ReadDWord();
2649 if (curidx < CURRENCY_END) {
2650 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2651 * which OTTD does not. For this reason, divide grf value by 1000,
2652 * to be compatible */
2653 _currency_specs[curidx].rate = rate / 1000;
2654 } else {
2655 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2657 break;
2660 case 0x0C: { // Currency options
2661 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2662 uint16 options = buf->ReadWord();
2664 if (curidx < CURRENCY_END) {
2665 _currency_specs[curidx].separator[0] = GB(options, 0, 8);
2666 _currency_specs[curidx].separator[1] = '\0';
2667 /* By specifying only one bit, we prevent errors,
2668 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2669 _currency_specs[curidx].symbol_pos = GB(options, 8, 1);
2670 } else {
2671 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2673 break;
2676 case 0x0D: { // Currency prefix symbol
2677 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2678 uint32 tempfix = buf->ReadDWord();
2680 if (curidx < CURRENCY_END) {
2681 memcpy(_currency_specs[curidx].prefix, &tempfix, 4);
2682 _currency_specs[curidx].prefix[4] = 0;
2683 } else {
2684 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2686 break;
2689 case 0x0E: { // Currency suffix symbol
2690 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2691 uint32 tempfix = buf->ReadDWord();
2693 if (curidx < CURRENCY_END) {
2694 memcpy(&_currency_specs[curidx].suffix, &tempfix, 4);
2695 _currency_specs[curidx].suffix[4] = 0;
2696 } else {
2697 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2699 break;
2702 case 0x0F: { // Euro introduction dates
2703 uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
2704 Year year_euro = buf->ReadWord();
2706 if (curidx < CURRENCY_END) {
2707 _currency_specs[curidx].to_euro = year_euro;
2708 } else {
2709 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2711 break;
2714 case 0x10: // Snow line height table
2715 if (numinfo > 1 || IsSnowLineSet()) {
2716 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2717 } else if (buf->Remaining() < SNOW_LINE_MONTHS * SNOW_LINE_DAYS) {
2718 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE ")", buf->Remaining());
2719 } else {
2720 byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS];
2722 for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
2723 for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
2724 table[i][j] = buf->ReadByte();
2725 if (_cur.grffile->grf_version >= 8) {
2726 if (table[i][j] != 0xFF) table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 256;
2727 } else {
2728 if (table[i][j] >= 128) {
2729 /* no snow */
2730 table[i][j] = 0xFF;
2731 } else {
2732 table[i][j] = table[i][j] * (1 + _settings_game.construction.max_heightlevel) / 128;
2737 SetSnowLine(table);
2739 break;
2741 case 0x11: // GRF match for engine allocation
2742 /* This is loaded during the reservation stage, so just skip it here. */
2743 /* Each entry is 8 bytes. */
2744 buf->Skip(8);
2745 break;
2747 case 0x13: // Gender translation table
2748 case 0x14: // Case translation table
2749 case 0x15: { // Plural form translation
2750 uint curidx = gvid + i; // The current index, i.e. language.
2751 const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : nullptr;
2752 if (lang == nullptr) {
2753 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2754 /* Skip over the data. */
2755 if (prop == 0x15) {
2756 buf->ReadByte();
2757 } else {
2758 while (buf->ReadByte() != 0) {
2759 buf->ReadString();
2762 break;
2765 if (_cur.grffile->language_map == nullptr) _cur.grffile->language_map = new LanguageMap[MAX_LANG];
2767 if (prop == 0x15) {
2768 uint plural_form = buf->ReadByte();
2769 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2770 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2771 } else {
2772 _cur.grffile->language_map[curidx].plural_form = plural_form;
2774 break;
2777 byte newgrf_id = buf->ReadByte(); // The NewGRF (custom) identifier.
2778 while (newgrf_id != 0) {
2779 const char *name = buf->ReadString(); // The name for the OpenTTD identifier.
2781 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2782 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2783 * is just a subset of UTF8, or they need the bigger UTF8 characters
2784 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2785 WChar c;
2786 size_t len = Utf8Decode(&c, name);
2787 if (c == NFO_UTF8_IDENTIFIER) name += len;
2789 LanguageMap::Mapping map;
2790 map.newgrf_id = newgrf_id;
2791 if (prop == 0x13) {
2792 map.openttd_id = lang->GetGenderIndex(name);
2793 if (map.openttd_id >= MAX_NUM_GENDERS) {
2794 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2795 } else {
2796 *_cur.grffile->language_map[curidx].gender_map.Append() = map;
2798 } else {
2799 map.openttd_id = lang->GetCaseIndex(name);
2800 if (map.openttd_id >= MAX_NUM_CASES) {
2801 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2802 } else {
2803 *_cur.grffile->language_map[curidx].case_map.Append() = map;
2806 newgrf_id = buf->ReadByte();
2808 break;
2811 default:
2812 ret = CIR_UNKNOWN;
2813 break;
2817 return ret;
2820 static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, ByteReader *buf)
2822 /* Properties which are handled as a whole */
2823 switch (prop) {
2824 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2825 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo");
2827 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2828 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type");
2830 case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined roadtypes)
2831 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->roadtype_list[ROADTYPE_ROAD], "Road type");
2833 case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined tramtypes)
2834 return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->roadtype_list[ROADTYPE_TRAM], "Tram type");
2836 default:
2837 break;
2840 /* Properties which are handled per item */
2841 ChangeInfoResult ret = CIR_SUCCESS;
2842 for (int i = 0; i < numinfo; i++) {
2843 switch (prop) {
2844 case 0x08: // Cost base factor
2845 case 0x15: // Plural form translation
2846 buf->ReadByte();
2847 break;
2849 case 0x0A: // Currency display names
2850 case 0x0C: // Currency options
2851 case 0x0F: // Euro introduction dates
2852 buf->ReadWord();
2853 break;
2855 case 0x0B: // Currency multipliers
2856 case 0x0D: // Currency prefix symbol
2857 case 0x0E: // Currency suffix symbol
2858 buf->ReadDWord();
2859 break;
2861 case 0x10: // Snow line height table
2862 buf->Skip(SNOW_LINE_MONTHS * SNOW_LINE_DAYS);
2863 break;
2865 case 0x11: { // GRF match for engine allocation
2866 uint32 s = buf->ReadDWord();
2867 uint32 t = buf->ReadDWord();
2868 SetNewGRFOverride(s, t);
2869 break;
2872 case 0x13: // Gender translation table
2873 case 0x14: // Case translation table
2874 while (buf->ReadByte() != 0) {
2875 buf->ReadString();
2877 break;
2879 default:
2880 ret = CIR_UNKNOWN;
2881 break;
2885 return ret;
2890 * Define properties for cargoes
2891 * @param cid Local ID of the cargo.
2892 * @param numinfo Number of subsequent IDs to change the property for.
2893 * @param prop The property to change.
2894 * @param buf The property value.
2895 * @return ChangeInfoResult.
2897 static ChangeInfoResult CargoChangeInfo(uint cid, int numinfo, int prop, ByteReader *buf)
2899 ChangeInfoResult ret = CIR_SUCCESS;
2901 if (cid + numinfo > NUM_CARGO) {
2902 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo, NUM_CARGO - 1);
2903 return CIR_INVALID_ID;
2906 for (int i = 0; i < numinfo; i++) {
2907 CargoSpec *cs = CargoSpec::Get(cid + i);
2909 switch (prop) {
2910 case 0x08: // Bit number of cargo
2911 cs->bitnum = buf->ReadByte();
2912 if (cs->IsValid()) {
2913 cs->grffile = _cur.grffile;
2914 SetBit(_cargo_mask, cid + i);
2915 } else {
2916 ClrBit(_cargo_mask, cid + i);
2918 break;
2920 case 0x09: // String ID for cargo type name
2921 AddStringForMapping(buf->ReadWord(), &cs->name);
2922 break;
2924 case 0x0A: // String for 1 unit of cargo
2925 AddStringForMapping(buf->ReadWord(), &cs->name_single);
2926 break;
2928 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2929 case 0x1B: // String for cargo units
2930 /* String for units of cargo. This is different in OpenTTD
2931 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2932 * Property 1B is used to set OpenTTD's behaviour. */
2933 AddStringForMapping(buf->ReadWord(), &cs->units_volume);
2934 break;
2936 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2937 case 0x1C: // String for any amount of cargo
2938 /* Strings for an amount of cargo. This is different in OpenTTD
2939 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2940 * Property 1C is used to set OpenTTD's behaviour. */
2941 AddStringForMapping(buf->ReadWord(), &cs->quantifier);
2942 break;
2944 case 0x0D: // String for two letter cargo abbreviation
2945 AddStringForMapping(buf->ReadWord(), &cs->abbrev);
2946 break;
2948 case 0x0E: // Sprite ID for cargo icon
2949 cs->sprite = buf->ReadWord();
2950 break;
2952 case 0x0F: // Weight of one unit of cargo
2953 cs->weight = buf->ReadByte();
2954 break;
2956 case 0x10: // Used for payment calculation
2957 cs->transit_days[0] = buf->ReadByte();
2958 break;
2960 case 0x11: // Used for payment calculation
2961 cs->transit_days[1] = buf->ReadByte();
2962 break;
2964 case 0x12: // Base cargo price
2965 cs->initial_payment = buf->ReadDWord();
2966 break;
2968 case 0x13: // Colour for station rating bars
2969 cs->rating_colour = buf->ReadByte();
2970 break;
2972 case 0x14: // Colour for cargo graph
2973 cs->legend_colour = buf->ReadByte();
2974 break;
2976 case 0x15: // Freight status
2977 cs->is_freight = (buf->ReadByte() != 0);
2978 break;
2980 case 0x16: // Cargo classes
2981 cs->classes = buf->ReadWord();
2982 break;
2984 case 0x17: // Cargo label
2985 cs->label = buf->ReadDWord();
2986 cs->label = BSWAP32(cs->label);
2987 break;
2989 case 0x18: { // Town growth substitute type
2990 uint8 substitute_type = buf->ReadByte();
2992 switch (substitute_type) {
2993 case 0x00: cs->town_effect = TE_PASSENGERS; break;
2994 case 0x02: cs->town_effect = TE_MAIL; break;
2995 case 0x05: cs->town_effect = TE_GOODS; break;
2996 case 0x09: cs->town_effect = TE_WATER; break;
2997 case 0x0B: cs->town_effect = TE_FOOD; break;
2998 default:
2999 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
3000 FALLTHROUGH;
3001 case 0xFF: cs->town_effect = TE_NONE; break;
3003 break;
3006 case 0x19: // Town growth coefficient
3007 cs->multipliertowngrowth = buf->ReadWord();
3008 break;
3010 case 0x1A: // Bitmask of callbacks to use
3011 cs->callback_mask = buf->ReadByte();
3012 break;
3014 case 0x1D: // Vehicle capacity muliplier
3015 cs->multiplier = max<uint16>(1u, buf->ReadWord());
3016 break;
3018 default:
3019 ret = CIR_UNKNOWN;
3020 break;
3024 return ret;
3029 * Define properties for sound effects
3030 * @param sid Local ID of the sound.
3031 * @param numinfo Number of subsequent IDs to change the property for.
3032 * @param prop The property to change.
3033 * @param buf The property value.
3034 * @return ChangeInfoResult.
3036 static ChangeInfoResult SoundEffectChangeInfo(uint sid, int numinfo, int prop, ByteReader *buf)
3038 ChangeInfoResult ret = CIR_SUCCESS;
3040 if (_cur.grffile->sound_offset == 0) {
3041 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3042 return CIR_INVALID_ID;
3045 if (sid + numinfo - ORIGINAL_SAMPLE_COUNT > _cur.grffile->num_sounds) {
3046 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo, ORIGINAL_SAMPLE_COUNT + _cur.grffile->num_sounds);
3047 return CIR_INVALID_ID;
3050 for (int i = 0; i < numinfo; i++) {
3051 SoundEntry *sound = GetSound(sid + i + _cur.grffile->sound_offset - ORIGINAL_SAMPLE_COUNT);
3053 switch (prop) {
3054 case 0x08: // Relative volume
3055 sound->volume = buf->ReadByte();
3056 break;
3058 case 0x09: // Priority
3059 sound->priority = buf->ReadByte();
3060 break;
3062 case 0x0A: { // Override old sound
3063 SoundID orig_sound = buf->ReadByte();
3065 if (orig_sound >= ORIGINAL_SAMPLE_COUNT) {
3066 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound, ORIGINAL_SAMPLE_COUNT);
3067 } else {
3068 SoundEntry *old_sound = GetSound(orig_sound);
3070 /* Literally copy the data of the new sound over the original */
3071 *old_sound = *sound;
3073 break;
3076 default:
3077 ret = CIR_UNKNOWN;
3078 break;
3082 return ret;
3086 * Ignore an industry tile property
3087 * @param prop The property to ignore.
3088 * @param buf The property value.
3089 * @return ChangeInfoResult.
3091 static ChangeInfoResult IgnoreIndustryTileProperty(int prop, ByteReader *buf)
3093 ChangeInfoResult ret = CIR_SUCCESS;
3095 switch (prop) {
3096 case 0x09:
3097 case 0x0D:
3098 case 0x0E:
3099 case 0x10:
3100 case 0x11:
3101 case 0x12:
3102 buf->ReadByte();
3103 break;
3105 case 0x0A:
3106 case 0x0B:
3107 case 0x0C:
3108 case 0x0F:
3109 buf->ReadWord();
3110 break;
3112 default:
3113 ret = CIR_UNKNOWN;
3114 break;
3116 return ret;
3120 * Define properties for industry tiles
3121 * @param indtid Local ID of the industry tile.
3122 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3123 * @param prop The property to change.
3124 * @param buf The property value.
3125 * @return ChangeInfoResult.
3127 static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int prop, ByteReader *buf)
3129 ChangeInfoResult ret = CIR_SUCCESS;
3131 if (indtid + numinfo > NUM_INDUSTRYTILES_PER_GRF) {
3132 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid + numinfo, NUM_INDUSTRYTILES_PER_GRF);
3133 return CIR_INVALID_ID;
3136 /* Allocate industry tile specs if they haven't been allocated already. */
3137 if (_cur.grffile->indtspec == nullptr) {
3138 _cur.grffile->indtspec = CallocT<IndustryTileSpec*>(NUM_INDUSTRYTILES_PER_GRF);
3141 for (int i = 0; i < numinfo; i++) {
3142 IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i];
3144 if (prop != 0x08 && tsp == nullptr) {
3145 ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf);
3146 if (cir > ret) ret = cir;
3147 continue;
3150 switch (prop) {
3151 case 0x08: { // Substitute industry tile type
3152 IndustryTileSpec **tilespec = &_cur.grffile->indtspec[indtid + i];
3153 byte subs_id = buf->ReadByte();
3155 if (subs_id >= NEW_INDUSTRYTILEOFFSET) {
3156 /* The substitute id must be one of the original industry tile. */
3157 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3158 continue;
3161 /* Allocate space for this industry. */
3162 if (*tilespec == nullptr) {
3163 *tilespec = CallocT<IndustryTileSpec>(1);
3164 tsp = *tilespec;
3166 memcpy(tsp, &_industry_tile_specs[subs_id], sizeof(_industry_tile_specs[subs_id]));
3167 tsp->enabled = true;
3169 /* A copied tile should not have the animation infos copied too.
3170 * The anim_state should be left untouched, though
3171 * It is up to the author to animate them himself */
3172 tsp->anim_production = INDUSTRYTILE_NOANIM;
3173 tsp->anim_next = INDUSTRYTILE_NOANIM;
3175 tsp->grf_prop.local_id = indtid + i;
3176 tsp->grf_prop.subst_id = subs_id;
3177 tsp->grf_prop.grffile = _cur.grffile;
3178 _industile_mngr.AddEntityID(indtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
3180 break;
3183 case 0x09: { // Industry tile override
3184 byte ovrid = buf->ReadByte();
3186 /* The industry being overridden must be an original industry. */
3187 if (ovrid >= NEW_INDUSTRYTILEOFFSET) {
3188 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3189 continue;
3192 _industile_mngr.Add(indtid + i, _cur.grffile->grfid, ovrid);
3193 break;
3196 case 0x0A: // Tile acceptance
3197 case 0x0B:
3198 case 0x0C: {
3199 uint16 acctp = buf->ReadWord();
3200 tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur.grffile);
3201 tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
3202 break;
3205 case 0x0D: // Land shape flags
3206 tsp->slopes_refused = (Slope)buf->ReadByte();
3207 break;
3209 case 0x0E: // Callback mask
3210 tsp->callback_mask = buf->ReadByte();
3211 break;
3213 case 0x0F: // Animation information
3214 tsp->animation.frames = buf->ReadByte();
3215 tsp->animation.status = buf->ReadByte();
3216 break;
3218 case 0x10: // Animation speed
3219 tsp->animation.speed = buf->ReadByte();
3220 break;
3222 case 0x11: // Triggers for callback 25
3223 tsp->animation.triggers = buf->ReadByte();
3224 break;
3226 case 0x12: // Special flags
3227 tsp->special_flags = (IndustryTileSpecialFlags)buf->ReadByte();
3228 break;
3230 default:
3231 ret = CIR_UNKNOWN;
3232 break;
3236 return ret;
3240 * Ignore an industry property
3241 * @param prop The property to ignore.
3242 * @param buf The property value.
3243 * @return ChangeInfoResult.
3245 static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf)
3247 ChangeInfoResult ret = CIR_SUCCESS;
3249 switch (prop) {
3250 case 0x09:
3251 case 0x0B:
3252 case 0x0F:
3253 case 0x12:
3254 case 0x13:
3255 case 0x14:
3256 case 0x17:
3257 case 0x18:
3258 case 0x19:
3259 case 0x21:
3260 case 0x22:
3261 buf->ReadByte();
3262 break;
3264 case 0x0C:
3265 case 0x0D:
3266 case 0x0E:
3267 case 0x10:
3268 case 0x1B:
3269 case 0x1F:
3270 case 0x24:
3271 buf->ReadWord();
3272 break;
3274 case 0x11:
3275 case 0x1A:
3276 case 0x1C:
3277 case 0x1D:
3278 case 0x1E:
3279 case 0x20:
3280 case 0x23:
3281 buf->ReadDWord();
3282 break;
3284 case 0x0A: {
3285 byte num_table = buf->ReadByte();
3286 for (byte j = 0; j < num_table; j++) {
3287 for (uint k = 0;; k++) {
3288 byte x = buf->ReadByte();
3289 if (x == 0xFE && k == 0) {
3290 buf->ReadByte();
3291 buf->ReadByte();
3292 break;
3295 byte y = buf->ReadByte();
3296 if (x == 0 && y == 0x80) break;
3298 byte gfx = buf->ReadByte();
3299 if (gfx == 0xFE) buf->ReadWord();
3302 break;
3305 case 0x16:
3306 for (byte j = 0; j < 3; j++) buf->ReadByte();
3307 break;
3309 case 0x15: {
3310 byte number_of_sounds = buf->ReadByte();
3311 for (uint8 j = 0; j < number_of_sounds; j++) {
3312 buf->ReadByte();
3314 break;
3317 default:
3318 ret = CIR_UNKNOWN;
3319 break;
3321 return ret;
3325 * Validate the industry layout; e.g. to prevent duplicate tiles.
3326 * @param layout The layout to check.
3327 * @param size The size of the layout.
3328 * @return True if the layout is deemed valid.
3330 static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size)
3332 for (int i = 0; i < size - 1; i++) {
3333 for (int j = i + 1; j < size; j++) {
3334 if (layout[i].ti.x == layout[j].ti.x &&
3335 layout[i].ti.y == layout[j].ti.y) {
3336 return false;
3340 return true;
3343 /** Clean the tile table of the IndustrySpec if it's needed. */
3344 static void CleanIndustryTileTable(IndustrySpec *ind)
3346 if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != nullptr) {
3347 for (int j = 0; j < ind->num_table; j++) {
3348 /* remove the individual layouts */
3349 free(ind->table[j]);
3351 /* remove the layouts pointers */
3352 free(ind->table);
3353 ind->table = nullptr;
3358 * Define properties for industries
3359 * @param indid Local ID of the industry.
3360 * @param numinfo Number of subsequent industry IDs to change the property for.
3361 * @param prop The property to change.
3362 * @param buf The property value.
3363 * @return ChangeInfoResult.
3365 static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, ByteReader *buf)
3367 ChangeInfoResult ret = CIR_SUCCESS;
3369 if (indid + numinfo > NUM_INDUSTRYTYPES_PER_GRF) {
3370 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid + numinfo, NUM_INDUSTRYTYPES_PER_GRF);
3371 return CIR_INVALID_ID;
3374 /* Allocate industry specs if they haven't been allocated already. */
3375 if (_cur.grffile->industryspec == nullptr) {
3376 _cur.grffile->industryspec = CallocT<IndustrySpec*>(NUM_INDUSTRYTYPES_PER_GRF);
3379 for (int i = 0; i < numinfo; i++) {
3380 IndustrySpec *indsp = _cur.grffile->industryspec[indid + i];
3382 if (prop != 0x08 && indsp == nullptr) {
3383 ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf);
3384 if (cir > ret) ret = cir;
3385 continue;
3388 switch (prop) {
3389 case 0x08: { // Substitute industry type
3390 IndustrySpec **indspec = &_cur.grffile->industryspec[indid + i];
3391 byte subs_id = buf->ReadByte();
3393 if (subs_id == 0xFF) {
3394 /* Instead of defining a new industry, a substitute industry id
3395 * of 0xFF disables the old industry with the current id. */
3396 _industry_specs[indid + i].enabled = false;
3397 continue;
3398 } else if (subs_id >= NEW_INDUSTRYOFFSET) {
3399 /* The substitute id must be one of the original industry. */
3400 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3401 continue;
3404 /* Allocate space for this industry.
3405 * Only need to do it once. If ever it is called again, it should not
3406 * do anything */
3407 if (*indspec == nullptr) {
3408 *indspec = CallocT<IndustrySpec>(1);
3409 indsp = *indspec;
3411 memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id]));
3412 indsp->enabled = true;
3413 indsp->grf_prop.local_id = indid + i;
3414 indsp->grf_prop.subst_id = subs_id;
3415 indsp->grf_prop.grffile = _cur.grffile;
3416 /* If the grf industry needs to check its surounding upon creation, it should
3417 * rely on callbacks, not on the original placement functions */
3418 indsp->check_proc = CHECK_NOTHING;
3420 break;
3423 case 0x09: { // Industry type override
3424 byte ovrid = buf->ReadByte();
3426 /* The industry being overridden must be an original industry. */
3427 if (ovrid >= NEW_INDUSTRYOFFSET) {
3428 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3429 continue;
3431 indsp->grf_prop.override = ovrid;
3432 _industry_mngr.Add(indid + i, _cur.grffile->grfid, ovrid);
3433 break;
3436 case 0x0A: { // Set industry layout(s)
3437 byte new_num_layouts = buf->ReadByte(); // Number of layaouts
3438 /* We read the total size in bytes, but we can't rely on the
3439 * newgrf to provide a sane value. First assume the value is
3440 * sane but later on we make sure we enlarge the array if the
3441 * newgrf contains more data. Each tile uses either 3 or 5
3442 * bytes, so to play it safe we assume 3. */
3443 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
3444 IndustryTileTable **tile_table = CallocT<IndustryTileTable*>(new_num_layouts); // Table with tiles to compose an industry
3445 IndustryTileTable *itt = CallocT<IndustryTileTable>(def_num_tiles); // Temporary array to read the tile layouts from the GRF
3446 uint size;
3447 const IndustryTileTable *copy_from;
3449 try {
3450 for (byte j = 0; j < new_num_layouts; j++) {
3451 for (uint k = 0;; k++) {
3452 if (k >= def_num_tiles) {
3453 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3454 /* Size reported by newgrf was not big enough so enlarge the array. */
3455 def_num_tiles *= 2;
3456 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
3459 itt[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3461 if (itt[k].ti.x == 0xFE && k == 0) {
3462 /* This means we have to borrow the layout from an old industry */
3463 IndustryType type = buf->ReadByte(); // industry holding required layout
3464 byte laynbr = buf->ReadByte(); // layout number to borrow
3466 copy_from = _origin_industry_specs[type].table[laynbr];
3467 for (size = 1;; size++) {
3468 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break;
3470 break;
3473 itt[k].ti.y = buf->ReadByte(); // Or table definition finalisation
3475 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
3476 /* Not the same terminator. The one we are using is rather
3477 x = -80, y = x . So, adjust it. */
3478 itt[k].ti.x = -0x80;
3479 itt[k].ti.y = 0;
3480 itt[k].gfx = 0;
3482 size = k + 1;
3483 copy_from = itt;
3484 break;
3487 itt[k].gfx = buf->ReadByte();
3489 if (itt[k].gfx == 0xFE) {
3490 /* Use a new tile from this GRF */
3491 int local_tile_id = buf->ReadWord();
3493 /* Read the ID from the _industile_mngr. */
3494 int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3496 if (tempid == INVALID_INDUSTRYTILE) {
3497 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3498 } else {
3499 /* Declared as been valid, can be used */
3500 itt[k].gfx = tempid;
3501 size = k + 1;
3502 copy_from = itt;
3504 } else if (itt[k].gfx == 0xFF) {
3505 itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8);
3506 itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8);
3508 /* When there were only 256x256 maps, TileIndex was a uint16 and
3509 * itt[k].ti was just a TileIndexDiff that was added to it.
3510 * As such negative "x" values were shifted into the "y" position.
3511 * x = -1, y = 1 -> x = 255, y = 0
3512 * Since GRF version 8 the position is interpreted as pair of independent int8.
3513 * For GRF version < 8 we need to emulate the old shifting behaviour.
3515 if (_cur.grffile->grf_version < 8 && itt[k].ti.x < 0) itt[k].ti.y += 1;
3519 if (!ValidateIndustryLayout(copy_from, size)) {
3520 /* The industry layout was not valid, so skip this one. */
3521 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3522 new_num_layouts--;
3523 j--;
3524 } else {
3525 tile_table[j] = CallocT<IndustryTileTable>(size);
3526 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3529 } catch (...) {
3530 for (int i = 0; i < new_num_layouts; i++) {
3531 free(tile_table[i]);
3533 free(tile_table);
3534 free(itt);
3535 throw;
3538 /* Clean the tile table if it was already set by a previous prop A. */
3539 CleanIndustryTileTable(indsp);
3540 /* Install final layout construction in the industry spec */
3541 indsp->num_table = new_num_layouts;
3542 indsp->table = tile_table;
3543 SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT);
3544 free(itt);
3545 break;
3548 case 0x0B: // Industry production flags
3549 indsp->life_type = (IndustryLifeType)buf->ReadByte();
3550 break;
3552 case 0x0C: // Industry closure message
3553 AddStringForMapping(buf->ReadWord(), &indsp->closure_text);
3554 break;
3556 case 0x0D: // Production increase message
3557 AddStringForMapping(buf->ReadWord(), &indsp->production_up_text);
3558 break;
3560 case 0x0E: // Production decrease message
3561 AddStringForMapping(buf->ReadWord(), &indsp->production_down_text);
3562 break;
3564 case 0x0F: // Fund cost multiplier
3565 indsp->cost_multiplier = buf->ReadByte();
3566 break;
3568 case 0x10: // Production cargo types
3569 for (byte j = 0; j < 2; j++) {
3570 indsp->produced_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3572 break;
3574 case 0x11: // Acceptance cargo types
3575 for (byte j = 0; j < 3; j++) {
3576 indsp->accepts_cargo[j] = GetCargoTranslation(buf->ReadByte(), _cur.grffile);
3578 buf->ReadByte(); // Unnused, eat it up
3579 break;
3581 case 0x12: // Production multipliers
3582 case 0x13:
3583 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3584 break;
3586 case 0x14: // Minimal amount of cargo distributed
3587 indsp->minimal_cargo = buf->ReadByte();
3588 break;
3590 case 0x15: { // Random sound effects
3591 indsp->number_of_sounds = buf->ReadByte();
3592 uint8 *sounds = MallocT<uint8>(indsp->number_of_sounds);
3594 try {
3595 for (uint8 j = 0; j < indsp->number_of_sounds; j++) {
3596 sounds[j] = buf->ReadByte();
3598 } catch (...) {
3599 free(sounds);
3600 throw;
3603 if (HasBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
3604 free(indsp->random_sounds);
3606 indsp->random_sounds = sounds;
3607 SetBit(indsp->cleanup_flag, CLEAN_RANDOMSOUNDS);
3608 break;
3611 case 0x16: // Conflicting industry types
3612 for (byte j = 0; j < 3; j++) indsp->conflicting[j] = buf->ReadByte();
3613 break;
3615 case 0x17: // Probability in random game
3616 indsp->appear_creation[_settings_game.game_creation.landscape] = buf->ReadByte();
3617 break;
3619 case 0x18: // Probability during gameplay
3620 indsp->appear_ingame[_settings_game.game_creation.landscape] = buf->ReadByte();
3621 break;
3623 case 0x19: // Map colour
3624 indsp->map_colour = buf->ReadByte();
3625 break;
3627 case 0x1A: // Special industry flags to define special behavior
3628 indsp->behaviour = (IndustryBehaviour)buf->ReadDWord();
3629 break;
3631 case 0x1B: // New industry text ID
3632 AddStringForMapping(buf->ReadWord(), &indsp->new_industry_text);
3633 break;
3635 case 0x1C: // Input cargo multipliers for the three input cargo types
3636 case 0x1D:
3637 case 0x1E: {
3638 uint32 multiples = buf->ReadDWord();
3639 indsp->input_cargo_multiplier[prop - 0x1C][0] = GB(multiples, 0, 16);
3640 indsp->input_cargo_multiplier[prop - 0x1C][1] = GB(multiples, 16, 16);
3641 break;
3644 case 0x1F: // Industry name
3645 AddStringForMapping(buf->ReadWord(), &indsp->name);
3646 break;
3648 case 0x20: // Prospecting success chance
3649 indsp->prospecting_chance = buf->ReadDWord();
3650 break;
3652 case 0x21: // Callback mask
3653 case 0x22: { // Callback additional mask
3654 byte aflag = buf->ReadByte();
3655 SB(indsp->callback_mask, (prop - 0x21) * 8, 8, aflag);
3656 break;
3659 case 0x23: // removal cost multiplier
3660 indsp->removal_cost_multiplier = buf->ReadDWord();
3661 break;
3663 case 0x24: { // name for nearby station
3664 uint16 str = buf->ReadWord();
3665 if (str == 0) {
3666 indsp->station_name = STR_NULL;
3667 } else {
3668 AddStringForMapping(str, &indsp->station_name);
3670 break;
3673 default:
3674 ret = CIR_UNKNOWN;
3675 break;
3679 return ret;
3683 * Create a copy of the tile table so it can be freed later
3684 * without problems.
3685 * @param as The AirportSpec to copy the arrays of.
3687 static void DuplicateTileTable(AirportSpec *as)
3689 AirportTileTable **table_list = MallocT<AirportTileTable*>(as->num_table);
3690 for (int i = 0; i < as->num_table; i++) {
3691 uint num_tiles = 1;
3692 const AirportTileTable *it = as->table[0];
3693 do {
3694 num_tiles++;
3695 } while ((++it)->ti.x != -0x80);
3696 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3697 MemCpyT(table_list[i], as->table[i], num_tiles);
3699 as->table = table_list;
3700 HangarTileTable *depot_table = nullptr;
3701 if (as->nof_depots > 0) {
3702 depot_table = MallocT<HangarTileTable>(as->nof_depots);
3703 MemCpyT(depot_table, as->depot_table, as->nof_depots);
3705 as->depot_table = depot_table;
3706 Direction *rotation = MallocT<Direction>(as->num_table);
3707 MemCpyT(rotation, as->rotation, as->num_table);
3708 as->rotation = rotation;
3712 * Define properties for airports
3713 * @param airport Local ID of the airport.
3714 * @param numinfo Number of subsequent airport IDs to change the property for.
3715 * @param prop The property to change.
3716 * @param buf The property value.
3717 * @return ChangeInfoResult.
3719 static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, ByteReader *buf)
3721 ChangeInfoResult ret = CIR_SUCCESS;
3723 if (airport + numinfo > NUM_AIRPORTS_PER_GRF) {
3724 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo, NUM_AIRPORTS_PER_GRF);
3725 return CIR_INVALID_ID;
3728 /* Allocate industry specs if they haven't been allocated already. */
3729 if (_cur.grffile->airportspec == nullptr) {
3730 _cur.grffile->airportspec = CallocT<AirportSpec*>(NUM_AIRPORTS_PER_GRF);
3733 for (int i = 0; i < numinfo; i++) {
3734 AirportSpec *as = _cur.grffile->airportspec[airport + i];
3736 if (as == nullptr && prop != 0x08 && prop != 0x09) {
3737 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3738 return CIR_INVALID_ID;
3741 switch (prop) {
3742 case 0x08: { // Modify original airport
3743 byte subs_id = buf->ReadByte();
3745 if (subs_id == 0xFF) {
3746 /* Instead of defining a new airport, an airport id
3747 * of 0xFF disables the old airport with the current id. */
3748 AirportSpec::GetWithoutOverride(airport + i)->enabled = false;
3749 continue;
3750 } else if (subs_id >= NEW_AIRPORT_OFFSET) {
3751 /* The substitute id must be one of the original airports. */
3752 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3753 continue;
3756 AirportSpec **spec = &_cur.grffile->airportspec[airport + i];
3757 /* Allocate space for this airport.
3758 * Only need to do it once. If ever it is called again, it should not
3759 * do anything */
3760 if (*spec == nullptr) {
3761 *spec = MallocT<AirportSpec>(1);
3762 as = *spec;
3764 memcpy(as, AirportSpec::GetWithoutOverride(subs_id), sizeof(*as));
3765 as->enabled = true;
3766 as->grf_prop.local_id = airport + i;
3767 as->grf_prop.subst_id = subs_id;
3768 as->grf_prop.grffile = _cur.grffile;
3769 /* override the default airport */
3770 _airport_mngr.Add(airport + i, _cur.grffile->grfid, subs_id);
3771 /* Create a copy of the original tiletable so it can be freed later. */
3772 DuplicateTileTable(as);
3774 break;
3777 case 0x0A: { // Set airport layout
3778 as->num_table = buf->ReadByte(); // Number of layaouts
3779 free(as->rotation);
3780 as->rotation = MallocT<Direction>(as->num_table);
3781 uint32 defsize = buf->ReadDWord(); // Total size of the definition
3782 AirportTileTable **tile_table = CallocT<AirportTileTable*>(as->num_table); // Table with tiles to compose the airport
3783 AirportTileTable *att = CallocT<AirportTileTable>(defsize); // Temporary array to read the tile layouts from the GRF
3784 int size;
3785 const AirportTileTable *copy_from;
3786 try {
3787 for (byte j = 0; j < as->num_table; j++) {
3788 const_cast<Direction&>(as->rotation[j]) = (Direction)buf->ReadByte();
3789 for (int k = 0;; k++) {
3790 att[k].ti.x = buf->ReadByte(); // Offsets from northermost tile
3791 att[k].ti.y = buf->ReadByte();
3793 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3794 /* Not the same terminator. The one we are using is rather
3795 * x = -80, y = 0 . So, adjust it. */
3796 att[k].ti.x = -0x80;
3797 att[k].ti.y = 0;
3798 att[k].gfx = 0;
3800 size = k + 1;
3801 copy_from = att;
3802 break;
3805 att[k].gfx = buf->ReadByte();
3807 if (att[k].gfx == 0xFE) {
3808 /* Use a new tile from this GRF */
3809 int local_tile_id = buf->ReadWord();
3811 /* Read the ID from the _airporttile_mngr. */
3812 uint16 tempid = _airporttile_mngr.GetID(local_tile_id, _cur.grffile->grfid);
3814 if (tempid == INVALID_AIRPORTTILE) {
3815 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3816 } else {
3817 /* Declared as been valid, can be used */
3818 att[k].gfx = tempid;
3819 size = k + 1;
3820 copy_from = att;
3822 } else if (att[k].gfx == 0xFF) {
3823 att[k].ti.x = (int8)GB(att[k].ti.x, 0, 8);
3824 att[k].ti.y = (int8)GB(att[k].ti.y, 0, 8);
3827 if (as->rotation[j] == DIR_E || as->rotation[j] == DIR_W) {
3828 as->size_x = max<byte>(as->size_x, att[k].ti.y + 1);
3829 as->size_y = max<byte>(as->size_y, att[k].ti.x + 1);
3830 } else {
3831 as->size_x = max<byte>(as->size_x, att[k].ti.x + 1);
3832 as->size_y = max<byte>(as->size_y, att[k].ti.y + 1);
3835 tile_table[j] = CallocT<AirportTileTable>(size);
3836 memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size);
3838 /* Install final layout construction in the airport spec */
3839 as->table = tile_table;
3840 free(att);
3841 } catch (...) {
3842 for (int i = 0; i < as->num_table; i++) {
3843 free(tile_table[i]);
3845 free(tile_table);
3846 free(att);
3847 throw;
3849 break;
3852 case 0x0C:
3853 as->min_year = buf->ReadWord();
3854 as->max_year = buf->ReadWord();
3855 if (as->max_year == 0xFFFF) as->max_year = MAX_YEAR;
3856 break;
3858 case 0x0D:
3859 as->ttd_airport_type = (TTDPAirportType)buf->ReadByte();
3860 break;
3862 case 0x0E:
3863 as->catchment = Clamp(buf->ReadByte(), 1, MAX_CATCHMENT);
3864 break;
3866 case 0x0F:
3867 as->noise_level = buf->ReadByte();
3868 break;
3870 case 0x10:
3871 AddStringForMapping(buf->ReadWord(), &as->name);
3872 break;
3874 case 0x11: // Maintenance cost factor
3875 as->maintenance_cost = buf->ReadWord();
3876 break;
3878 case 0x12: { // Accept seaplanes
3879 byte is_seaplane = buf->ReadByte();
3880 if (is_seaplane == 0x01){
3881 as->cls_id = APC_SEA;
3883 break;
3886 default:
3887 ret = CIR_UNKNOWN;
3888 break;
3892 return ret;
3896 * Ignore properties for objects
3897 * @param prop The property to ignore.
3898 * @param buf The property value.
3899 * @return ChangeInfoResult.
3901 static ChangeInfoResult IgnoreObjectProperty(uint prop, ByteReader *buf)
3903 ChangeInfoResult ret = CIR_SUCCESS;
3905 switch (prop) {
3906 case 0x0B:
3907 case 0x0C:
3908 case 0x0D:
3909 case 0x12:
3910 case 0x14:
3911 case 0x16:
3912 case 0x17:
3913 buf->ReadByte();
3914 break;
3916 case 0x09:
3917 case 0x0A:
3918 case 0x10:
3919 case 0x11:
3920 case 0x13:
3921 case 0x15:
3922 buf->ReadWord();
3923 break;
3925 case 0x08:
3926 case 0x0E:
3927 case 0x0F:
3928 buf->ReadDWord();
3929 break;
3931 default:
3932 ret = CIR_UNKNOWN;
3933 break;
3936 return ret;
3940 * Define properties for objects
3941 * @param id Local ID of the object.
3942 * @param numinfo Number of subsequent objectIDs to change the property for.
3943 * @param prop The property to change.
3944 * @param buf The property value.
3945 * @return ChangeInfoResult.
3947 static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
3949 ChangeInfoResult ret = CIR_SUCCESS;
3951 if (id + numinfo > NUM_OBJECTS_PER_GRF) {
3952 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id + numinfo, NUM_OBJECTS_PER_GRF);
3953 return CIR_INVALID_ID;
3956 /* Allocate object specs if they haven't been allocated already. */
3957 if (_cur.grffile->objectspec == nullptr) {
3958 _cur.grffile->objectspec = CallocT<ObjectSpec*>(NUM_OBJECTS_PER_GRF);
3961 for (int i = 0; i < numinfo; i++) {
3962 ObjectSpec *spec = _cur.grffile->objectspec[id + i];
3964 if (prop != 0x08 && spec == nullptr) {
3965 /* If the object property 08 is not yet set, ignore this property */
3966 ChangeInfoResult cir = IgnoreObjectProperty(prop, buf);
3967 if (cir > ret) ret = cir;
3968 continue;
3971 switch (prop) {
3972 case 0x08: { // Class ID
3973 ObjectSpec **ospec = &_cur.grffile->objectspec[id + i];
3975 /* Allocate space for this object. */
3976 if (*ospec == nullptr) {
3977 *ospec = CallocT<ObjectSpec>(1);
3978 (*ospec)->views = 1; // Default for NewGRFs that don't set it.
3981 /* Swap classid because we read it in BE. */
3982 uint32 classid = buf->ReadDWord();
3983 (*ospec)->cls_id = ObjectClass::Allocate(BSWAP32(classid));
3984 (*ospec)->enabled = true;
3985 break;
3988 case 0x09: { // Class name
3989 ObjectClass *objclass = ObjectClass::Get(spec->cls_id);
3990 AddStringForMapping(buf->ReadWord(), &objclass->name);
3991 break;
3994 case 0x0A: // Object name
3995 AddStringForMapping(buf->ReadWord(), &spec->name);
3996 break;
3998 case 0x0B: // Climate mask
3999 spec->climate = buf->ReadByte();
4000 break;
4002 case 0x0C: // Size
4003 spec->size = buf->ReadByte();
4004 break;
4006 case 0x0D: // Build cost multipler
4007 spec->build_cost_multiplier = buf->ReadByte();
4008 spec->clear_cost_multiplier = spec->build_cost_multiplier;
4009 break;
4011 case 0x0E: // Introduction date
4012 spec->introduction_date = buf->ReadDWord();
4013 break;
4015 case 0x0F: // End of life
4016 spec->end_of_life_date = buf->ReadDWord();
4017 break;
4019 case 0x10: // Flags
4020 spec->flags = (ObjectFlags)buf->ReadWord();
4021 _loaded_newgrf_features.has_2CC |= (spec->flags & OBJECT_FLAG_2CC_COLOUR) != 0;
4022 break;
4024 case 0x11: // Animation info
4025 spec->animation.frames = buf->ReadByte();
4026 spec->animation.status = buf->ReadByte();
4027 break;
4029 case 0x12: // Animation speed
4030 spec->animation.speed = buf->ReadByte();
4031 break;
4033 case 0x13: // Animation triggers
4034 spec->animation.triggers = buf->ReadWord();
4035 break;
4037 case 0x14: // Removal cost multiplier
4038 spec->clear_cost_multiplier = buf->ReadByte();
4039 break;
4041 case 0x15: // Callback mask
4042 spec->callback_mask = buf->ReadWord();
4043 break;
4045 case 0x16: // Building height
4046 spec->height = buf->ReadByte();
4047 break;
4049 case 0x17: // Views
4050 spec->views = buf->ReadByte();
4051 if (spec->views != 1 && spec->views != 2 && spec->views != 4) {
4052 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->views, id + i);
4053 spec->views = 1;
4055 break;
4057 case 0x18: // Amount placed on 256^2 map on map creation
4058 spec->generate_amount = buf->ReadByte();
4059 break;
4061 default:
4062 ret = CIR_UNKNOWN;
4063 break;
4067 return ret;
4071 * Define properties for railtypes
4072 * @param id ID of the railtype.
4073 * @param numinfo Number of subsequent IDs to change the property for.
4074 * @param prop The property to change.
4075 * @param buf The property value.
4076 * @return ChangeInfoResult.
4078 static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4080 ChangeInfoResult ret = CIR_SUCCESS;
4082 extern RailtypeInfo _railtypes[RAILTYPE_END];
4084 if (id + numinfo > RAILTYPE_END) {
4085 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4086 return CIR_INVALID_ID;
4089 for (int i = 0; i < numinfo; i++) {
4090 RailType rt = _cur.grffile->railtype_map[id + i];
4091 if (rt == INVALID_RAILTYPE) return CIR_INVALID_ID;
4093 RailtypeInfo *rti = &_railtypes[rt];
4095 switch (prop) {
4096 case 0x08: // Label of rail type
4097 /* Skipped here as this is loaded during reservation stage. */
4098 buf->ReadDWord();
4099 break;
4101 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4102 uint16 str = buf->ReadWord();
4103 AddStringForMapping(str, &rti->strings.toolbar_caption);
4104 if (_cur.grffile->grf_version < 8) {
4105 AddStringForMapping(str, &rti->strings.name);
4107 break;
4110 case 0x0A: // Menu text of railtype
4111 AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4112 break;
4114 case 0x0B: // Build window caption
4115 AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4116 break;
4118 case 0x0C: // Autoreplace text
4119 AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4120 break;
4122 case 0x0D: // New locomotive text
4123 AddStringForMapping(buf->ReadWord(), &rti->strings.new_loco);
4124 break;
4126 case 0x0E: // Compatible railtype list
4127 case 0x0F: // Powered railtype list
4128 case 0x18: // Railtype list required for date introduction
4129 case 0x19: // Introduced railtype list
4131 /* Rail type compatibility bits are added to the existing bits
4132 * to allow multiple GRFs to modify compatibility with the
4133 * default rail types. */
4134 int n = buf->ReadByte();
4135 for (int j = 0; j != n; j++) {
4136 RailTypeLabel label = buf->ReadDWord();
4137 RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
4138 if (rt != INVALID_RAILTYPE) {
4139 switch (prop) {
4140 case 0x0F: SetBit(rti->powered_railtypes, rt); FALLTHROUGH; // Powered implies compatible.
4141 case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
4142 case 0x18: SetBit(rti->introduction_required_railtypes, rt); break;
4143 case 0x19: SetBit(rti->introduces_railtypes, rt); break;
4147 break;
4150 case 0x10: // Rail Type flags
4151 rti->flags = (RailTypeFlags)buf->ReadByte();
4152 break;
4154 case 0x11: // Curve speed advantage
4155 rti->curve_speed = buf->ReadByte();
4156 break;
4158 case 0x12: // Station graphic
4159 rti->fallback_railtype = Clamp(buf->ReadByte(), 0, 2);
4160 break;
4162 case 0x13: // Construction cost factor
4163 rti->cost_multiplier = buf->ReadWord();
4164 break;
4166 case 0x14: // Speed limit
4167 rti->max_speed = buf->ReadWord();
4168 break;
4170 case 0x15: // Acceleration model
4171 rti->acceleration_type = Clamp(buf->ReadByte(), 0, 2);
4172 break;
4174 case 0x16: // Map colour
4175 rti->map_colour = buf->ReadByte();
4176 break;
4178 case 0x17: // Introduction date
4179 rti->introduction_date = buf->ReadDWord();
4180 break;
4182 case 0x1A: // Sort order
4183 rti->sorting_order = buf->ReadByte();
4184 break;
4186 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4187 AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4188 break;
4190 case 0x1C: // Maintenance cost factor
4191 rti->maintenance_multiplier = buf->ReadWord();
4192 break;
4194 case 0x1D: // Alternate rail type label list
4195 /* Skipped here as this is loaded during reservation stage. */
4196 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4197 break;
4199 default:
4200 ret = CIR_UNKNOWN;
4201 break;
4205 return ret;
4208 static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4210 ChangeInfoResult ret = CIR_SUCCESS;
4212 extern RailtypeInfo _railtypes[RAILTYPE_END];
4214 if (id + numinfo > RAILTYPE_END) {
4215 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
4216 return CIR_INVALID_ID;
4219 for (int i = 0; i < numinfo; i++) {
4220 switch (prop) {
4221 case 0x08: // Label of rail type
4223 RailTypeLabel rtl = buf->ReadDWord();
4224 rtl = BSWAP32(rtl);
4226 RailType rt = GetRailTypeByLabel(rtl, false);
4227 if (rt == INVALID_RAILTYPE) {
4228 /* Set up new rail type */
4229 rt = AllocateRailType(rtl);
4232 _cur.grffile->railtype_map[id + i] = rt;
4233 break;
4236 case 0x09: // Toolbar caption of railtype
4237 case 0x0A: // Menu text
4238 case 0x0B: // Build window caption
4239 case 0x0C: // Autoreplace text
4240 case 0x0D: // New loco
4241 case 0x13: // Construction cost
4242 case 0x14: // Speed limit
4243 case 0x1B: // Name of railtype
4244 case 0x1C: // Maintenance cost factor
4245 buf->ReadWord();
4246 break;
4248 case 0x1D: // Alternate rail type label list
4249 if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
4250 int n = buf->ReadByte();
4251 for (int j = 0; j != n; j++) {
4252 *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord());
4254 break;
4256 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
4257 FALLTHROUGH;
4259 case 0x0E: // Compatible railtype list
4260 case 0x0F: // Powered railtype list
4261 case 0x18: // Railtype list required for date introduction
4262 case 0x19: // Introduced railtype list
4263 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4264 break;
4266 case 0x10: // Rail Type flags
4267 case 0x11: // Curve speed advantage
4268 case 0x12: // Station graphic
4269 case 0x15: // Acceleration model
4270 case 0x16: // Map colour
4271 case 0x1A: // Sort order
4272 buf->ReadByte();
4273 break;
4275 case 0x17: // Introduction date
4276 buf->ReadDWord();
4277 break;
4279 default:
4280 ret = CIR_UNKNOWN;
4281 break;
4285 return ret;
4289 * Define properties for roadtypes
4290 * @param id ID of the roadtype.
4291 * @param numinfo Number of subsequent IDs to change the property for.
4292 * @param prop The property to change.
4293 * @param buf The property value.
4294 * @return ChangeInfoResult.
4296 static ChangeInfoResult RoadTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf, RoadType basetype)
4298 ChangeInfoResult ret = CIR_SUCCESS;
4300 extern RoadtypeInfo _roadtypes[ROADTYPE_END][ROADSUBTYPE_END];
4302 if (basetype > ROADTYPE_END) {
4303 grfmsg(1, "RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring", basetype, ROADTYPE_END);
4304 return CIR_INVALID_ID;
4307 if (id + numinfo > ROADSUBTYPE_END) {
4308 grfmsg(1, "RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring", id + numinfo, ROADSUBTYPE_END);
4309 return CIR_INVALID_ID;
4312 for (int i = 0; i < numinfo; i++) {
4313 RoadTypeIdentifier rtid = RoadTypeIdentifier(basetype, (RoadSubType)_cur.grffile->roadtype_map[basetype][id + i]);
4314 if (!rtid.IsValid()) return CIR_INVALID_ID;
4316 RoadtypeInfo *rti = &_roadtypes[basetype][rtid.subtype];
4318 switch (prop) {
4319 case 0x08: // Label of road type
4320 /* Skipped here as this is loaded during reservation stage. */
4321 buf->ReadDWord();
4322 break;
4324 case 0x09: { // Toolbar caption of roadtype (sets name as well for backwards compatibility for grf ver < 8)
4325 uint16 str = buf->ReadWord();
4326 AddStringForMapping(str, &rti->strings.toolbar_caption);
4327 break;
4330 case 0x0A: // Menu text of roadtype
4331 AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text);
4332 break;
4334 case 0x0B: // Build window caption
4335 AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption);
4336 break;
4338 case 0x0C: // Autoreplace text
4339 AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text);
4340 break;
4342 case 0x0D: // New engine text
4343 AddStringForMapping(buf->ReadWord(), &rti->strings.new_engine);
4344 break;
4346 case 0x0F: // Powered roadtype list
4347 case 0x18: // Roadtype list required for date introduction
4348 case 0x19: { // Introduced roadtype list
4349 /* Road type compatibility bits are added to the existing bits
4350 * to allow multiple GRFs to modify compatibility with the
4351 * default road types. */
4352 int n = buf->ReadByte();
4353 for (int j = 0; j != n; j++) {
4354 RoadTypeLabel label = buf->ReadDWord();
4355 RoadTypeIdentifier c_rtid = GetRoadTypeByLabel(BSWAP32(label), basetype, false);
4356 if (c_rtid.IsValid()) {
4357 switch (prop) {
4358 case 0x0F: SetBit(rti->powered_roadtypes, c_rtid.subtype); break;
4359 case 0x18: SetBit(rti->introduction_required_roadtypes, c_rtid.subtype); break;
4360 case 0x19: SetBit(rti->introduces_roadtypes, c_rtid.subtype); break;
4364 break;
4367 case 0x10: // Road Type flags
4368 rti->flags = (RoadTypeFlags)buf->ReadByte();
4369 break;
4371 case 0x13: // Construction cost factor
4372 rti->cost_multiplier = buf->ReadWord();
4373 break;
4375 case 0x14: // Speed limit
4376 rti->max_speed = buf->ReadWord();
4377 break;
4379 case 0x16: // Map colour
4380 rti->map_colour = buf->ReadByte();
4381 break;
4383 case 0x17: // Introduction date
4384 rti->introduction_date = buf->ReadDWord();
4385 break;
4387 case 0x1A: // Sort order
4388 rti->sorting_order = buf->ReadByte();
4389 break;
4391 case 0x1B: // Name of roadtype
4392 AddStringForMapping(buf->ReadWord(), &rti->strings.name);
4393 break;
4395 case 0x1C: // Maintenance cost factor
4396 rti->maintenance_multiplier = buf->ReadWord();
4397 break;
4399 case 0x1D: // Alternate road type label list
4400 /* Skipped here as this is loaded during reservation stage. */
4401 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4402 break;
4404 default:
4405 ret = CIR_UNKNOWN;
4406 break;
4410 return ret;
4413 static ChangeInfoResult RoadTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4415 return RoadTypeChangeInfo(id, numinfo, prop, buf, ROADTYPE_ROAD);
4418 static ChangeInfoResult TramTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf)
4420 return RoadTypeChangeInfo(id, numinfo, prop, buf, ROADTYPE_TRAM);
4424 static ChangeInfoResult RoadTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf, RoadType basetype)
4426 ChangeInfoResult ret = CIR_SUCCESS;
4428 extern RoadtypeInfo _roadtypes[ROADTYPE_END][ROADSUBTYPE_END];
4430 if (basetype > ROADTYPE_END) {
4431 grfmsg(1, "RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring", basetype, ROADTYPE_END);
4432 return CIR_INVALID_ID;
4435 if (id + numinfo > ROADSUBTYPE_END) {
4436 grfmsg(1, "RoadTypeReserveInfo: Road sub type %u is invalid, max %u, ignoring", id + numinfo, ROADSUBTYPE_END);
4437 return CIR_INVALID_ID;
4440 for (int i = 0; i < numinfo; i++) {
4441 switch (prop) {
4442 case 0x08: { // Label of road type
4443 RoadTypeLabel rtl = buf->ReadDWord();
4444 rtl = BSWAP32(rtl);
4446 RoadTypeIdentifier rtid = GetRoadTypeByLabel(rtl, basetype, false);
4447 if (!rtid.IsValid()) {
4448 /* Set up new road type */
4449 rtid = AllocateRoadType(rtl, basetype);
4452 _cur.grffile->roadtype_map[basetype][id + i] = rtid.subtype;
4453 break;
4455 case 0x09: // Toolbar caption of roadtype
4456 case 0x0A: // Menu text
4457 case 0x0B: // Build window caption
4458 case 0x0C: // Autoreplace text
4459 case 0x0D: // New loco
4460 case 0x13: // Construction cost
4461 case 0x14: // Speed limit
4462 case 0x1B: // Name of roadtype
4463 case 0x1C: // Maintenance cost factor
4464 buf->ReadWord();
4465 break;
4467 case 0x1D: // Alternate road type label list
4468 if (_cur.grffile->roadtype_map[basetype][id + i] != INVALID_ROADSUBTYPE) {
4469 int n = buf->ReadByte();
4470 for (int j = 0; j != n; j++) {
4471 *_roadtypes[basetype][_cur.grffile->roadtype_map[basetype][id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord());
4473 break;
4475 grfmsg(1, "RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set", id + i);
4476 /* FALL THROUGH */
4478 case 0x0F: // Powered roadtype list
4479 case 0x18: // Roadtype list required for date introduction
4480 case 0x19: // Introduced roadtype list
4481 for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4482 break;
4484 case 0x10: // Road Type flags
4485 case 0x12: // Station graphic
4486 case 0x15: // Acceleration model
4487 case 0x16: // Map colour
4488 case 0x1A: // Sort order
4489 buf->ReadByte();
4490 break;
4492 case 0x17: // Introduction date
4493 buf->ReadDWord();
4494 break;
4496 default:
4497 ret = CIR_UNKNOWN;
4498 break;
4502 return ret;
4505 static ChangeInfoResult RoadTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4507 return RoadTypeReserveInfo(id, numinfo, prop, buf, ROADTYPE_ROAD);
4510 static ChangeInfoResult TramTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf)
4512 return RoadTypeReserveInfo(id, numinfo, prop, buf, ROADTYPE_TRAM);
4515 static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf)
4517 ChangeInfoResult ret = CIR_SUCCESS;
4519 if (airtid + numinfo > NUM_AIRPORTTILES_PER_GRF) {
4520 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid + numinfo, NUM_AIRPORTTILES_PER_GRF);
4521 return CIR_INVALID_ID;
4524 /* Allocate airport tile specs if they haven't been allocated already. */
4525 if (_cur.grffile->airtspec == nullptr) {
4526 _cur.grffile->airtspec = CallocT<AirportTileSpec*>(NUM_AIRPORTTILES_PER_GRF);
4529 for (int i = 0; i < numinfo; i++) {
4530 AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i];
4532 if (prop != 0x08 && tsp == nullptr) {
4533 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4534 return CIR_INVALID_ID;
4537 switch (prop) {
4538 case 0x08: { // Substitute airport tile type
4539 AirportTileSpec **tilespec = &_cur.grffile->airtspec[airtid + i];
4540 byte subs_id = buf->ReadByte();
4542 if (subs_id >= NEW_AIRPORTTILE_OFFSET) {
4543 /* The substitute id must be one of the original airport tiles. */
4544 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4545 continue;
4548 /* Allocate space for this airport tile. */
4549 if (*tilespec == nullptr) {
4550 *tilespec = CallocT<AirportTileSpec>(1);
4551 tsp = *tilespec;
4553 memcpy(tsp, AirportTileSpec::Get(subs_id), sizeof(AirportTileSpec));
4554 tsp->enabled = true;
4556 tsp->animation.status = ANIM_STATUS_NO_ANIMATION;
4558 tsp->grf_prop.local_id = airtid + i;
4559 tsp->grf_prop.subst_id = subs_id;
4560 tsp->grf_prop.grffile = _cur.grffile;
4561 _airporttile_mngr.AddEntityID(airtid + i, _cur.grffile->grfid, subs_id); // pre-reserve the tile slot
4563 break;
4566 case 0x09: { // Airport tile override
4567 byte override = buf->ReadByte();
4569 /* The airport tile being overridden must be an original airport tile. */
4570 if (override >= NEW_AIRPORTTILE_OFFSET) {
4571 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override, airtid + i);
4572 continue;
4575 _airporttile_mngr.Add(airtid + i, _cur.grffile->grfid, override);
4576 break;
4579 case 0x0E: // Callback mask
4580 tsp->callback_mask = buf->ReadByte();
4581 break;
4583 case 0x0F: // Animation information
4584 tsp->animation.frames = buf->ReadByte();
4585 tsp->animation.status = buf->ReadByte();
4586 break;
4588 case 0x10: // Animation speed
4589 tsp->animation.speed = buf->ReadByte();
4590 break;
4592 case 0x11: // Animation triggers
4593 tsp->animation.triggers = buf->ReadByte();
4594 break;
4596 default:
4597 ret = CIR_UNKNOWN;
4598 break;
4602 return ret;
4605 static bool HandleChangeInfoResult(const char *caller, ChangeInfoResult cir, uint8 feature, uint8 property)
4607 switch (cir) {
4608 default: NOT_REACHED();
4610 case CIR_DISABLED:
4611 /* Error has already been printed; just stop parsing */
4612 return true;
4614 case CIR_SUCCESS:
4615 return false;
4617 case CIR_UNHANDLED:
4618 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4619 return false;
4621 case CIR_UNKNOWN:
4622 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4623 FALLTHROUGH;
4625 case CIR_INVALID_ID: {
4626 /* No debug message for an invalid ID, as it has already been output */
4627 GRFError *error = DisableGrf(cir == CIR_INVALID_ID ? STR_NEWGRF_ERROR_INVALID_ID : STR_NEWGRF_ERROR_UNKNOWN_PROPERTY);
4628 if (cir != CIR_INVALID_ID) error->param_value[1] = property;
4629 return true;
4634 /* Action 0x00 */
4635 static void FeatureChangeInfo(ByteReader *buf)
4637 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4639 * B feature
4640 * B num-props how many properties to change per vehicle/station
4641 * B num-info how many vehicles/stations to change
4642 * E id ID of first vehicle/station to change, if num-info is
4643 * greater than one, this one and the following
4644 * vehicles/stations will be changed
4645 * B property what property to change, depends on the feature
4646 * V new-info new bytes of info (variable size; depends on properties) */
4648 static const VCI_Handler handler[] = {
4649 /* GSF_TRAINS */ RailVehicleChangeInfo,
4650 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo,
4651 /* GSF_SHIPS */ ShipVehicleChangeInfo,
4652 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
4653 /* GSF_STATIONS */ StationChangeInfo,
4654 /* GSF_CANALS */ CanalChangeInfo,
4655 /* GSF_BRIDGES */ BridgeChangeInfo,
4656 /* GSF_HOUSES */ TownHouseChangeInfo,
4657 /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
4658 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo,
4659 /* GSF_INDUSTRIES */ IndustriesChangeInfo,
4660 /* GSF_CARGOES */ nullptr, // Cargo is handled during reservation
4661 /* GSF_SOUNDFX */ SoundEffectChangeInfo,
4662 /* GSF_AIRPORTS */ AirportChangeInfo,
4663 /* GSF_SIGNALS */ nullptr,
4664 /* GSF_OBJECTS */ ObjectChangeInfo,
4665 /* GSF_RAILTYPES */ RailTypeChangeInfo,
4666 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
4667 /* GSF_ROADTYPES */ RoadTypeChangeInfo,
4668 /* GSF_TRAMTYPES */ TramTypeChangeInfo,
4671 uint8 feature = buf->ReadByte();
4672 uint8 numprops = buf->ReadByte();
4673 uint numinfo = buf->ReadByte();
4674 uint engine = buf->ReadExtendedByte();
4676 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4677 feature, numprops, engine, numinfo);
4679 if (feature >= lengthof(handler) || handler[feature] == nullptr) {
4680 if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature);
4681 return;
4684 /* Mark the feature as used by the grf */
4685 SetBit(_cur.grffile->grf_features, feature);
4687 while (numprops-- && buf->HasData()) {
4688 uint8 prop = buf->ReadByte();
4690 ChangeInfoResult cir = handler[feature](engine, numinfo, prop, buf);
4691 if (HandleChangeInfoResult("FeatureChangeInfo", cir, feature, prop)) return;
4695 /* Action 0x00 (GLS_SAFETYSCAN) */
4696 static void SafeChangeInfo(ByteReader *buf)
4698 uint8 feature = buf->ReadByte();
4699 uint8 numprops = buf->ReadByte();
4700 uint numinfo = buf->ReadByte();
4701 buf->ReadExtendedByte(); // id
4703 if (feature == GSF_BRIDGES && numprops == 1) {
4704 uint8 prop = buf->ReadByte();
4705 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4706 * is considered safe. */
4707 if (prop == 0x0D) return;
4708 } else if (feature == GSF_GLOBALVAR && numprops == 1) {
4709 uint8 prop = buf->ReadByte();
4710 /* Engine ID Mappings are safe, if the source is static */
4711 if (prop == 0x11) {
4712 bool is_safe = true;
4713 for (uint i = 0; i < numinfo; i++) {
4714 uint32 s = buf->ReadDWord();
4715 buf->ReadDWord(); // dest
4716 const GRFConfig *grfconfig = GetGRFConfig(s);
4717 if (grfconfig != nullptr && !HasBit(grfconfig->flags, GCF_STATIC)) {
4718 is_safe = false;
4719 break;
4722 if (is_safe) return;
4726 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
4728 /* Skip remainder of GRF */
4729 _cur.skip_sprites = -1;
4732 /* Action 0x00 (GLS_RESERVE) */
4733 static void ReserveChangeInfo(ByteReader *buf)
4735 uint8 feature = buf->ReadByte();
4737 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES && feature != GSF_ROADTYPES && feature != GSF_TRAMTYPES) return;
4739 uint8 numprops = buf->ReadByte();
4740 uint8 numinfo = buf->ReadByte();
4741 uint8 index = buf->ReadExtendedByte();
4743 while (numprops-- && buf->HasData()) {
4744 uint8 prop = buf->ReadByte();
4745 ChangeInfoResult cir = CIR_SUCCESS;
4747 switch (feature) {
4748 default: NOT_REACHED();
4749 case GSF_CARGOES:
4750 cir = CargoChangeInfo(index, numinfo, prop, buf);
4751 break;
4753 case GSF_GLOBALVAR:
4754 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4755 break;
4757 case GSF_RAILTYPES:
4758 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4759 break;
4761 case GSF_ROADTYPES:
4762 cir = RoadTypeReserveInfo(index, numinfo, prop, buf);
4763 break;
4765 case GSF_TRAMTYPES:
4766 cir = TramTypeReserveInfo(index, numinfo, prop, buf);
4767 break;
4770 if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return;
4774 /* Action 0x01 */
4775 static void NewSpriteSet(ByteReader *buf)
4777 /* Basic format: <01> <feature> <num-sets> <num-ent>
4778 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4780 * B feature feature to define sprites for
4781 * 0, 1, 2, 3: veh-type, 4: train stations
4782 * E first-set first sprite set to define
4783 * B num-sets number of sprite sets (extended byte in extended format)
4784 * E num-ent how many entries per sprite set
4785 * For vehicles, this is the number of different
4786 * vehicle directions in each sprite set
4787 * Set num-dirs=8, unless your sprites are symmetric.
4788 * In that case, use num-dirs=4.
4791 uint8 feature = buf->ReadByte();
4792 uint16 num_sets = buf->ReadByte();
4793 uint16 first_set = 0;
4795 if (num_sets == 0 && buf->HasData(3)) {
4796 /* Extended Action1 format.
4797 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4798 first_set = buf->ReadExtendedByte();
4799 num_sets = buf->ReadExtendedByte();
4801 uint16 num_ents = buf->ReadExtendedByte();
4803 _cur.AddSpriteSets(feature, _cur.spriteid, first_set, num_sets, num_ents);
4805 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4806 _cur.spriteid, feature, num_sets, num_ents, num_sets * num_ents
4809 for (int i = 0; i < num_sets * num_ents; i++) {
4810 _cur.nfo_line++;
4811 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
4815 /* Action 0x01 (SKIP) */
4816 static void SkipAct1(ByteReader *buf)
4818 buf->ReadByte();
4819 uint16 num_sets = buf->ReadByte();
4821 if (num_sets == 0 && buf->HasData(3)) {
4822 /* Extended Action1 format.
4823 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4824 buf->ReadExtendedByte(); // first_set
4825 num_sets = buf->ReadExtendedByte();
4827 uint16 num_ents = buf->ReadExtendedByte();
4829 _cur.skip_sprites = num_sets * num_ents;
4831 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
4834 /* Helper function to either create a callback or link to a previously
4835 * defined spritegroup. */
4836 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4838 if (HasBit(groupid, 15)) {
4839 assert(CallbackResultSpriteGroup::CanAllocateItem());
4840 return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
4843 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == nullptr) {
4844 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4845 return nullptr;
4848 return _cur.spritegroups[groupid];
4852 * Helper function to either create a callback or a result sprite group.
4853 * @param feature GrfSpecFeature to define spritegroup for.
4854 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4855 * @param type Type of the currently being parsed Action2. (only for debug output)
4856 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4857 * @return Created spritegroup.
4859 static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
4861 if (HasBit(spriteid, 15)) {
4862 assert(CallbackResultSpriteGroup::CanAllocateItem());
4863 return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
4866 if (!_cur.IsValidSpriteSet(feature, spriteid)) {
4867 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4868 return nullptr;
4871 SpriteID spriteset_start = _cur.GetSprite(feature, spriteid);
4872 uint num_sprites = _cur.GetNumEnts(feature, spriteid);
4874 /* Ensure that the sprites are loeded */
4875 assert(spriteset_start + num_sprites <= _cur.spriteid);
4877 assert(ResultSpriteGroup::CanAllocateItem());
4878 return new ResultSpriteGroup(spriteset_start, num_sprites);
4881 /* Action 0x02 */
4882 static void NewSpriteGroup(ByteReader *buf)
4884 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4886 * B feature see action 1
4887 * B set-id ID of this particular definition
4888 * B type/num-entries
4889 * if 80 or greater, this is a randomized or variational
4890 * list definition, see below
4891 * otherwise it specifies a number of entries, the exact
4892 * meaning depends on the feature
4893 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4894 SpriteGroup *act_group = nullptr;
4896 uint8 feature = buf->ReadByte();
4897 uint8 setid = buf->ReadByte();
4898 uint8 type = buf->ReadByte();
4900 /* Sprite Groups are created here but they are allocated from a pool, so
4901 * we do not need to delete anything if there is an exception from the
4902 * ByteReader. */
4904 switch (type) {
4905 /* Deterministic Sprite Group */
4906 case 0x81: // Self scope, byte
4907 case 0x82: // Parent scope, byte
4908 case 0x85: // Self scope, word
4909 case 0x86: // Parent scope, word
4910 case 0x89: // Self scope, dword
4911 case 0x8A: // Parent scope, dword
4913 byte varadjust;
4914 byte varsize;
4916 assert(DeterministicSpriteGroup::CanAllocateItem());
4917 DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
4918 act_group = group;
4919 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
4921 switch (GB(type, 2, 2)) {
4922 default: NOT_REACHED();
4923 case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
4924 case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
4925 case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
4928 static SmallVector<DeterministicSpriteGroupAdjust, 16> adjusts;
4929 adjusts.Clear();
4931 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4932 * from the outset, so we shall have to keep reallocing. */
4933 do {
4934 DeterministicSpriteGroupAdjust *adjust = adjusts.Append();
4936 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4937 adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
4938 adjust->variable = buf->ReadByte();
4939 if (adjust->variable == 0x7E) {
4940 /* Link subroutine group */
4941 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
4942 } else {
4943 adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0;
4946 varadjust = buf->ReadByte();
4947 adjust->shift_num = GB(varadjust, 0, 5);
4948 adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
4949 adjust->and_mask = buf->ReadVarSize(varsize);
4951 if (adjust->type != DSGA_TYPE_NONE) {
4952 adjust->add_val = buf->ReadVarSize(varsize);
4953 adjust->divmod_val = buf->ReadVarSize(varsize);
4954 } else {
4955 adjust->add_val = 0;
4956 adjust->divmod_val = 0;
4959 /* Continue reading var adjusts while bit 5 is set. */
4960 } while (HasBit(varadjust, 5));
4962 group->num_adjusts = adjusts.Length();
4963 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
4964 MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts);
4966 std::vector<DeterministicSpriteGroupRange> ranges;
4967 ranges.resize(buf->ReadByte());
4968 for (uint i = 0; i < ranges.size(); i++) {
4969 ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4970 ranges[i].low = buf->ReadVarSize(varsize);
4971 ranges[i].high = buf->ReadVarSize(varsize);
4974 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4975 group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
4976 /* nvar == 0 is a special case -- we turn our value into a callback result */
4977 group->calculated_result = ranges.size() == 0;
4979 /* Sort ranges ascending. When ranges overlap, this may required clamping or splitting them */
4980 std::vector<uint32> bounds;
4981 for (uint i = 0; i < ranges.size(); i++) {
4982 bounds.push_back(ranges[i].low);
4983 if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
4985 std::sort(bounds.begin(), bounds.end());
4986 bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
4988 std::vector<const SpriteGroup *> target;
4989 for (uint j = 0; j < bounds.size(); ++j) {
4990 uint32 v = bounds[j];
4991 const SpriteGroup *t = group->default_group;
4992 for (uint i = 0; i < ranges.size(); i++) {
4993 if (ranges[i].low <= v && v <= ranges[i].high) {
4994 t = ranges[i].group;
4995 break;
4998 target.push_back(t);
5000 assert(target.size() == bounds.size());
5002 std::vector<DeterministicSpriteGroupRange> optimised;
5003 for (uint j = 0; j < bounds.size(); ) {
5004 if (target[j] != group->default_group) {
5005 DeterministicSpriteGroupRange r;
5006 r.group = target[j];
5007 r.low = bounds[j];
5008 while (j < bounds.size() && target[j] == r.group) {
5009 j++;
5011 r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
5012 optimised.push_back(r);
5013 } else {
5014 j++;
5018 group->num_ranges = (uint)optimised.size();
5019 if (group->num_ranges > 0) {
5020 group->ranges = MallocT<DeterministicSpriteGroupRange>(group->num_ranges);
5021 MemCpyT(group->ranges, &optimised.front(), group->num_ranges);
5023 break;
5026 /* Randomized Sprite Group */
5027 case 0x80: // Self scope
5028 case 0x83: // Parent scope
5029 case 0x84: // Relative scope
5031 assert(RandomizedSpriteGroup::CanAllocateItem());
5032 RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
5033 act_group = group;
5034 group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
5036 if (HasBit(type, 2)) {
5037 if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
5038 group->count = buf->ReadByte();
5041 uint8 triggers = buf->ReadByte();
5042 group->triggers = GB(triggers, 0, 7);
5043 group->cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
5044 group->lowest_randbit = buf->ReadByte();
5045 group->num_groups = buf->ReadByte();
5046 group->groups = CallocT<const SpriteGroup*>(group->num_groups);
5048 for (uint i = 0; i < group->num_groups; i++) {
5049 group->groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
5052 break;
5055 /* Neither a variable or randomized sprite group... must be a real group */
5056 default:
5058 switch (feature) {
5059 case GSF_TRAINS:
5060 case GSF_ROADVEHICLES:
5061 case GSF_SHIPS:
5062 case GSF_AIRCRAFT:
5063 case GSF_STATIONS:
5064 case GSF_CANALS:
5065 case GSF_CARGOES:
5066 case GSF_AIRPORTS:
5067 case GSF_RAILTYPES:
5068 case GSF_ROADTYPES:
5069 case GSF_TRAMTYPES:
5071 byte num_loaded = type;
5072 byte num_loading = buf->ReadByte();
5074 if (!_cur.HasValidSpriteSets(feature)) {
5075 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
5076 return;
5079 assert(RealSpriteGroup::CanAllocateItem());
5080 RealSpriteGroup *group = new RealSpriteGroup();
5081 act_group = group;
5083 group->num_loaded = num_loaded;
5084 group->num_loading = num_loading;
5085 if (num_loaded > 0) group->loaded = CallocT<const SpriteGroup*>(num_loaded);
5086 if (num_loading > 0) group->loading = CallocT<const SpriteGroup*>(num_loading);
5088 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
5089 setid, num_loaded, num_loading);
5091 for (uint i = 0; i < num_loaded; i++) {
5092 uint16 spriteid = buf->ReadWord();
5093 group->loaded[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
5094 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
5097 for (uint i = 0; i < num_loading; i++) {
5098 uint16 spriteid = buf->ReadWord();
5099 group->loading[i] = CreateGroupFromGroupID(feature, setid, type, spriteid);
5100 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
5103 break;
5106 case GSF_HOUSES:
5107 case GSF_AIRPORTTILES:
5108 case GSF_OBJECTS:
5109 case GSF_INDUSTRYTILES: {
5110 byte num_building_sprites = max((uint8)1, type);
5112 assert(TileLayoutSpriteGroup::CanAllocateItem());
5113 TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup();
5114 act_group = group;
5116 /* On error, bail out immediately. Temporary GRF data was already freed */
5117 if (ReadSpriteLayout(buf, num_building_sprites, true, feature, false, type == 0, &group->dts)) return;
5118 break;
5121 case GSF_INDUSTRIES: {
5122 if (type > 1) {
5123 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type);
5124 break;
5127 assert(IndustryProductionSpriteGroup::CanAllocateItem());
5128 IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup();
5129 act_group = group;
5130 group->version = type;
5131 if (type == 0) {
5132 for (uint i = 0; i < 3; i++) {
5133 group->subtract_input[i] = (int16)buf->ReadWord(); // signed
5135 for (uint i = 0; i < 2; i++) {
5136 group->add_output[i] = buf->ReadWord(); // unsigned
5138 group->again = buf->ReadByte();
5139 } else {
5140 for (uint i = 0; i < 3; i++) {
5141 group->subtract_input[i] = buf->ReadByte();
5143 for (uint i = 0; i < 2; i++) {
5144 group->add_output[i] = buf->ReadByte();
5146 group->again = buf->ReadByte();
5148 break;
5151 /* Loading of Tile Layout and Production Callback groups would happen here */
5152 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature);
5157 _cur.spritegroups[setid] = act_group;
5160 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
5162 if (feature == GSF_OBJECTS) {
5163 switch (ctype) {
5164 case 0: return 0;
5165 case 0xFF: return CT_PURCHASE_OBJECT;
5166 default:
5167 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
5168 return CT_INVALID;
5171 /* Special cargo types for purchase list and stations */
5172 if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA;
5173 if (ctype == 0xFF) return CT_PURCHASE;
5175 if (_cur.grffile->cargo_list.Length() == 0) {
5176 /* No cargo table, so use bitnum values */
5177 if (ctype >= 32) {
5178 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
5179 return CT_INVALID;
5182 const CargoSpec *cs;
5183 FOR_ALL_CARGOSPECS(cs) {
5184 if (cs->bitnum == ctype) {
5185 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
5186 return cs->Index();
5190 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
5191 return CT_INVALID;
5194 /* Check if the cargo type is out of bounds of the cargo translation table */
5195 if (ctype >= _cur.grffile->cargo_list.Length()) {
5196 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1);
5197 return CT_INVALID;
5200 /* Look up the cargo label from the translation table */
5201 CargoLabel cl = _cur.grffile->cargo_list[ctype];
5202 if (cl == 0) {
5203 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
5204 return CT_INVALID;
5207 ctype = GetCargoIDByLabel(cl);
5208 if (ctype == CT_INVALID) {
5209 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));
5210 return CT_INVALID;
5213 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);
5214 return ctype;
5218 static bool IsValidGroupID(uint16 groupid, const char *function)
5220 if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == nullptr) {
5221 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid);
5222 return false;
5225 return true;
5228 static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount)
5230 static EngineID *last_engines;
5231 static uint last_engines_count;
5232 bool wagover = false;
5234 /* Test for 'wagon override' flag */
5235 if (HasBit(idcount, 7)) {
5236 wagover = true;
5237 /* Strip off the flag */
5238 idcount = GB(idcount, 0, 7);
5240 if (last_engines_count == 0) {
5241 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5242 return;
5245 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5246 last_engines_count, idcount);
5247 } else {
5248 if (last_engines_count != idcount) {
5249 last_engines = ReallocT(last_engines, idcount);
5250 last_engines_count = idcount;
5254 EngineID *engines = AllocaM(EngineID, idcount);
5255 for (uint i = 0; i < idcount; i++) {
5256 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte());
5257 if (e == nullptr) {
5258 /* No engine could be allocated?!? Deal with it. Okay,
5259 * this might look bad. Also make sure this NewGRF
5260 * gets disabled, as a half loaded one is bad. */
5261 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, 0, 0);
5262 return;
5265 engines[i] = e->index;
5266 if (!wagover) last_engines[i] = engines[i];
5269 uint8 cidcount = buf->ReadByte();
5270 for (uint c = 0; c < cidcount; c++) {
5271 uint8 ctype = buf->ReadByte();
5272 uint16 groupid = buf->ReadWord();
5273 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
5275 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5277 ctype = TranslateCargo(feature, ctype);
5278 if (ctype == CT_INVALID) continue;
5280 for (uint i = 0; i < idcount; i++) {
5281 EngineID engine = engines[i];
5283 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5285 if (wagover) {
5286 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5287 } else {
5288 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5293 uint16 groupid = buf->ReadWord();
5294 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
5296 grfmsg(8, "-- Default group id 0x%04X", groupid);
5298 for (uint i = 0; i < idcount; i++) {
5299 EngineID engine = engines[i];
5301 if (wagover) {
5302 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5303 } else {
5304 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5305 SetEngineGRF(engine, _cur.grffile);
5311 static void CanalMapSpriteGroup(ByteReader *buf, uint8 idcount)
5313 CanalFeature *cfs = AllocaM(CanalFeature, idcount);
5314 for (uint i = 0; i < idcount; i++) {
5315 cfs[i] = (CanalFeature)buf->ReadByte();
5318 uint8 cidcount = buf->ReadByte();
5319 buf->Skip(cidcount * 3);
5321 uint16 groupid = buf->ReadWord();
5322 if (!IsValidGroupID(groupid, "CanalMapSpriteGroup")) return;
5324 for (uint i = 0; i < idcount; i++) {
5325 CanalFeature cf = cfs[i];
5327 if (cf >= CF_END) {
5328 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5329 continue;
5332 _water_feature[cf].grffile = _cur.grffile;
5333 _water_feature[cf].group = _cur.spritegroups[groupid];
5338 static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount)
5340 uint8 *stations = AllocaM(uint8, idcount);
5341 for (uint i = 0; i < idcount; i++) {
5342 stations[i] = buf->ReadByte();
5345 uint8 cidcount = buf->ReadByte();
5346 for (uint c = 0; c < cidcount; c++) {
5347 uint8 ctype = buf->ReadByte();
5348 uint16 groupid = buf->ReadWord();
5349 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) continue;
5351 ctype = TranslateCargo(GSF_STATIONS, ctype);
5352 if (ctype == CT_INVALID) continue;
5354 for (uint i = 0; i < idcount; i++) {
5355 StationSpec *statspec = _cur.grffile->stations == nullptr ? nullptr : _cur.grffile->stations[stations[i]];
5357 if (statspec == nullptr) {
5358 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5359 continue;
5362 statspec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5366 uint16 groupid = buf->ReadWord();
5367 if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return;
5369 for (uint i = 0; i < idcount; i++) {
5370 StationSpec *statspec = _cur.grffile->stations == nullptr ? nullptr : _cur.grffile->stations[stations[i]];
5372 if (statspec == nullptr) {
5373 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5374 continue;
5377 if (statspec->grf_prop.grffile != nullptr) {
5378 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5379 continue;
5382 statspec->grf_prop.spritegroup[CT_DEFAULT] = _cur.spritegroups[groupid];
5383 statspec->grf_prop.grffile = _cur.grffile;
5384 statspec->grf_prop.local_id = stations[i];
5385 StationClass::Assign(statspec);
5390 static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount)
5392 uint8 *houses = AllocaM(uint8, idcount);
5393 for (uint i = 0; i < idcount; i++) {
5394 houses[i] = buf->ReadByte();
5397 /* Skip the cargo type section, we only care about the default group */
5398 uint8 cidcount = buf->ReadByte();
5399 buf->Skip(cidcount * 3);
5401 uint16 groupid = buf->ReadWord();
5402 if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return;
5404 if (_cur.grffile->housespec == nullptr) {
5405 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5406 return;
5409 for (uint i = 0; i < idcount; i++) {
5410 HouseSpec *hs = _cur.grffile->housespec[houses[i]];
5412 if (hs == nullptr) {
5413 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5414 continue;
5417 hs->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5421 static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount)
5423 uint8 *industries = AllocaM(uint8, idcount);
5424 for (uint i = 0; i < idcount; i++) {
5425 industries[i] = buf->ReadByte();
5428 /* Skip the cargo type section, we only care about the default group */
5429 uint8 cidcount = buf->ReadByte();
5430 buf->Skip(cidcount * 3);
5432 uint16 groupid = buf->ReadWord();
5433 if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return;
5435 if (_cur.grffile->industryspec == nullptr) {
5436 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5437 return;
5440 for (uint i = 0; i < idcount; i++) {
5441 IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]];
5443 if (indsp == nullptr) {
5444 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5445 continue;
5448 indsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5452 static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5454 uint8 *indtiles = AllocaM(uint8, idcount);
5455 for (uint i = 0; i < idcount; i++) {
5456 indtiles[i] = buf->ReadByte();
5459 /* Skip the cargo type section, we only care about the default group */
5460 uint8 cidcount = buf->ReadByte();
5461 buf->Skip(cidcount * 3);
5463 uint16 groupid = buf->ReadWord();
5464 if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return;
5466 if (_cur.grffile->indtspec == nullptr) {
5467 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5468 return;
5471 for (uint i = 0; i < idcount; i++) {
5472 IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]];
5474 if (indtsp == nullptr) {
5475 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5476 continue;
5479 indtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5483 static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
5485 CargoID *cargoes = AllocaM(CargoID, idcount);
5486 for (uint i = 0; i < idcount; i++) {
5487 cargoes[i] = buf->ReadByte();
5490 /* Skip the cargo type section, we only care about the default group */
5491 uint8 cidcount = buf->ReadByte();
5492 buf->Skip(cidcount * 3);
5494 uint16 groupid = buf->ReadWord();
5495 if (!IsValidGroupID(groupid, "CargoMapSpriteGroup")) return;
5497 for (uint i = 0; i < idcount; i++) {
5498 CargoID cid = cargoes[i];
5500 if (cid >= NUM_CARGO) {
5501 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5502 continue;
5505 CargoSpec *cs = CargoSpec::Get(cid);
5506 cs->grffile = _cur.grffile;
5507 cs->group = _cur.spritegroups[groupid];
5511 static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
5513 if (_cur.grffile->objectspec == nullptr) {
5514 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5515 return;
5518 uint8 *objects = AllocaM(uint8, idcount);
5519 for (uint i = 0; i < idcount; i++) {
5520 objects[i] = buf->ReadByte();
5523 uint8 cidcount = buf->ReadByte();
5524 for (uint c = 0; c < cidcount; c++) {
5525 uint8 ctype = buf->ReadByte();
5526 uint16 groupid = buf->ReadWord();
5527 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) continue;
5529 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5530 if (ctype == CT_INVALID) continue;
5532 for (uint i = 0; i < idcount; i++) {
5533 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5535 if (spec == nullptr) {
5536 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5537 continue;
5540 spec->grf_prop.spritegroup[ctype] = _cur.spritegroups[groupid];
5544 uint16 groupid = buf->ReadWord();
5545 if (!IsValidGroupID(groupid, "ObjectMapSpriteGroup")) return;
5547 for (uint i = 0; i < idcount; i++) {
5548 ObjectSpec *spec = _cur.grffile->objectspec[objects[i]];
5550 if (spec == nullptr) {
5551 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5552 continue;
5555 if (spec->grf_prop.grffile != nullptr) {
5556 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5557 continue;
5560 spec->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5561 spec->grf_prop.grffile = _cur.grffile;
5562 spec->grf_prop.local_id = objects[i];
5566 static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
5568 uint8 *railtypes = AllocaM(uint8, idcount);
5569 for (uint i = 0; i < idcount; i++) {
5570 railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()];
5573 uint8 cidcount = buf->ReadByte();
5574 for (uint c = 0; c < cidcount; c++) {
5575 uint8 ctype = buf->ReadByte();
5576 uint16 groupid = buf->ReadWord();
5577 if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
5579 if (ctype >= RTSG_END) continue;
5581 extern RailtypeInfo _railtypes[RAILTYPE_END];
5582 for (uint i = 0; i < idcount; i++) {
5583 if (railtypes[i] != INVALID_RAILTYPE) {
5584 RailtypeInfo *rti = &_railtypes[railtypes[i]];
5586 rti->grffile[ctype] = _cur.grffile;
5587 rti->group[ctype] = _cur.spritegroups[groupid];
5592 /* Railtypes do not use the default group. */
5593 buf->ReadWord();
5596 static void RoadTypeMapSpriteGroup(ByteReader *buf, uint8 idcount, RoadType basetype)
5598 uint8 *roadtypes = AllocaM(uint8, idcount);
5599 for (uint i = 0; i < idcount; i++) {
5600 roadtypes[i] = _cur.grffile->roadtype_map[basetype][buf->ReadByte()];
5603 uint8 cidcount = buf->ReadByte();
5604 for (uint c = 0; c < cidcount; c++) {
5605 uint8 ctype = buf->ReadByte();
5606 uint16 groupid = buf->ReadWord();
5607 if (!IsValidGroupID(groupid, "RoadTypeMapSpriteGroup")) continue;
5609 if (ctype >= ROTSG_END) continue;
5611 extern RoadtypeInfo _roadtypes[ROADTYPE_END][ROADSUBTYPE_END];
5612 for (uint i = 0; i < idcount; i++) {
5613 if (roadtypes[i] != INVALID_ROADSUBTYPE) {
5614 RoadtypeInfo *rti = &_roadtypes[basetype][roadtypes[i]];
5616 rti->grffile[ctype] = _cur.grffile;
5617 rti->group[ctype] = _cur.spritegroups[groupid];
5622 /* Roadtypes do not use the default group. */
5623 buf->ReadWord();
5626 static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount)
5628 uint8 *airports = AllocaM(uint8, idcount);
5629 for (uint i = 0; i < idcount; i++) {
5630 airports[i] = buf->ReadByte();
5633 /* Skip the cargo type section, we only care about the default group */
5634 uint8 cidcount = buf->ReadByte();
5635 buf->Skip(cidcount * 3);
5637 uint16 groupid = buf->ReadWord();
5638 if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return;
5640 if (_cur.grffile->airportspec == nullptr) {
5641 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5642 return;
5645 for (uint i = 0; i < idcount; i++) {
5646 AirportSpec *as = _cur.grffile->airportspec[airports[i]];
5648 if (as == nullptr) {
5649 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5650 continue;
5653 as->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5657 static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount)
5659 uint8 *airptiles = AllocaM(uint8, idcount);
5660 for (uint i = 0; i < idcount; i++) {
5661 airptiles[i] = buf->ReadByte();
5664 /* Skip the cargo type section, we only care about the default group */
5665 uint8 cidcount = buf->ReadByte();
5666 buf->Skip(cidcount * 3);
5668 uint16 groupid = buf->ReadWord();
5669 if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return;
5671 if (_cur.grffile->airtspec == nullptr) {
5672 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5673 return;
5676 for (uint i = 0; i < idcount; i++) {
5677 AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]];
5679 if (airtsp == nullptr) {
5680 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5681 continue;
5684 airtsp->grf_prop.spritegroup[0] = _cur.spritegroups[groupid];
5689 /* Action 0x03 */
5690 static void FeatureMapSpriteGroup(ByteReader *buf)
5692 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5693 * id-list := [<id>] [id-list]
5694 * cargo-list := <cargo-type> <cid> [cargo-list]
5696 * B feature see action 0
5697 * B n-id bits 0-6: how many IDs this definition applies to
5698 * bit 7: if set, this is a wagon override definition (see below)
5699 * B ids the IDs for which this definition applies
5700 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5701 * can be zero, in that case the def-cid is used always
5702 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5703 * W cid cargo ID (sprite group ID) for this type of cargo
5704 * W def-cid default cargo ID (sprite group ID) */
5706 uint8 feature = buf->ReadByte();
5707 uint8 idcount = buf->ReadByte();
5709 /* If idcount is zero, this is a feature callback */
5710 if (idcount == 0) {
5711 /* Skip number of cargo ids? */
5712 buf->ReadByte();
5713 uint16 groupid = buf->ReadWord();
5714 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
5716 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
5718 AddGenericCallback(feature, _cur.grffile, _cur.spritegroups[groupid]);
5719 return;
5722 /* Mark the feature as used by the grf (generic callbacks do not count) */
5723 SetBit(_cur.grffile->grf_features, feature);
5725 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
5727 switch (feature) {
5728 case GSF_TRAINS:
5729 case GSF_ROADVEHICLES:
5730 case GSF_SHIPS:
5731 case GSF_AIRCRAFT:
5732 VehicleMapSpriteGroup(buf, feature, idcount);
5733 return;
5735 case GSF_CANALS:
5736 CanalMapSpriteGroup(buf, idcount);
5737 return;
5739 case GSF_STATIONS:
5740 StationMapSpriteGroup(buf, idcount);
5741 return;
5743 case GSF_HOUSES:
5744 TownHouseMapSpriteGroup(buf, idcount);
5745 return;
5747 case GSF_INDUSTRIES:
5748 IndustryMapSpriteGroup(buf, idcount);
5749 return;
5751 case GSF_INDUSTRYTILES:
5752 IndustrytileMapSpriteGroup(buf, idcount);
5753 return;
5755 case GSF_CARGOES:
5756 CargoMapSpriteGroup(buf, idcount);
5757 return;
5759 case GSF_AIRPORTS:
5760 AirportMapSpriteGroup(buf, idcount);
5761 return;
5763 case GSF_OBJECTS:
5764 ObjectMapSpriteGroup(buf, idcount);
5765 break;
5767 case GSF_RAILTYPES:
5768 RailTypeMapSpriteGroup(buf, idcount);
5769 break;
5771 case GSF_ROADTYPES:
5772 RoadTypeMapSpriteGroup(buf, idcount, ROADTYPE_ROAD);
5773 break;
5775 case GSF_TRAMTYPES:
5776 RoadTypeMapSpriteGroup(buf, idcount, ROADTYPE_TRAM);
5777 break;
5779 case GSF_AIRPORTTILES:
5780 AirportTileMapSpriteGroup(buf, idcount);
5781 return;
5783 default:
5784 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
5785 return;
5789 /* Action 0x04 */
5790 static void FeatureNewName(ByteReader *buf)
5792 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5794 * B veh-type see action 0 (as 00..07, + 0A
5795 * But IF veh-type = 48, then generic text
5796 * B language-id If bit 6 is set, This is the extended language scheme,
5797 * with up to 64 language.
5798 * Otherwise, it is a mapping where set bits have meaning
5799 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5800 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5801 * B num-veh number of vehicles which are getting a new name
5802 * B/W offset number of the first vehicle that gets a new name
5803 * Byte : ID of vehicle to change
5804 * Word : ID of string to change/add
5805 * S data new texts, each of them zero-terminated, after
5806 * which the next name begins. */
5808 bool new_scheme = _cur.grffile->grf_version >= 7;
5810 uint8 feature = buf->ReadByte();
5811 uint8 lang = buf->ReadByte();
5812 uint8 num = buf->ReadByte();
5813 bool generic = HasBit(lang, 7);
5814 uint16 id;
5815 if (generic) {
5816 id = buf->ReadWord();
5817 } else if (feature <= GSF_AIRCRAFT) {
5818 id = buf->ReadExtendedByte();
5819 } else {
5820 id = buf->ReadByte();
5823 ClrBit(lang, 7);
5825 uint16 endid = id + num;
5827 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5828 id, endid, feature, lang);
5830 for (; id < endid && buf->HasData(); id++) {
5831 const char *name = buf->ReadString();
5832 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id, name);
5834 switch (feature) {
5835 case GSF_TRAINS:
5836 case GSF_ROADVEHICLES:
5837 case GSF_SHIPS:
5838 case GSF_AIRCRAFT:
5839 if (!generic) {
5840 Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC));
5841 if (e == nullptr) break;
5842 StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id);
5843 e->info.string_id = string;
5844 } else {
5845 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5847 break;
5849 default:
5850 if (IsInsideMM(id, 0xD000, 0xD400) || IsInsideMM(id, 0xD800, 0xE000)) {
5851 AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED);
5852 break;
5855 switch (GB(id, 8, 8)) {
5856 case 0xC4: // Station class name
5857 if (_cur.grffile->stations == nullptr || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) {
5858 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5859 } else {
5860 StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id;
5861 StationClass::Get(cls_id)->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5863 break;
5865 case 0xC5: // Station name
5866 if (_cur.grffile->stations == nullptr || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) {
5867 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8));
5868 } else {
5869 _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5871 break;
5873 case 0xC7: // Airporttile name
5874 if (_cur.grffile->airtspec == nullptr || _cur.grffile->airtspec[GB(id, 0, 8)] == nullptr) {
5875 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8));
5876 } else {
5877 _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5879 break;
5881 case 0xC9: // House name
5882 if (_cur.grffile->housespec == nullptr || _cur.grffile->housespec[GB(id, 0, 8)] == nullptr) {
5883 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8));
5884 } else {
5885 _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
5887 break;
5889 default:
5890 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id);
5891 break;
5893 break;
5899 * Sanitize incoming sprite offsets for Action 5 graphics replacements.
5900 * @param num The number of sprites to load.
5901 * @param offset Offset from the base.
5902 * @param max_sprites The maximum number of sprites that can be loaded in this action 5.
5903 * @param name Used for error warnings.
5904 * @return The number of sprites that is going to be skipped.
5906 static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
5909 if (offset >= max_sprites) {
5910 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
5911 uint orig_num = num;
5912 num = 0;
5913 return orig_num;
5916 if (offset + num > max_sprites) {
5917 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
5918 uint orig_num = num;
5919 num = max(max_sprites - offset, 0);
5920 return orig_num - num;
5923 return 0;
5927 /** The type of action 5 type. */
5928 enum Action5BlockType {
5929 A5BLOCK_FIXED, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5930 A5BLOCK_ALLOW_OFFSET, ///< Allow replacing any subset by specifiing an offset.
5931 A5BLOCK_INVALID, ///< unknown/not-implemented type
5933 /** Information about a single action 5 type. */
5934 struct Action5Type {
5935 Action5BlockType block_type; ///< How is this Action5 type processed?
5936 SpriteID sprite_base; ///< Load the sprites starting from this sprite.
5937 uint16 min_sprites; ///< If the Action5 contains less sprites, the whole block will be ignored.
5938 uint16 max_sprites; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5939 const char *name; ///< Name for error messages.
5942 /** The information about action 5 types. */
5943 static const Action5Type _action5_types[] = {
5944 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5945 /* 0x00 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x00" },
5946 /* 0x01 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x01" },
5947 /* 0x02 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x02" },
5948 /* 0x03 */ { A5BLOCK_INVALID, 0, 0, 0, "Type 0x03" },
5949 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT, "Signal graphics" },
5950 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET, SPR_ELRAIL_BASE, 1, ELRAIL_SPRITE_COUNT, "Rail catenary graphics" },
5951 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT, "Foundation graphics" },
5952 /* 0x07 */ { A5BLOCK_INVALID, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5953 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET, SPR_CANALS_BASE, 1, CANALS_SPRITE_COUNT, "Canal graphics" },
5954 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET, SPR_ONEWAY_BASE, 1, ONEWAY_SPRITE_COUNT, "One way road graphics" },
5955 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET, SPR_2CCMAP_BASE, 1, TWOCCMAP_SPRITE_COUNT, "2CC colour maps" },
5956 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET, SPR_TRAMWAY_BASE, 1, TRAMWAY_SPRITE_COUNT, "Tramway graphics" },
5957 /* 0x0C */ { A5BLOCK_INVALID, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5958 /* 0x0D */ { A5BLOCK_FIXED, SPR_SHORE_BASE, 16, SPR_SHORE_SPRITE_COUNT, "Shore graphics" },
5959 /* 0x0E */ { A5BLOCK_INVALID, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5960 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET, SPR_TRACKS_FOR_SLOPES_BASE, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT, "Sloped rail track" },
5961 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORTX_BASE, 1, AIRPORTX_SPRITE_COUNT, "Airport graphics" },
5962 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET, SPR_ROADSTOP_BASE, 1, ROADSTOP_SPRITE_COUNT, "Road stop graphics" },
5963 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET, SPR_AQUEDUCT_BASE, 1, AQUEDUCT_SPRITE_COUNT, "Aqueduct graphics" },
5964 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET, SPR_AUTORAIL_BASE, 1, AUTORAIL_SPRITE_COUNT, "Autorail graphics" },
5965 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET, SPR_FLAGS_BASE, 1, FLAGS_SPRITE_COUNT, "Flag graphics" },
5966 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET, SPR_OPENTTD_BASE, 1, OPENTTD_SPRITE_COUNT, "OpenTTD GUI graphics" },
5967 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET, SPR_AIRPORT_PREVIEW_BASE, 1, SPR_AIRPORT_PREVIEW_COUNT, "Airport preview graphics" },
5968 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET, SPR_RAILTYPE_TUNNEL_BASE, 1, RAILTYPE_TUNNEL_BASE_COUNT, "Railtype tunnel base" },
5969 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET, SPR_PALETTE_BASE, 1, PALETTE_SPRITE_COUNT, "Palette" },
5972 /* Action 0x05 */
5973 static void GraphicsNew(ByteReader *buf)
5975 /* <05> <graphics-type> <num-sprites> <other data...>
5977 * B graphics-type What set of graphics the sprites define.
5978 * E num-sprites How many sprites are in this set?
5979 * V other data Graphics type specific data. Currently unused. */
5980 /* TODO */
5982 uint8 type = buf->ReadByte();
5983 uint16 num = buf->ReadExtendedByte();
5984 uint16 offset = HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
5985 ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
5987 if ((type == 0x0D) && (num == 10) && HasBit(_cur.grfconfig->flags, GCF_SYSTEM)) {
5988 /* Special not-TTDP-compatible case used in openttd.grf
5989 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5990 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5991 LoadNextSprite(SPR_SHORE_BASE + 0, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_S
5992 LoadNextSprite(SPR_SHORE_BASE + 5, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_W
5993 LoadNextSprite(SPR_SHORE_BASE + 7, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_WSE
5994 LoadNextSprite(SPR_SHORE_BASE + 10, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_N
5995 LoadNextSprite(SPR_SHORE_BASE + 11, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NWS
5996 LoadNextSprite(SPR_SHORE_BASE + 13, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_ENW
5997 LoadNextSprite(SPR_SHORE_BASE + 14, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_SEN
5998 LoadNextSprite(SPR_SHORE_BASE + 15, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_STEEP_E
5999 LoadNextSprite(SPR_SHORE_BASE + 16, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_EW
6000 LoadNextSprite(SPR_SHORE_BASE + 17, _cur.file_index, _cur.nfo_line++, _cur.grf_container_ver); // SLOPE_NS
6001 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ONLY_NEW;
6002 return;
6005 /* Supported type? */
6006 if ((type >= lengthof(_action5_types)) || (_action5_types[type].block_type == A5BLOCK_INVALID)) {
6007 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
6008 _cur.skip_sprites = num;
6009 return;
6012 const Action5Type *action5_type = &_action5_types[type];
6014 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
6015 * except for the long version of the shore type:
6016 * Ignore offset if not allowed */
6017 if ((action5_type->block_type != A5BLOCK_ALLOW_OFFSET) && (offset != 0)) {
6018 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->name, type);
6019 offset = 0;
6022 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
6023 * This does not make sense, if <offset> is allowed */
6024 if ((action5_type->block_type == A5BLOCK_FIXED) && (num < action5_type->min_sprites)) {
6025 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);
6026 _cur.skip_sprites = num;
6027 return;
6030 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
6031 uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name);
6032 SpriteID replace = action5_type->sprite_base + offset;
6034 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
6035 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);
6037 if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5;
6039 if (type == 0x0B) {
6040 static const SpriteID depot_with_track_offset = SPR_TRAMWAY_DEPOT_WITH_TRACK - SPR_TRAMWAY_BASE;
6041 static const SpriteID depot_no_track_offset = SPR_TRAMWAY_DEPOT_NO_TRACK - SPR_TRAMWAY_BASE;
6042 if (offset <= depot_with_track_offset && offset + num > depot_with_track_offset) _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_WITH_TRACK;
6043 if (offset <= depot_no_track_offset && offset + num > depot_no_track_offset) _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_NO_TRACK;
6046 for (; num > 0; num--) {
6047 _cur.nfo_line++;
6048 LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
6051 _cur.skip_sprites = skip_num;
6054 /* Action 0x05 (SKIP) */
6055 static void SkipAct5(ByteReader *buf)
6057 /* Ignore type byte */
6058 buf->ReadByte();
6060 /* Skip the sprites of this action */
6061 _cur.skip_sprites = buf->ReadExtendedByte();
6063 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur.skip_sprites);
6067 * Reads a variable common to VarAction2 and Action7/9/D.
6069 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
6070 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
6072 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
6073 * @param value returns the value of the variable.
6074 * @param grffile NewGRF querying the variable
6075 * @return true iff the variable is known and the value is returned in 'value'.
6077 bool GetGlobalVariable(byte param, uint32 *value, const GRFFile *grffile)
6079 switch (param) {
6080 case 0x00: // current date
6081 *value = max(_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0);
6082 return true;
6084 case 0x01: // current year
6085 *value = Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
6086 return true;
6088 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)
6089 Date start_of_year = ConvertYMDToDate(_cur_date_ymd.year, 0, 1);
6090 *value = _cur_date_ymd.month | (_cur_date_ymd.day - 1) << 8 | (IsLeapYear(_cur_date_ymd.year) ? 1 << 15 : 0) | (_date - start_of_year) << 16;
6091 return true;
6094 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
6095 *value = _settings_game.game_creation.landscape;
6096 return true;
6098 case 0x06: // road traffic side, bit 4 clear=left, set=right
6099 *value = _settings_game.vehicle.road_side << 4;
6100 return true;
6102 case 0x09: // date fraction
6103 *value = _date_fract * 885;
6104 return true;
6106 case 0x0A: // animation counter
6107 *value = _tick_counter;
6108 return true;
6110 case 0x0B: { // TTDPatch version
6111 uint major = 2;
6112 uint minor = 6;
6113 uint revision = 1; // special case: 2.0.1 is 2.0.10
6114 uint build = 1382;
6115 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
6116 return true;
6119 case 0x0D: // TTD Version, 00=DOS, 01=Windows
6120 *value = _cur.grfconfig->palette & GRFP_USE_MASK;
6121 return true;
6123 case 0x0E: // Y-offset for train sprites
6124 *value = _cur.grffile->traininfo_vehicle_pitch;
6125 return true;
6127 case 0x0F: // Rail track type cost factors
6128 *value = 0;
6129 SB(*value, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL)->cost_multiplier); // normal rail
6130 if (_settings_game.vehicle.disable_elrails) {
6131 /* skip elrail multiplier - disabled */
6132 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_MONO)->cost_multiplier); // monorail
6133 } else {
6134 SB(*value, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC)->cost_multiplier); // electified railway
6135 /* Skip monorail multiplier - no space in result */
6137 SB(*value, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV)->cost_multiplier); // maglev
6138 return true;
6140 case 0x11: // current rail tool type
6141 *value = 0; // constant fake value to avoid desync
6142 return true;
6144 case 0x12: // Game mode
6145 *value = _game_mode;
6146 return true;
6148 /* case 0x13: // Tile refresh offset to left not implemented */
6149 /* case 0x14: // Tile refresh offset to right not implemented */
6150 /* case 0x15: // Tile refresh offset upwards not implemented */
6151 /* case 0x16: // Tile refresh offset downwards not implemented */
6152 /* case 0x17: // temperate snow line not implemented */
6154 case 0x1A: // Always -1
6155 *value = UINT_MAX;
6156 return true;
6158 case 0x1B: // Display options
6159 *value = 0x3F; // constant fake value to avoid desync
6160 return true;
6162 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
6163 *value = 1;
6164 return true;
6166 case 0x1E: // Miscellaneous GRF features
6167 *value = _misc_grf_features;
6169 /* Add the local flags */
6170 assert(!HasBit(*value, GMB_TRAIN_WIDTH_32_PIXELS));
6171 if (_cur.grffile->traininfo_vehicle_width == VEHICLEINFO_FULL_VEHICLE_WIDTH) SetBit(*value, GMB_TRAIN_WIDTH_32_PIXELS);
6172 return true;
6174 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
6176 case 0x20: { // snow line height
6177 byte snowline = GetSnowLine();
6178 if (_settings_game.game_creation.landscape == LT_ARCTIC && snowline <= _settings_game.construction.max_heightlevel) {
6179 *value = Clamp(snowline * (grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFE);
6180 } else {
6181 /* No snow */
6182 *value = 0xFF;
6184 return true;
6187 case 0x21: // OpenTTD version
6188 *value = _openttd_newgrf_version;
6189 return true;
6191 case 0x22: // difficulty level
6192 *value = SP_CUSTOM;
6193 return true;
6195 case 0x23: // long format date
6196 *value = _date;
6197 return true;
6199 case 0x24: // long format year
6200 *value = _cur_year;
6201 return true;
6203 default: return false;
6207 static uint32 GetParamVal(byte param, uint32 *cond_val)
6209 /* First handle variable common with VarAction2 */
6210 uint32 value;
6211 if (GetGlobalVariable(param - 0x80, &value, _cur.grffile)) return value;
6213 /* Non-common variable */
6214 switch (param) {
6215 case 0x84: { // GRF loading stage
6216 uint32 res = 0;
6218 if (_cur.stage > GLS_INIT) SetBit(res, 0);
6219 if (_cur.stage == GLS_RESERVE) SetBit(res, 8);
6220 if (_cur.stage == GLS_ACTIVATION) SetBit(res, 9);
6221 return res;
6224 case 0x85: // TTDPatch flags, only for bit tests
6225 if (cond_val == nullptr) {
6226 /* Supported in Action 0x07 and 0x09, not 0x0D */
6227 return 0;
6228 } else {
6229 uint32 param_val = _ttdpatch_flags[*cond_val / 0x20];
6230 *cond_val %= 0x20;
6231 return param_val;
6234 case 0x88: // GRF ID check
6235 return 0;
6237 /* case 0x99: Global ID offset not implemented */
6239 default:
6240 /* GRF Parameter */
6241 if (param < 0x80) return _cur.grffile->GetParam(param);
6243 /* In-game variable. */
6244 grfmsg(1, "Unsupported in-game variable 0x%02X", param);
6245 return UINT_MAX;
6249 /* Action 0x06 */
6250 static void CfgApply(ByteReader *buf)
6252 /* <06> <param-num> <param-size> <offset> ... <FF>
6254 * B param-num Number of parameter to substitute (First = "zero")
6255 * Ignored if that parameter was not specified in newgrf.cfg
6256 * B param-size How many bytes to replace. If larger than 4, the
6257 * bytes of the following parameter are used. In that
6258 * case, nothing is applied unless *all* parameters
6259 * were specified.
6260 * B offset Offset into data from beginning of next sprite
6261 * to place where parameter is to be stored. */
6263 /* Preload the next sprite */
6264 size_t pos = FioGetPos();
6265 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
6266 uint8 type = FioReadByte();
6267 byte *preload_sprite = nullptr;
6269 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
6270 if (type == 0xFF) {
6271 preload_sprite = MallocT<byte>(num);
6272 FioReadBlock(preload_sprite, num);
6275 /* Reset the file position to the start of the next sprite */
6276 FioSeekTo(pos, SEEK_SET);
6278 if (type != 0xFF) {
6279 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
6280 free(preload_sprite);
6281 return;
6284 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line + 1);
6285 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
6286 if (it != _grf_line_to_action6_sprite_override.end()) {
6287 free(preload_sprite);
6288 preload_sprite = it->second;
6289 } else {
6290 _grf_line_to_action6_sprite_override[location] = preload_sprite;
6293 /* Now perform the Action 0x06 on our data. */
6295 for (;;) {
6296 uint i;
6297 uint param_num;
6298 uint param_size;
6299 uint offset;
6300 bool add_value;
6302 /* Read the parameter to apply. 0xFF indicates no more data to change. */
6303 param_num = buf->ReadByte();
6304 if (param_num == 0xFF) break;
6306 /* Get the size of the parameter to use. If the size covers multiple
6307 * double words, sequential parameter values are used. */
6308 param_size = buf->ReadByte();
6310 /* Bit 7 of param_size indicates we should add to the original value
6311 * instead of replacing it. */
6312 add_value = HasBit(param_size, 7);
6313 param_size = GB(param_size, 0, 7);
6315 /* Where to apply the data to within the pseudo sprite data. */
6316 offset = buf->ReadExtendedByte();
6318 /* If the parameter is a GRF parameter (not an internal variable) check
6319 * if it (and all further sequential parameters) has been defined. */
6320 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.grffile->param_end) {
6321 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6322 break;
6325 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6327 bool carry = false;
6328 for (i = 0; i < param_size && offset + i < num; i++) {
6329 uint32 value = GetParamVal(param_num + i / 4, nullptr);
6330 /* Reset carry flag for each iteration of the variable (only really
6331 * matters if param_size is greater than 4) */
6332 if (i % 4 == 0) carry = false;
6334 if (add_value) {
6335 uint new_value = preload_sprite[offset + i] + GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6336 preload_sprite[offset + i] = GB(new_value, 0, 8);
6337 /* Check if the addition overflowed */
6338 carry = new_value >= 256;
6339 } else {
6340 preload_sprite[offset + i] = GB(value, (i % 4) * 8, 8);
6347 * Disable a static NewGRF when it is influencing another (non-static)
6348 * NewGRF as this could cause desyncs.
6350 * We could just tell the NewGRF querying that the file doesn't exist,
6351 * but that might give unwanted results. Disabling the NewGRF gives the
6352 * best result as no NewGRF author can complain about that.
6353 * @param c The NewGRF to disable.
6355 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig *c)
6357 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC, c);
6358 error->data = stredup(_cur.grfconfig->GetName());
6361 /* Action 0x07
6362 * Action 0x09 */
6363 static void SkipIf(ByteReader *buf)
6365 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6367 * B param-num
6368 * B param-size
6369 * B condition-type
6370 * V value
6371 * B num-sprites */
6372 /* TODO: More params. More condition types. */
6373 uint32 cond_val = 0;
6374 uint32 mask = 0;
6375 bool result;
6377 uint8 param = buf->ReadByte();
6378 uint8 paramsize = buf->ReadByte();
6379 uint8 condtype = buf->ReadByte();
6381 if (condtype < 2) {
6382 /* Always 1 for bit tests, the given value should be ignored. */
6383 paramsize = 1;
6386 switch (paramsize) {
6387 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord(); break;
6388 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF; break;
6389 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF; break;
6390 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF; break;
6391 default: break;
6394 if (param < 0x80 && _cur.grffile->param_end <= param) {
6395 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param);
6396 return;
6399 uint32 param_val = GetParamVal(param, &cond_val);
6401 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
6404 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6405 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6406 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6407 * So, when the condition type is one of those, the specific variable
6408 * 0x88 code is skipped, so the "general" code for the cargo
6409 * availability conditions kicks in.
6411 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
6412 /* GRF ID checks */
6414 GRFConfig *c = GetGRFConfig(cond_val, mask);
6416 if (c != nullptr && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
6417 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
6418 c = nullptr;
6421 if (condtype != 10 && c == nullptr) {
6422 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val));
6423 return;
6426 switch (condtype) {
6427 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6428 case 0x06: // Is GRFID active?
6429 result = c->status == GCS_ACTIVATED;
6430 break;
6432 case 0x07: // Is GRFID non-active?
6433 result = c->status != GCS_ACTIVATED;
6434 break;
6436 case 0x08: // GRFID is not but will be active?
6437 result = c->status == GCS_INITIALISED;
6438 break;
6440 case 0x09: // GRFID is or will be active?
6441 result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
6442 break;
6444 case 0x0A: // GRFID is not nor will be active
6445 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6446 result = c == nullptr || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND;
6447 break;
6449 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
6451 } else {
6452 /* Parameter or variable tests */
6453 switch (condtype) {
6454 case 0x00: result = !!(param_val & (1 << cond_val));
6455 break;
6456 case 0x01: result = !(param_val & (1 << cond_val));
6457 break;
6458 case 0x02: result = (param_val & mask) == cond_val;
6459 break;
6460 case 0x03: result = (param_val & mask) != cond_val;
6461 break;
6462 case 0x04: result = (param_val & mask) < cond_val;
6463 break;
6464 case 0x05: result = (param_val & mask) > cond_val;
6465 break;
6466 case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
6467 break;
6468 case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
6469 break;
6470 case 0x0D: result = GetRailTypeByLabel(BSWAP32(cond_val)) == INVALID_RAILTYPE;
6471 break;
6472 case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE;
6473 break;
6474 case 0x0F: result = !GetRoadTypeByLabel(BSWAP32(cond_val), ROADTYPE_ROAD).IsValid();
6475 break;
6476 case 0x10: result = GetRoadTypeByLabel(BSWAP32(cond_val), ROADTYPE_ROAD).IsValid();
6477 break;
6478 case 0x11: result = !GetRoadTypeByLabel(BSWAP32(cond_val), ROADTYPE_TRAM).IsValid();
6479 break;
6480 case 0x12: result = GetRoadTypeByLabel(BSWAP32(cond_val), ROADTYPE_TRAM).IsValid();
6481 break;
6483 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
6487 if (!result) {
6488 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6489 return;
6492 uint8 numsprites = buf->ReadByte();
6494 /* numsprites can be a GOTO label if it has been defined in the GRF
6495 * file. The jump will always be the first matching label that follows
6496 * the current nfo_line. If no matching label is found, the first matching
6497 * label in the file is used. */
6498 GRFLabel *choice = nullptr;
6499 for (GRFLabel *label = _cur.grffile->label; label != nullptr; label = label->next) {
6500 if (label->label != numsprites) continue;
6502 /* Remember a goto before the current line */
6503 if (choice == nullptr) choice = label;
6504 /* If we find a label here, this is definitely good */
6505 if (label->nfo_line > _cur.nfo_line) {
6506 choice = label;
6507 break;
6511 if (choice != nullptr) {
6512 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6513 FioSeekTo(choice->pos, SEEK_SET);
6514 _cur.nfo_line = choice->nfo_line;
6515 return;
6518 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites);
6519 _cur.skip_sprites = numsprites;
6520 if (_cur.skip_sprites == 0) {
6521 /* Zero means there are no sprites to skip, so
6522 * we use -1 to indicate that all further
6523 * sprites should be skipped. */
6524 _cur.skip_sprites = -1;
6526 /* If an action 8 hasn't been encountered yet, disable the grf. */
6527 if (_cur.grfconfig->status != (_cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED)) {
6528 DisableGrf();
6534 /* Action 0x08 (GLS_FILESCAN) */
6535 static void ScanInfo(ByteReader *buf)
6537 uint8 grf_version = buf->ReadByte();
6538 uint32 grfid = buf->ReadDWord();
6539 const char *name = buf->ReadString();
6541 _cur.grfconfig->ident.grfid = grfid;
6543 if (grf_version < 2 || grf_version > 8) {
6544 SetBit(_cur.grfconfig->flags, GCF_INVALID);
6545 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);
6548 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6549 if (GB(grfid, 0, 8) == 0xFF) SetBit(_cur.grfconfig->flags, GCF_SYSTEM);
6551 AddGRFTextToList(&_cur.grfconfig->name->text, 0x7F, grfid, false, name);
6553 if (buf->HasData()) {
6554 const char *info = buf->ReadString();
6555 AddGRFTextToList(&_cur.grfconfig->info->text, 0x7F, grfid, true, info);
6558 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6559 _cur.skip_sprites = -1;
6562 /* Action 0x08 */
6563 static void GRFInfo(ByteReader *buf)
6565 /* <08> <version> <grf-id> <name> <info>
6567 * B version newgrf version, currently 06
6568 * 4*B grf-id globally unique ID of this .grf file
6569 * S name name of this .grf set
6570 * S info string describing the set, and e.g. author and copyright */
6572 uint8 version = buf->ReadByte();
6573 uint32 grfid = buf->ReadDWord();
6574 const char *name = buf->ReadString();
6576 if (_cur.stage < GLS_RESERVE && _cur.grfconfig->status != GCS_UNKNOWN) {
6577 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6578 return;
6581 if (_cur.grffile->grfid != grfid) {
6582 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));
6583 _cur.grffile->grfid = grfid;
6586 _cur.grffile->grf_version = version;
6587 _cur.grfconfig->status = _cur.stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
6589 /* Do swap the GRFID for displaying purposes since people expect that */
6590 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);
6593 /* Action 0x0A */
6594 static void SpriteReplace(ByteReader *buf)
6596 /* <0A> <num-sets> <set1> [<set2> ...]
6597 * <set>: <num-sprites> <first-sprite>
6599 * B num-sets How many sets of sprites to replace.
6600 * Each set:
6601 * B num-sprites How many sprites are in this set
6602 * W first-sprite First sprite number to replace */
6604 uint8 num_sets = buf->ReadByte();
6606 for (uint i = 0; i < num_sets; i++) {
6607 uint8 num_sprites = buf->ReadByte();
6608 uint16 first_sprite = buf->ReadWord();
6610 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6611 i, num_sprites, first_sprite
6614 for (uint j = 0; j < num_sprites; j++) {
6615 int load_index = first_sprite + j;
6616 _cur.nfo_line++;
6617 LoadNextSprite(load_index, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); // XXX
6619 /* Shore sprites now located at different addresses.
6620 * So detect when the old ones get replaced. */
6621 if (IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6622 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
6628 /* Action 0x0A (SKIP) */
6629 static void SkipActA(ByteReader *buf)
6631 uint8 num_sets = buf->ReadByte();
6633 for (uint i = 0; i < num_sets; i++) {
6634 /* Skip the sprites this replaces */
6635 _cur.skip_sprites += buf->ReadByte();
6636 /* But ignore where they go */
6637 buf->ReadWord();
6640 grfmsg(3, "SkipActA: Skipping %d sprites", _cur.skip_sprites);
6643 /* Action 0x0B */
6644 static void GRFLoadError(ByteReader *buf)
6646 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6648 * B severity 00: notice, contine loading grf file
6649 * 01: warning, continue loading grf file
6650 * 02: error, but continue loading grf file, and attempt
6651 * loading grf again when loading or starting next game
6652 * 03: error, abort loading and prevent loading again in
6653 * the future (only when restarting the patch)
6654 * B language-id see action 4, use 1F for built-in error messages
6655 * B message-id message to show, see below
6656 * S message for custom messages (message-id FF), text of the message
6657 * not present for built-in messages.
6658 * V data additional data for built-in (or custom) messages
6659 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6661 static const StringID msgstr[] = {
6662 STR_NEWGRF_ERROR_VERSION_NUMBER,
6663 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6664 STR_NEWGRF_ERROR_UNSET_SWITCH,
6665 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6666 STR_NEWGRF_ERROR_LOAD_BEFORE,
6667 STR_NEWGRF_ERROR_LOAD_AFTER,
6668 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6671 static const StringID sevstr[] = {
6672 STR_NEWGRF_ERROR_MSG_INFO,
6673 STR_NEWGRF_ERROR_MSG_WARNING,
6674 STR_NEWGRF_ERROR_MSG_ERROR,
6675 STR_NEWGRF_ERROR_MSG_FATAL
6678 byte severity = buf->ReadByte();
6679 byte lang = buf->ReadByte();
6680 byte message_id = buf->ReadByte();
6682 /* Skip the error if it isn't valid for the current language. */
6683 if (!CheckGrfLangID(lang, _cur.grffile->grf_version)) return;
6685 /* Skip the error until the activation stage unless bit 7 of the severity
6686 * is set. */
6687 if (!HasBit(severity, 7) && _cur.stage == GLS_INIT) {
6688 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.stage);
6689 return;
6691 ClrBit(severity, 7);
6693 if (severity >= lengthof(sevstr)) {
6694 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6695 severity = 2;
6696 } else if (severity == 3) {
6697 /* This is a fatal error, so make sure the GRF is deactivated and no
6698 * more of it gets loaded. */
6699 DisableGrf();
6701 /* Make sure we show fatal errors, instead of silly infos from before */
6702 delete _cur.grfconfig->error;
6703 _cur.grfconfig->error = nullptr;
6706 if (message_id >= lengthof(msgstr) && message_id != 0xFF) {
6707 grfmsg(7, "GRFLoadError: Invalid message id.");
6708 return;
6711 if (buf->Remaining() <= 1) {
6712 grfmsg(7, "GRFLoadError: No message data supplied.");
6713 return;
6716 /* For now we can only show one message per newgrf file. */
6717 if (_cur.grfconfig->error != nullptr) return;
6719 GRFError *error = new GRFError(sevstr[severity]);
6721 if (message_id == 0xFF) {
6722 /* This is a custom error message. */
6723 if (buf->HasData()) {
6724 const char *message = buf->ReadString();
6726 error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, nullptr, SCC_RAW_STRING_POINTER);
6727 } else {
6728 grfmsg(7, "GRFLoadError: No custom message supplied.");
6729 error->custom_message = stredup("");
6731 } else {
6732 error->message = msgstr[message_id];
6735 if (buf->HasData()) {
6736 const char *data = buf->ReadString();
6738 error->data = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, data);
6739 } else {
6740 grfmsg(7, "GRFLoadError: No message data supplied.");
6741 error->data = stredup("");
6744 /* Only two parameter numbers can be used in the string. */
6745 for (uint i = 0; i < lengthof(error->param_value) && buf->HasData(); i++) {
6746 uint param_number = buf->ReadByte();
6747 error->param_value[i] = _cur.grffile->GetParam(param_number);
6750 _cur.grfconfig->error = error;
6753 /* Action 0x0C */
6754 static void GRFComment(ByteReader *buf)
6756 /* <0C> [<ignored...>]
6758 * V ignored Anything following the 0C is ignored */
6760 if (!buf->HasData()) return;
6762 const char *text = buf->ReadString();
6763 grfmsg(2, "GRFComment: %s", text);
6766 /* Action 0x0D (GLS_SAFETYSCAN) */
6767 static void SafeParamSet(ByteReader *buf)
6769 uint8 target = buf->ReadByte();
6771 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6772 if (target < 0x80 || target == 0x9E) return;
6774 /* GRM could be unsafe, but as here it can only happen after other GRFs
6775 * are loaded, it should be okay. If the GRF tried to use the slots it
6776 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6777 * sprites is considered safe. */
6779 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
6781 /* Skip remainder of GRF */
6782 _cur.skip_sprites = -1;
6786 static uint32 GetPatchVariable(uint8 param)
6788 switch (param) {
6789 /* start year - 1920 */
6790 case 0x0B: return max(_settings_game.game_creation.starting_year, ORIGINAL_BASE_YEAR) - ORIGINAL_BASE_YEAR;
6792 /* freight trains weight factor */
6793 case 0x0E: return _settings_game.vehicle.freight_trains;
6795 /* empty wagon speed increase */
6796 case 0x0F: return 0;
6798 /* plane speed factor; our patch option is reversed from TTDPatch's,
6799 * the following is good for 1x, 2x and 4x (most common?) and...
6800 * well not really for 3x. */
6801 case 0x10:
6802 switch (_settings_game.vehicle.plane_speed) {
6803 default:
6804 case 4: return 1;
6805 case 3: return 2;
6806 case 2: return 2;
6807 case 1: return 4;
6811 /* 2CC colourmap base sprite */
6812 case 0x11: return SPR_2CCMAP_BASE;
6814 /* map size: format = -MABXYSS
6815 * M : the type of map
6816 * bit 0 : set : squared map. Bit 1 is now not relevant
6817 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6818 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6819 * clear : X is the bigger edge.
6820 * A : minimum edge(log2) of the map
6821 * B : maximum edge(log2) of the map
6822 * XY : edges(log2) of each side of the map.
6823 * SS : combination of both X and Y, thus giving the size(log2) of the map
6825 case 0x13: {
6826 byte map_bits = 0;
6827 byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6828 byte log_Y = MapLogY() - 6;
6829 byte max_edge = max(log_X, log_Y);
6831 if (log_X == log_Y) { // we have a squared map, since both edges are identical
6832 SetBit(map_bits, 0);
6833 } else {
6834 if (max_edge == log_Y) SetBit(map_bits, 1); // edge Y been the biggest, mark it
6837 return (map_bits << 24) | (min(log_X, log_Y) << 20) | (max_edge << 16) |
6838 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
6841 /* The maximum height of the map. */
6842 case 0x14:
6843 return _settings_game.construction.max_heightlevel;
6845 /* Extra foundations base sprite */
6846 case 0x15:
6847 return SPR_SLOPES_BASE;
6849 /* Shore base sprite */
6850 case 0x16:
6851 return SPR_SHORE_BASE;
6853 default:
6854 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param);
6855 return 0;
6860 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target, const char *type)
6862 uint start = 0;
6863 uint size = 0;
6865 if (op == 6) {
6866 /* Return GRFID of set that reserved ID */
6867 return grm[_cur.grffile->GetParam(target)];
6870 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6871 if (op == 2 || op == 3) start = _cur.grffile->GetParam(target);
6873 for (uint i = start; i < num_ids; i++) {
6874 if (grm[i] == 0) {
6875 size++;
6876 } else {
6877 if (op == 2 || op == 3) break;
6878 start = i + 1;
6879 size = 0;
6882 if (size == count) break;
6885 if (size == count) {
6886 /* Got the slot... */
6887 if (op == 0 || op == 3) {
6888 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count, type, start);
6889 for (uint i = 0; i < count; i++) grm[start + i] = _cur.grffile->grfid;
6891 return start;
6894 /* Unable to allocate */
6895 if (op != 4 && op != 5) {
6896 /* Deactivate GRF */
6897 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
6898 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6899 return UINT_MAX;
6902 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count, type);
6903 return UINT_MAX;
6907 /** Action 0x0D: Set parameter */
6908 static void ParamSet(ByteReader *buf)
6910 /* <0D> <target> <operation> <source1> <source2> [<data>]
6912 * B target parameter number where result is stored
6913 * B operation operation to perform, see below
6914 * B source1 first source operand
6915 * B source2 second source operand
6916 * D data data to use in the calculation, not necessary
6917 * if both source1 and source2 refer to actual parameters
6919 * Operations
6920 * 00 Set parameter equal to source1
6921 * 01 Addition, source1 + source2
6922 * 02 Subtraction, source1 - source2
6923 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6924 * 04 Signed multiplication, source1 * source2 (both signed)
6925 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6926 * signed quantity; left shift if positive and right shift if
6927 * negative, source1 is unsigned)
6928 * 06 Signed bit shift, source1 by source2
6929 * (source2 like in 05, and source1 as well)
6932 uint8 target = buf->ReadByte();
6933 uint8 oper = buf->ReadByte();
6934 uint32 src1 = buf->ReadByte();
6935 uint32 src2 = buf->ReadByte();
6937 uint32 data = 0;
6938 if (buf->Remaining() >= 4) data = buf->ReadDWord();
6940 /* You can add 80 to the operation to make it apply only if the target
6941 * is not defined yet. In this respect, a parameter is taken to be
6942 * defined if any of the following applies:
6943 * - it has been set to any value in the newgrf(w).cfg parameter list
6944 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6945 * an earlier action D */
6946 if (HasBit(oper, 7)) {
6947 if (target < 0x80 && target < _cur.grffile->param_end) {
6948 grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
6949 return;
6952 oper = GB(oper, 0, 7);
6955 if (src2 == 0xFE) {
6956 if (GB(data, 0, 8) == 0xFF) {
6957 if (data == 0x0000FFFF) {
6958 /* Patch variables */
6959 src1 = GetPatchVariable(src1);
6960 } else {
6961 /* GRF Resource Management */
6962 uint8 op = src1;
6963 uint8 feature = GB(data, 8, 8);
6964 uint16 count = GB(data, 16, 16);
6966 if (_cur.stage == GLS_RESERVE) {
6967 if (feature == 0x08) {
6968 /* General sprites */
6969 if (op == 0) {
6970 /* Check if the allocated sprites will fit below the original sprite limit */
6971 if (_cur.spriteid + count >= 16384) {
6972 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
6973 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED);
6974 return;
6977 /* Reserve space at the current sprite ID */
6978 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count, _cur.spriteid);
6979 _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)] = _cur.spriteid;
6980 _cur.spriteid += count;
6983 /* Ignore GRM result during reservation */
6984 src1 = 0;
6985 } else if (_cur.stage == GLS_ACTIVATION) {
6986 switch (feature) {
6987 case 0x00: // Trains
6988 case 0x01: // Road Vehicles
6989 case 0x02: // Ships
6990 case 0x03: // Aircraft
6991 if (!_settings_game.vehicle.dynamic_engines) {
6992 src1 = PerformGRM(&_grm_engines[_engine_offsets[feature]], _engine_counts[feature], count, op, target, "vehicles");
6993 if (_cur.skip_sprites == -1) return;
6994 } else {
6995 /* GRM does not apply for dynamic engine allocation. */
6996 switch (op) {
6997 case 2:
6998 case 3:
6999 src1 = _cur.grffile->GetParam(target);
7000 break;
7002 default:
7003 src1 = 0;
7004 break;
7007 break;
7009 case 0x08: // General sprites
7010 switch (op) {
7011 case 0:
7012 /* Return space reserved during reservation stage */
7013 src1 = _grm_sprites[GRFLocation(_cur.grffile->grfid, _cur.nfo_line)];
7014 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1);
7015 break;
7017 case 1:
7018 src1 = _cur.spriteid;
7019 break;
7021 default:
7022 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op);
7023 return;
7025 break;
7027 case 0x0B: // Cargo
7028 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
7029 src1 = PerformGRM(_grm_cargoes, NUM_CARGO * 2, count, op, target, "cargoes");
7030 if (_cur.skip_sprites == -1) return;
7031 break;
7033 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature); return;
7035 } else {
7036 /* Ignore GRM during initialization */
7037 src1 = 0;
7040 } else {
7041 /* Read another GRF File's parameter */
7042 const GRFFile *file = GetFileByGRFID(data);
7043 GRFConfig *c = GetGRFConfig(data);
7044 if (c != nullptr && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) {
7045 /* Disable the read GRF if it is a static NewGRF. */
7046 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c);
7047 src1 = 0;
7048 } else if (file == nullptr || c == nullptr || c->status == GCS_DISABLED) {
7049 src1 = 0;
7050 } else if (src1 == 0xFE) {
7051 src1 = c->version;
7052 } else {
7053 src1 = file->GetParam(src1);
7056 } else {
7057 /* The source1 and source2 operands refer to the grf parameter number
7058 * like in action 6 and 7. In addition, they can refer to the special
7059 * variables available in action 7, or they can be FF to use the value
7060 * of <data>. If referring to parameters that are undefined, a value
7061 * of 0 is used instead. */
7062 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, nullptr);
7063 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, nullptr);
7066 /* TODO: You can access the parameters of another GRF file by using
7067 * source2=FE, source1=the other GRF's parameter number and data=GRF
7068 * ID. This is only valid with operation 00 (set). If the GRF ID
7069 * cannot be found, a value of 0 is used for the parameter value
7070 * instead. */
7072 uint32 res;
7073 switch (oper) {
7074 case 0x00:
7075 res = src1;
7076 break;
7078 case 0x01:
7079 res = src1 + src2;
7080 break;
7082 case 0x02:
7083 res = src1 - src2;
7084 break;
7086 case 0x03:
7087 res = src1 * src2;
7088 break;
7090 case 0x04:
7091 res = (int32)src1 * (int32)src2;
7092 break;
7094 case 0x05:
7095 if ((int32)src2 < 0) {
7096 res = src1 >> -(int32)src2;
7097 } else {
7098 res = src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
7100 break;
7102 case 0x06:
7103 if ((int32)src2 < 0) {
7104 res = (int32)src1 >> -(int32)src2;
7105 } else {
7106 res = (int32)src1 << (src2 & 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
7108 break;
7110 case 0x07: // Bitwise AND
7111 res = src1 & src2;
7112 break;
7114 case 0x08: // Bitwise OR
7115 res = src1 | src2;
7116 break;
7118 case 0x09: // Unsigned division
7119 if (src2 == 0) {
7120 res = src1;
7121 } else {
7122 res = src1 / src2;
7124 break;
7126 case 0x0A: // Signed divison
7127 if (src2 == 0) {
7128 res = src1;
7129 } else {
7130 res = (int32)src1 / (int32)src2;
7132 break;
7134 case 0x0B: // Unsigned modulo
7135 if (src2 == 0) {
7136 res = src1;
7137 } else {
7138 res = src1 % src2;
7140 break;
7142 case 0x0C: // Signed modulo
7143 if (src2 == 0) {
7144 res = src1;
7145 } else {
7146 res = (int32)src1 % (int32)src2;
7148 break;
7150 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper); return;
7153 switch (target) {
7154 case 0x8E: // Y-Offset for train sprites
7155 _cur.grffile->traininfo_vehicle_pitch = res;
7156 break;
7158 case 0x8F: { // Rail track type cost factors
7159 extern RailtypeInfo _railtypes[RAILTYPE_END];
7160 _railtypes[RAILTYPE_RAIL].cost_multiplier = GB(res, 0, 8);
7161 if (_settings_game.vehicle.disable_elrails) {
7162 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 0, 8);
7163 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 8, 8);
7164 } else {
7165 _railtypes[RAILTYPE_ELECTRIC].cost_multiplier = GB(res, 8, 8);
7166 _railtypes[RAILTYPE_MONO].cost_multiplier = GB(res, 16, 8);
7168 _railtypes[RAILTYPE_MAGLEV].cost_multiplier = GB(res, 16, 8);
7169 break;
7172 /* @todo implement */
7173 case 0x93: // Tile refresh offset to left
7174 case 0x94: // Tile refresh offset to right
7175 case 0x95: // Tile refresh offset upwards
7176 case 0x96: // Tile refresh offset downwards
7177 case 0x97: // Snow line height
7178 case 0x99: // Global ID offset
7179 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
7180 break;
7182 case 0x9E: // Miscellaneous GRF features
7183 /* Set train list engine width */
7184 _cur.grffile->traininfo_vehicle_width = HasBit(res, GMB_TRAIN_WIDTH_32_PIXELS) ? VEHICLEINFO_FULL_VEHICLE_WIDTH : TRAININFO_DEFAULT_VEHICLE_WIDTH;
7185 /* Remove the local flags from the global flags */
7186 ClrBit(res, GMB_TRAIN_WIDTH_32_PIXELS);
7188 /* Only copy safe bits for static grfs */
7189 if (HasBit(_cur.grfconfig->flags, GCF_STATIC)) {
7190 uint32 safe_bits = 0;
7191 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
7193 _misc_grf_features = (_misc_grf_features & ~safe_bits) | (res & safe_bits);
7194 } else {
7195 _misc_grf_features = res;
7197 break;
7199 case 0x9F: // locale-dependent settings
7200 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target);
7201 break;
7203 default:
7204 if (target < 0x80) {
7205 _cur.grffile->param[target] = res;
7206 /* param is zeroed by default */
7207 if (target + 1U > _cur.grffile->param_end) _cur.grffile->param_end = target + 1;
7208 } else {
7209 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target);
7211 break;
7215 /* Action 0x0E (GLS_SAFETYSCAN) */
7216 static void SafeGRFInhibit(ByteReader *buf)
7218 /* <0E> <num> <grfids...>
7220 * B num Number of GRFIDs that follow
7221 * D grfids GRFIDs of the files to deactivate */
7223 uint8 num = buf->ReadByte();
7225 for (uint i = 0; i < num; i++) {
7226 uint32 grfid = buf->ReadDWord();
7228 /* GRF is unsafe it if tries to deactivate other GRFs */
7229 if (grfid != _cur.grfconfig->ident.grfid) {
7230 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
7232 /* Skip remainder of GRF */
7233 _cur.skip_sprites = -1;
7235 return;
7240 /* Action 0x0E */
7241 static void GRFInhibit(ByteReader *buf)
7243 /* <0E> <num> <grfids...>
7245 * B num Number of GRFIDs that follow
7246 * D grfids GRFIDs of the files to deactivate */
7248 uint8 num = buf->ReadByte();
7250 for (uint i = 0; i < num; i++) {
7251 uint32 grfid = buf->ReadDWord();
7252 GRFConfig *file = GetGRFConfig(grfid);
7254 /* Unset activation flag */
7255 if (file != nullptr && file != _cur.grfconfig) {
7256 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename);
7257 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file);
7258 error->data = stredup(_cur.grfconfig->GetName());
7263 /** Action 0x0F - Define Town names */
7264 static void FeatureTownName(ByteReader *buf)
7266 /* <0F> <id> <style-name> <num-parts> <parts>
7268 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
7269 * V style-name Name of the style (only for final definition)
7270 * B num-parts Number of parts in this definition
7271 * V parts The parts */
7273 uint32 grfid = _cur.grffile->grfid;
7275 GRFTownName *townname = AddGRFTownName(grfid);
7277 byte id = buf->ReadByte();
7278 grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
7280 if (HasBit(id, 7)) {
7281 /* Final definition */
7282 ClrBit(id, 7);
7283 bool new_scheme = _cur.grffile->grf_version >= 7;
7285 byte lang = buf->ReadByte();
7287 byte nb_gen = townname->nb_gen;
7288 do {
7289 ClrBit(lang, 7);
7291 const char *name = buf->ReadString();
7293 char *lang_name = TranslateTTDPatchCodes(grfid, lang, false, name);
7294 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
7295 free(lang_name);
7297 townname->name[nb_gen] = AddGRFString(grfid, id, lang, new_scheme, false, name, STR_UNDEFINED);
7299 lang = buf->ReadByte();
7300 } while (lang != 0);
7301 townname->id[nb_gen] = id;
7302 townname->nb_gen++;
7305 byte nb = buf->ReadByte();
7306 grfmsg(6, "FeatureTownName: %u parts", nb);
7308 townname->nbparts[id] = nb;
7309 townname->partlist[id] = CallocT<NamePartList>(nb);
7311 for (int i = 0; i < nb; i++) {
7312 byte nbtext = buf->ReadByte();
7313 townname->partlist[id][i].bitstart = buf->ReadByte();
7314 townname->partlist[id][i].bitcount = buf->ReadByte();
7315 townname->partlist[id][i].maxprob = 0;
7316 townname->partlist[id][i].partcount = nbtext;
7317 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
7318 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);
7320 for (int j = 0; j < nbtext; j++) {
7321 byte prob = buf->ReadByte();
7323 if (HasBit(prob, 7)) {
7324 byte ref_id = buf->ReadByte();
7326 if (townname->nbparts[ref_id] == 0) {
7327 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7328 DelGRFTownName(grfid);
7329 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID);
7330 return;
7333 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7334 townname->partlist[id][i].parts[j].data.id = ref_id;
7335 } else {
7336 const char *text = buf->ReadString();
7337 townname->partlist[id][i].parts[j].data.text = TranslateTTDPatchCodes(grfid, 0, false, text);
7338 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[id][i].parts[j].data.text, prob);
7340 townname->partlist[id][i].parts[j].prob = prob;
7341 townname->partlist[id][i].maxprob += GB(prob, 0, 7);
7343 grfmsg(6, "FeatureTownName: part %d, total probability %d", i, townname->partlist[id][i].maxprob);
7347 /** Action 0x10 - Define goto label */
7348 static void DefineGotoLabel(ByteReader *buf)
7350 /* <10> <label> [<comment>]
7352 * B label The label to define
7353 * V comment Optional comment - ignored */
7355 byte nfo_label = buf->ReadByte();
7357 GRFLabel *label = MallocT<GRFLabel>(1);
7358 label->label = nfo_label;
7359 label->nfo_line = _cur.nfo_line;
7360 label->pos = FioGetPos();
7361 label->next = nullptr;
7363 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7364 if (_cur.grffile->label == nullptr) {
7365 _cur.grffile->label = label;
7366 } else {
7367 /* Attach the label to the end of the list */
7368 GRFLabel *l;
7369 for (l = _cur.grffile->label; l->next != nullptr; l = l->next) {}
7370 l->next = label;
7373 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7377 * Process a sound import from another GRF file.
7378 * @param sound Destination for sound.
7380 static void ImportGRFSound(SoundEntry *sound)
7382 const GRFFile *file;
7383 uint32 grfid = FioReadDword();
7384 SoundID sound_id = FioReadWord();
7386 file = GetFileByGRFID(grfid);
7387 if (file == nullptr || file->sound_offset == 0) {
7388 grfmsg(1, "ImportGRFSound: Source file not available");
7389 return;
7392 if (sound_id >= file->num_sounds) {
7393 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id);
7394 return;
7397 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7399 *sound = *GetSound(file->sound_offset + sound_id);
7401 /* Reset volume and priority, which TTDPatch doesn't copy */
7402 sound->volume = 128;
7403 sound->priority = 0;
7407 * Load a sound from a file.
7408 * @param offs File offset to read sound from.
7409 * @param sound Destination for sound.
7411 static void LoadGRFSound(size_t offs, SoundEntry *sound)
7413 /* Set default volume and priority */
7414 sound->volume = 0x80;
7415 sound->priority = 0;
7417 if (offs != SIZE_MAX) {
7418 /* Sound is present in the NewGRF. */
7419 sound->file_slot = _cur.file_index;
7420 sound->file_offset = offs;
7421 sound->grf_container_ver = _cur.grf_container_ver;
7425 /* Action 0x11 */
7426 static void GRFSound(ByteReader *buf)
7428 /* <11> <num>
7430 * W num Number of sound files that follow */
7432 uint16 num = buf->ReadWord();
7433 if (num == 0) return;
7435 SoundEntry *sound;
7436 if (_cur.grffile->sound_offset == 0) {
7437 _cur.grffile->sound_offset = GetNumSounds();
7438 _cur.grffile->num_sounds = num;
7439 sound = AllocateSound(num);
7440 } else {
7441 sound = GetSound(_cur.grffile->sound_offset);
7444 for (int i = 0; i < num; i++) {
7445 _cur.nfo_line++;
7447 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7448 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7449 bool invalid = i >= _cur.grffile->num_sounds;
7451 size_t offs = FioGetPos();
7453 uint32 len = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
7454 byte type = FioReadByte();
7456 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
7457 /* Reference to sprite section. */
7458 if (invalid) {
7459 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7460 FioSkipBytes(len);
7461 } else if (len != 4) {
7462 grfmsg(1, "GRFSound: Invalid sprite section import");
7463 FioSkipBytes(len);
7464 } else {
7465 uint32 id = FioReadDword();
7466 if (_cur.stage == GLS_INIT) LoadGRFSound(GetGRFSpriteOffset(id), sound + i);
7468 continue;
7471 if (type != 0xFF) {
7472 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7473 FioSkipBytes(7);
7474 SkipSpriteData(type, len - 8);
7475 continue;
7478 if (invalid) {
7479 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7480 FioSkipBytes(len);
7483 byte action = FioReadByte();
7484 switch (action) {
7485 case 0xFF:
7486 /* Allocate sound only in init stage. */
7487 if (_cur.stage == GLS_INIT) {
7488 if (_cur.grf_container_ver >= 2) {
7489 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7490 } else {
7491 LoadGRFSound(offs, sound + i);
7494 FioSkipBytes(len - 1); // already read <action>
7495 break;
7497 case 0xFE:
7498 if (_cur.stage == GLS_ACTIVATION) {
7499 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7500 * importing sounds, so this is probably all wrong... */
7501 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7502 ImportGRFSound(sound + i);
7503 } else {
7504 FioSkipBytes(len - 1); // already read <action>
7506 break;
7508 default:
7509 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action);
7510 FioSkipBytes(len - 1); // already read <action>
7511 break;
7516 /* Action 0x11 (SKIP) */
7517 static void SkipAct11(ByteReader *buf)
7519 /* <11> <num>
7521 * W num Number of sound files that follow */
7523 _cur.skip_sprites = buf->ReadWord();
7525 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur.skip_sprites);
7528 /** Action 0x12 */
7529 static void LoadFontGlyph(ByteReader *buf)
7531 /* <12> <num_def> <font_size> <num_char> <base_char>
7533 * B num_def Number of definitions
7534 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7535 * B num_char Number of consecutive glyphs
7536 * W base_char First character index */
7538 uint8 num_def = buf->ReadByte();
7540 for (uint i = 0; i < num_def; i++) {
7541 FontSize size = (FontSize)buf->ReadByte();
7542 uint8 num_char = buf->ReadByte();
7543 uint16 base_char = buf->ReadWord();
7545 if (size >= FS_END) {
7546 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size);
7549 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7551 for (uint c = 0; c < num_char; c++) {
7552 if (size < FS_END) SetUnicodeGlyph(size, base_char + c, _cur.spriteid);
7553 _cur.nfo_line++;
7554 LoadNextSprite(_cur.spriteid++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver);
7559 /** Action 0x12 (SKIP) */
7560 static void SkipAct12(ByteReader *buf)
7562 /* <12> <num_def> <font_size> <num_char> <base_char>
7564 * B num_def Number of definitions
7565 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7566 * B num_char Number of consecutive glyphs
7567 * W base_char First character index */
7569 uint8 num_def = buf->ReadByte();
7571 for (uint i = 0; i < num_def; i++) {
7572 /* Ignore 'size' byte */
7573 buf->ReadByte();
7575 /* Sum up number of characters */
7576 _cur.skip_sprites += buf->ReadByte();
7578 /* Ignore 'base_char' word */
7579 buf->ReadWord();
7582 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur.skip_sprites);
7585 /** Action 0x13 */
7586 static void TranslateGRFStrings(ByteReader *buf)
7588 /* <13> <grfid> <num-ent> <offset> <text...>
7590 * 4*B grfid The GRFID of the file whose texts are to be translated
7591 * B num-ent Number of strings
7592 * W offset First text ID
7593 * S text... Zero-terminated strings */
7595 uint32 grfid = buf->ReadDWord();
7596 const GRFConfig *c = GetGRFConfig(grfid);
7597 if (c == nullptr || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) {
7598 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid));
7599 return;
7602 if (c->status == GCS_INITIALISED) {
7603 /* If the file is not active but will be activated later, give an error
7604 * and disable this file. */
7605 GRFError *error = DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER);
7607 char tmp[256];
7608 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE, lastof(tmp));
7609 error->data = stredup(tmp);
7611 return;
7614 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7615 * to be added as a generic string, thus the language id of 0x7F. For this to work
7616 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7617 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7618 * not change anything if a string has been provided specifically for this language. */
7619 byte language = _cur.grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7620 byte num_strings = buf->ReadByte();
7621 uint16 first_id = buf->ReadWord();
7623 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7624 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7625 return;
7628 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7629 const char *string = buf->ReadString();
7631 if (StrEmpty(string)) {
7632 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7633 continue;
7636 AddGRFString(grfid, first_id + i, language, true, true, string, STR_UNDEFINED);
7640 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7641 static bool ChangeGRFName(byte langid, const char *str)
7643 AddGRFTextToList(&_cur.grfconfig->name->text, langid, _cur.grfconfig->ident.grfid, false, str);
7644 return true;
7647 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7648 static bool ChangeGRFDescription(byte langid, const char *str)
7650 AddGRFTextToList(&_cur.grfconfig->info->text, langid, _cur.grfconfig->ident.grfid, true, str);
7651 return true;
7654 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7655 static bool ChangeGRFURL(byte langid, const char *str)
7657 AddGRFTextToList(&_cur.grfconfig->url->text, langid, _cur.grfconfig->ident.grfid, false, str);
7658 return true;
7661 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7662 static bool ChangeGRFNumUsedParams(size_t len, ByteReader *buf)
7664 if (len != 1) {
7665 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE ", ignoring this field", len);
7666 buf->Skip(len);
7667 } else {
7668 _cur.grfconfig->num_valid_params = min(buf->ReadByte(), lengthof(_cur.grfconfig->param));
7670 return true;
7673 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7674 static bool ChangeGRFPalette(size_t len, ByteReader *buf)
7676 if (len != 1) {
7677 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
7678 buf->Skip(len);
7679 } else {
7680 char data = buf->ReadByte();
7681 GRFPalette pal = GRFP_GRF_UNSET;
7682 switch (data) {
7683 case '*':
7684 case 'A': pal = GRFP_GRF_ANY; break;
7685 case 'W': pal = GRFP_GRF_WINDOWS; break;
7686 case 'D': pal = GRFP_GRF_DOS; break;
7687 default:
7688 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7689 break;
7691 if (pal != GRFP_GRF_UNSET) {
7692 _cur.grfconfig->palette &= ~GRFP_GRF_MASK;
7693 _cur.grfconfig->palette |= pal;
7696 return true;
7699 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7700 static bool ChangeGRFBlitter(size_t len, ByteReader *buf)
7702 if (len != 1) {
7703 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE ", ignoring this field", len);
7704 buf->Skip(len);
7705 } else {
7706 char data = buf->ReadByte();
7707 GRFPalette pal = GRFP_BLT_UNSET;
7708 switch (data) {
7709 case '8': pal = GRFP_BLT_UNSET; break;
7710 case '3': pal = GRFP_BLT_32BPP; break;
7711 default:
7712 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7713 return true;
7715 _cur.grfconfig->palette &= ~GRFP_BLT_MASK;
7716 _cur.grfconfig->palette |= pal;
7718 return true;
7721 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7722 static bool ChangeGRFVersion(size_t len, ByteReader *buf)
7724 if (len != 4) {
7725 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
7726 buf->Skip(len);
7727 } else {
7728 /* Set min_loadable_version as well (default to minimal compatibility) */
7729 _cur.grfconfig->version = _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7731 return true;
7734 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7735 static bool ChangeGRFMinVersion(size_t len, ByteReader *buf)
7737 if (len != 4) {
7738 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE ", ignoring this field", len);
7739 buf->Skip(len);
7740 } else {
7741 _cur.grfconfig->min_loadable_version = buf->ReadDWord();
7742 if (_cur.grfconfig->version == 0) {
7743 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7744 _cur.grfconfig->min_loadable_version = 0;
7746 if (_cur.grfconfig->version < _cur.grfconfig->min_loadable_version) {
7747 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur.grfconfig->min_loadable_version);
7748 _cur.grfconfig->min_loadable_version = _cur.grfconfig->version;
7751 return true;
7754 static GRFParameterInfo *_cur_parameter; ///< The parameter which info is currently changed by the newgrf.
7756 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7757 static bool ChangeGRFParamName(byte langid, const char *str)
7759 AddGRFTextToList(&_cur_parameter->name, langid, _cur.grfconfig->ident.grfid, false, str);
7760 return true;
7763 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7764 static bool ChangeGRFParamDescription(byte langid, const char *str)
7766 AddGRFTextToList(&_cur_parameter->desc, langid, _cur.grfconfig->ident.grfid, true, str);
7767 return true;
7770 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7771 static bool ChangeGRFParamType(size_t len, ByteReader *buf)
7773 if (len != 1) {
7774 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
7775 buf->Skip(len);
7776 } else {
7777 GRFParameterType type = (GRFParameterType)buf->ReadByte();
7778 if (type < PTYPE_END) {
7779 _cur_parameter->type = type;
7780 } else {
7781 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7784 return true;
7787 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7788 static bool ChangeGRFParamLimits(size_t len, ByteReader *buf)
7790 if (_cur_parameter->type != PTYPE_UINT_ENUM) {
7791 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7792 buf->Skip(len);
7793 } else if (len != 8) {
7794 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len);
7795 buf->Skip(len);
7796 } else {
7797 _cur_parameter->min_value = buf->ReadDWord();
7798 _cur_parameter->max_value = buf->ReadDWord();
7800 return true;
7803 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7804 static bool ChangeGRFParamMask(size_t len, ByteReader *buf)
7806 if (len < 1 || len > 3) {
7807 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE ", ignoring this field", len);
7808 buf->Skip(len);
7809 } else {
7810 byte param_nr = buf->ReadByte();
7811 if (param_nr >= lengthof(_cur.grfconfig->param)) {
7812 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7813 buf->Skip(len - 1);
7814 } else {
7815 _cur_parameter->param_nr = param_nr;
7816 if (len >= 2) _cur_parameter->first_bit = min(buf->ReadByte(), 31);
7817 if (len >= 3) _cur_parameter->num_bit = min(buf->ReadByte(), 32 - _cur_parameter->first_bit);
7821 return true;
7824 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7825 static bool ChangeGRFParamDefault(size_t len, ByteReader *buf)
7827 if (len != 4) {
7828 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE ", ignoring this field", len);
7829 buf->Skip(len);
7830 } else {
7831 _cur_parameter->def_value = buf->ReadDWord();
7833 _cur.grfconfig->has_param_defaults = true;
7834 return true;
7837 typedef bool (*DataHandler)(size_t, ByteReader *); ///< Type of callback function for binary nodes
7838 typedef bool (*TextHandler)(byte, const char *str); ///< Type of callback function for text nodes
7839 typedef bool (*BranchHandler)(ByteReader *); ///< Type of callback function for branch nodes
7842 * Data structure to store the allowed id/type combinations for action 14. The
7843 * data can be represented as a tree with 3 types of nodes:
7844 * 1. Branch nodes (identified by 'C' for choice).
7845 * 2. Binary leaf nodes (identified by 'B').
7846 * 3. Text leaf nodes (identified by 'T').
7848 struct AllowedSubtags {
7849 /** Create empty subtags object used to identify the end of a list. */
7850 AllowedSubtags() :
7851 id(0),
7852 type(0)
7856 * Create a binary leaf node.
7857 * @param id The id for this node.
7858 * @param handler The callback function to call.
7860 AllowedSubtags(uint32 id, DataHandler handler) :
7861 id(id),
7862 type('B')
7864 this->handler.data = handler;
7868 * Create a text leaf node.
7869 * @param id The id for this node.
7870 * @param handler The callback function to call.
7872 AllowedSubtags(uint32 id, TextHandler handler) :
7873 id(id),
7874 type('T')
7876 this->handler.text = handler;
7880 * Create a branch node with a callback handler
7881 * @param id The id for this node.
7882 * @param handler The callback function to call.
7884 AllowedSubtags(uint32 id, BranchHandler handler) :
7885 id(id),
7886 type('C')
7888 this->handler.call_handler = true;
7889 this->handler.u.branch = handler;
7893 * Create a branch node with a list of sub-nodes.
7894 * @param id The id for this node.
7895 * @param subtags Array with all valid subtags.
7897 AllowedSubtags(uint32 id, AllowedSubtags *subtags) :
7898 id(id),
7899 type('C')
7901 this->handler.call_handler = false;
7902 this->handler.u.subtags = subtags;
7905 uint32 id; ///< The identifier for this node
7906 byte type; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7907 union {
7908 DataHandler data; ///< Callback function for a binary node, only valid if type == 'B'.
7909 TextHandler text; ///< Callback function for a text node, only valid if type == 'T'.
7910 struct {
7911 union {
7912 BranchHandler branch; ///< Callback function for a branch node, only valid if type == 'C' && call_handler.
7913 AllowedSubtags *subtags; ///< Pointer to a list of subtags, only valid if type == 'C' && !call_handler.
7914 } u;
7915 bool call_handler; ///< True if there is a callback function for this node, false if there is a list of subnodes.
7917 } handler;
7920 static bool SkipUnknownInfo(ByteReader *buf, byte type);
7921 static bool HandleNodes(ByteReader *buf, AllowedSubtags *tags);
7924 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7925 * of some parameter values (type uint/enum) or the names of some bits
7926 * (type bitmask). In both cases the format is the same:
7927 * Each subnode should be a text node with the value/bit number as id.
7929 static bool ChangeGRFParamValueNames(ByteReader *buf)
7931 byte type = buf->ReadByte();
7932 while (type != 0) {
7933 uint32 id = buf->ReadDWord();
7934 if (type != 'T' || id > _cur_parameter->max_value) {
7935 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7936 if (!SkipUnknownInfo(buf, type)) return false;
7937 type = buf->ReadByte();
7938 continue;
7941 byte langid = buf->ReadByte();
7942 const char *name_string = buf->ReadString();
7944 SmallPair<uint32, GRFText *> *val_name = _cur_parameter->value_names.Find(id);
7945 if (val_name != _cur_parameter->value_names.End()) {
7946 AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string);
7947 } else {
7948 GRFText *list = nullptr;
7949 AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string);
7950 _cur_parameter->value_names.Insert(id, list);
7953 type = buf->ReadByte();
7955 return true;
7958 /** Action14 parameter tags */
7959 AllowedSubtags _tags_parameters[] = {
7960 AllowedSubtags('NAME', ChangeGRFParamName),
7961 AllowedSubtags('DESC', ChangeGRFParamDescription),
7962 AllowedSubtags('TYPE', ChangeGRFParamType),
7963 AllowedSubtags('LIMI', ChangeGRFParamLimits),
7964 AllowedSubtags('MASK', ChangeGRFParamMask),
7965 AllowedSubtags('VALU', ChangeGRFParamValueNames),
7966 AllowedSubtags('DFLT', ChangeGRFParamDefault),
7967 AllowedSubtags()
7971 * Callback function for 'INFO'->'PARA' to set extra information about the
7972 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7973 * the parameter number as id. The first parameter has id 0. The maximum
7974 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7976 static bool HandleParameterInfo(ByteReader *buf)
7978 byte type = buf->ReadByte();
7979 while (type != 0) {
7980 uint32 id = buf->ReadDWord();
7981 if (type != 'C' || id >= _cur.grfconfig->num_valid_params) {
7982 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7983 if (!SkipUnknownInfo(buf, type)) return false;
7984 type = buf->ReadByte();
7985 continue;
7988 if (id >= _cur.grfconfig->param_info.Length()) {
7989 uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1;
7990 GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add);
7991 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
7993 if (_cur.grfconfig->param_info[id] == nullptr) {
7994 _cur.grfconfig->param_info[id] = new GRFParameterInfo(id);
7996 _cur_parameter = _cur.grfconfig->param_info[id];
7997 /* Read all parameter-data and process each node. */
7998 if (!HandleNodes(buf, _tags_parameters)) return false;
7999 type = buf->ReadByte();
8001 return true;
8004 /** Action14 tags for the INFO node */
8005 AllowedSubtags _tags_info[] = {
8006 AllowedSubtags('NAME', ChangeGRFName),
8007 AllowedSubtags('DESC', ChangeGRFDescription),
8008 AllowedSubtags('URL_', ChangeGRFURL),
8009 AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
8010 AllowedSubtags('PALS', ChangeGRFPalette),
8011 AllowedSubtags('BLTR', ChangeGRFBlitter),
8012 AllowedSubtags('VRSN', ChangeGRFVersion),
8013 AllowedSubtags('MINV', ChangeGRFMinVersion),
8014 AllowedSubtags('PARA', HandleParameterInfo),
8015 AllowedSubtags()
8018 /** Action14 root tags */
8019 AllowedSubtags _tags_root[] = {
8020 AllowedSubtags('INFO', _tags_info),
8021 AllowedSubtags()
8026 * Try to skip the current node and all subnodes (if it's a branch node).
8027 * @param buf Buffer.
8028 * @param type The node type to skip.
8029 * @return True if we could skip the node, false if an error occurred.
8031 static bool SkipUnknownInfo(ByteReader *buf, byte type)
8033 /* type and id are already read */
8034 switch (type) {
8035 case 'C': {
8036 byte new_type = buf->ReadByte();
8037 while (new_type != 0) {
8038 buf->ReadDWord(); // skip the id
8039 if (!SkipUnknownInfo(buf, new_type)) return false;
8040 new_type = buf->ReadByte();
8042 break;
8045 case 'T':
8046 buf->ReadByte(); // lang
8047 buf->ReadString(); // actual text
8048 break;
8050 case 'B': {
8051 uint16 size = buf->ReadWord();
8052 buf->Skip(size);
8053 break;
8056 default:
8057 return false;
8060 return true;
8064 * Handle the nodes of an Action14
8065 * @param type Type of node.
8066 * @param id ID.
8067 * @param buf Buffer.
8068 * @param subtags Allowed subtags.
8069 * @return Whether all tags could be handled.
8071 static bool HandleNode(byte type, uint32 id, ByteReader *buf, AllowedSubtags subtags[])
8073 uint i = 0;
8074 AllowedSubtags *tag;
8075 while ((tag = &subtags[i++])->type != 0) {
8076 if (tag->id != BSWAP32(id) || tag->type != type) continue;
8077 switch (type) {
8078 default: NOT_REACHED();
8080 case 'T': {
8081 byte langid = buf->ReadByte();
8082 return tag->handler.text(langid, buf->ReadString());
8085 case 'B': {
8086 size_t len = buf->ReadWord();
8087 if (buf->Remaining() < len) return false;
8088 return tag->handler.data(len, buf);
8091 case 'C': {
8092 if (tag->handler.call_handler) {
8093 return tag->handler.u.branch(buf);
8095 return HandleNodes(buf, tag->handler.u.subtags);
8099 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type, id);
8100 return SkipUnknownInfo(buf, type);
8104 * Handle the contents of a 'C' choice of an Action14
8105 * @param buf Buffer.
8106 * @param subtags List of subtags.
8107 * @return Whether the nodes could all be handled.
8109 static bool HandleNodes(ByteReader *buf, AllowedSubtags subtags[])
8111 byte type = buf->ReadByte();
8112 while (type != 0) {
8113 uint32 id = buf->ReadDWord();
8114 if (!HandleNode(type, id, buf, subtags)) return false;
8115 type = buf->ReadByte();
8117 return true;
8121 * Handle Action 0x14
8122 * @param buf Buffer.
8124 static void StaticGRFInfo(ByteReader *buf)
8126 /* <14> <type> <id> <text/data...> */
8127 HandleNodes(buf, _tags_root);
8131 * Set the current NewGRF as unsafe for static use
8132 * @param buf Unused.
8133 * @note Used during safety scan on unsafe actions.
8135 static void GRFUnsafe(ByteReader *buf)
8137 SetBit(_cur.grfconfig->flags, GCF_UNSAFE);
8139 /* Skip remainder of GRF */
8140 _cur.skip_sprites = -1;
8144 /** Initialize the TTDPatch flags */
8145 static void InitializeGRFSpecial()
8147 _ttdpatch_flags[0] = ((_settings_game.station.never_expire_airports ? 1 : 0) << 0x0C) // keepsmallairport
8148 | (1 << 0x0D) // newairports
8149 | (1 << 0x0E) // largestations
8150 | ((_settings_game.construction.max_bridge_length > 16 ? 1 : 0) << 0x0F) // longbridges
8151 | (0 << 0x10) // loadtime
8152 | (1 << 0x12) // presignals
8153 | (1 << 0x13) // extpresignals
8154 | ((_settings_game.vehicle.never_expire_vehicles ? 1 : 0) << 0x16) // enginespersist
8155 | (1 << 0x1B) // multihead
8156 | (1 << 0x1D) // lowmemory
8157 | (1 << 0x1E); // generalfixes
8159 _ttdpatch_flags[1] = ((_settings_game.economy.station_noise_level ? 1 : 0) << 0x07) // moreairports - based on units of noise
8160 | (1 << 0x08) // mammothtrains
8161 | (1 << 0x09) // trainrefit
8162 | (0 << 0x0B) // subsidiaries
8163 | ((_settings_game.order.gradual_loading ? 1 : 0) << 0x0C) // gradualloading
8164 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
8165 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
8166 | (1 << 0x14) // bridgespeedlimits
8167 | (1 << 0x16) // eternalgame
8168 | (1 << 0x17) // newtrains
8169 | (1 << 0x18) // newrvs
8170 | (1 << 0x19) // newships
8171 | (1 << 0x1A) // newplanes
8172 | ((_settings_game.construction.train_signal_side == 1 ? 1 : 0) << 0x1B) // signalsontrafficside
8173 | ((_settings_game.vehicle.disable_elrails ? 0 : 1) << 0x1C); // electrifiedrailway
8175 _ttdpatch_flags[2] = (1 << 0x01) // loadallgraphics - obsolote
8176 | (1 << 0x03) // semaphores
8177 | (1 << 0x0A) // newobjects
8178 | (0 << 0x0B) // enhancedgui
8179 | (0 << 0x0C) // newagerating
8180 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x0D) // buildonslopes
8181 | (1 << 0x0E) // fullloadany
8182 | (1 << 0x0F) // planespeed
8183 | (0 << 0x10) // moreindustriesperclimate - obsolete
8184 | (0 << 0x11) // moretoylandfeatures
8185 | (1 << 0x12) // newstations
8186 | (1 << 0x13) // tracktypecostdiff
8187 | (1 << 0x14) // manualconvert
8188 | ((_settings_game.construction.build_on_slopes ? 1 : 0) << 0x15) // buildoncoasts
8189 | (1 << 0x16) // canals
8190 | (1 << 0x17) // newstartyear
8191 | ((_settings_game.vehicle.freight_trains > 1 ? 1 : 0) << 0x18) // freighttrains
8192 | (1 << 0x19) // newhouses
8193 | (1 << 0x1A) // newbridges
8194 | (1 << 0x1B) // newtownnames
8195 | (1 << 0x1C) // moreanimation
8196 | ((_settings_game.vehicle.wagon_speed_limits ? 1 : 0) << 0x1D) // wagonspeedlimits
8197 | (1 << 0x1E) // newshistory
8198 | (0 << 0x1F); // custombridgeheads
8200 _ttdpatch_flags[3] = (0 << 0x00) // newcargodistribution
8201 | (1 << 0x01) // windowsnap
8202 | ((_settings_game.economy.allow_town_roads || _generating_world ? 0 : 1) << 0x02) // townbuildnoroad
8203 | (1 << 0x03) // pathbasedsignalling
8204 | (0 << 0x04) // aichoosechance
8205 | (1 << 0x05) // resolutionwidth
8206 | (1 << 0x06) // resolutionheight
8207 | (1 << 0x07) // newindustries
8208 | ((_settings_game.order.improved_load ? 1 : 0) << 0x08) // fifoloading
8209 | (0 << 0x09) // townroadbranchprob
8210 | (0 << 0x0A) // tempsnowline
8211 | (1 << 0x0B) // newcargo
8212 | (1 << 0x0C) // enhancemultiplayer
8213 | (1 << 0x0D) // onewayroads
8214 | (1 << 0x0E) // irregularstations
8215 | (1 << 0x0F) // statistics
8216 | (1 << 0x10) // newsounds
8217 | (1 << 0x11) // autoreplace
8218 | (1 << 0x12) // autoslope
8219 | (0 << 0x13) // followvehicle
8220 | (1 << 0x14) // trams
8221 | (0 << 0x15) // enhancetunnels
8222 | (1 << 0x16) // shortrvs
8223 | (1 << 0x17) // articulatedrvs
8224 | ((_settings_game.vehicle.dynamic_engines ? 1 : 0) << 0x18) // dynamic engines
8225 | (1 << 0x1E) // variablerunningcosts
8226 | (1 << 0x1F); // any switch is on
8229 /** Reset and clear all NewGRF stations */
8230 static void ResetCustomStations()
8232 const GRFFile * const *end = _grf_files.End();
8233 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8234 StationSpec **&stations = (*file)->stations;
8235 if (stations == nullptr) continue;
8236 for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) {
8237 if (stations[i] == nullptr) continue;
8238 StationSpec *statspec = stations[i];
8240 delete[] statspec->renderdata;
8242 /* Release platforms and layouts */
8243 if (!statspec->copied_layouts) {
8244 for (uint l = 0; l < statspec->lengths; l++) {
8245 for (uint p = 0; p < statspec->platforms[l]; p++) {
8246 free(statspec->layouts[l][p]);
8248 free(statspec->layouts[l]);
8250 free(statspec->layouts);
8251 free(statspec->platforms);
8254 /* Release this station */
8255 free(statspec);
8258 /* Free and reset the station data */
8259 free(stations);
8260 stations = nullptr;
8264 /** Reset and clear all NewGRF houses */
8265 static void ResetCustomHouses()
8267 const GRFFile * const *end = _grf_files.End();
8268 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8269 HouseSpec **&housespec = (*file)->housespec;
8270 if (housespec == nullptr) continue;
8271 for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8272 free(housespec[i]);
8275 free(housespec);
8276 housespec = nullptr;
8280 /** Reset and clear all NewGRF airports */
8281 static void ResetCustomAirports()
8283 const GRFFile * const *end = _grf_files.End();
8284 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8285 AirportSpec **aslist = (*file)->airportspec;
8286 if (aslist != nullptr) {
8287 for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
8288 AirportSpec *as = aslist[i];
8290 if (as != nullptr) {
8291 /* We need to remove the tiles layouts */
8292 for (int j = 0; j < as->num_table; j++) {
8293 /* remove the individual layouts */
8294 free(as->table[j]);
8296 free(as->table);
8297 free(as->depot_table);
8298 free(as->rotation);
8300 free(as);
8303 free(aslist);
8304 (*file)->airportspec = nullptr;
8307 AirportTileSpec **&airporttilespec = (*file)->airtspec;
8308 if (airporttilespec != nullptr) {
8309 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
8310 free(airporttilespec[i]);
8312 free(airporttilespec);
8313 airporttilespec = nullptr;
8318 /** Reset and clear all NewGRF industries */
8319 static void ResetCustomIndustries()
8321 const GRFFile * const *end = _grf_files.End();
8322 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8323 IndustrySpec **&industryspec = (*file)->industryspec;
8324 IndustryTileSpec **&indtspec = (*file)->indtspec;
8326 /* We are verifiying both tiles and industries specs loaded from the grf file
8327 * First, let's deal with industryspec */
8328 if (industryspec != nullptr) {
8329 for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8330 IndustrySpec *ind = industryspec[i];
8331 if (ind == nullptr) continue;
8333 /* We need to remove the sounds array */
8334 if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
8335 free(ind->random_sounds);
8338 /* We need to remove the tiles layouts */
8339 CleanIndustryTileTable(ind);
8341 free(ind);
8344 free(industryspec);
8345 industryspec = nullptr;
8348 if (indtspec == nullptr) continue;
8349 for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
8350 free(indtspec[i]);
8353 free(indtspec);
8354 indtspec = nullptr;
8358 /** Reset and clear all NewObjects */
8359 static void ResetCustomObjects()
8361 const GRFFile * const *end = _grf_files.End();
8362 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8363 ObjectSpec **&objectspec = (*file)->objectspec;
8364 if (objectspec == nullptr) continue;
8365 for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
8366 free(objectspec[i]);
8369 free(objectspec);
8370 objectspec = nullptr;
8374 /** Reset and clear all NewGRFs */
8375 static void ResetNewGRF()
8377 const GRFFile * const *end = _grf_files.End();
8378 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8379 delete *file;
8382 _grf_files.Clear();
8383 _cur.grffile = nullptr;
8386 /** Clear all NewGRF errors */
8387 static void ResetNewGRFErrors()
8389 for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
8390 if (!HasBit(c->flags, GCF_COPY) && c->error != nullptr) {
8391 delete c->error;
8392 c->error = nullptr;
8398 * Reset all NewGRF loaded data
8400 void ResetNewGRFData()
8402 CleanUpStrings();
8403 CleanUpGRFTownNames();
8405 /* Copy/reset original engine info data */
8406 SetupEngines();
8408 /* Copy/reset original bridge info data */
8409 ResetBridges();
8411 /* Reset rail type information */
8412 ResetRailTypes();
8414 /* Copy/reset original road type info data */
8415 ResetRoadTypes();
8417 /* Allocate temporary refit/cargo class data */
8418 _gted = CallocT<GRFTempEngineData>(Engine::GetPoolSize());
8420 /* Fill rail type label temporary data for default trains */
8421 Engine *e;
8422 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
8423 _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label;
8426 /* Reset GRM reservations */
8427 memset(&_grm_engines, 0, sizeof(_grm_engines));
8428 memset(&_grm_cargoes, 0, sizeof(_grm_cargoes));
8430 /* Reset generic feature callback lists */
8431 ResetGenericCallbacks();
8433 /* Reset price base data */
8434 ResetPriceBaseMultipliers();
8436 /* Reset the curencies array */
8437 ResetCurrencies();
8439 /* Reset the house array */
8440 ResetCustomHouses();
8441 ResetHouses();
8443 /* Reset the industries structures*/
8444 ResetCustomIndustries();
8445 ResetIndustries();
8447 /* Reset the objects. */
8448 ObjectClass::Reset();
8449 ResetCustomObjects();
8450 ResetObjects();
8452 /* Reset station classes */
8453 StationClass::Reset();
8454 ResetCustomStations();
8456 /* Reset airport-related structures */
8457 AirportClass::Reset();
8458 ResetCustomAirports();
8459 AirportSpec::ResetAirports();
8460 AirportTileSpec::ResetAirportTiles();
8462 /* Reset canal sprite groups and flags */
8463 memset(_water_feature, 0, sizeof(_water_feature));
8465 /* Reset the snowline table. */
8466 ClearSnowLine();
8468 /* Reset NewGRF files */
8469 ResetNewGRF();
8471 /* Reset NewGRF errors. */
8472 ResetNewGRFErrors();
8474 /* Set up the default cargo types */
8475 SetupCargoForClimate(_settings_game.game_creation.landscape);
8477 /* Reset misc GRF features and train list display variables */
8478 _misc_grf_features = 0;
8480 _loaded_newgrf_features.has_2CC = false;
8481 _loaded_newgrf_features.used_liveries = 1 << LS_DEFAULT;
8482 _loaded_newgrf_features.has_newhouses = false;
8483 _loaded_newgrf_features.has_newindustries = false;
8484 _loaded_newgrf_features.shore = SHORE_REPLACE_NONE;
8485 _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_NONE;
8487 /* Clear all GRF overrides */
8488 _grf_id_overrides.clear();
8490 InitializeSoundPool();
8491 _spritegroup_pool.CleanPool();
8495 * Reset NewGRF data which is stored persistently in savegames.
8497 void ResetPersistentNewGRFData()
8499 /* Reset override managers */
8500 _engine_mngr.ResetToDefaultMapping();
8501 _house_mngr.ResetMapping();
8502 _industry_mngr.ResetMapping();
8503 _industile_mngr.ResetMapping();
8504 _airport_mngr.ResetMapping();
8505 _airporttile_mngr.ResetMapping();
8509 * Construct the Cargo Mapping
8510 * @note This is the reverse of a cargo translation table
8512 static void BuildCargoTranslationMap()
8514 memset(_cur.grffile->cargo_map, 0xFF, sizeof(_cur.grffile->cargo_map));
8516 for (CargoID c = 0; c < NUM_CARGO; c++) {
8517 const CargoSpec *cs = CargoSpec::Get(c);
8518 if (!cs->IsValid()) continue;
8520 if (_cur.grffile->cargo_list.Length() == 0) {
8521 /* Default translation table, so just a straight mapping to bitnum */
8522 _cur.grffile->cargo_map[c] = cs->bitnum;
8523 } else {
8524 /* Check the translation table for this cargo's label */
8525 int index = _cur.grffile->cargo_list.FindIndex(cs->label);
8526 if (index >= 0) _cur.grffile->cargo_map[c] = index;
8532 * Prepare loading a NewGRF file with its config
8533 * @param config The NewGRF configuration struct with name, id, parameters and alike.
8535 static void InitNewGRFFile(const GRFConfig *config)
8537 GRFFile *newfile = GetFileByFilename(config->filename);
8538 if (newfile != nullptr) {
8539 /* We already loaded it once. */
8540 _cur.grffile = newfile;
8541 return;
8544 newfile = new GRFFile(config);
8545 *_grf_files.Append() = _cur.grffile = newfile;
8549 * Constructor for GRFFile
8550 * @param config GRFConfig to copy name, grfid and parameters from.
8552 GRFFile::GRFFile(const GRFConfig *config)
8554 this->filename = stredup(config->filename);
8555 this->grfid = config->ident.grfid;
8557 /* Initialise local settings to defaults */
8558 this->traininfo_vehicle_pitch = 0;
8559 this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
8561 /* Mark price_base_multipliers as 'not set' */
8562 for (Price i = PR_BEGIN; i < PR_END; i++) {
8563 this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
8566 /* Initialise rail type map with default rail types */
8567 memset(this->railtype_map, INVALID_RAILTYPE, sizeof(this->railtype_map));
8568 this->railtype_map[0] = RAILTYPE_RAIL;
8569 this->railtype_map[1] = RAILTYPE_ELECTRIC;
8570 this->railtype_map[2] = RAILTYPE_MONO;
8571 this->railtype_map[3] = RAILTYPE_MAGLEV;
8573 /* Initialise road type map with default road types */
8574 memset(this->roadtype_map, INVALID_ROADSUBTYPE, sizeof(this->roadtype_map));
8575 this->roadtype_map[ROADTYPE_ROAD][0] = ROADSUBTYPE_NORMAL;
8576 this->roadtype_map[ROADTYPE_ROAD][1] = ROADSUBTYPE_ELECTRIC;
8577 this->roadtype_map[ROADTYPE_TRAM][0] = ROADSUBTYPE_NORMAL;
8578 this->roadtype_map[ROADTYPE_TRAM][1] = ROADSUBTYPE_ELECTRIC;
8580 /* Copy the initial parameter list
8581 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8582 assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80);
8584 assert(config->num_params <= lengthof(config->param));
8585 this->param_end = config->num_params;
8586 if (this->param_end > 0) {
8587 MemCpyT(this->param, config->param, this->param_end);
8591 GRFFile::~GRFFile()
8593 free(this->filename);
8594 delete[] this->language_map;
8599 * List of what cargo labels are refittable for the given the vehicle-type.
8600 * Only currently active labels are applied.
8602 static const CargoLabel _default_refitmasks_rail[] = {
8603 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8604 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8605 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8606 'PLST', 'FZDR',
8607 0 };
8609 static const CargoLabel _default_refitmasks_road[] = {
8610 0 };
8612 static const CargoLabel _default_refitmasks_ships[] = {
8613 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8614 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8615 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8616 'PLST', 'FZDR',
8617 0 };
8619 static const CargoLabel _default_refitmasks_aircraft[] = {
8620 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8621 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8622 0 };
8624 static const CargoLabel * const _default_refitmasks[] = {
8625 _default_refitmasks_rail,
8626 _default_refitmasks_road,
8627 _default_refitmasks_ships,
8628 _default_refitmasks_aircraft,
8633 * Precalculate refit masks from cargo classes for all vehicles.
8635 static void CalculateRefitMasks()
8637 Engine *e;
8639 FOR_ALL_ENGINES(e) {
8640 EngineID engine = e->index;
8641 EngineInfo *ei = &e->info;
8642 bool only_defaultcargo; ///< Set if the vehicle shall carry only the default cargo
8644 /* Did the newgrf specify any refitting? If not, use defaults. */
8645 if (_gted[engine].refittability != GRFTempEngineData::UNSET) {
8646 uint32 mask = 0;
8647 uint32 not_mask = 0;
8648 uint32 xor_mask = ei->refit_mask;
8650 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8651 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8652 only_defaultcargo = _gted[engine].refittability == GRFTempEngineData::EMPTY;
8654 if (_gted[engine].cargo_allowed != 0) {
8655 /* Build up the list of cargo types from the set cargo classes. */
8656 const CargoSpec *cs;
8657 FOR_ALL_CARGOSPECS(cs) {
8658 if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
8659 if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
8663 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) & _cargo_mask;
8665 /* Apply explicit refit includes/excludes. */
8666 ei->refit_mask |= _gted[engine].ctt_include_mask;
8667 ei->refit_mask &= ~_gted[engine].ctt_exclude_mask;
8668 } else {
8669 uint32 xor_mask = 0;
8671 /* Don't apply default refit mask to wagons nor engines with no capacity */
8672 if (e->type != VEH_TRAIN || (e->u.rail.capacity != 0 && e->u.rail.railveh_type != RAILVEH_WAGON)) {
8673 const CargoLabel *cl = _default_refitmasks[e->type];
8674 for (uint i = 0;; i++) {
8675 if (cl[i] == 0) break;
8677 CargoID cargo = GetCargoIDByLabel(cl[i]);
8678 if (cargo == CT_INVALID) continue;
8680 SetBit(xor_mask, cargo);
8684 ei->refit_mask = xor_mask & _cargo_mask;
8686 /* If the mask is zero, the vehicle shall only carry the default cargo */
8687 only_defaultcargo = (ei->refit_mask == 0);
8690 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8691 if (ei->cargo_type != CT_INVALID && !HasBit(_cargo_mask, ei->cargo_type)) ei->cargo_type = CT_INVALID;
8693 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8694 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8695 if (!only_defaultcargo && (e->type != VEH_SHIP || e->u.ship.old_refittable) && ei->cargo_type != CT_INVALID && !HasBit(ei->refit_mask, ei->cargo_type)) {
8696 ei->cargo_type = CT_INVALID;
8699 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8700 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8701 if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) {
8702 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8703 const uint8 *cargo_map_for_first_refittable = nullptr;
8705 const GRFFile *file = _gted[engine].defaultcargo_grf;
8706 if (file == nullptr) file = e->GetGRF();
8707 if (file != nullptr && file->grf_version >= 8 && file->cargo_list.Length() != 0) {
8708 cargo_map_for_first_refittable = file->cargo_map;
8712 if (cargo_map_for_first_refittable != nullptr) {
8713 /* Use first refittable cargo from cargo translation table */
8714 byte best_local_slot = 0xFF;
8715 CargoID cargo_type;
8716 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8717 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8718 if (local_slot < best_local_slot) {
8719 best_local_slot = local_slot;
8720 ei->cargo_type = cargo_type;
8725 if (ei->cargo_type == CT_INVALID) {
8726 /* Use first refittable cargo slot */
8727 ei->cargo_type = (CargoID)FindFirstBit(ei->refit_mask);
8730 if (ei->cargo_type == CT_INVALID) ei->climates = 0;
8732 /* Clear refit_mask for not refittable ships */
8733 if (e->type == VEH_SHIP && !e->u.ship.old_refittable) {
8734 ei->refit_mask = 0;
8739 /** Set to use the correct action0 properties for each canal feature */
8740 static void FinaliseCanals()
8742 for (uint i = 0; i < CF_END; i++) {
8743 if (_water_feature[i].grffile != nullptr) {
8744 _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask;
8745 _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags;
8750 /** Check for invalid engines */
8751 static void FinaliseEngineArray()
8753 Engine *e;
8755 FOR_ALL_ENGINES(e) {
8756 if (e->GetGRF() == nullptr) {
8757 const EngineIDMapping &eid = _engine_mngr[e->index];
8758 if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) {
8759 e->info.string_id = STR_NEWGRF_INVALID_ENGINE;
8763 /* When the train does not set property 27 (misc flags), but it
8764 * is overridden by a NewGRF graphically we want to disable the
8765 * flipping possibility. */
8766 if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != nullptr && is_custom_sprite(e->u.rail.image_index)) {
8767 ClrBit(e->info.misc_flags, EF_RAIL_FLIPS);
8770 /* Skip wagons, there livery is defined via the engine */
8771 if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) {
8772 LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, nullptr);
8773 SetBit(_loaded_newgrf_features.used_liveries, ls);
8774 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8776 if (e->type == VEH_TRAIN) {
8777 SetBit(_loaded_newgrf_features.used_liveries, LS_FREIGHT_WAGON);
8778 switch (ls) {
8779 case LS_STEAM:
8780 case LS_DIESEL:
8781 case LS_ELECTRIC:
8782 case LS_MONORAIL:
8783 case LS_MAGLEV:
8784 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_STEAM + ls - LS_STEAM);
8785 break;
8787 case LS_DMU:
8788 case LS_EMU:
8789 SetBit(_loaded_newgrf_features.used_liveries, LS_PASSENGER_WAGON_DIESEL + ls - LS_DMU);
8790 break;
8792 default: NOT_REACHED();
8799 /** Check for invalid cargoes */
8800 static void FinaliseCargoArray()
8802 for (CargoID c = 0; c < NUM_CARGO; c++) {
8803 CargoSpec *cs = CargoSpec::Get(c);
8804 if (!cs->IsValid()) {
8805 cs->name = cs->name_single = cs->units_volume = STR_NEWGRF_INVALID_CARGO;
8806 cs->quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8807 cs->abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8813 * Check if a given housespec is valid and disable it if it's not.
8814 * The housespecs that follow it are used to check the validity of
8815 * multitile houses.
8816 * @param hs The housespec to check.
8817 * @param next1 The housespec that follows \c hs.
8818 * @param next2 The housespec that follows \c next1.
8819 * @param next3 The housespec that follows \c next2.
8820 * @param filename The filename of the newgrf this house was defined in.
8821 * @return Whether the given housespec is valid.
8823 static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename)
8825 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 &&
8826 (next1 == nullptr || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) ||
8827 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 &&
8828 (next2 == nullptr || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 ||
8829 next3 == nullptr || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) {
8830 hs->enabled = false;
8831 if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", filename, hs->grf_prop.local_id);
8832 return false;
8835 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8836 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8837 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8838 if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) ||
8839 ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) {
8840 hs->enabled = false;
8841 if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", filename, hs->grf_prop.local_id);
8842 return false;
8845 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8846 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8847 if (filename != nullptr && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) {
8848 hs->enabled = false;
8849 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);
8850 return false;
8853 /* Make sure that additional parts of multitile houses are not available. */
8854 if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) {
8855 hs->enabled = false;
8856 if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d without a size but marked it as available. Disabling house.", filename, hs->grf_prop.local_id);
8857 return false;
8860 return true;
8864 * Make sure there is at least one house available in the year 0 for the given
8865 * climate / housezone combination.
8866 * @param bitmask The climate and housezone to check for. Exactly one climate
8867 * bit and one housezone bit should be set.
8869 static void EnsureEarlyHouse(HouseZones bitmask)
8871 std::map<int32, Year> min_year;
8873 for (int i = 0; i < NUM_HOUSES; i++) {
8874 HouseSpec *hs = HouseSpec::Get(i);
8875 if (hs == nullptr || !hs->enabled) continue;
8876 if ((hs->building_availability & bitmask) != bitmask) continue;
8878 int32 grfid = (hs->grf_prop.grffile != nullptr) ? hs->grf_prop.grffile->grfid : -1;
8879 min_year[grfid] = MAX_YEAR;
8882 for (int i = 0; i < NUM_HOUSES; i++) {
8883 HouseSpec *hs = HouseSpec::Get(i);
8884 if (hs == nullptr || !hs->enabled) continue;
8885 if ((hs->building_availability & bitmask) != bitmask) continue;
8887 int32 grfid = (hs->grf_prop.grffile != nullptr) ? hs->grf_prop.grffile->grfid : -1;
8888 if (hs->min_year < min_year[grfid]) min_year[grfid] = hs->min_year;
8891 for (int i = 0; i < NUM_HOUSES; i++) {
8892 HouseSpec *hs = HouseSpec::Get(i);
8893 if (hs == nullptr || !hs->enabled) continue;
8894 if ((hs->building_availability & bitmask) != bitmask) continue;
8896 int32 grfid = (hs->grf_prop.grffile != nullptr) ? hs->grf_prop.grffile->grfid : -1;
8897 if (hs->min_year == min_year[grfid]) hs->min_year = 0;
8902 * Add all new houses to the house array. House properties can be set at any
8903 * time in the GRF file, so we can only add a house spec to the house array
8904 * after the file has finished loading. We also need to check the dates, due to
8905 * the TTDPatch behaviour described below that we need to emulate.
8907 static void FinaliseHouseArray()
8909 /* If there are no houses with start dates before 1930, then all houses
8910 * with start dates of 1930 have them reset to 0. This is in order to be
8911 * compatible with TTDPatch, where if no houses have start dates before
8912 * 1930 and the date is before 1930, the game pretends that this is 1930.
8913 * If there have been any houses defined with start dates before 1930 then
8914 * the dates are left alone.
8915 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8916 * minimum introduction date to 0.
8918 const GRFFile * const *end = _grf_files.End();
8919 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8920 HouseSpec **&housespec = (*file)->housespec;
8921 if (housespec == nullptr) continue;
8923 for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) {
8924 HouseSpec *hs = housespec[i];
8926 if (hs == nullptr) continue;
8928 const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : nullptr);
8929 const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : nullptr);
8930 const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : nullptr);
8932 if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue;
8934 _house_mngr.SetEntitySpec(hs);
8938 for (int i = 0; i < NUM_HOUSES; i++) {
8939 HouseSpec *hs = HouseSpec::Get(i);
8940 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr);
8941 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr);
8942 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : nullptr);
8944 /* We need to check all houses again to we are sure that multitile houses
8945 * did get consecutive IDs and none of the parts are missing. */
8946 if (!IsHouseSpecValid(hs, next1, next2, next3, nullptr)) {
8947 /* GetHouseNorthPart checks 3 houses that are directly before
8948 * it in the house pool. If any of those houses have multi-tile
8949 * flags set it assumes it's part of a multitile house. Since
8950 * we can have invalid houses in the pool marked as disabled, we
8951 * don't want to have them influencing valid tiles. As such set
8952 * building_flags to zero here to make sure any house following
8953 * this one in the pool is properly handled as 1x1 house. */
8954 hs->building_flags = TILE_NO_FLAG;
8958 HouseZones climate_mask = (HouseZones)(1 << (_settings_game.game_creation.landscape + 12));
8959 EnsureEarlyHouse(HZ_ZON1 | climate_mask);
8960 EnsureEarlyHouse(HZ_ZON2 | climate_mask);
8961 EnsureEarlyHouse(HZ_ZON3 | climate_mask);
8962 EnsureEarlyHouse(HZ_ZON4 | climate_mask);
8963 EnsureEarlyHouse(HZ_ZON5 | climate_mask);
8965 if (_settings_game.game_creation.landscape == LT_ARCTIC) {
8966 EnsureEarlyHouse(HZ_ZON1 | HZ_SUBARTC_ABOVE);
8967 EnsureEarlyHouse(HZ_ZON2 | HZ_SUBARTC_ABOVE);
8968 EnsureEarlyHouse(HZ_ZON3 | HZ_SUBARTC_ABOVE);
8969 EnsureEarlyHouse(HZ_ZON4 | HZ_SUBARTC_ABOVE);
8970 EnsureEarlyHouse(HZ_ZON5 | HZ_SUBARTC_ABOVE);
8975 * Add all new industries to the industry array. Industry properties can be set at any
8976 * time in the GRF file, so we can only add a industry spec to the industry array
8977 * after the file has finished loading.
8979 static void FinaliseIndustriesArray()
8981 const GRFFile * const *end = _grf_files.End();
8982 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
8983 IndustrySpec **&industryspec = (*file)->industryspec;
8984 IndustryTileSpec **&indtspec = (*file)->indtspec;
8985 if (industryspec != nullptr) {
8986 for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) {
8987 IndustrySpec *indsp = industryspec[i];
8989 if (indsp != nullptr && indsp->enabled) {
8990 StringID strid;
8991 /* process the conversion of text at the end, so to be sure everything will be fine
8992 * and available. Check if it does not return undefind marker, which is a very good sign of a
8993 * substitute industry who has not changed the string been examined, thus using it as such */
8994 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->name);
8995 if (strid != STR_UNDEFINED) indsp->name = strid;
8997 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->closure_text);
8998 if (strid != STR_UNDEFINED) indsp->closure_text = strid;
9000 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_up_text);
9001 if (strid != STR_UNDEFINED) indsp->production_up_text = strid;
9003 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->production_down_text);
9004 if (strid != STR_UNDEFINED) indsp->production_down_text = strid;
9006 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
9007 if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
9009 if (indsp->station_name != STR_NULL) {
9010 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
9011 * station's name. Don't want to lose the value, therefore, do not process. */
9012 strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->station_name);
9013 if (strid != STR_UNDEFINED) indsp->station_name = strid;
9016 _industry_mngr.SetEntitySpec(indsp);
9017 _loaded_newgrf_features.has_newindustries = true;
9022 if (indtspec != nullptr) {
9023 for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) {
9024 IndustryTileSpec *indtsp = indtspec[i];
9025 if (indtsp != nullptr) {
9026 _industile_mngr.SetEntitySpec(indtsp);
9032 for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) {
9033 IndustrySpec *indsp = &_industry_specs[j];
9034 if (indsp->enabled && indsp->grf_prop.grffile != nullptr) {
9035 for (uint i = 0; i < 3; i++) {
9036 indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid);
9039 if (!indsp->enabled) {
9040 indsp->name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
9046 * Add all new objects to the object array. Object properties can be set at any
9047 * time in the GRF file, so we can only add an object spec to the object array
9048 * after the file has finished loading.
9050 static void FinaliseObjectsArray()
9052 const GRFFile * const *end = _grf_files.End();
9053 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9054 ObjectSpec **&objectspec = (*file)->objectspec;
9055 if (objectspec != nullptr) {
9056 for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) {
9057 if (objectspec[i] != nullptr && objectspec[i]->grf_prop.grffile != nullptr && objectspec[i]->enabled) {
9058 _object_mngr.SetEntitySpec(objectspec[i]);
9066 * Add all new airports to the airport array. Airport properties can be set at any
9067 * time in the GRF file, so we can only add a airport spec to the airport array
9068 * after the file has finished loading.
9070 static void FinaliseAirportsArray()
9072 const GRFFile * const *end = _grf_files.End();
9073 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9074 AirportSpec **&airportspec = (*file)->airportspec;
9075 if (airportspec != nullptr) {
9076 for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) {
9077 if (airportspec[i] != nullptr && airportspec[i]->enabled) {
9078 _airport_mngr.SetEntitySpec(airportspec[i]);
9083 AirportTileSpec **&airporttilespec = (*file)->airtspec;
9084 if (airporttilespec != nullptr) {
9085 for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) {
9086 if (airporttilespec[i] != nullptr && airporttilespec[i]->enabled) {
9087 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
9094 /* Here we perform initial decoding of some special sprites (as are they
9095 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
9096 * partial implementation yet).
9097 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
9098 * a crafted invalid GRF file. We should tell that to the user somehow, or
9099 * better make this more robust in the future. */
9100 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
9102 /* XXX: There is a difference between staged loading in TTDPatch and
9103 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
9104 * during stage 1, whilst action 3 is carried out during stage 2 (to
9105 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
9106 * IDs are valid only within a given set (action 1) block, and may be
9107 * overwritten after action 3 associates them. But overwriting happens
9108 * in an earlier stage than associating, so... We just process actions
9109 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
9110 * --pasky
9111 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
9112 * is not in memory and scanning the file every time would be too expensive.
9113 * In other stages we skip action 0x10 since it's already dealt with. */
9114 static const SpecialSpriteHandler handlers[][GLS_END] = {
9115 /* 0x00 */ { nullptr, SafeChangeInfo, nullptr, nullptr, ReserveChangeInfo, FeatureChangeInfo, },
9116 /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
9117 /* 0x02 */ { nullptr, nullptr, nullptr, nullptr, nullptr, NewSpriteGroup, },
9118 /* 0x03 */ { nullptr, GRFUnsafe, nullptr, nullptr, nullptr, FeatureMapSpriteGroup, },
9119 /* 0x04 */ { nullptr, nullptr, nullptr, nullptr, nullptr, FeatureNewName, },
9120 /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
9121 /* 0x06 */ { nullptr, nullptr, nullptr, CfgApply, CfgApply, CfgApply, },
9122 /* 0x07 */ { nullptr, nullptr, nullptr, nullptr, SkipIf, SkipIf, },
9123 /* 0x08 */ { ScanInfo, nullptr, nullptr, GRFInfo, GRFInfo, GRFInfo, },
9124 /* 0x09 */ { nullptr, nullptr, nullptr, SkipIf, SkipIf, SkipIf, },
9125 /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
9126 /* 0x0B */ { nullptr, nullptr, nullptr, GRFLoadError, GRFLoadError, GRFLoadError, },
9127 /* 0x0C */ { nullptr, nullptr, nullptr, GRFComment, nullptr, GRFComment, },
9128 /* 0x0D */ { nullptr, SafeParamSet, nullptr, ParamSet, ParamSet, ParamSet, },
9129 /* 0x0E */ { nullptr, SafeGRFInhibit, nullptr, GRFInhibit, GRFInhibit, GRFInhibit, },
9130 /* 0x0F */ { nullptr, GRFUnsafe, nullptr, FeatureTownName, nullptr, nullptr, },
9131 /* 0x10 */ { nullptr, nullptr, DefineGotoLabel, nullptr, nullptr, nullptr, },
9132 /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
9133 /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, },
9134 /* 0x13 */ { nullptr, nullptr, nullptr, nullptr, nullptr, TranslateGRFStrings, },
9135 /* 0x14 */ { StaticGRFInfo, nullptr, nullptr, nullptr, nullptr, nullptr, },
9138 GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line);
9140 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
9141 if (it == _grf_line_to_action6_sprite_override.end()) {
9142 /* No preloaded sprite to work with; read the
9143 * pseudo sprite content. */
9144 FioReadBlock(buf, num);
9145 } else {
9146 /* Use the preloaded sprite data. */
9147 buf = it->second;
9148 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
9150 /* Skip the real (original) content of this action. */
9151 FioSeekTo(num, SEEK_CUR);
9154 ByteReader br(buf, buf + num);
9155 ByteReader *bufp = &br;
9157 try {
9158 byte action = bufp->ReadByte();
9160 if (action == 0xFF) {
9161 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
9162 } else if (action == 0xFE) {
9163 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
9164 } else if (action >= lengthof(handlers)) {
9165 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
9166 } else if (handlers[action][stage] == nullptr) {
9167 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
9168 } else {
9169 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
9170 handlers[action][stage](bufp);
9172 } catch (...) {
9173 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
9174 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS);
9179 /** Signature of a container version 2 GRF. */
9180 extern const byte _grf_cont_v2_sig[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
9183 * Get the container version of the currently opened GRF file.
9184 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
9186 byte GetGRFContainerVersion()
9188 size_t pos = FioGetPos();
9190 if (FioReadWord() == 0) {
9191 /* Check for GRF container version 2, which is identified by the bytes
9192 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
9193 for (uint i = 0; i < lengthof(_grf_cont_v2_sig); i++) {
9194 if (FioReadByte() != _grf_cont_v2_sig[i]) return 0; // Invalid format
9197 return 2;
9200 /* Container version 1 has no header, rewind to start. */
9201 FioSeekTo(pos, SEEK_SET);
9202 return 1;
9206 * Load a particular NewGRF.
9207 * @param config The configuration of the to be loaded NewGRF.
9208 * @param file_index The Fio index of the first NewGRF to load.
9209 * @param stage The loading stage of the NewGRF.
9210 * @param subdir The sub directory to find the NewGRF in.
9212 void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, Subdirectory subdir)
9214 const char *filename = config->filename;
9216 /* A .grf file is activated only if it was active when the game was
9217 * started. If a game is loaded, only its active .grfs will be
9218 * reactivated, unless "loadallgraphics on" is used. A .grf file is
9219 * considered active if its action 8 has been processed, i.e. its
9220 * action 8 hasn't been skipped using an action 7.
9222 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
9223 * carried out. All others are ignored, because they only need to be
9224 * processed once at initialization. */
9225 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
9226 _cur.grffile = GetFileByFilename(filename);
9227 if (_cur.grffile == nullptr) usererror("File '%s' lost in cache.\n", filename);
9228 if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
9229 if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
9232 if (file_index >= MAX_FILE_SLOTS) {
9233 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of file slots has been reached", filename);
9234 config->status = GCS_DISABLED;
9235 config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9236 return;
9239 FioOpenFile(file_index, filename, subdir);
9240 _cur.file_index = file_index; // XXX
9241 _palette_remap_grf[_cur.file_index] = (config->palette & GRFP_USE_MASK);
9243 _cur.grfconfig = config;
9245 DEBUG(grf, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
9247 _cur.grf_container_ver = GetGRFContainerVersion();
9248 if (_cur.grf_container_ver == 0) {
9249 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
9250 return;
9253 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
9254 /* We need the sprite offsets in the init stage for NewGRF sounds
9255 * and in the activation stage for real sprites. */
9256 ReadGRFSpriteOffsets(_cur.grf_container_ver);
9257 } else {
9258 /* Skip sprite section offset if present. */
9259 if (_cur.grf_container_ver >= 2) FioReadDword();
9262 if (_cur.grf_container_ver >= 2) {
9263 /* Read compression value. */
9264 byte compression = FioReadByte();
9265 if (compression != 0) {
9266 DEBUG(grf, 7, "LoadNewGRFFile: Unsupported compression format");
9267 return;
9271 /* Skip the first sprite; we don't care about how many sprites this
9272 * does contain; newest TTDPatches and George's longvehicles don't
9273 * neither, apparently. */
9274 uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord();
9275 if (num == 4 && FioReadByte() == 0xFF) {
9276 FioReadDword();
9277 } else {
9278 DEBUG(grf, 7, "LoadNewGRFFile: Custom .grf has invalid format");
9279 return;
9282 _cur.ClearDataForNextFile();
9284 ReusableBuffer<byte> buf;
9286 while ((num = (_cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord())) != 0) {
9287 byte type = FioReadByte();
9288 _cur.nfo_line++;
9290 if (type == 0xFF) {
9291 if (_cur.skip_sprites == 0) {
9292 DecodeSpecialSprite(buf.Allocate(num), num, stage);
9294 /* Stop all processing if we are to skip the remaining sprites */
9295 if (_cur.skip_sprites == -1) break;
9297 continue;
9298 } else {
9299 FioSkipBytes(num);
9301 } else {
9302 if (_cur.skip_sprites == 0) {
9303 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
9304 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
9305 break;
9308 if (_cur.grf_container_ver >= 2 && type == 0xFD) {
9309 /* Reference to data section. Container version >= 2 only. */
9310 FioSkipBytes(num);
9311 } else {
9312 FioSkipBytes(7);
9313 SkipSpriteData(type, num - 8);
9317 if (_cur.skip_sprites > 0) _cur.skip_sprites--;
9322 * Relocates the old shore sprites at new positions.
9324 * 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)
9325 * 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)
9326 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
9328 static void ActivateOldShore()
9330 /* Use default graphics, if no shore sprites were loaded.
9331 * Should not happen, as the base set's extra grf should include some. */
9332 if (_loaded_newgrf_features.shore == SHORE_REPLACE_NONE) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_A;
9334 if (_loaded_newgrf_features.shore != SHORE_REPLACE_ACTION_5) {
9335 DupSprite(SPR_ORIGINALSHORE_START + 1, SPR_SHORE_BASE + 1); // SLOPE_W
9336 DupSprite(SPR_ORIGINALSHORE_START + 2, SPR_SHORE_BASE + 2); // SLOPE_S
9337 DupSprite(SPR_ORIGINALSHORE_START + 6, SPR_SHORE_BASE + 3); // SLOPE_SW
9338 DupSprite(SPR_ORIGINALSHORE_START + 0, SPR_SHORE_BASE + 4); // SLOPE_E
9339 DupSprite(SPR_ORIGINALSHORE_START + 4, SPR_SHORE_BASE + 6); // SLOPE_SE
9340 DupSprite(SPR_ORIGINALSHORE_START + 3, SPR_SHORE_BASE + 8); // SLOPE_N
9341 DupSprite(SPR_ORIGINALSHORE_START + 7, SPR_SHORE_BASE + 9); // SLOPE_NW
9342 DupSprite(SPR_ORIGINALSHORE_START + 5, SPR_SHORE_BASE + 12); // SLOPE_NE
9345 if (_loaded_newgrf_features.shore == SHORE_REPLACE_ACTION_A) {
9346 DupSprite(SPR_FLAT_GRASS_TILE + 16, SPR_SHORE_BASE + 0); // SLOPE_STEEP_S
9347 DupSprite(SPR_FLAT_GRASS_TILE + 17, SPR_SHORE_BASE + 5); // SLOPE_STEEP_W
9348 DupSprite(SPR_FLAT_GRASS_TILE + 7, SPR_SHORE_BASE + 7); // SLOPE_WSE
9349 DupSprite(SPR_FLAT_GRASS_TILE + 15, SPR_SHORE_BASE + 10); // SLOPE_STEEP_N
9350 DupSprite(SPR_FLAT_GRASS_TILE + 11, SPR_SHORE_BASE + 11); // SLOPE_NWS
9351 DupSprite(SPR_FLAT_GRASS_TILE + 13, SPR_SHORE_BASE + 13); // SLOPE_ENW
9352 DupSprite(SPR_FLAT_GRASS_TILE + 14, SPR_SHORE_BASE + 14); // SLOPE_SEN
9353 DupSprite(SPR_FLAT_GRASS_TILE + 18, SPR_SHORE_BASE + 15); // SLOPE_STEEP_E
9355 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
9356 * If they would be used somewhen, then these grass tiles will most like not look as needed */
9357 DupSprite(SPR_FLAT_GRASS_TILE + 5, SPR_SHORE_BASE + 16); // SLOPE_EW
9358 DupSprite(SPR_FLAT_GRASS_TILE + 10, SPR_SHORE_BASE + 17); // SLOPE_NS
9363 * Replocate the old tram depot sprites to the new position, if no new ones were loaded.
9365 static void ActivateOldTramDepot()
9367 if (_loaded_newgrf_features.tram == TRAMWAY_REPLACE_DEPOT_WITH_TRACK) {
9368 DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0); // use road depot graphics for "no tracks"
9369 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1);
9370 DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2); // use road depot graphics for "no tracks"
9371 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3);
9372 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4);
9373 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5);
9378 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
9380 static void FinalisePriceBaseMultipliers()
9382 extern const PriceBaseSpec _price_base_specs[];
9383 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
9384 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9386 /* Evaluate grf overrides */
9387 int num_grfs = _grf_files.Length();
9388 int *grf_overrides = AllocaM(int, num_grfs);
9389 for (int i = 0; i < num_grfs; i++) {
9390 grf_overrides[i] = -1;
9392 GRFFile *source = _grf_files[i];
9393 uint32 override = _grf_id_overrides[source->grfid];
9394 if (override == 0) continue;
9396 GRFFile *dest = GetFileByGRFID(override);
9397 if (dest == nullptr) continue;
9399 grf_overrides[i] = _grf_files.FindIndex(dest);
9400 assert(grf_overrides[i] >= 0);
9403 /* Override features and price base multipliers of earlier loaded grfs */
9404 for (int i = 0; i < num_grfs; i++) {
9405 if (grf_overrides[i] < 0 || grf_overrides[i] >= i) continue;
9406 GRFFile *source = _grf_files[i];
9407 GRFFile *dest = _grf_files[grf_overrides[i]];
9409 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9410 source->grf_features |= features;
9411 dest->grf_features |= features;
9413 for (Price p = PR_BEGIN; p < PR_END; p++) {
9414 /* No price defined -> nothing to do */
9415 if (!HasBit(features, _price_base_specs[p].grf_feature) || source->price_base_multipliers[p] == INVALID_PRICE_MODIFIER) continue;
9416 DEBUG(grf, 3, "'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9417 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9421 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9422 for (int i = num_grfs - 1; i >= 0; i--) {
9423 if (grf_overrides[i] < 0 || grf_overrides[i] <= i) continue;
9424 GRFFile *source = _grf_files[i];
9425 GRFFile *dest = _grf_files[grf_overrides[i]];
9427 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9428 source->grf_features |= features;
9429 dest->grf_features |= features;
9431 for (Price p = PR_BEGIN; p < PR_END; p++) {
9432 /* Already a price defined -> nothing to do */
9433 if (!HasBit(features, _price_base_specs[p].grf_feature) || dest->price_base_multipliers[p] != INVALID_PRICE_MODIFIER) continue;
9434 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9435 dest->price_base_multipliers[p] = source->price_base_multipliers[p];
9439 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9440 for (int i = 0; i < num_grfs; i++) {
9441 if (grf_overrides[i] < 0) continue;
9442 GRFFile *source = _grf_files[i];
9443 GRFFile *dest = _grf_files[grf_overrides[i]];
9445 uint32 features = (source->grf_features | dest->grf_features) & override_features;
9446 source->grf_features |= features;
9447 dest->grf_features |= features;
9449 for (Price p = PR_BEGIN; p < PR_END; p++) {
9450 if (!HasBit(features, _price_base_specs[p].grf_feature)) continue;
9451 if (source->price_base_multipliers[p] != dest->price_base_multipliers[p]) {
9452 DEBUG(grf, 3, "Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9454 source->price_base_multipliers[p] = dest->price_base_multipliers[p];
9458 /* Apply fallback prices for grf version < 8 */
9459 const GRFFile * const *end = _grf_files.End();
9460 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9461 if ((*file)->grf_version >= 8) continue;
9462 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9463 for (Price p = PR_BEGIN; p < PR_END; p++) {
9464 Price fallback_price = _price_base_specs[p].fallback_price;
9465 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9466 /* No price multiplier has been set.
9467 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9468 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9473 /* Decide local/global scope of price base multipliers */
9474 for (GRFFile **file = _grf_files.Begin(); file != end; file++) {
9475 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9476 for (Price p = PR_BEGIN; p < PR_END; p++) {
9477 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9478 /* No multiplier was set; set it to a neutral value */
9479 price_base_multipliers[p] = 0;
9480 } else {
9481 if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) {
9482 /* The grf does not define any objects of the feature,
9483 * so it must be a difficulty setting. Apply it globally */
9484 DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p);
9485 SetPriceBaseMultiplier(p, price_base_multipliers[p]);
9486 price_base_multipliers[p] = 0;
9487 } else {
9488 DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p);
9495 extern void InitGRFTownGeneratorNames();
9497 /** Finish loading NewGRFs and execute needed post-processing */
9498 static void AfterLoadGRFs()
9500 for (StringIDMapping *it = _string_to_grf_mapping.Begin(); it != _string_to_grf_mapping.End(); it++) {
9501 *it->target = MapGRFStringID(it->grfid, it->source);
9503 _string_to_grf_mapping.Clear();
9505 /* Free the action 6 override sprites. */
9506 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9507 free((*it).second);
9509 _grf_line_to_action6_sprite_override.clear();
9511 /* Polish cargoes */
9512 FinaliseCargoArray();
9514 /* Pre-calculate all refit masks after loading GRF files. */
9515 CalculateRefitMasks();
9517 /* Polish engines */
9518 FinaliseEngineArray();
9520 /* Set the actually used Canal properties */
9521 FinaliseCanals();
9523 /* Add all new houses to the house array. */
9524 FinaliseHouseArray();
9526 /* Add all new industries to the industry array. */
9527 FinaliseIndustriesArray();
9529 /* Add all new objects to the object array. */
9530 FinaliseObjectsArray();
9532 InitializeSortedCargoSpecs();
9534 /* Sort the list of industry types. */
9535 SortIndustryTypes();
9537 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9538 BuildIndustriesLegend();
9540 /* Build the routemap legend, based on the available cargos */
9541 BuildLinkStatsLegend();
9543 /* Add all new airports to the airports array. */
9544 FinaliseAirportsArray();
9545 BindAirportSpecs();
9547 /* Update the townname generators list */
9548 InitGRFTownGeneratorNames();
9550 /* Run all queued vehicle list order changes */
9551 CommitVehicleListOrderChanges();
9553 /* Load old shore sprites in new position, if they were replaced by ActionA */
9554 ActivateOldShore();
9556 /* Load old tram depot sprites in new position, if no new ones are present */
9557 ActivateOldTramDepot();
9559 /* Set up custom rail types */
9560 InitRailTypes();
9561 InitRoadTypes();
9563 Engine *e;
9564 FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
9565 RoadType rt = HasBit(e->info.misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
9566 const GRFFile *file = e->GetGRF();
9567 if (file != NULL && _gted[e->index].roadsubtype < file->roadtype_list[rt].Length()) {
9568 RoadTypeIdentifier rtid = GetRoadTypeByLabel(file->roadtype_list[rt][_gted[e->index].roadsubtype], rt, true);
9569 if (rtid.IsValid()) {
9570 e->u.road.roadsubtype = rtid.subtype;
9571 } else {
9572 /* Road type is not available, so disable this engine */
9573 e->info.climates = 0;
9575 } else {
9576 e->u.road.roadsubtype = rt == ROADTYPE_TRAM ? ROADSUBTYPE_ELECTRIC : ROADSUBTYPE_NORMAL;
9579 if (_gted[e->index].rv_max_speed != 0) {
9580 /* Set RV maximum speed from the mph/0.8 unit value */
9581 e->u.road.max_speed = _gted[e->index].rv_max_speed * 4;
9585 FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) {
9586 RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel);
9587 if (railtype == INVALID_RAILTYPE) {
9588 /* Rail type is not available, so disable this engine */
9589 e->info.climates = 0;
9590 } else {
9591 e->u.rail.railtype = railtype;
9595 SetYearEngineAgingStops();
9597 FinalisePriceBaseMultipliers();
9599 /* Deallocate temporary loading data */
9600 free(_gted);
9601 _grm_sprites.clear();
9605 * Load all the NewGRFs.
9606 * @param load_index The offset for the first sprite to add.
9607 * @param file_index The Fio index of the first NewGRF to load.
9608 * @param num_baseset Number of NewGRFs at the front of the list to look up in the baseset dir instead of the newgrf dir.
9610 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9612 /* In case of networking we need to "sync" the start values
9613 * so all NewGRFs are loaded equally. For this we use the
9614 * start date of the game and we set the counters, etc. to
9615 * 0 so they're the same too. */
9616 Date date = _date;
9617 Year year = _cur_year;
9618 DateFract date_fract = _date_fract;
9619 uint16 tick_counter = _tick_counter;
9620 byte display_opt = _display_opt;
9622 if (_networking) {
9623 _cur_year = _settings_game.game_creation.starting_year;
9624 _date = ConvertYMDToDate(_cur_year, 0, 1);
9625 _date_fract = 0;
9626 _tick_counter = 0;
9627 _display_opt = 0;
9630 InitializeGRFSpecial();
9632 ResetNewGRFData();
9635 * Reset the status of all files, so we can 'retry' to load them.
9636 * This is needed when one for example rearranges the NewGRFs in-game
9637 * and a previously disabled NewGRF becomes useable. If it would not
9638 * be reset, the NewGRF would remain disabled even though it should
9639 * have been enabled.
9641 for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
9642 if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN;
9645 _cur.spriteid = load_index;
9647 /* Load newgrf sprites
9648 * in each loading stage, (try to) open each file specified in the config
9649 * and load information from it. */
9650 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9651 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9652 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9653 for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
9654 if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
9657 if (stage == GLS_RESERVE) {
9658 static const uint32 overrides[][2] = {
9659 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9660 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9661 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9663 for (size_t i = 0; i < lengthof(overrides); i++) {
9664 SetNewGRFOverride(BSWAP32(overrides[i][0]), BSWAP32(overrides[i][1]));
9668 uint slot = file_index;
9669 uint num_non_static = 0;
9671 _cur.stage = stage;
9672 for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
9673 if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
9674 if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
9676 Subdirectory subdir = slot < file_index + num_baseset ? BASESET_DIR : NEWGRF_DIR;
9677 if (!FioCheckFileExists(c->filename, subdir)) {
9678 DEBUG(grf, 0, "NewGRF file is missing '%s'; disabling", c->filename);
9679 c->status = GCS_NOT_FOUND;
9680 continue;
9683 if (stage == GLS_LABELSCAN) InitNewGRFFile(c);
9685 if (!HasBit(c->flags, GCF_STATIC) && !HasBit(c->flags, GCF_SYSTEM)) {
9686 if (slot == MAX_FILE_SLOTS) {
9687 DEBUG(grf, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->filename);
9688 c->status = GCS_DISABLED;
9689 c->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9690 continue;
9692 num_non_static++;
9694 LoadNewGRFFile(c, slot++, stage, subdir);
9695 if (stage == GLS_RESERVE) {
9696 SetBit(c->flags, GCF_RESERVED);
9697 } else if (stage == GLS_ACTIVATION) {
9698 ClrBit(c->flags, GCF_RESERVED);
9699 assert(GetFileByGRFID(c->ident.grfid) == _cur.grffile);
9700 ClearTemporaryNewGRFData(_cur.grffile);
9701 BuildCargoTranslationMap();
9702 DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur.spriteid);
9703 } else if (stage == GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) {
9704 /* We're not going to activate this, so free whatever data we allocated */
9705 ClearTemporaryNewGRFData(_cur.grffile);
9710 /* Pseudo sprite processing is finished; free temporary stuff */
9711 _cur.ClearDataForNextFile();
9713 /* Call any functions that should be run after GRFs have been loaded. */
9714 AfterLoadGRFs();
9716 /* Now revert back to the original situation */
9717 _cur_year = year;
9718 _date = date;
9719 _date_fract = date_fract;
9720 _tick_counter = tick_counter;
9721 _display_opt = display_opt;
9725 * Returns amount of user selected NewGRFs files.
9727 uint CountSelectedGRFs(GRFConfig *grfconf)
9729 uint i = 0;
9731 /* Find last entry in the list */
9732 for (const GRFConfig *list = grfconf; list != nullptr; list = list->next) {
9733 if (!HasBit(list->flags, GCF_STATIC) && !HasBit(list->flags, GCF_SYSTEM)) i++;
9735 return i;