2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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 /** @file newgrf.cpp Base of all NewGRF support. */
16 #include "fileio_func.h"
17 #include "engine_func.h"
18 #include "engine_base.h"
21 #include "newgrf_engine.h"
22 #include "newgrf_text.h"
23 #include "fontcache.h"
25 #include "landscape.h"
26 #include "newgrf_cargo.h"
27 #include "newgrf_house.h"
28 #include "newgrf_sound.h"
29 #include "newgrf_station.h"
30 #include "industrytype.h"
31 #include "newgrf_canal.h"
32 #include "newgrf_townname.h"
33 #include "newgrf_industries.h"
34 #include "newgrf_airporttiles.h"
35 #include "newgrf_airport.h"
36 #include "newgrf_object.h"
39 #include "strings_func.h"
40 #include "date_func.h"
41 #include "string_func.h"
42 #include "network/network.h"
44 #include "smallmap_gui.h"
47 #include "vehicle_func.h"
49 #include "vehicle_base.h"
52 #include "table/strings.h"
53 #include "table/build_industry.h"
55 #include "safeguards.h"
57 /* TTDPatch extended GRF format codec
58 * (c) Petr Baudis 2004 (GPL'd)
59 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
61 * Contains portions of documentation by TTDPatch team.
62 * Thanks especially to Josef Drexler for the documentation as well as a lot
63 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
64 * served as subject to the initial testing of this codec. */
66 /** List of all loaded GRF files */
67 static std::vector
<GRFFile
*> _grf_files
;
69 /** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
70 byte _misc_grf_features
= 0;
72 /** 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
73 static uint32 _ttdpatch_flags
[8];
75 /** Indicates which are the newgrf features currently loaded ingame */
76 GRFLoadedFeatures _loaded_newgrf_features
;
78 static const uint MAX_SPRITEGROUP
= UINT8_MAX
; ///< Maximum GRF-local ID for a spritegroup.
80 /** Temporary data during loading of GRFs */
81 struct GrfProcessingState
{
83 /** Definition of a single Action1 spriteset */
85 SpriteID sprite
; ///< SpriteID of the first sprite of the set.
86 uint num_sprites
; ///< Number of sprites in the set.
89 /** Currently referenceable spritesets */
90 std::map
<uint
, SpriteSet
> spritesets
[GSF_END
];
94 GrfLoadingStage stage
; ///< Current loading stage
95 SpriteID spriteid
; ///< First available SpriteID for loading realsprites.
97 /* Local state in the file */
98 uint file_index
; ///< File index of currently processed GRF file.
99 GRFFile
*grffile
; ///< Currently processed GRF file.
100 GRFConfig
*grfconfig
; ///< Config of the currently processed GRF file.
101 uint32 nfo_line
; ///< Currently processed pseudo sprite number in the GRF.
102 byte grf_container_ver
; ///< Container format of the current GRF file.
104 /* Kind of return values when processing certain actions */
105 int skip_sprites
; ///< Number of pseudo sprites to skip before processing the next one. (-1 to skip to end of file)
107 /* Currently referenceable spritegroups */
108 SpriteGroup
*spritegroups
[MAX_SPRITEGROUP
+ 1];
110 /** Clear temporary data before processing the next file in the current loading stage */
111 void ClearDataForNextFile()
114 this->skip_sprites
= 0;
116 for (uint i
= 0; i
< GSF_END
; i
++) {
117 this->spritesets
[i
].clear();
120 memset(this->spritegroups
, 0, sizeof(this->spritegroups
));
124 * Records new spritesets.
125 * @param feature GrfSpecFeature the set is defined for.
126 * @param first_sprite SpriteID of the first sprite in the set.
127 * @param first_set First spriteset to define.
128 * @param numsets Number of sets to define.
129 * @param numents Number of sprites per set to define.
131 void AddSpriteSets(byte feature
, SpriteID first_sprite
, uint first_set
, uint numsets
, uint numents
)
133 assert(feature
< GSF_END
);
134 for (uint i
= 0; i
< numsets
; i
++) {
135 SpriteSet
&set
= this->spritesets
[feature
][first_set
+ i
];
136 set
.sprite
= first_sprite
+ i
* numents
;
137 set
.num_sprites
= numents
;
142 * Check whether there are any valid spritesets for a feature.
143 * @param feature GrfSpecFeature to check.
144 * @return true if there are any valid sets.
145 * @note Spritesets with zero sprites are valid to allow callback-failures.
147 bool HasValidSpriteSets(byte feature
) const
149 assert(feature
< GSF_END
);
150 return !this->spritesets
[feature
].empty();
154 * Check whether a specific set is defined.
155 * @param feature GrfSpecFeature to check.
156 * @param set Set to check.
157 * @return true if the set is valid.
158 * @note Spritesets with zero sprites are valid to allow callback-failures.
160 bool IsValidSpriteSet(byte feature
, uint set
) const
162 assert(feature
< GSF_END
);
163 return this->spritesets
[feature
].find(set
) != this->spritesets
[feature
].end();
167 * Returns the first sprite of a spriteset.
168 * @param feature GrfSpecFeature to query.
169 * @param set Set to query.
170 * @return First sprite of the set.
172 SpriteID
GetSprite(byte feature
, uint set
) const
174 assert(IsValidSpriteSet(feature
, set
));
175 return this->spritesets
[feature
].find(set
)->second
.sprite
;
179 * Returns the number of sprites in a spriteset
180 * @param feature GrfSpecFeature to query.
181 * @param set Set to query.
182 * @return Number of sprites in the set.
184 uint
GetNumEnts(byte feature
, uint set
) const
186 assert(IsValidSpriteSet(feature
, set
));
187 return this->spritesets
[feature
].find(set
)->second
.num_sprites
;
191 static GrfProcessingState _cur
;
195 * Helper to check whether an image index is valid for a particular NewGRF vehicle.
196 * @tparam T The type of vehicle.
197 * @param image_index The image index to check.
198 * @return True iff the image index is valid, or 0xFD (use new graphics).
200 template <VehicleType T
>
201 static inline bool IsValidNewGRFImageIndex(uint8 image_index
)
203 return image_index
== 0xFD || IsValidImageIndex
<T
>(image_index
);
206 class OTTDByteReaderSignal
{ };
208 /** Class to read from a NewGRF file */
215 ByteReader(byte
*data
, byte
*end
) : data(data
), end(end
) { }
217 inline byte
ReadByte()
219 if (data
< end
) return *(data
)++;
220 throw OTTDByteReaderSignal();
225 uint16 val
= ReadByte();
226 return val
| (ReadByte() << 8);
229 uint16
ReadExtendedByte()
231 uint16 val
= ReadByte();
232 return val
== 0xFF ? ReadWord() : val
;
237 uint32 val
= ReadWord();
238 return val
| (ReadWord() << 16);
241 uint32
ReadVarSize(byte size
)
244 case 1: return ReadByte();
245 case 2: return ReadWord();
246 case 4: return ReadDWord();
253 const char *ReadString()
255 char *string
= reinterpret_cast<char *>(data
);
256 size_t string_length
= ttd_strnlen(string
, Remaining());
258 if (string_length
== Remaining()) {
259 /* String was not NUL terminated, so make sure it is now. */
260 string
[string_length
- 1] = '\0';
261 grfmsg(7, "String was not terminated with a zero byte.");
263 /* Increase the string length to include the NUL byte. */
271 inline size_t Remaining() const
276 inline bool HasData(size_t count
= 1) const
278 return data
+ count
<= end
;
286 inline void Skip(size_t len
)
289 /* It is valid to move the buffer to exactly the end of the data,
290 * as there may not be any more data read. */
291 if (data
> end
) throw OTTDByteReaderSignal();
295 typedef void (*SpecialSpriteHandler
)(ByteReader
*buf
);
297 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.
299 /** Temporary engine data used when loading only */
300 struct GRFTempEngineData
{
301 /** Summary state of refittability properties */
303 UNSET
= 0, ///< No properties assigned. Default refit masks shall be activated.
304 EMPTY
, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
305 NONEMPTY
, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
308 uint16 cargo_allowed
;
309 uint16 cargo_disallowed
;
310 RailTypeLabel railtypelabel
;
312 const GRFFile
*defaultcargo_grf
; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
313 Refittability refittability
; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
314 bool prop27_set
; ///< Did the NewGRF set property 27 (misc flags)?
315 uint8 rv_max_speed
; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
316 CargoTypes ctt_include_mask
; ///< Cargo types always included in the refit mask.
317 CargoTypes ctt_exclude_mask
; ///< Cargo types always excluded from the refit mask.
320 * Update the summary refittability on setting a refittability property.
321 * @param non_empty true if the GRF sets the vehicle to be refittable.
323 void UpdateRefittability(bool non_empty
)
326 this->refittability
= NONEMPTY
;
327 } else if (this->refittability
== UNSET
) {
328 this->refittability
= EMPTY
;
333 static GRFTempEngineData
*_gted
; ///< Temporary engine data used during NewGRF loading
336 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
337 * GRM for vehicles is only used if dynamic engine allocation is disabled,
338 * so 256 is the number of original engines. */
339 static uint32 _grm_engines
[256];
341 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
342 static uint32 _grm_cargoes
[NUM_CARGO
* 2];
348 GRFLocation(uint32 grfid
, uint32 nfoline
) : grfid(grfid
), nfoline(nfoline
) { }
350 bool operator<(const GRFLocation
&other
) const
352 return this->grfid
< other
.grfid
|| (this->grfid
== other
.grfid
&& this->nfoline
< other
.nfoline
);
355 bool operator == (const GRFLocation
&other
) const
357 return this->grfid
== other
.grfid
&& this->nfoline
== other
.nfoline
;
361 static std::map
<GRFLocation
, SpriteID
> _grm_sprites
;
362 typedef std::map
<GRFLocation
, byte
*> GRFLineToSpriteOverride
;
363 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override
;
366 * DEBUG() function dedicated to newGRF debugging messages
367 * Function is essentially the same as DEBUG(grf, severity, ...) with the
368 * addition of file:line information when parsing grf files.
369 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
370 * loading/parsing grf files, not for runtime debug messages as there
371 * is no file information available during that time.
372 * @param severity debugging severity level, see debug.h
373 * @param str message in printf() format
375 void CDECL
grfmsg(int severity
, const char *str
, ...)
381 vseprintf(buf
, lastof(buf
), str
, va
);
384 DEBUG(grf
, severity
, "[%s:%d] %s", _cur
.grfconfig
->filename
, _cur
.nfo_line
, buf
);
388 * Obtain a NewGRF file by its grfID
389 * @param grfid The grfID to obtain the file for
392 static GRFFile
*GetFileByGRFID(uint32 grfid
)
394 for (GRFFile
* const file
: _grf_files
) {
395 if (file
->grfid
== grfid
) return file
;
401 * Obtain a NewGRF file by its filename
402 * @param filename The filename to obtain the file for.
405 static GRFFile
*GetFileByFilename(const char *filename
)
407 for (GRFFile
* const file
: _grf_files
) {
408 if (strcmp(file
->filename
, filename
) == 0) return file
;
413 /** Reset all NewGRFData that was used only while processing data */
414 static void ClearTemporaryNewGRFData(GRFFile
*gf
)
416 /* Clear the GOTO labels used for GRF processing */
417 for (GRFLabel
*l
= gf
->label
; l
!= nullptr;) {
418 GRFLabel
*l2
= l
->next
;
427 * @param message Error message or STR_NULL.
428 * @param config GRFConfig to disable, nullptr for current.
429 * @return Error message of the GRF for further customisation.
431 static GRFError
*DisableGrf(StringID message
= STR_NULL
, GRFConfig
*config
= nullptr)
434 if (config
!= nullptr) {
435 file
= GetFileByGRFID(config
->ident
.grfid
);
437 config
= _cur
.grfconfig
;
441 config
->status
= GCS_DISABLED
;
442 if (file
!= nullptr) ClearTemporaryNewGRFData(file
);
443 if (config
== _cur
.grfconfig
) _cur
.skip_sprites
= -1;
445 if (message
!= STR_NULL
) {
446 delete config
->error
;
447 config
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, message
);
448 if (config
== _cur
.grfconfig
) config
->error
->param_value
[0] = _cur
.nfo_line
;
451 return config
->error
;
455 * Information for mapping static StringIDs.
457 struct StringIDMapping
{
458 uint32 grfid
; ///< Source NewGRF.
459 StringID source
; ///< Source StringID (GRF local).
460 StringID
*target
; ///< Destination for mapping result.
462 typedef std::vector
<StringIDMapping
> StringIDMappingVector
;
463 static StringIDMappingVector _string_to_grf_mapping
;
466 * Record a static StringID for getting translated later.
467 * @param source Source StringID (GRF local).
468 * @param target Destination for the mapping result.
470 static void AddStringForMapping(StringID source
, StringID
*target
)
472 *target
= STR_UNDEFINED
;
473 _string_to_grf_mapping
.push_back({_cur
.grffile
->grfid
, source
, target
});
477 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
478 * string IDs, but only for the ones we are aware off; the rest
479 * like likely unused and will show a warning.
480 * @param str the string ID to convert
481 * @return the converted string ID
483 static StringID
TTDPStringIDToOTTDStringIDMapping(StringID str
)
485 /* StringID table for TextIDs 0x4E->0x6D */
486 static const StringID units_volume
[] = {
487 STR_ITEMS
, STR_PASSENGERS
, STR_TONS
, STR_BAGS
,
488 STR_LITERS
, STR_ITEMS
, STR_CRATES
, STR_TONS
,
489 STR_TONS
, STR_TONS
, STR_TONS
, STR_BAGS
,
490 STR_TONS
, STR_TONS
, STR_TONS
, STR_BAGS
,
491 STR_TONS
, STR_TONS
, STR_BAGS
, STR_LITERS
,
492 STR_TONS
, STR_LITERS
, STR_TONS
, STR_ITEMS
,
493 STR_BAGS
, STR_LITERS
, STR_TONS
, STR_ITEMS
,
494 STR_TONS
, STR_ITEMS
, STR_LITERS
, STR_ITEMS
497 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
498 assert(!IsInsideMM(str
, 0xD000, 0xD7FF));
500 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
501 assert_compile(stringend - stringid == end - begin); \
502 if (str >= begin && str <= end) return str + (stringid - begin)
504 /* We have some changes in our cargo strings, resulting in some missing. */
505 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING
, STR_CARGO_PLURAL_FIZZY_DRINKS
);
506 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING
, STR_CARGO_SINGULAR_FIZZY_DRINK
);
507 if (str
>= 0x004E && str
<= 0x006D) return units_volume
[str
- 0x004E];
508 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING
, STR_QUANTITY_FIZZY_DRINKS
);
509 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING
, STR_ABBREV_FIZZY_DRINKS
);
510 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE
, STR_COLOUR_WHITE
);
512 /* Map building names according to our lang file changes. There are several
513 * ranges of house ids, all of which need to be remapped to allow newgrfs
514 * to use original house names. */
515 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1
, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1
);
516 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1
, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1
);
517 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1
, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1
);
519 /* Same thing for industries */
520 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE
, STR_INDUSTRY_NAME_SUGAR_MINE
);
521 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION
, STR_NEWS_INDUSTRY_PLANTED
);
522 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL
, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES
);
523 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL
, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM
);
524 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL
, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM
);
527 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY
;
528 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED
;
529 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED
;
531 #undef TEXTID_TO_STRINGID
533 if (str
== STR_NULL
) return STR_EMPTY
;
535 DEBUG(grf
, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str
);
541 * Used when setting an object's property to map to the GRF's strings
542 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
543 * @param grfid Id of the grf file.
544 * @param str StringID that we want to have the equivalent in OoenTTD.
545 * @return The properly adjusted StringID.
547 StringID
MapGRFStringID(uint32 grfid
, StringID str
)
549 if (IsInsideMM(str
, 0xD800, 0xE000)) {
550 /* General text provided by NewGRF.
551 * In the specs this is called the 0xDCxx range (misc persistent texts),
552 * but we meanwhile extended the range to 0xD800-0xDFFF.
553 * Note: We are not involved in the "persistent" business, since we do not store
554 * any NewGRF strings in savegames. */
555 return GetGRFStringID(grfid
, str
);
556 } else if (IsInsideMM(str
, 0xD000, 0xD800)) {
557 /* Callback text provided by NewGRF.
558 * In the specs this is called the 0xD0xx range (misc graphics texts).
559 * These texts can be returned by various callbacks.
561 * Due to how TTDP implements the GRF-local- to global-textid translation
562 * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
563 * We do not care about that difference and just mask out the 0x400 bit.
566 return GetGRFStringID(grfid
, str
);
568 /* The NewGRF wants to include/reference an original TTD string.
569 * Try our best to find an equivalent one. */
570 return TTDPStringIDToOTTDStringIDMapping(str
);
574 static std::map
<uint32
, uint32
> _grf_id_overrides
;
577 * Set the override for a NewGRF
578 * @param source_grfid The grfID which wants to override another NewGRF.
579 * @param target_grfid The grfID which is being overridden.
581 static void SetNewGRFOverride(uint32 source_grfid
, uint32 target_grfid
)
583 _grf_id_overrides
[source_grfid
] = target_grfid
;
584 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid
), BSWAP32(target_grfid
));
588 * Returns the engine associated to a certain internal_id, resp. allocates it.
589 * @param file NewGRF that wants to change the engine.
590 * @param type Vehicle type.
591 * @param internal_id Engine ID inside the NewGRF.
592 * @param static_access If the engine is not present, return nullptr instead of allocating a new engine. (Used for static Action 0x04).
593 * @return The requested engine.
595 static Engine
*GetNewEngine(const GRFFile
*file
, VehicleType type
, uint16 internal_id
, bool static_access
= false)
597 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
598 * them use the same engine slots. */
599 uint32 scope_grfid
= INVALID_GRFID
; // If not using dynamic_engines, all newgrfs share their ID range
600 if (_settings_game
.vehicle
.dynamic_engines
) {
601 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
602 scope_grfid
= file
->grfid
;
603 uint32 override
= _grf_id_overrides
[file
->grfid
];
605 scope_grfid
= override
;
606 const GRFFile
*grf_match
= GetFileByGRFID(override
);
607 if (grf_match
== nullptr) {
608 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file
->grfid
), BSWAP32(override
));
610 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file
->grfid
), BSWAP32(override
));
614 /* Check if the engine is registered in the override manager */
615 EngineID engine
= _engine_mngr
.GetID(type
, internal_id
, scope_grfid
);
616 if (engine
!= INVALID_ENGINE
) {
617 Engine
*e
= Engine::Get(engine
);
618 if (e
->grf_prop
.grffile
== nullptr) e
->grf_prop
.grffile
= file
;
623 /* Check if there is an unreserved slot */
624 EngineID engine
= _engine_mngr
.GetID(type
, internal_id
, INVALID_GRFID
);
625 if (engine
!= INVALID_ENGINE
) {
626 Engine
*e
= Engine::Get(engine
);
628 if (e
->grf_prop
.grffile
== nullptr) {
629 e
->grf_prop
.grffile
= file
;
630 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e
->index
, BSWAP32(file
->grfid
), type
, internal_id
);
633 /* Reserve the engine slot */
634 if (!static_access
) {
635 EngineIDMapping
*eid
= _engine_mngr
.data() + engine
;
636 eid
->grfid
= scope_grfid
; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
642 if (static_access
) return nullptr;
644 if (!Engine::CanAllocateItem()) {
645 grfmsg(0, "Can't allocate any more engines");
649 size_t engine_pool_size
= Engine::GetPoolSize();
651 /* ... it's not, so create a new one based off an existing engine */
652 Engine
*e
= new Engine(type
, internal_id
);
653 e
->grf_prop
.grffile
= file
;
655 /* Reserve the engine slot */
656 assert(_engine_mngr
.size() == e
->index
);
657 _engine_mngr
.push_back({
658 scope_grfid
, // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
661 static_cast<uint8
>(min(internal_id
, _engine_counts
[type
])) // substitute_id == _engine_counts[subtype] means "no substitute"
664 if (engine_pool_size
!= Engine::GetPoolSize()) {
665 /* Resize temporary engine data ... */
666 _gted
= ReallocT(_gted
, Engine::GetPoolSize());
668 /* and blank the new block. */
669 size_t len
= (Engine::GetPoolSize() - engine_pool_size
) * sizeof(*_gted
);
670 memset(_gted
+ engine_pool_size
, 0, len
);
672 if (type
== VEH_TRAIN
) {
673 _gted
[e
->index
].railtypelabel
= GetRailTypeInfo(e
->u
.rail
.railtype
)->label
;
676 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e
->index
, BSWAP32(file
->grfid
), type
, internal_id
);
682 * Return the ID of a new engine
683 * @param file The NewGRF file providing the engine.
684 * @param type The Vehicle type.
685 * @param internal_id NewGRF-internal ID of the engine.
686 * @return The new EngineID.
687 * @note depending on the dynamic_engine setting and a possible override
688 * property the grfID may be unique or overwriting or partially re-defining
689 * properties of an existing engine.
691 EngineID
GetNewEngineID(const GRFFile
*file
, VehicleType type
, uint16 internal_id
)
693 uint32 scope_grfid
= INVALID_GRFID
; // If not using dynamic_engines, all newgrfs share their ID range
694 if (_settings_game
.vehicle
.dynamic_engines
) {
695 scope_grfid
= file
->grfid
;
696 uint32 override
= _grf_id_overrides
[file
->grfid
];
697 if (override
!= 0) scope_grfid
= override
;
700 return _engine_mngr
.GetID(type
, internal_id
, scope_grfid
);
704 * Map the colour modifiers of TTDPatch to those that Open is using.
705 * @param grf_sprite Pointer to the structure been modified.
707 static void MapSpriteMappingRecolour(PalSpriteID
*grf_sprite
)
709 if (HasBit(grf_sprite
->pal
, 14)) {
710 ClrBit(grf_sprite
->pal
, 14);
711 SetBit(grf_sprite
->sprite
, SPRITE_MODIFIER_OPAQUE
);
714 if (HasBit(grf_sprite
->sprite
, 14)) {
715 ClrBit(grf_sprite
->sprite
, 14);
716 SetBit(grf_sprite
->sprite
, PALETTE_MODIFIER_TRANSPARENT
);
719 if (HasBit(grf_sprite
->sprite
, 15)) {
720 ClrBit(grf_sprite
->sprite
, 15);
721 SetBit(grf_sprite
->sprite
, PALETTE_MODIFIER_COLOUR
);
726 * Read a sprite and a palette from the GRF and convert them into a format
727 * suitable to OpenTTD.
728 * @param buf Input stream.
729 * @param read_flags Whether to read TileLayoutFlags.
730 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
731 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
732 * @param feature GrfSpecFeature to use spritesets from.
733 * @param[out] grf_sprite Read sprite and palette.
734 * @param[out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
735 * @param[out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
736 * @return Read TileLayoutFlags.
738 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)
740 grf_sprite
->sprite
= buf
->ReadWord();
741 grf_sprite
->pal
= buf
->ReadWord();
742 TileLayoutFlags flags
= read_flags
? (TileLayoutFlags
)buf
->ReadWord() : TLF_NOTHING
;
744 MapSpriteMappingRecolour(grf_sprite
);
746 bool custom_sprite
= HasBit(grf_sprite
->pal
, 15) != invert_action1_flag
;
747 ClrBit(grf_sprite
->pal
, 15);
749 /* Use sprite from Action 1 */
750 uint index
= GB(grf_sprite
->sprite
, 0, 14);
751 if (use_cur_spritesets
&& (!_cur
.IsValidSpriteSet(feature
, index
) || _cur
.GetNumEnts(feature
, index
) == 0)) {
752 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index
);
753 grf_sprite
->sprite
= SPR_IMG_QUERY
;
754 grf_sprite
->pal
= PAL_NONE
;
756 SpriteID sprite
= use_cur_spritesets
? _cur
.GetSprite(feature
, index
) : index
;
757 if (max_sprite_offset
!= nullptr) *max_sprite_offset
= use_cur_spritesets
? _cur
.GetNumEnts(feature
, index
) : UINT16_MAX
;
758 SB(grf_sprite
->sprite
, 0, SPRITE_WIDTH
, sprite
);
759 SetBit(grf_sprite
->sprite
, SPRITE_MODIFIER_CUSTOM_SPRITE
);
761 } else if ((flags
& TLF_SPRITE_VAR10
) && !(flags
& TLF_SPRITE_REG_FLAGS
)) {
762 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
763 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
767 if (flags
& TLF_CUSTOM_PALETTE
) {
768 /* Use palette from Action 1 */
769 uint index
= GB(grf_sprite
->pal
, 0, 14);
770 if (use_cur_spritesets
&& (!_cur
.IsValidSpriteSet(feature
, index
) || _cur
.GetNumEnts(feature
, index
) == 0)) {
771 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index
);
772 grf_sprite
->pal
= PAL_NONE
;
774 SpriteID sprite
= use_cur_spritesets
? _cur
.GetSprite(feature
, index
) : index
;
775 if (max_palette_offset
!= nullptr) *max_palette_offset
= use_cur_spritesets
? _cur
.GetNumEnts(feature
, index
) : UINT16_MAX
;
776 SB(grf_sprite
->pal
, 0, SPRITE_WIDTH
, sprite
);
777 SetBit(grf_sprite
->pal
, SPRITE_MODIFIER_CUSTOM_SPRITE
);
779 } else if ((flags
& TLF_PALETTE_VAR10
) && !(flags
& TLF_PALETTE_REG_FLAGS
)) {
780 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
781 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
789 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
790 * @param buf Input stream.
791 * @param flags TileLayoutFlags to process.
792 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
793 * @param dts Sprite layout to insert data into.
794 * @param index Sprite index to process; 0 for ground sprite.
796 static void ReadSpriteLayoutRegisters(ByteReader
*buf
, TileLayoutFlags flags
, bool is_parent
, NewGRFSpriteLayout
*dts
, uint index
)
798 if (!(flags
& TLF_DRAWING_FLAGS
)) return;
800 if (dts
->registers
== nullptr) dts
->AllocateRegisters();
801 TileLayoutRegisters
®s
= const_cast<TileLayoutRegisters
&>(dts
->registers
[index
]);
802 regs
.flags
= flags
& TLF_DRAWING_FLAGS
;
804 if (flags
& TLF_DODRAW
) regs
.dodraw
= buf
->ReadByte();
805 if (flags
& TLF_SPRITE
) regs
.sprite
= buf
->ReadByte();
806 if (flags
& TLF_PALETTE
) regs
.palette
= buf
->ReadByte();
809 if (flags
& TLF_BB_XY_OFFSET
) {
810 regs
.delta
.parent
[0] = buf
->ReadByte();
811 regs
.delta
.parent
[1] = buf
->ReadByte();
813 if (flags
& TLF_BB_Z_OFFSET
) regs
.delta
.parent
[2] = buf
->ReadByte();
815 if (flags
& TLF_CHILD_X_OFFSET
) regs
.delta
.child
[0] = buf
->ReadByte();
816 if (flags
& TLF_CHILD_Y_OFFSET
) regs
.delta
.child
[1] = buf
->ReadByte();
819 if (flags
& TLF_SPRITE_VAR10
) {
820 regs
.sprite_var10
= buf
->ReadByte();
821 if (regs
.sprite_var10
> TLR_MAX_VAR10
) {
822 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs
.sprite_var10
, TLR_MAX_VAR10
);
823 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
828 if (flags
& TLF_PALETTE_VAR10
) {
829 regs
.palette_var10
= buf
->ReadByte();
830 if (regs
.palette_var10
> TLR_MAX_VAR10
) {
831 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs
.palette_var10
, TLR_MAX_VAR10
);
832 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
839 * Read a spritelayout from the GRF.
841 * @param num_building_sprites Number of building sprites to read
842 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
843 * @param feature GrfSpecFeature to use spritesets from.
844 * @param allow_var10 Whether the spritelayout may specify var10 values for resolving multiple action-1-2-3 chains
845 * @param no_z_position Whether bounding boxes have no Z offset
846 * @param dts Layout container to output into
847 * @return True on error (GRF was disabled).
849 static bool ReadSpriteLayout(ByteReader
*buf
, uint num_building_sprites
, bool use_cur_spritesets
, byte feature
, bool allow_var10
, bool no_z_position
, NewGRFSpriteLayout
*dts
)
851 bool has_flags
= HasBit(num_building_sprites
, 6);
852 ClrBit(num_building_sprites
, 6);
853 TileLayoutFlags valid_flags
= TLF_KNOWN_FLAGS
;
854 if (!allow_var10
) valid_flags
&= ~TLF_VAR10_FLAGS
;
855 dts
->Allocate(num_building_sprites
); // allocate before reading groundsprite flags
857 uint16
*max_sprite_offset
= AllocaM(uint16
, num_building_sprites
+ 1);
858 uint16
*max_palette_offset
= AllocaM(uint16
, num_building_sprites
+ 1);
859 MemSetT(max_sprite_offset
, 0, num_building_sprites
+ 1);
860 MemSetT(max_palette_offset
, 0, num_building_sprites
+ 1);
863 TileLayoutFlags flags
= ReadSpriteLayoutSprite(buf
, has_flags
, false, use_cur_spritesets
, feature
, &dts
->ground
, max_sprite_offset
, max_palette_offset
);
864 if (_cur
.skip_sprites
< 0) return true;
866 if (flags
& ~(valid_flags
& ~TLF_NON_GROUND_FLAGS
)) {
867 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags
& ~(valid_flags
& ~TLF_NON_GROUND_FLAGS
));
868 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
872 ReadSpriteLayoutRegisters(buf
, flags
, false, dts
, 0);
873 if (_cur
.skip_sprites
< 0) return true;
875 for (uint i
= 0; i
< num_building_sprites
; i
++) {
876 DrawTileSeqStruct
*seq
= const_cast<DrawTileSeqStruct
*>(&dts
->seq
[i
]);
878 flags
= ReadSpriteLayoutSprite(buf
, has_flags
, false, use_cur_spritesets
, feature
, &seq
->image
, max_sprite_offset
+ i
+ 1, max_palette_offset
+ i
+ 1);
879 if (_cur
.skip_sprites
< 0) return true;
881 if (flags
& ~valid_flags
) {
882 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags
& ~valid_flags
);
883 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
887 seq
->delta_x
= buf
->ReadByte();
888 seq
->delta_y
= buf
->ReadByte();
890 if (!no_z_position
) seq
->delta_z
= buf
->ReadByte();
892 if (seq
->IsParentSprite()) {
893 seq
->size_x
= buf
->ReadByte();
894 seq
->size_y
= buf
->ReadByte();
895 seq
->size_z
= buf
->ReadByte();
898 ReadSpriteLayoutRegisters(buf
, flags
, seq
->IsParentSprite(), dts
, i
+ 1);
899 if (_cur
.skip_sprites
< 0) return true;
902 /* Check if the number of sprites per spriteset is consistent */
903 bool is_consistent
= true;
904 dts
->consistent_max_offset
= 0;
905 for (uint i
= 0; i
< num_building_sprites
+ 1; i
++) {
906 if (max_sprite_offset
[i
] > 0) {
907 if (dts
->consistent_max_offset
== 0) {
908 dts
->consistent_max_offset
= max_sprite_offset
[i
];
909 } else if (dts
->consistent_max_offset
!= max_sprite_offset
[i
]) {
910 is_consistent
= false;
914 if (max_palette_offset
[i
] > 0) {
915 if (dts
->consistent_max_offset
== 0) {
916 dts
->consistent_max_offset
= max_palette_offset
[i
];
917 } else if (dts
->consistent_max_offset
!= max_palette_offset
[i
]) {
918 is_consistent
= false;
924 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
925 assert(use_cur_spritesets
|| (is_consistent
&& (dts
->consistent_max_offset
== 0 || dts
->consistent_max_offset
== UINT16_MAX
)));
927 if (!is_consistent
|| dts
->registers
!= nullptr) {
928 dts
->consistent_max_offset
= 0;
929 if (dts
->registers
== nullptr) dts
->AllocateRegisters();
931 for (uint i
= 0; i
< num_building_sprites
+ 1; i
++) {
932 TileLayoutRegisters
®s
= const_cast<TileLayoutRegisters
&>(dts
->registers
[i
]);
933 regs
.max_sprite_offset
= max_sprite_offset
[i
];
934 regs
.max_palette_offset
= max_palette_offset
[i
];
942 * Translate the refit mask. refit_mask is uint32 as it has not been mapped to CargoTypes.
944 static CargoTypes
TranslateRefitMask(uint32 refit_mask
)
946 CargoTypes result
= 0;
948 FOR_EACH_SET_BIT(bit
, refit_mask
) {
949 CargoID cargo
= GetCargoTranslation(bit
, _cur
.grffile
, true);
950 if (cargo
!= CT_INVALID
) SetBit(result
, cargo
);
956 * Converts TTD(P) Base Price pointers into the enum used by OTTD
957 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
958 * @param base_pointer TTD(P) Base Price Pointer
959 * @param error_location Function name for grf error messages
960 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
962 static void ConvertTTDBasePrice(uint32 base_pointer
, const char *error_location
, Price
*index
)
964 /* Special value for 'none' */
965 if (base_pointer
== 0) {
966 *index
= INVALID_PRICE
;
970 static const uint32 start
= 0x4B34; ///< Position of first base price
971 static const uint32 size
= 6; ///< Size of each base price record
973 if (base_pointer
< start
|| (base_pointer
- start
) % size
!= 0 || (base_pointer
- start
) / size
>= PR_END
) {
974 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location
, base_pointer
);
978 *index
= (Price
)((base_pointer
- start
) / size
);
981 /** Possible return values for the FeatureChangeInfo functions */
982 enum ChangeInfoResult
{
983 CIR_SUCCESS
, ///< Variable was parsed and read
984 CIR_DISABLED
, ///< GRF was disabled due to error
985 CIR_UNHANDLED
, ///< Variable was parsed but unread
986 CIR_UNKNOWN
, ///< Variable is unknown
987 CIR_INVALID_ID
, ///< Attempt to modify an invalid ID
990 typedef ChangeInfoResult (*VCI_Handler
)(uint engine
, int numinfo
, int prop
, ByteReader
*buf
);
993 * Define properties common to all vehicles
994 * @param ei Engine info.
995 * @param prop The property to change.
996 * @param buf The property value.
997 * @return ChangeInfoResult.
999 static ChangeInfoResult
CommonVehicleChangeInfo(EngineInfo
*ei
, int prop
, ByteReader
*buf
)
1002 case 0x00: // Introduction date
1003 ei
->base_intro
= buf
->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR
;
1006 case 0x02: // Decay speed
1007 ei
->decay_speed
= buf
->ReadByte();
1010 case 0x03: // Vehicle life
1011 ei
->lifelength
= buf
->ReadByte();
1014 case 0x04: // Model life
1015 ei
->base_life
= buf
->ReadByte();
1018 case 0x06: // Climates available
1019 ei
->climates
= buf
->ReadByte();
1022 case PROP_VEHICLE_LOAD_AMOUNT
: // 0x07 Loading speed
1023 /* Amount of cargo loaded during a vehicle's "loading tick" */
1024 ei
->load_amount
= buf
->ReadByte();
1035 * Define properties for rail vehicles
1036 * @param engine :ocal ID of the first vehicle.
1037 * @param numinfo Number of subsequent IDs to change the property for.
1038 * @param prop The property to change.
1039 * @param buf The property value.
1040 * @return ChangeInfoResult.
1042 static ChangeInfoResult
RailVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1044 ChangeInfoResult ret
= CIR_SUCCESS
;
1046 for (int i
= 0; i
< numinfo
; i
++) {
1047 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_TRAIN
, engine
+ i
);
1048 if (e
== nullptr) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1050 EngineInfo
*ei
= &e
->info
;
1051 RailVehicleInfo
*rvi
= &e
->u
.rail
;
1054 case 0x05: { // Track type
1055 uint8 tracktype
= buf
->ReadByte();
1057 if (tracktype
< _cur
.grffile
->railtype_list
.size()) {
1058 _gted
[e
->index
].railtypelabel
= _cur
.grffile
->railtype_list
[tracktype
];
1062 switch (tracktype
) {
1063 case 0: _gted
[e
->index
].railtypelabel
= rvi
->engclass
>= 2 ? RAILTYPE_ELECTRIC_LABEL
: RAILTYPE_RAIL_LABEL
; break;
1064 case 1: _gted
[e
->index
].railtypelabel
= RAILTYPE_MONO_LABEL
; break;
1065 case 2: _gted
[e
->index
].railtypelabel
= RAILTYPE_MAGLEV_LABEL
; break;
1067 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype
);
1073 case 0x08: // AI passenger service
1074 /* Tells the AI that this engine is designed for
1075 * passenger services and shouldn't be used for freight. */
1076 rvi
->ai_passenger_only
= buf
->ReadByte();
1079 case PROP_TRAIN_SPEED
: { // 0x09 Speed (1 unit is 1 km-ish/h)
1080 uint16 speed
= buf
->ReadWord();
1081 if (speed
== 0xFFFF) speed
= 0;
1083 rvi
->max_speed
= speed
;
1087 case PROP_TRAIN_POWER
: // 0x0B Power
1088 rvi
->power
= buf
->ReadWord();
1090 /* Set engine / wagon state based on power */
1091 if (rvi
->power
!= 0) {
1092 if (rvi
->railveh_type
== RAILVEH_WAGON
) {
1093 rvi
->railveh_type
= RAILVEH_SINGLEHEAD
;
1096 rvi
->railveh_type
= RAILVEH_WAGON
;
1100 case PROP_TRAIN_RUNNING_COST_FACTOR
: // 0x0D Running cost factor
1101 rvi
->running_cost
= buf
->ReadByte();
1104 case 0x0E: // Running cost base
1105 ConvertTTDBasePrice(buf
->ReadDWord(), "RailVehicleChangeInfo", &rvi
->running_cost_class
);
1108 case 0x12: { // Sprite ID
1109 uint8 spriteid
= buf
->ReadByte();
1110 uint8 orig_spriteid
= spriteid
;
1112 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1113 * as an array index, so we need it to be half the original value. */
1114 if (spriteid
< 0xFD) spriteid
>>= 1;
1116 if (IsValidNewGRFImageIndex
<VEH_TRAIN
>(spriteid
)) {
1117 rvi
->image_index
= spriteid
;
1119 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1120 rvi
->image_index
= 0;
1125 case 0x13: { // Dual-headed
1126 uint8 dual
= buf
->ReadByte();
1129 rvi
->railveh_type
= RAILVEH_MULTIHEAD
;
1131 rvi
->railveh_type
= rvi
->power
== 0 ?
1132 RAILVEH_WAGON
: RAILVEH_SINGLEHEAD
;
1137 case PROP_TRAIN_CARGO_CAPACITY
: // 0x14 Cargo capacity
1138 rvi
->capacity
= buf
->ReadByte();
1141 case 0x15: { // Cargo type
1142 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1143 uint8 ctype
= buf
->ReadByte();
1145 if (ctype
== 0xFF) {
1146 /* 0xFF is specified as 'use first refittable' */
1147 ei
->cargo_type
= CT_INVALID
;
1148 } else if (_cur
.grffile
->grf_version
>= 8) {
1149 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1150 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1151 } else if (ctype
< NUM_CARGO
) {
1152 /* Use untranslated cargo. */
1153 ei
->cargo_type
= ctype
;
1155 ei
->cargo_type
= CT_INVALID
;
1156 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1161 case PROP_TRAIN_WEIGHT
: // 0x16 Weight
1162 SB(rvi
->weight
, 0, 8, buf
->ReadByte());
1165 case PROP_TRAIN_COST_FACTOR
: // 0x17 Cost factor
1166 rvi
->cost_factor
= buf
->ReadByte();
1169 case 0x18: // AI rank
1170 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1174 case 0x19: { // Engine traction type
1175 /* What do the individual numbers mean?
1176 * 0x00 .. 0x07: Steam
1177 * 0x08 .. 0x27: Diesel
1178 * 0x28 .. 0x31: Electric
1179 * 0x32 .. 0x37: Monorail
1180 * 0x38 .. 0x41: Maglev
1182 uint8 traction
= buf
->ReadByte();
1183 EngineClass engclass
;
1185 if (traction
<= 0x07) {
1186 engclass
= EC_STEAM
;
1187 } else if (traction
<= 0x27) {
1188 engclass
= EC_DIESEL
;
1189 } else if (traction
<= 0x31) {
1190 engclass
= EC_ELECTRIC
;
1191 } else if (traction
<= 0x37) {
1192 engclass
= EC_MONORAIL
;
1193 } else if (traction
<= 0x41) {
1194 engclass
= EC_MAGLEV
;
1199 if (_cur
.grffile
->railtype_list
.size() == 0) {
1200 /* Use traction type to select between normal and electrified
1201 * rail only when no translation list is in place. */
1202 if (_gted
[e
->index
].railtypelabel
== RAILTYPE_RAIL_LABEL
&& engclass
>= EC_ELECTRIC
) _gted
[e
->index
].railtypelabel
= RAILTYPE_ELECTRIC_LABEL
;
1203 if (_gted
[e
->index
].railtypelabel
== RAILTYPE_ELECTRIC_LABEL
&& engclass
< EC_ELECTRIC
) _gted
[e
->index
].railtypelabel
= RAILTYPE_RAIL_LABEL
;
1206 rvi
->engclass
= engclass
;
1210 case 0x1A: // Alter purchase list sort order
1211 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1214 case 0x1B: // Powered wagons power bonus
1215 rvi
->pow_wag_power
= buf
->ReadWord();
1218 case 0x1C: // Refit cost
1219 ei
->refit_cost
= buf
->ReadByte();
1222 case 0x1D: { // Refit cargo
1223 uint32 mask
= buf
->ReadDWord();
1224 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1225 ei
->refit_mask
= TranslateRefitMask(mask
);
1226 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1230 case 0x1E: // Callback
1231 ei
->callback_mask
= buf
->ReadByte();
1234 case PROP_TRAIN_TRACTIVE_EFFORT
: // 0x1F Tractive effort coefficient
1235 rvi
->tractive_effort
= buf
->ReadByte();
1238 case 0x20: // Air drag
1239 rvi
->air_drag
= buf
->ReadByte();
1242 case PROP_TRAIN_SHORTEN_FACTOR
: // 0x21 Shorter vehicle
1243 rvi
->shorten_factor
= buf
->ReadByte();
1246 case 0x22: // Visual effect
1247 rvi
->visual_effect
= buf
->ReadByte();
1248 /* Avoid accidentally setting visual_effect to the default value
1249 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1250 if (rvi
->visual_effect
== VE_DEFAULT
) {
1251 assert(HasBit(rvi
->visual_effect
, VE_DISABLE_EFFECT
));
1252 SB(rvi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1256 case 0x23: // Powered wagons weight bonus
1257 rvi
->pow_wag_weight
= buf
->ReadByte();
1260 case 0x24: { // High byte of vehicle weight
1261 byte weight
= buf
->ReadByte();
1264 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight
<< 8);
1266 SB(rvi
->weight
, 8, 8, weight
);
1271 case PROP_TRAIN_USER_DATA
: // 0x25 User-defined bit mask to set when checking veh. var. 42
1272 rvi
->user_def_data
= buf
->ReadByte();
1275 case 0x26: // Retire vehicle early
1276 ei
->retire_early
= buf
->ReadByte();
1279 case 0x27: // Miscellaneous flags
1280 ei
->misc_flags
= buf
->ReadByte();
1281 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1282 _gted
[e
->index
].prop27_set
= true;
1285 case 0x28: // Cargo classes allowed
1286 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1287 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1288 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1291 case 0x29: // Cargo classes disallowed
1292 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1293 _gted
[e
->index
].UpdateRefittability(false);
1296 case 0x2A: // Long format introduction date (days since year 0)
1297 ei
->base_intro
= buf
->ReadDWord();
1300 case PROP_TRAIN_CARGO_AGE_PERIOD
: // 0x2B Cargo aging period
1301 ei
->cargo_age_period
= buf
->ReadWord();
1304 case 0x2C: // CTT refit include list
1305 case 0x2D: { // CTT refit exclude list
1306 uint8 count
= buf
->ReadByte();
1307 _gted
[e
->index
].UpdateRefittability(prop
== 0x2C && count
!= 0);
1308 if (prop
== 0x2C) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1309 CargoTypes
&ctt
= prop
== 0x2C ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1312 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1313 if (ctype
== CT_INVALID
) continue;
1320 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1329 * Define properties for road vehicles
1330 * @param engine Local ID of the first vehicle.
1331 * @param numinfo Number of subsequent IDs to change the property for.
1332 * @param prop The property to change.
1333 * @param buf The property value.
1334 * @return ChangeInfoResult.
1336 static ChangeInfoResult
RoadVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1338 ChangeInfoResult ret
= CIR_SUCCESS
;
1340 for (int i
= 0; i
< numinfo
; i
++) {
1341 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_ROAD
, engine
+ i
);
1342 if (e
== nullptr) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1344 EngineInfo
*ei
= &e
->info
;
1345 RoadVehicleInfo
*rvi
= &e
->u
.road
;
1348 case 0x05: // Road/tram type
1349 /* RoadTypeLabel is looked up later after the engine's road/tram
1350 * flag is set, however 0 means the value has not been set. */
1351 _gted
[e
->index
].roadtramtype
= buf
->ReadByte() + 1;
1354 case 0x08: // Speed (1 unit is 0.5 kmh)
1355 rvi
->max_speed
= buf
->ReadByte();
1358 case PROP_ROADVEH_RUNNING_COST_FACTOR
: // 0x09 Running cost factor
1359 rvi
->running_cost
= buf
->ReadByte();
1362 case 0x0A: // Running cost base
1363 ConvertTTDBasePrice(buf
->ReadDWord(), "RoadVehicleChangeInfo", &rvi
->running_cost_class
);
1366 case 0x0E: { // Sprite ID
1367 uint8 spriteid
= buf
->ReadByte();
1368 uint8 orig_spriteid
= spriteid
;
1370 /* cars have different custom id in the GRF file */
1371 if (spriteid
== 0xFF) spriteid
= 0xFD;
1373 if (spriteid
< 0xFD) spriteid
>>= 1;
1375 if (IsValidNewGRFImageIndex
<VEH_ROAD
>(spriteid
)) {
1376 rvi
->image_index
= spriteid
;
1378 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1379 rvi
->image_index
= 0;
1384 case PROP_ROADVEH_CARGO_CAPACITY
: // 0x0F Cargo capacity
1385 rvi
->capacity
= buf
->ReadByte();
1388 case 0x10: { // Cargo type
1389 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1390 uint8 ctype
= buf
->ReadByte();
1392 if (ctype
== 0xFF) {
1393 /* 0xFF is specified as 'use first refittable' */
1394 ei
->cargo_type
= CT_INVALID
;
1395 } else if (_cur
.grffile
->grf_version
>= 8) {
1396 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1397 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1398 } else if (ctype
< NUM_CARGO
) {
1399 /* Use untranslated cargo. */
1400 ei
->cargo_type
= ctype
;
1402 ei
->cargo_type
= CT_INVALID
;
1403 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1408 case PROP_ROADVEH_COST_FACTOR
: // 0x11 Cost factor
1409 rvi
->cost_factor
= buf
->ReadByte();
1413 rvi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1416 case PROP_ROADVEH_POWER
: // Power in units of 10 HP.
1417 rvi
->power
= buf
->ReadByte();
1420 case PROP_ROADVEH_WEIGHT
: // Weight in units of 1/4 tons.
1421 rvi
->weight
= buf
->ReadByte();
1424 case PROP_ROADVEH_SPEED
: // Speed in mph/0.8
1425 _gted
[e
->index
].rv_max_speed
= buf
->ReadByte();
1428 case 0x16: { // Cargoes available for refitting
1429 uint32 mask
= buf
->ReadDWord();
1430 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1431 ei
->refit_mask
= TranslateRefitMask(mask
);
1432 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1436 case 0x17: // Callback mask
1437 ei
->callback_mask
= buf
->ReadByte();
1440 case PROP_ROADVEH_TRACTIVE_EFFORT
: // Tractive effort coefficient in 1/256.
1441 rvi
->tractive_effort
= buf
->ReadByte();
1444 case 0x19: // Air drag
1445 rvi
->air_drag
= buf
->ReadByte();
1448 case 0x1A: // Refit cost
1449 ei
->refit_cost
= buf
->ReadByte();
1452 case 0x1B: // Retire vehicle early
1453 ei
->retire_early
= buf
->ReadByte();
1456 case 0x1C: // Miscellaneous flags
1457 ei
->misc_flags
= buf
->ReadByte();
1458 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1461 case 0x1D: // Cargo classes allowed
1462 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1463 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1464 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1467 case 0x1E: // Cargo classes disallowed
1468 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1469 _gted
[e
->index
].UpdateRefittability(false);
1472 case 0x1F: // Long format introduction date (days since year 0)
1473 ei
->base_intro
= buf
->ReadDWord();
1476 case 0x20: // Alter purchase list sort order
1477 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1480 case 0x21: // Visual effect
1481 rvi
->visual_effect
= buf
->ReadByte();
1482 /* Avoid accidentally setting visual_effect to the default value
1483 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1484 if (rvi
->visual_effect
== VE_DEFAULT
) {
1485 assert(HasBit(rvi
->visual_effect
, VE_DISABLE_EFFECT
));
1486 SB(rvi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1490 case PROP_ROADVEH_CARGO_AGE_PERIOD
: // 0x22 Cargo aging period
1491 ei
->cargo_age_period
= buf
->ReadWord();
1494 case PROP_ROADVEH_SHORTEN_FACTOR
: // 0x23 Shorter vehicle
1495 rvi
->shorten_factor
= buf
->ReadByte();
1498 case 0x24: // CTT refit include list
1499 case 0x25: { // CTT refit exclude list
1500 uint8 count
= buf
->ReadByte();
1501 _gted
[e
->index
].UpdateRefittability(prop
== 0x24 && count
!= 0);
1502 if (prop
== 0x24) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1503 CargoTypes
&ctt
= prop
== 0x24 ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1506 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1507 if (ctype
== CT_INVALID
) continue;
1514 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1523 * Define properties for ships
1524 * @param engine Local ID of the first vehicle.
1525 * @param numinfo Number of subsequent IDs to change the property for.
1526 * @param prop The property to change.
1527 * @param buf The property value.
1528 * @return ChangeInfoResult.
1530 static ChangeInfoResult
ShipVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1532 ChangeInfoResult ret
= CIR_SUCCESS
;
1534 for (int i
= 0; i
< numinfo
; i
++) {
1535 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_SHIP
, engine
+ i
);
1536 if (e
== nullptr) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1538 EngineInfo
*ei
= &e
->info
;
1539 ShipVehicleInfo
*svi
= &e
->u
.ship
;
1542 case 0x08: { // Sprite ID
1543 uint8 spriteid
= buf
->ReadByte();
1544 uint8 orig_spriteid
= spriteid
;
1546 /* ships have different custom id in the GRF file */
1547 if (spriteid
== 0xFF) spriteid
= 0xFD;
1549 if (spriteid
< 0xFD) spriteid
>>= 1;
1551 if (IsValidNewGRFImageIndex
<VEH_SHIP
>(spriteid
)) {
1552 svi
->image_index
= spriteid
;
1554 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1555 svi
->image_index
= 0;
1560 case 0x09: // Refittable
1561 svi
->old_refittable
= (buf
->ReadByte() != 0);
1564 case PROP_SHIP_COST_FACTOR
: // 0x0A Cost factor
1565 svi
->cost_factor
= buf
->ReadByte();
1568 case PROP_SHIP_SPEED
: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1569 svi
->max_speed
= buf
->ReadByte();
1572 case 0x0C: { // Cargo type
1573 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1574 uint8 ctype
= buf
->ReadByte();
1576 if (ctype
== 0xFF) {
1577 /* 0xFF is specified as 'use first refittable' */
1578 ei
->cargo_type
= CT_INVALID
;
1579 } else if (_cur
.grffile
->grf_version
>= 8) {
1580 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1581 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1582 } else if (ctype
< NUM_CARGO
) {
1583 /* Use untranslated cargo. */
1584 ei
->cargo_type
= ctype
;
1586 ei
->cargo_type
= CT_INVALID
;
1587 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1592 case PROP_SHIP_CARGO_CAPACITY
: // 0x0D Cargo capacity
1593 svi
->capacity
= buf
->ReadWord();
1596 case PROP_SHIP_RUNNING_COST_FACTOR
: // 0x0F Running cost factor
1597 svi
->running_cost
= buf
->ReadByte();
1601 svi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1604 case 0x11: { // Cargoes available for refitting
1605 uint32 mask
= buf
->ReadDWord();
1606 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1607 ei
->refit_mask
= TranslateRefitMask(mask
);
1608 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1612 case 0x12: // Callback mask
1613 ei
->callback_mask
= buf
->ReadByte();
1616 case 0x13: // Refit cost
1617 ei
->refit_cost
= buf
->ReadByte();
1620 case 0x14: // Ocean speed fraction
1621 svi
->ocean_speed_frac
= buf
->ReadByte();
1624 case 0x15: // Canal speed fraction
1625 svi
->canal_speed_frac
= buf
->ReadByte();
1628 case 0x16: // Retire vehicle early
1629 ei
->retire_early
= buf
->ReadByte();
1632 case 0x17: // Miscellaneous flags
1633 ei
->misc_flags
= buf
->ReadByte();
1634 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1637 case 0x18: // Cargo classes allowed
1638 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1639 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1640 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1643 case 0x19: // Cargo classes disallowed
1644 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1645 _gted
[e
->index
].UpdateRefittability(false);
1648 case 0x1A: // Long format introduction date (days since year 0)
1649 ei
->base_intro
= buf
->ReadDWord();
1652 case 0x1B: // Alter purchase list sort order
1653 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1656 case 0x1C: // Visual effect
1657 svi
->visual_effect
= buf
->ReadByte();
1658 /* Avoid accidentally setting visual_effect to the default value
1659 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1660 if (svi
->visual_effect
== VE_DEFAULT
) {
1661 assert(HasBit(svi
->visual_effect
, VE_DISABLE_EFFECT
));
1662 SB(svi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1666 case PROP_SHIP_CARGO_AGE_PERIOD
: // 0x1D Cargo aging period
1667 ei
->cargo_age_period
= buf
->ReadWord();
1670 case 0x1E: // CTT refit include list
1671 case 0x1F: { // CTT refit exclude list
1672 uint8 count
= buf
->ReadByte();
1673 _gted
[e
->index
].UpdateRefittability(prop
== 0x1E && count
!= 0);
1674 if (prop
== 0x1E) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1675 CargoTypes
&ctt
= prop
== 0x1E ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1678 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1679 if (ctype
== CT_INVALID
) continue;
1686 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1695 * Define properties for aircraft
1696 * @param engine Local ID of the aircraft.
1697 * @param numinfo Number of subsequent IDs to change the property for.
1698 * @param prop The property to change.
1699 * @param buf The property value.
1700 * @return ChangeInfoResult.
1702 static ChangeInfoResult
AircraftVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1704 ChangeInfoResult ret
= CIR_SUCCESS
;
1706 for (int i
= 0; i
< numinfo
; i
++) {
1707 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_AIRCRAFT
, engine
+ i
);
1708 if (e
== nullptr) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1710 EngineInfo
*ei
= &e
->info
;
1711 AircraftVehicleInfo
*avi
= &e
->u
.air
;
1714 case 0x08: { // Sprite ID
1715 uint8 spriteid
= buf
->ReadByte();
1716 uint8 orig_spriteid
= spriteid
;
1718 /* aircraft have different custom id in the GRF file */
1719 if (spriteid
== 0xFF) spriteid
= 0xFD;
1721 if (spriteid
< 0xFD) spriteid
>>= 1;
1723 if (IsValidNewGRFImageIndex
<VEH_AIRCRAFT
>(spriteid
)) {
1724 avi
->image_index
= spriteid
;
1726 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1727 avi
->image_index
= 0;
1732 case 0x09: // Helicopter
1733 if (buf
->ReadByte() == 0) {
1734 avi
->subtype
= AIR_HELI
;
1736 SB(avi
->subtype
, 0, 1, 1); // AIR_CTOL
1741 SB(avi
->subtype
, 1, 1, (buf
->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1744 case PROP_AIRCRAFT_COST_FACTOR
: // 0x0B Cost factor
1745 avi
->cost_factor
= buf
->ReadByte();
1748 case PROP_AIRCRAFT_SPEED
: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1749 avi
->max_speed
= (buf
->ReadByte() * 128) / 10;
1752 case 0x0D: // Acceleration
1753 avi
->acceleration
= buf
->ReadByte();
1756 case PROP_AIRCRAFT_RUNNING_COST_FACTOR
: // 0x0E Running cost factor
1757 avi
->running_cost
= buf
->ReadByte();
1760 case PROP_AIRCRAFT_PASSENGER_CAPACITY
: // 0x0F Passenger capacity
1761 avi
->passenger_capacity
= buf
->ReadWord();
1764 case PROP_AIRCRAFT_MAIL_CAPACITY
: // 0x11 Mail capacity
1765 avi
->mail_capacity
= buf
->ReadByte();
1769 avi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1772 case 0x13: { // Cargoes available for refitting
1773 uint32 mask
= buf
->ReadDWord();
1774 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1775 ei
->refit_mask
= TranslateRefitMask(mask
);
1776 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1780 case 0x14: // Callback mask
1781 ei
->callback_mask
= buf
->ReadByte();
1784 case 0x15: // Refit cost
1785 ei
->refit_cost
= buf
->ReadByte();
1788 case 0x16: // Retire vehicle early
1789 ei
->retire_early
= buf
->ReadByte();
1792 case 0x17: // Miscellaneous flags
1793 ei
->misc_flags
= buf
->ReadByte();
1794 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1797 case 0x18: // Cargo classes allowed
1798 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1799 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1800 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1803 case 0x19: // Cargo classes disallowed
1804 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1805 _gted
[e
->index
].UpdateRefittability(false);
1808 case 0x1A: // Long format introduction date (days since year 0)
1809 ei
->base_intro
= buf
->ReadDWord();
1812 case 0x1B: // Alter purchase list sort order
1813 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1816 case PROP_AIRCRAFT_CARGO_AGE_PERIOD
: // 0x1C Cargo aging period
1817 ei
->cargo_age_period
= buf
->ReadWord();
1820 case 0x1D: // CTT refit include list
1821 case 0x1E: { // CTT refit exclude list
1822 uint8 count
= buf
->ReadByte();
1823 _gted
[e
->index
].UpdateRefittability(prop
== 0x1D && count
!= 0);
1824 if (prop
== 0x1D) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1825 CargoTypes
&ctt
= prop
== 0x1D ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1828 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1829 if (ctype
== CT_INVALID
) continue;
1835 case PROP_AIRCRAFT_RANGE
: // 0x1F Max aircraft range
1836 avi
->max_range
= buf
->ReadWord();
1840 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1849 * Define properties for stations
1850 * @param stid StationID of the first station tile.
1851 * @param numinfo Number of subsequent station tiles to change the property for.
1852 * @param prop The property to change.
1853 * @param buf The property value.
1854 * @return ChangeInfoResult.
1856 static ChangeInfoResult
StationChangeInfo(uint stid
, int numinfo
, int prop
, ByteReader
*buf
)
1858 ChangeInfoResult ret
= CIR_SUCCESS
;
1860 if (stid
+ numinfo
> NUM_STATIONS_PER_GRF
) {
1861 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid
+ numinfo
, NUM_STATIONS_PER_GRF
);
1862 return CIR_INVALID_ID
;
1865 /* Allocate station specs if necessary */
1866 if (_cur
.grffile
->stations
== nullptr) _cur
.grffile
->stations
= CallocT
<StationSpec
*>(NUM_STATIONS_PER_GRF
);
1868 for (int i
= 0; i
< numinfo
; i
++) {
1869 StationSpec
*statspec
= _cur
.grffile
->stations
[stid
+ i
];
1871 /* Check that the station we are modifying is defined. */
1872 if (statspec
== nullptr && prop
!= 0x08) {
1873 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid
+ i
);
1874 return CIR_INVALID_ID
;
1878 case 0x08: { // Class ID
1879 StationSpec
**spec
= &_cur
.grffile
->stations
[stid
+ i
];
1881 /* Property 0x08 is special; it is where the station is allocated */
1882 if (*spec
== nullptr) *spec
= CallocT
<StationSpec
>(1);
1884 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1885 uint32 classid
= buf
->ReadDWord();
1886 (*spec
)->cls_id
= StationClass::Allocate(BSWAP32(classid
));
1890 case 0x09: // Define sprite layout
1891 statspec
->tiles
= buf
->ReadExtendedByte();
1892 delete[] statspec
->renderdata
; // delete earlier loaded stuff
1893 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
1895 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
1896 NewGRFSpriteLayout
*dts
= &statspec
->renderdata
[t
];
1897 dts
->consistent_max_offset
= UINT16_MAX
; // Spritesets are unknown, so no limit.
1899 if (buf
->HasData(4) && *(uint32
*)buf
->Data() == 0) {
1901 extern const DrawTileSprites _station_display_datas_rail
[8];
1902 dts
->Clone(&_station_display_datas_rail
[t
% 8]);
1906 ReadSpriteLayoutSprite(buf
, false, false, false, GSF_STATIONS
, &dts
->ground
);
1907 /* On error, bail out immediately. Temporary GRF data was already freed */
1908 if (_cur
.skip_sprites
< 0) return CIR_DISABLED
;
1910 static std::vector
<DrawTileSeqStruct
> tmp_layout
;
1913 /* no relative bounding box support */
1914 /*C++17: DrawTileSeqStruct &dtss = */ tmp_layout
.emplace_back();
1915 DrawTileSeqStruct
&dtss
= tmp_layout
.back();
1918 dtss
.delta_x
= buf
->ReadByte();
1919 if (dtss
.IsTerminator()) break;
1920 dtss
.delta_y
= buf
->ReadByte();
1921 dtss
.delta_z
= buf
->ReadByte();
1922 dtss
.size_x
= buf
->ReadByte();
1923 dtss
.size_y
= buf
->ReadByte();
1924 dtss
.size_z
= buf
->ReadByte();
1926 ReadSpriteLayoutSprite(buf
, false, true, false, GSF_STATIONS
, &dtss
.image
);
1927 /* On error, bail out immediately. Temporary GRF data was already freed */
1928 if (_cur
.skip_sprites
< 0) return CIR_DISABLED
;
1930 dts
->Clone(tmp_layout
.data());
1934 case 0x0A: { // Copy sprite layout
1935 byte srcid
= buf
->ReadByte();
1936 const StationSpec
*srcstatspec
= _cur
.grffile
->stations
[srcid
];
1938 if (srcstatspec
== nullptr) {
1939 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid
, stid
+ i
);
1943 delete[] statspec
->renderdata
; // delete earlier loaded stuff
1945 statspec
->tiles
= srcstatspec
->tiles
;
1946 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
1947 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
1948 statspec
->renderdata
[t
].Clone(&srcstatspec
->renderdata
[t
]);
1953 case 0x0B: // Callback mask
1954 statspec
->callback_mask
= buf
->ReadByte();
1957 case 0x0C: // Disallowed number of platforms
1958 statspec
->disallowed_platforms
= buf
->ReadByte();
1961 case 0x0D: // Disallowed platform lengths
1962 statspec
->disallowed_lengths
= buf
->ReadByte();
1965 case 0x0E: // Define custom layout
1966 statspec
->copied_layouts
= false;
1968 while (buf
->HasData()) {
1969 byte length
= buf
->ReadByte();
1970 byte number
= buf
->ReadByte();
1971 StationLayout layout
;
1974 if (length
== 0 || number
== 0) break;
1976 if (length
> statspec
->lengths
) {
1977 byte diff_length
= length
- statspec
->lengths
;
1978 statspec
->platforms
= ReallocT(statspec
->platforms
, length
);
1979 memset(statspec
->platforms
+ statspec
->lengths
, 0, diff_length
);
1981 statspec
->layouts
= ReallocT(statspec
->layouts
, length
);
1982 memset(statspec
->layouts
+ statspec
->lengths
, 0, diff_length
* sizeof(*statspec
->layouts
));
1984 statspec
->lengths
= length
;
1986 l
= length
- 1; // index is zero-based
1988 if (number
> statspec
->platforms
[l
]) {
1989 statspec
->layouts
[l
] = ReallocT(statspec
->layouts
[l
], number
);
1990 /* We expect nullptr being 0 here, but C99 guarantees that. */
1991 memset(statspec
->layouts
[l
] + statspec
->platforms
[l
], 0,
1992 (number
- statspec
->platforms
[l
]) * sizeof(**statspec
->layouts
));
1994 statspec
->platforms
[l
] = number
;
1998 layout
= MallocT
<byte
>(length
* number
);
2000 for (l
= 0; l
< length
; l
++) {
2001 for (p
= 0; p
< number
; p
++) {
2002 layout
[l
* number
+ p
] = buf
->ReadByte();
2012 free(statspec
->layouts
[l
][p
]);
2013 statspec
->layouts
[l
][p
] = layout
;
2017 case 0x0F: { // Copy custom layout
2018 byte srcid
= buf
->ReadByte();
2019 const StationSpec
*srcstatspec
= _cur
.grffile
->stations
[srcid
];
2021 if (srcstatspec
== nullptr) {
2022 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid
, stid
+ i
);
2026 statspec
->lengths
= srcstatspec
->lengths
;
2027 statspec
->platforms
= srcstatspec
->platforms
;
2028 statspec
->layouts
= srcstatspec
->layouts
;
2029 statspec
->copied_layouts
= true;
2033 case 0x10: // Little/lots cargo threshold
2034 statspec
->cargo_threshold
= buf
->ReadWord();
2037 case 0x11: // Pylon placement
2038 statspec
->pylons
= buf
->ReadByte();
2041 case 0x12: // Cargo types for random triggers
2042 if (_cur
.grffile
->grf_version
>= 7) {
2043 statspec
->cargo_triggers
= TranslateRefitMask(buf
->ReadDWord());
2045 statspec
->cargo_triggers
= (CargoTypes
)buf
->ReadDWord();
2049 case 0x13: // General flags
2050 statspec
->flags
= buf
->ReadByte();
2053 case 0x14: // Overhead wire placement
2054 statspec
->wires
= buf
->ReadByte();
2057 case 0x15: // Blocked tiles
2058 statspec
->blocked
= buf
->ReadByte();
2061 case 0x16: // Animation info
2062 statspec
->animation
.frames
= buf
->ReadByte();
2063 statspec
->animation
.status
= buf
->ReadByte();
2066 case 0x17: // Animation speed
2067 statspec
->animation
.speed
= buf
->ReadByte();
2070 case 0x18: // Animation triggers
2071 statspec
->animation
.triggers
= buf
->ReadWord();
2074 case 0x1A: // Advanced sprite layout
2075 statspec
->tiles
= buf
->ReadExtendedByte();
2076 delete[] statspec
->renderdata
; // delete earlier loaded stuff
2077 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
2079 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
2080 NewGRFSpriteLayout
*dts
= &statspec
->renderdata
[t
];
2081 uint num_building_sprites
= buf
->ReadByte();
2082 /* On error, bail out immediately. Temporary GRF data was already freed */
2083 if (ReadSpriteLayout(buf
, num_building_sprites
, false, GSF_STATIONS
, true, false, dts
)) return CIR_DISABLED
;
2097 * Define properties for water features
2098 * @param id Type of the first water feature.
2099 * @param numinfo Number of subsequent water feature ids to change the property for.
2100 * @param prop The property to change.
2101 * @param buf The property value.
2102 * @return ChangeInfoResult.
2104 static ChangeInfoResult
CanalChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
2106 ChangeInfoResult ret
= CIR_SUCCESS
;
2108 if (id
+ numinfo
> CF_END
) {
2109 grfmsg(1, "CanalChangeInfo: Canal feature 0x%02X is invalid, max %u, ignoring", id
+ numinfo
, CF_END
);
2110 return CIR_INVALID_ID
;
2113 for (int i
= 0; i
< numinfo
; i
++) {
2114 CanalProperties
*cp
= &_cur
.grffile
->canal_local_properties
[id
+ i
];
2118 cp
->callback_mask
= buf
->ReadByte();
2122 cp
->flags
= buf
->ReadByte();
2135 * Define properties for bridges
2136 * @param brid BridgeID of the bridge.
2137 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2138 * @param prop The property to change.
2139 * @param buf The property value.
2140 * @return ChangeInfoResult.
2142 static ChangeInfoResult
BridgeChangeInfo(uint brid
, int numinfo
, int prop
, ByteReader
*buf
)
2144 ChangeInfoResult ret
= CIR_SUCCESS
;
2146 if (brid
+ numinfo
> MAX_BRIDGES
) {
2147 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid
+ numinfo
, MAX_BRIDGES
);
2148 return CIR_INVALID_ID
;
2151 for (int i
= 0; i
< numinfo
; i
++) {
2152 BridgeSpec
*bridge
= &_bridge
[brid
+ i
];
2155 case 0x08: { // Year of availability
2156 /* We treat '0' as always available */
2157 byte year
= buf
->ReadByte();
2158 bridge
->avail_year
= (year
> 0 ? ORIGINAL_BASE_YEAR
+ year
: 0);
2162 case 0x09: // Minimum length
2163 bridge
->min_length
= buf
->ReadByte();
2166 case 0x0A: // Maximum length
2167 bridge
->max_length
= buf
->ReadByte();
2168 if (bridge
->max_length
> 16) bridge
->max_length
= 0xFFFF;
2171 case 0x0B: // Cost factor
2172 bridge
->price
= buf
->ReadByte();
2175 case 0x0C: // Maximum speed
2176 bridge
->speed
= buf
->ReadWord();
2179 case 0x0D: { // Bridge sprite tables
2180 byte tableid
= buf
->ReadByte();
2181 byte numtables
= buf
->ReadByte();
2183 if (bridge
->sprite_table
== nullptr) {
2184 /* Allocate memory for sprite table pointers and zero out */
2185 bridge
->sprite_table
= CallocT
<PalSpriteID
*>(7);
2188 for (; numtables
-- != 0; tableid
++) {
2189 if (tableid
>= 7) { // skip invalid data
2190 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid
);
2191 for (byte sprite
= 0; sprite
< 32; sprite
++) buf
->ReadDWord();
2195 if (bridge
->sprite_table
[tableid
] == nullptr) {
2196 bridge
->sprite_table
[tableid
] = MallocT
<PalSpriteID
>(32);
2199 for (byte sprite
= 0; sprite
< 32; sprite
++) {
2200 SpriteID image
= buf
->ReadWord();
2201 PaletteID pal
= buf
->ReadWord();
2203 bridge
->sprite_table
[tableid
][sprite
].sprite
= image
;
2204 bridge
->sprite_table
[tableid
][sprite
].pal
= pal
;
2206 MapSpriteMappingRecolour(&bridge
->sprite_table
[tableid
][sprite
]);
2212 case 0x0E: // Flags; bit 0 - disable far pillars
2213 bridge
->flags
= buf
->ReadByte();
2216 case 0x0F: // Long format year of availability (year since year 0)
2217 bridge
->avail_year
= Clamp(buf
->ReadDWord(), MIN_YEAR
, MAX_YEAR
);
2220 case 0x10: { // purchase string
2221 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2222 if (newone
!= STR_UNDEFINED
) bridge
->material
= newone
;
2226 case 0x11: // description of bridge with rails or roads
2228 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2229 if (newone
!= STR_UNDEFINED
) bridge
->transport_name
[prop
- 0x11] = newone
;
2233 case 0x13: // 16 bits cost multiplier
2234 bridge
->price
= buf
->ReadWord();
2247 * Ignore a house property
2248 * @param prop Property to read.
2249 * @param buf Property value.
2250 * @return ChangeInfoResult.
2252 static ChangeInfoResult
IgnoreTownHouseProperty(int prop
, ByteReader
*buf
)
2254 ChangeInfoResult ret
= CIR_SUCCESS
;
2291 for (uint j
= 0; j
< 4; j
++) buf
->ReadByte();
2295 byte count
= buf
->ReadByte();
2296 for (byte j
= 0; j
< count
; j
++) buf
->ReadByte();
2301 buf
->Skip(buf
->ReadByte() * 2);
2312 * Define properties for houses
2313 * @param hid HouseID of the house.
2314 * @param numinfo Number of subsequent houseIDs to change the property for.
2315 * @param prop The property to change.
2316 * @param buf The property value.
2317 * @return ChangeInfoResult.
2319 static ChangeInfoResult
TownHouseChangeInfo(uint hid
, int numinfo
, int prop
, ByteReader
*buf
)
2321 ChangeInfoResult ret
= CIR_SUCCESS
;
2323 if (hid
+ numinfo
> NUM_HOUSES_PER_GRF
) {
2324 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid
+ numinfo
, NUM_HOUSES_PER_GRF
);
2325 return CIR_INVALID_ID
;
2328 /* Allocate house specs if they haven't been allocated already. */
2329 if (_cur
.grffile
->housespec
== nullptr) {
2330 _cur
.grffile
->housespec
= CallocT
<HouseSpec
*>(NUM_HOUSES_PER_GRF
);
2333 for (int i
= 0; i
< numinfo
; i
++) {
2334 HouseSpec
*housespec
= _cur
.grffile
->housespec
[hid
+ i
];
2336 if (prop
!= 0x08 && housespec
== nullptr) {
2337 /* If the house property 08 is not yet set, ignore this property */
2338 ChangeInfoResult cir
= IgnoreTownHouseProperty(prop
, buf
);
2339 if (cir
> ret
) ret
= cir
;
2344 case 0x08: { // Substitute building type, and definition of a new house
2345 HouseSpec
**house
= &_cur
.grffile
->housespec
[hid
+ i
];
2346 byte subs_id
= buf
->ReadByte();
2348 if (subs_id
== 0xFF) {
2349 /* Instead of defining a new house, a substitute house id
2350 * of 0xFF disables the old house with the current id. */
2351 HouseSpec::Get(hid
+ i
)->enabled
= false;
2353 } else if (subs_id
>= NEW_HOUSE_OFFSET
) {
2354 /* The substitute id must be one of the original houses. */
2355 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id
, hid
+ i
);
2359 /* Allocate space for this house. */
2360 if (*house
== nullptr) *house
= CallocT
<HouseSpec
>(1);
2364 MemCpyT(housespec
, HouseSpec::Get(subs_id
));
2366 housespec
->enabled
= true;
2367 housespec
->grf_prop
.local_id
= hid
+ i
;
2368 housespec
->grf_prop
.subst_id
= subs_id
;
2369 housespec
->grf_prop
.grffile
= _cur
.grffile
;
2370 housespec
->random_colour
[0] = 0x04; // those 4 random colours are the base colour
2371 housespec
->random_colour
[1] = 0x08; // for all new houses
2372 housespec
->random_colour
[2] = 0x0C; // they stand for red, blue, orange and green
2373 housespec
->random_colour
[3] = 0x06;
2375 /* Make sure that the third cargo type is valid in this
2376 * climate. This can cause problems when copying the properties
2377 * of a house that accepts food, where the new house is valid
2378 * in the temperate climate. */
2379 if (!CargoSpec::Get(housespec
->accepts_cargo
[2])->IsValid()) {
2380 housespec
->cargo_acceptance
[2] = 0;
2383 _loaded_newgrf_features
.has_newhouses
= true;
2387 case 0x09: // Building flags
2388 housespec
->building_flags
= (BuildingFlags
)buf
->ReadByte();
2391 case 0x0A: { // Availability years
2392 uint16 years
= buf
->ReadWord();
2393 housespec
->min_year
= GB(years
, 0, 8) > 150 ? MAX_YEAR
: ORIGINAL_BASE_YEAR
+ GB(years
, 0, 8);
2394 housespec
->max_year
= GB(years
, 8, 8) > 150 ? MAX_YEAR
: ORIGINAL_BASE_YEAR
+ GB(years
, 8, 8);
2398 case 0x0B: // Population
2399 housespec
->population
= buf
->ReadByte();
2402 case 0x0C: // Mail generation multiplier
2403 housespec
->mail_generation
= buf
->ReadByte();
2406 case 0x0D: // Passenger acceptance
2407 case 0x0E: // Mail acceptance
2408 housespec
->cargo_acceptance
[prop
- 0x0D] = buf
->ReadByte();
2411 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2412 int8 goods
= buf
->ReadByte();
2414 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2415 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2416 CargoID cid
= (goods
>= 0) ? ((_settings_game
.game_creation
.landscape
== LT_TOYLAND
) ? CT_CANDY
: CT_GOODS
) :
2417 ((_settings_game
.game_creation
.landscape
== LT_TOYLAND
) ? CT_FIZZY_DRINKS
: CT_FOOD
);
2419 /* Make sure the cargo type is valid in this climate. */
2420 if (!CargoSpec::Get(cid
)->IsValid()) goods
= 0;
2422 housespec
->accepts_cargo
[2] = cid
;
2423 housespec
->cargo_acceptance
[2] = abs(goods
); // but we do need positive value here
2427 case 0x10: // Local authority rating decrease on removal
2428 housespec
->remove_rating_decrease
= buf
->ReadWord();
2431 case 0x11: // Removal cost multiplier
2432 housespec
->removal_cost
= buf
->ReadByte();
2435 case 0x12: // Building name ID
2436 AddStringForMapping(buf
->ReadWord(), &housespec
->building_name
);
2439 case 0x13: // Building availability mask
2440 housespec
->building_availability
= (HouseZones
)buf
->ReadWord();
2443 case 0x14: // House callback mask
2444 housespec
->callback_mask
|= buf
->ReadByte();
2447 case 0x15: { // House override byte
2448 byte override
= buf
->ReadByte();
2450 /* The house being overridden must be an original house. */
2451 if (override
>= NEW_HOUSE_OFFSET
) {
2452 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override
, hid
+ i
);
2456 _house_mngr
.Add(hid
+ i
, _cur
.grffile
->grfid
, override
);
2460 case 0x16: // Periodic refresh multiplier
2461 housespec
->processing_time
= min(buf
->ReadByte(), 63);
2464 case 0x17: // Four random colours to use
2465 for (uint j
= 0; j
< 4; j
++) housespec
->random_colour
[j
] = buf
->ReadByte();
2468 case 0x18: // Relative probability of appearing
2469 housespec
->probability
= buf
->ReadByte();
2472 case 0x19: // Extra flags
2473 housespec
->extra_flags
= (HouseExtraFlags
)buf
->ReadByte();
2476 case 0x1A: // Animation frames
2477 housespec
->animation
.frames
= buf
->ReadByte();
2478 housespec
->animation
.status
= GB(housespec
->animation
.frames
, 7, 1);
2479 SB(housespec
->animation
.frames
, 7, 1, 0);
2482 case 0x1B: // Animation speed
2483 housespec
->animation
.speed
= Clamp(buf
->ReadByte(), 2, 16);
2486 case 0x1C: // Class of the building type
2487 housespec
->class_id
= AllocateHouseClassID(buf
->ReadByte(), _cur
.grffile
->grfid
);
2490 case 0x1D: // Callback mask part 2
2491 housespec
->callback_mask
|= (buf
->ReadByte() << 8);
2494 case 0x1E: { // Accepted cargo types
2495 uint32 cargotypes
= buf
->ReadDWord();
2497 /* Check if the cargo types should not be changed */
2498 if (cargotypes
== 0xFFFFFFFF) break;
2500 for (uint j
= 0; j
< 3; j
++) {
2501 /* Get the cargo number from the 'list' */
2502 uint8 cargo_part
= GB(cargotypes
, 8 * j
, 8);
2503 CargoID cargo
= GetCargoTranslation(cargo_part
, _cur
.grffile
);
2505 if (cargo
== CT_INVALID
) {
2506 /* Disable acceptance of invalid cargo type */
2507 housespec
->cargo_acceptance
[j
] = 0;
2509 housespec
->accepts_cargo
[j
] = cargo
;
2515 case 0x1F: // Minimum life span
2516 housespec
->minimum_life
= buf
->ReadByte();
2519 case 0x20: { // Cargo acceptance watch list
2520 byte count
= buf
->ReadByte();
2521 for (byte j
= 0; j
< count
; j
++) {
2522 CargoID cargo
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
2523 if (cargo
!= CT_INVALID
) SetBit(housespec
->watched_cargoes
, cargo
);
2528 case 0x21: // long introduction year
2529 housespec
->min_year
= buf
->ReadWord();
2532 case 0x22: // long maximum year
2533 housespec
->max_year
= buf
->ReadWord();
2536 case 0x23: { // variable length cargo types accepted
2537 uint count
= buf
->ReadByte();
2538 if (count
> lengthof(housespec
->accepts_cargo
)) {
2539 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG
);
2540 error
->param_value
[1] = prop
;
2541 return CIR_DISABLED
;
2543 /* Always write the full accepts_cargo array, and check each index for being inside the
2544 * provided data. This ensures all values are properly initialized, and also avoids
2545 * any risks of array overrun. */
2546 for (uint i
= 0; i
< lengthof(housespec
->accepts_cargo
); i
++) {
2548 housespec
->accepts_cargo
[i
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
2549 housespec
->cargo_acceptance
[i
] = buf
->ReadByte();
2551 housespec
->accepts_cargo
[i
] = CT_INVALID
;
2552 housespec
->cargo_acceptance
[i
] = 0;
2568 * Get the language map associated with a given NewGRF and language.
2569 * @param grfid The NewGRF to get the map for.
2570 * @param language_id The (NewGRF) language ID to get the map for.
2571 * @return The LanguageMap, or nullptr if it couldn't be found.
2573 /* static */ const LanguageMap
*LanguageMap::GetLanguageMap(uint32 grfid
, uint8 language_id
)
2575 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2576 const GRFFile
*grffile
= GetFileByGRFID(grfid
);
2577 return (grffile
!= nullptr && grffile
->language_map
!= nullptr && language_id
< MAX_LANG
) ? &grffile
->language_map
[language_id
] : nullptr;
2581 * Load a cargo- or railtype-translation table.
2582 * @param gvid ID of the global variable. This is basically only checked for zerones.
2583 * @param numinfo Number of subsequent IDs to change the property for.
2584 * @param buf The property value.
2585 * @param[in,out] translation_table Storage location for the translation table.
2586 * @param name Name of the table for debug output.
2587 * @return ChangeInfoResult.
2589 template <typename T
>
2590 static ChangeInfoResult
LoadTranslationTable(uint gvid
, int numinfo
, ByteReader
*buf
, T
&translation_table
, const char *name
)
2593 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name
);
2594 return CIR_INVALID_ID
;
2597 translation_table
.clear();
2598 for (int i
= 0; i
< numinfo
; i
++) {
2599 uint32 item
= buf
->ReadDWord();
2600 translation_table
.push_back(BSWAP32(item
));
2607 * Define properties for global variables
2608 * @param gvid ID of the global variable.
2609 * @param numinfo Number of subsequent IDs to change the property for.
2610 * @param prop The property to change.
2611 * @param buf The property value.
2612 * @return ChangeInfoResult.
2614 static ChangeInfoResult
GlobalVarChangeInfo(uint gvid
, int numinfo
, int prop
, ByteReader
*buf
)
2616 /* Properties which are handled as a whole */
2618 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2619 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->cargo_list
, "Cargo");
2621 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2622 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->railtype_list
, "Rail type");
2624 case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2625 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->roadtype_list
, "Road type");
2627 case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2628 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->tramtype_list
, "Tram type");
2634 /* Properties which are handled per item */
2635 ChangeInfoResult ret
= CIR_SUCCESS
;
2636 for (int i
= 0; i
< numinfo
; i
++) {
2638 case 0x08: { // Cost base factor
2639 int factor
= buf
->ReadByte();
2640 uint price
= gvid
+ i
;
2642 if (price
< PR_END
) {
2643 _cur
.grffile
->price_base_multipliers
[price
] = min
<int>(factor
- 8, MAX_PRICE_MODIFIER
);
2645 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price
);
2650 case 0x0A: { // Currency display names
2651 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2652 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2654 if ((newone
!= STR_UNDEFINED
) && (curidx
< CURRENCY_END
)) {
2655 _currency_specs
[curidx
].name
= newone
;
2660 case 0x0B: { // Currency multipliers
2661 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2662 uint32 rate
= buf
->ReadDWord();
2664 if (curidx
< CURRENCY_END
) {
2665 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2666 * which OTTD does not. For this reason, divide grf value by 1000,
2667 * to be compatible */
2668 _currency_specs
[curidx
].rate
= rate
/ 1000;
2670 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx
);
2675 case 0x0C: { // Currency options
2676 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2677 uint16 options
= buf
->ReadWord();
2679 if (curidx
< CURRENCY_END
) {
2680 _currency_specs
[curidx
].separator
[0] = GB(options
, 0, 8);
2681 _currency_specs
[curidx
].separator
[1] = '\0';
2682 /* By specifying only one bit, we prevent errors,
2683 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2684 _currency_specs
[curidx
].symbol_pos
= GB(options
, 8, 1);
2686 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx
);
2691 case 0x0D: { // Currency prefix symbol
2692 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2693 uint32 tempfix
= buf
->ReadDWord();
2695 if (curidx
< CURRENCY_END
) {
2696 memcpy(_currency_specs
[curidx
].prefix
, &tempfix
, 4);
2697 _currency_specs
[curidx
].prefix
[4] = 0;
2699 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx
);
2704 case 0x0E: { // Currency suffix symbol
2705 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2706 uint32 tempfix
= buf
->ReadDWord();
2708 if (curidx
< CURRENCY_END
) {
2709 memcpy(&_currency_specs
[curidx
].suffix
, &tempfix
, 4);
2710 _currency_specs
[curidx
].suffix
[4] = 0;
2712 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx
);
2717 case 0x0F: { // Euro introduction dates
2718 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2719 Year year_euro
= buf
->ReadWord();
2721 if (curidx
< CURRENCY_END
) {
2722 _currency_specs
[curidx
].to_euro
= year_euro
;
2724 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx
);
2729 case 0x10: // Snow line height table
2730 if (numinfo
> 1 || IsSnowLineSet()) {
2731 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo
);
2732 } else if (buf
->Remaining() < SNOW_LINE_MONTHS
* SNOW_LINE_DAYS
) {
2733 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf
->Remaining());
2735 byte table
[SNOW_LINE_MONTHS
][SNOW_LINE_DAYS
];
2737 for (uint i
= 0; i
< SNOW_LINE_MONTHS
; i
++) {
2738 for (uint j
= 0; j
< SNOW_LINE_DAYS
; j
++) {
2739 table
[i
][j
] = buf
->ReadByte();
2740 if (_cur
.grffile
->grf_version
>= 8) {
2741 if (table
[i
][j
] != 0xFF) table
[i
][j
] = table
[i
][j
] * (1 + _settings_game
.construction
.max_heightlevel
) / 256;
2743 if (table
[i
][j
] >= 128) {
2747 table
[i
][j
] = table
[i
][j
] * (1 + _settings_game
.construction
.max_heightlevel
) / 128;
2756 case 0x11: // GRF match for engine allocation
2757 /* This is loaded during the reservation stage, so just skip it here. */
2758 /* Each entry is 8 bytes. */
2762 case 0x13: // Gender translation table
2763 case 0x14: // Case translation table
2764 case 0x15: { // Plural form translation
2765 uint curidx
= gvid
+ i
; // The current index, i.e. language.
2766 const LanguageMetadata
*lang
= curidx
< MAX_LANG
? GetLanguage(curidx
) : nullptr;
2767 if (lang
== nullptr) {
2768 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx
);
2769 /* Skip over the data. */
2773 while (buf
->ReadByte() != 0) {
2780 if (_cur
.grffile
->language_map
== nullptr) _cur
.grffile
->language_map
= new LanguageMap
[MAX_LANG
];
2783 uint plural_form
= buf
->ReadByte();
2784 if (plural_form
>= LANGUAGE_MAX_PLURAL
) {
2785 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form
);
2787 _cur
.grffile
->language_map
[curidx
].plural_form
= plural_form
;
2792 byte newgrf_id
= buf
->ReadByte(); // The NewGRF (custom) identifier.
2793 while (newgrf_id
!= 0) {
2794 const char *name
= buf
->ReadString(); // The name for the OpenTTD identifier.
2796 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2797 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2798 * is just a subset of UTF8, or they need the bigger UTF8 characters
2799 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2801 size_t len
= Utf8Decode(&c
, name
);
2802 if (c
== NFO_UTF8_IDENTIFIER
) name
+= len
;
2804 LanguageMap::Mapping map
;
2805 map
.newgrf_id
= newgrf_id
;
2807 map
.openttd_id
= lang
->GetGenderIndex(name
);
2808 if (map
.openttd_id
>= MAX_NUM_GENDERS
) {
2809 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name
);
2811 _cur
.grffile
->language_map
[curidx
].gender_map
.push_back(map
);
2814 map
.openttd_id
= lang
->GetCaseIndex(name
);
2815 if (map
.openttd_id
>= MAX_NUM_CASES
) {
2816 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name
);
2818 _cur
.grffile
->language_map
[curidx
].case_map
.push_back(map
);
2821 newgrf_id
= buf
->ReadByte();
2835 static ChangeInfoResult
GlobalVarReserveInfo(uint gvid
, int numinfo
, int prop
, ByteReader
*buf
)
2837 /* Properties which are handled as a whole */
2839 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2840 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->cargo_list
, "Cargo");
2842 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2843 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->railtype_list
, "Rail type");
2845 case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined roadtypes)
2846 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->roadtype_list
, "Road type");
2848 case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined tramtypes)
2849 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->tramtype_list
, "Tram type");
2855 /* Properties which are handled per item */
2856 ChangeInfoResult ret
= CIR_SUCCESS
;
2857 for (int i
= 0; i
< numinfo
; i
++) {
2859 case 0x08: // Cost base factor
2860 case 0x15: // Plural form translation
2864 case 0x0A: // Currency display names
2865 case 0x0C: // Currency options
2866 case 0x0F: // Euro introduction dates
2870 case 0x0B: // Currency multipliers
2871 case 0x0D: // Currency prefix symbol
2872 case 0x0E: // Currency suffix symbol
2876 case 0x10: // Snow line height table
2877 buf
->Skip(SNOW_LINE_MONTHS
* SNOW_LINE_DAYS
);
2880 case 0x11: { // GRF match for engine allocation
2881 uint32 s
= buf
->ReadDWord();
2882 uint32 t
= buf
->ReadDWord();
2883 SetNewGRFOverride(s
, t
);
2887 case 0x13: // Gender translation table
2888 case 0x14: // Case translation table
2889 while (buf
->ReadByte() != 0) {
2905 * Define properties for cargoes
2906 * @param cid Local ID of the cargo.
2907 * @param numinfo Number of subsequent IDs to change the property for.
2908 * @param prop The property to change.
2909 * @param buf The property value.
2910 * @return ChangeInfoResult.
2912 static ChangeInfoResult
CargoChangeInfo(uint cid
, int numinfo
, int prop
, ByteReader
*buf
)
2914 ChangeInfoResult ret
= CIR_SUCCESS
;
2916 if (cid
+ numinfo
> NUM_CARGO
) {
2917 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid
+ numinfo
, NUM_CARGO
- 1);
2918 return CIR_INVALID_ID
;
2921 for (int i
= 0; i
< numinfo
; i
++) {
2922 CargoSpec
*cs
= CargoSpec::Get(cid
+ i
);
2925 case 0x08: // Bit number of cargo
2926 cs
->bitnum
= buf
->ReadByte();
2927 if (cs
->IsValid()) {
2928 cs
->grffile
= _cur
.grffile
;
2929 SetBit(_cargo_mask
, cid
+ i
);
2931 ClrBit(_cargo_mask
, cid
+ i
);
2935 case 0x09: // String ID for cargo type name
2936 AddStringForMapping(buf
->ReadWord(), &cs
->name
);
2939 case 0x0A: // String for 1 unit of cargo
2940 AddStringForMapping(buf
->ReadWord(), &cs
->name_single
);
2943 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2944 case 0x1B: // String for cargo units
2945 /* String for units of cargo. This is different in OpenTTD
2946 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2947 * Property 1B is used to set OpenTTD's behaviour. */
2948 AddStringForMapping(buf
->ReadWord(), &cs
->units_volume
);
2951 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2952 case 0x1C: // String for any amount of cargo
2953 /* Strings for an amount of cargo. This is different in OpenTTD
2954 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2955 * Property 1C is used to set OpenTTD's behaviour. */
2956 AddStringForMapping(buf
->ReadWord(), &cs
->quantifier
);
2959 case 0x0D: // String for two letter cargo abbreviation
2960 AddStringForMapping(buf
->ReadWord(), &cs
->abbrev
);
2963 case 0x0E: // Sprite ID for cargo icon
2964 cs
->sprite
= buf
->ReadWord();
2967 case 0x0F: // Weight of one unit of cargo
2968 cs
->weight
= buf
->ReadByte();
2971 case 0x10: // Used for payment calculation
2972 cs
->transit_days
[0] = buf
->ReadByte();
2975 case 0x11: // Used for payment calculation
2976 cs
->transit_days
[1] = buf
->ReadByte();
2979 case 0x12: // Base cargo price
2980 cs
->initial_payment
= buf
->ReadDWord();
2983 case 0x13: // Colour for station rating bars
2984 cs
->rating_colour
= buf
->ReadByte();
2987 case 0x14: // Colour for cargo graph
2988 cs
->legend_colour
= buf
->ReadByte();
2991 case 0x15: // Freight status
2992 cs
->is_freight
= (buf
->ReadByte() != 0);
2995 case 0x16: // Cargo classes
2996 cs
->classes
= buf
->ReadWord();
2999 case 0x17: // Cargo label
3000 cs
->label
= buf
->ReadDWord();
3001 cs
->label
= BSWAP32(cs
->label
);
3004 case 0x18: { // Town growth substitute type
3005 uint8 substitute_type
= buf
->ReadByte();
3007 switch (substitute_type
) {
3008 case 0x00: cs
->town_effect
= TE_PASSENGERS
; break;
3009 case 0x02: cs
->town_effect
= TE_MAIL
; break;
3010 case 0x05: cs
->town_effect
= TE_GOODS
; break;
3011 case 0x09: cs
->town_effect
= TE_WATER
; break;
3012 case 0x0B: cs
->town_effect
= TE_FOOD
; break;
3014 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type
);
3016 case 0xFF: cs
->town_effect
= TE_NONE
; break;
3021 case 0x19: // Town growth coefficient
3022 cs
->multipliertowngrowth
= buf
->ReadWord();
3025 case 0x1A: // Bitmask of callbacks to use
3026 cs
->callback_mask
= buf
->ReadByte();
3029 case 0x1D: // Vehicle capacity muliplier
3030 cs
->multiplier
= max
<uint16
>(1u, buf
->ReadWord());
3044 * Define properties for sound effects
3045 * @param sid Local ID of the sound.
3046 * @param numinfo Number of subsequent IDs to change the property for.
3047 * @param prop The property to change.
3048 * @param buf The property value.
3049 * @return ChangeInfoResult.
3051 static ChangeInfoResult
SoundEffectChangeInfo(uint sid
, int numinfo
, int prop
, ByteReader
*buf
)
3053 ChangeInfoResult ret
= CIR_SUCCESS
;
3055 if (_cur
.grffile
->sound_offset
== 0) {
3056 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3057 return CIR_INVALID_ID
;
3060 if (sid
+ numinfo
- ORIGINAL_SAMPLE_COUNT
> _cur
.grffile
->num_sounds
) {
3061 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid
+ numinfo
, ORIGINAL_SAMPLE_COUNT
+ _cur
.grffile
->num_sounds
);
3062 return CIR_INVALID_ID
;
3065 for (int i
= 0; i
< numinfo
; i
++) {
3066 SoundEntry
*sound
= GetSound(sid
+ i
+ _cur
.grffile
->sound_offset
- ORIGINAL_SAMPLE_COUNT
);
3069 case 0x08: // Relative volume
3070 sound
->volume
= buf
->ReadByte();
3073 case 0x09: // Priority
3074 sound
->priority
= buf
->ReadByte();
3077 case 0x0A: { // Override old sound
3078 SoundID orig_sound
= buf
->ReadByte();
3080 if (orig_sound
>= ORIGINAL_SAMPLE_COUNT
) {
3081 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound
, ORIGINAL_SAMPLE_COUNT
);
3083 SoundEntry
*old_sound
= GetSound(orig_sound
);
3085 /* Literally copy the data of the new sound over the original */
3086 *old_sound
= *sound
;
3101 * Ignore an industry tile property
3102 * @param prop The property to ignore.
3103 * @param buf The property value.
3104 * @return ChangeInfoResult.
3106 static ChangeInfoResult
IgnoreIndustryTileProperty(int prop
, ByteReader
*buf
)
3108 ChangeInfoResult ret
= CIR_SUCCESS
;
3128 buf
->Skip(buf
->ReadByte() * 2);
3139 * Define properties for industry tiles
3140 * @param indtid Local ID of the industry tile.
3141 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3142 * @param prop The property to change.
3143 * @param buf The property value.
3144 * @return ChangeInfoResult.
3146 static ChangeInfoResult
IndustrytilesChangeInfo(uint indtid
, int numinfo
, int prop
, ByteReader
*buf
)
3148 ChangeInfoResult ret
= CIR_SUCCESS
;
3150 if (indtid
+ numinfo
> NUM_INDUSTRYTILES_PER_GRF
) {
3151 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid
+ numinfo
, NUM_INDUSTRYTILES_PER_GRF
);
3152 return CIR_INVALID_ID
;
3155 /* Allocate industry tile specs if they haven't been allocated already. */
3156 if (_cur
.grffile
->indtspec
== nullptr) {
3157 _cur
.grffile
->indtspec
= CallocT
<IndustryTileSpec
*>(NUM_INDUSTRYTILES_PER_GRF
);
3160 for (int i
= 0; i
< numinfo
; i
++) {
3161 IndustryTileSpec
*tsp
= _cur
.grffile
->indtspec
[indtid
+ i
];
3163 if (prop
!= 0x08 && tsp
== nullptr) {
3164 ChangeInfoResult cir
= IgnoreIndustryTileProperty(prop
, buf
);
3165 if (cir
> ret
) ret
= cir
;
3170 case 0x08: { // Substitute industry tile type
3171 IndustryTileSpec
**tilespec
= &_cur
.grffile
->indtspec
[indtid
+ i
];
3172 byte subs_id
= buf
->ReadByte();
3174 if (subs_id
>= NEW_INDUSTRYTILEOFFSET
) {
3175 /* The substitute id must be one of the original industry tile. */
3176 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id
, indtid
+ i
);
3180 /* Allocate space for this industry. */
3181 if (*tilespec
== nullptr) {
3182 *tilespec
= CallocT
<IndustryTileSpec
>(1);
3185 memcpy(tsp
, &_industry_tile_specs
[subs_id
], sizeof(_industry_tile_specs
[subs_id
]));
3186 tsp
->enabled
= true;
3188 /* A copied tile should not have the animation infos copied too.
3189 * The anim_state should be left untouched, though
3190 * It is up to the author to animate them himself */
3191 tsp
->anim_production
= INDUSTRYTILE_NOANIM
;
3192 tsp
->anim_next
= INDUSTRYTILE_NOANIM
;
3194 tsp
->grf_prop
.local_id
= indtid
+ i
;
3195 tsp
->grf_prop
.subst_id
= subs_id
;
3196 tsp
->grf_prop
.grffile
= _cur
.grffile
;
3197 _industile_mngr
.AddEntityID(indtid
+ i
, _cur
.grffile
->grfid
, subs_id
); // pre-reserve the tile slot
3202 case 0x09: { // Industry tile override
3203 byte ovrid
= buf
->ReadByte();
3205 /* The industry being overridden must be an original industry. */
3206 if (ovrid
>= NEW_INDUSTRYTILEOFFSET
) {
3207 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid
, indtid
+ i
);
3211 _industile_mngr
.Add(indtid
+ i
, _cur
.grffile
->grfid
, ovrid
);
3215 case 0x0A: // Tile acceptance
3218 uint16 acctp
= buf
->ReadWord();
3219 tsp
->accepts_cargo
[prop
- 0x0A] = GetCargoTranslation(GB(acctp
, 0, 8), _cur
.grffile
);
3220 tsp
->acceptance
[prop
- 0x0A] = Clamp(GB(acctp
, 8, 8), 0, 16);
3224 case 0x0D: // Land shape flags
3225 tsp
->slopes_refused
= (Slope
)buf
->ReadByte();
3228 case 0x0E: // Callback mask
3229 tsp
->callback_mask
= buf
->ReadByte();
3232 case 0x0F: // Animation information
3233 tsp
->animation
.frames
= buf
->ReadByte();
3234 tsp
->animation
.status
= buf
->ReadByte();
3237 case 0x10: // Animation speed
3238 tsp
->animation
.speed
= buf
->ReadByte();
3241 case 0x11: // Triggers for callback 25
3242 tsp
->animation
.triggers
= buf
->ReadByte();
3245 case 0x12: // Special flags
3246 tsp
->special_flags
= (IndustryTileSpecialFlags
)buf
->ReadByte();
3249 case 0x13: { // variable length cargo acceptance
3250 byte num_cargoes
= buf
->ReadByte();
3251 if (num_cargoes
> lengthof(tsp
->acceptance
)) {
3252 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG
);
3253 error
->param_value
[1] = prop
;
3254 return CIR_DISABLED
;
3256 for (uint i
= 0; i
< lengthof(tsp
->acceptance
); i
++) {
3257 if (i
< num_cargoes
) {
3258 tsp
->accepts_cargo
[i
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3259 /* Tile acceptance can be negative to counteract the INDTILE_SPECIAL_ACCEPTS_ALL_CARGO flag */
3260 tsp
->acceptance
[i
] = (int8
)buf
->ReadByte();
3262 tsp
->accepts_cargo
[i
] = CT_INVALID
;
3263 tsp
->acceptance
[i
] = 0;
3279 * Ignore an industry property
3280 * @param prop The property to ignore.
3281 * @param buf The property value.
3282 * @return ChangeInfoResult.
3284 static ChangeInfoResult
IgnoreIndustryProperty(int prop
, ByteReader
*buf
)
3286 ChangeInfoResult ret
= CIR_SUCCESS
;
3324 byte num_table
= buf
->ReadByte();
3325 for (byte j
= 0; j
< num_table
; j
++) {
3326 for (uint k
= 0;; k
++) {
3327 byte x
= buf
->ReadByte();
3328 if (x
== 0xFE && k
== 0) {
3334 byte y
= buf
->ReadByte();
3335 if (x
== 0 && y
== 0x80) break;
3337 byte gfx
= buf
->ReadByte();
3338 if (gfx
== 0xFE) buf
->ReadWord();
3345 for (byte j
= 0; j
< 3; j
++) buf
->ReadByte();
3352 buf
->Skip(buf
->ReadByte());
3356 int num_inputs
= buf
->ReadByte();
3357 int num_outputs
= buf
->ReadByte();
3358 buf
->Skip(num_inputs
* num_outputs
* 2);
3370 * Validate the industry layout; e.g. to prevent duplicate tiles.
3371 * @param layout The layout to check.
3372 * @return True if the layout is deemed valid.
3374 static bool ValidateIndustryLayout(const IndustryTileLayout
&layout
)
3376 const size_t size
= layout
.size();
3377 for (size_t i
= 0; i
< size
- 1; i
++) {
3378 for (size_t j
= i
+ 1; j
< size
; j
++) {
3379 if (layout
[i
].ti
.x
== layout
[j
].ti
.x
&&
3380 layout
[i
].ti
.y
== layout
[j
].ti
.y
) {
3389 * Define properties for industries
3390 * @param indid Local ID of the industry.
3391 * @param numinfo Number of subsequent industry IDs to change the property for.
3392 * @param prop The property to change.
3393 * @param buf The property value.
3394 * @return ChangeInfoResult.
3396 static ChangeInfoResult
IndustriesChangeInfo(uint indid
, int numinfo
, int prop
, ByteReader
*buf
)
3398 ChangeInfoResult ret
= CIR_SUCCESS
;
3400 if (indid
+ numinfo
> NUM_INDUSTRYTYPES_PER_GRF
) {
3401 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid
+ numinfo
, NUM_INDUSTRYTYPES_PER_GRF
);
3402 return CIR_INVALID_ID
;
3405 /* Allocate industry specs if they haven't been allocated already. */
3406 if (_cur
.grffile
->industryspec
== nullptr) {
3407 _cur
.grffile
->industryspec
= CallocT
<IndustrySpec
*>(NUM_INDUSTRYTYPES_PER_GRF
);
3410 for (int i
= 0; i
< numinfo
; i
++) {
3411 IndustrySpec
*indsp
= _cur
.grffile
->industryspec
[indid
+ i
];
3413 if (prop
!= 0x08 && indsp
== nullptr) {
3414 ChangeInfoResult cir
= IgnoreIndustryProperty(prop
, buf
);
3415 if (cir
> ret
) ret
= cir
;
3420 case 0x08: { // Substitute industry type
3421 IndustrySpec
**indspec
= &_cur
.grffile
->industryspec
[indid
+ i
];
3422 byte subs_id
= buf
->ReadByte();
3424 if (subs_id
== 0xFF) {
3425 /* Instead of defining a new industry, a substitute industry id
3426 * of 0xFF disables the old industry with the current id. */
3427 _industry_specs
[indid
+ i
].enabled
= false;
3429 } else if (subs_id
>= NEW_INDUSTRYOFFSET
) {
3430 /* The substitute id must be one of the original industry. */
3431 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id
, indid
+ i
);
3435 /* Allocate space for this industry.
3436 * Only need to do it once. If ever it is called again, it should not
3438 if (*indspec
== nullptr) {
3439 *indspec
= new IndustrySpec
;
3442 *indsp
= _origin_industry_specs
[subs_id
];
3443 indsp
->enabled
= true;
3444 indsp
->grf_prop
.local_id
= indid
+ i
;
3445 indsp
->grf_prop
.subst_id
= subs_id
;
3446 indsp
->grf_prop
.grffile
= _cur
.grffile
;
3447 /* If the grf industry needs to check its surrounding upon creation, it should
3448 * rely on callbacks, not on the original placement functions */
3449 indsp
->check_proc
= CHECK_NOTHING
;
3454 case 0x09: { // Industry type override
3455 byte ovrid
= buf
->ReadByte();
3457 /* The industry being overridden must be an original industry. */
3458 if (ovrid
>= NEW_INDUSTRYOFFSET
) {
3459 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid
, indid
+ i
);
3462 indsp
->grf_prop
.override
= ovrid
;
3463 _industry_mngr
.Add(indid
+ i
, _cur
.grffile
->grfid
, ovrid
);
3467 case 0x0A: { // Set industry layout(s)
3468 byte new_num_layouts
= buf
->ReadByte();
3469 uint32 definition_size
= buf
->ReadDWord();
3470 uint32 bytes_read
= 0;
3471 std::vector
<IndustryTileLayout
> new_layouts
;
3472 IndustryTileLayout layout
;
3474 for (byte j
= 0; j
< new_num_layouts
; j
++) {
3477 for (uint k
= 0;; k
++) {
3478 if (bytes_read
>= definition_size
) {
3479 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid
);
3480 /* Avoid warning twice */
3481 definition_size
= UINT32_MAX
;
3484 layout
.push_back(IndustryTileLayoutTile
{});
3485 IndustryTileLayoutTile
&it
= layout
.back();
3487 it
.ti
.x
= buf
->ReadByte(); // Offsets from northermost tile
3490 if (it
.ti
.x
== 0xFE && k
== 0) {
3491 /* This means we have to borrow the layout from an old industry */
3492 IndustryType type
= buf
->ReadByte();
3493 byte laynbr
= buf
->ReadByte();
3496 if (type
>= lengthof(_origin_industry_specs
)) {
3497 grfmsg(1, "IndustriesChangeInfo: Invalid original industry number for layout import, industry %u", indid
);
3498 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID
);
3499 return CIR_DISABLED
;
3501 if (laynbr
>= _origin_industry_specs
[type
].layouts
.size()) {
3502 grfmsg(1, "IndustriesChangeInfo: Invalid original industry layout index for layout import, industry %u", indid
);
3503 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID
);
3504 return CIR_DISABLED
;
3506 layout
= _origin_industry_specs
[type
].layouts
[laynbr
];
3510 it
.ti
.y
= buf
->ReadByte(); // Or table definition finalisation
3513 if (it
.ti
.x
== 0 && it
.ti
.y
== 0x80) {
3514 /* Terminator, remove and finish up */
3519 it
.gfx
= buf
->ReadByte();
3522 if (it
.gfx
== 0xFE) {
3523 /* Use a new tile from this GRF */
3524 int local_tile_id
= buf
->ReadWord();
3527 /* Read the ID from the _industile_mngr. */
3528 int tempid
= _industile_mngr
.GetID(local_tile_id
, _cur
.grffile
->grfid
);
3530 if (tempid
== INVALID_INDUSTRYTILE
) {
3531 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id
, indid
);
3533 /* Declared as been valid, can be used */
3536 } else if (it
.gfx
== 0xFF) {
3537 it
.ti
.x
= (int8
)GB(it
.ti
.x
, 0, 8);
3538 it
.ti
.y
= (int8
)GB(it
.ti
.y
, 0, 8);
3540 /* When there were only 256x256 maps, TileIndex was a uint16 and
3541 * it.ti was just a TileIndexDiff that was added to it.
3542 * As such negative "x" values were shifted into the "y" position.
3543 * x = -1, y = 1 -> x = 255, y = 0
3544 * Since GRF version 8 the position is interpreted as pair of independent int8.
3545 * For GRF version < 8 we need to emulate the old shifting behaviour.
3547 if (_cur
.grffile
->grf_version
< 8 && it
.ti
.x
< 0) it
.ti
.y
+= 1;
3551 if (!ValidateIndustryLayout(layout
)) {
3552 /* The industry layout was not valid, so skip this one. */
3553 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid
);
3557 new_layouts
.push_back(layout
);
3561 /* Install final layout construction in the industry spec */
3562 indsp
->layouts
= new_layouts
;
3566 case 0x0B: // Industry production flags
3567 indsp
->life_type
= (IndustryLifeType
)buf
->ReadByte();
3570 case 0x0C: // Industry closure message
3571 AddStringForMapping(buf
->ReadWord(), &indsp
->closure_text
);
3574 case 0x0D: // Production increase message
3575 AddStringForMapping(buf
->ReadWord(), &indsp
->production_up_text
);
3578 case 0x0E: // Production decrease message
3579 AddStringForMapping(buf
->ReadWord(), &indsp
->production_down_text
);
3582 case 0x0F: // Fund cost multiplier
3583 indsp
->cost_multiplier
= buf
->ReadByte();
3586 case 0x10: // Production cargo types
3587 for (byte j
= 0; j
< 2; j
++) {
3588 indsp
->produced_cargo
[j
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3592 case 0x11: // Acceptance cargo types
3593 for (byte j
= 0; j
< 3; j
++) {
3594 indsp
->accepts_cargo
[j
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3596 buf
->ReadByte(); // Unnused, eat it up
3599 case 0x12: // Production multipliers
3601 indsp
->production_rate
[prop
- 0x12] = buf
->ReadByte();
3604 case 0x14: // Minimal amount of cargo distributed
3605 indsp
->minimal_cargo
= buf
->ReadByte();
3608 case 0x15: { // Random sound effects
3609 indsp
->number_of_sounds
= buf
->ReadByte();
3610 uint8
*sounds
= MallocT
<uint8
>(indsp
->number_of_sounds
);
3613 for (uint8 j
= 0; j
< indsp
->number_of_sounds
; j
++) {
3614 sounds
[j
] = buf
->ReadByte();
3621 if (HasBit(indsp
->cleanup_flag
, CLEAN_RANDOMSOUNDS
)) {
3622 free(indsp
->random_sounds
);
3624 indsp
->random_sounds
= sounds
;
3625 SetBit(indsp
->cleanup_flag
, CLEAN_RANDOMSOUNDS
);
3629 case 0x16: // Conflicting industry types
3630 for (byte j
= 0; j
< 3; j
++) indsp
->conflicting
[j
] = buf
->ReadByte();
3633 case 0x17: // Probability in random game
3634 indsp
->appear_creation
[_settings_game
.game_creation
.landscape
] = buf
->ReadByte();
3637 case 0x18: // Probability during gameplay
3638 indsp
->appear_ingame
[_settings_game
.game_creation
.landscape
] = buf
->ReadByte();
3641 case 0x19: // Map colour
3642 indsp
->map_colour
= buf
->ReadByte();
3645 case 0x1A: // Special industry flags to define special behavior
3646 indsp
->behaviour
= (IndustryBehaviour
)buf
->ReadDWord();
3649 case 0x1B: // New industry text ID
3650 AddStringForMapping(buf
->ReadWord(), &indsp
->new_industry_text
);
3653 case 0x1C: // Input cargo multipliers for the three input cargo types
3656 uint32 multiples
= buf
->ReadDWord();
3657 indsp
->input_cargo_multiplier
[prop
- 0x1C][0] = GB(multiples
, 0, 16);
3658 indsp
->input_cargo_multiplier
[prop
- 0x1C][1] = GB(multiples
, 16, 16);
3662 case 0x1F: // Industry name
3663 AddStringForMapping(buf
->ReadWord(), &indsp
->name
);
3666 case 0x20: // Prospecting success chance
3667 indsp
->prospecting_chance
= buf
->ReadDWord();
3670 case 0x21: // Callback mask
3671 case 0x22: { // Callback additional mask
3672 byte aflag
= buf
->ReadByte();
3673 SB(indsp
->callback_mask
, (prop
- 0x21) * 8, 8, aflag
);
3677 case 0x23: // removal cost multiplier
3678 indsp
->removal_cost_multiplier
= buf
->ReadDWord();
3681 case 0x24: { // name for nearby station
3682 uint16 str
= buf
->ReadWord();
3684 indsp
->station_name
= STR_NULL
;
3686 AddStringForMapping(str
, &indsp
->station_name
);
3691 case 0x25: { // variable length produced cargoes
3692 byte num_cargoes
= buf
->ReadByte();
3693 if (num_cargoes
> lengthof(indsp
->produced_cargo
)) {
3694 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG
);
3695 error
->param_value
[1] = prop
;
3696 return CIR_DISABLED
;
3698 for (uint i
= 0; i
< lengthof(indsp
->produced_cargo
); i
++) {
3699 if (i
< num_cargoes
) {
3700 CargoID cargo
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3701 indsp
->produced_cargo
[i
] = cargo
;
3703 indsp
->produced_cargo
[i
] = CT_INVALID
;
3709 case 0x26: { // variable length accepted cargoes
3710 byte num_cargoes
= buf
->ReadByte();
3711 if (num_cargoes
> lengthof(indsp
->accepts_cargo
)) {
3712 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG
);
3713 error
->param_value
[1] = prop
;
3714 return CIR_DISABLED
;
3716 for (uint i
= 0; i
< lengthof(indsp
->accepts_cargo
); i
++) {
3717 if (i
< num_cargoes
) {
3718 CargoID cargo
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3719 indsp
->accepts_cargo
[i
] = cargo
;
3721 indsp
->accepts_cargo
[i
] = CT_INVALID
;
3727 case 0x27: { // variable length production rates
3728 byte num_cargoes
= buf
->ReadByte();
3729 if (num_cargoes
> lengthof(indsp
->production_rate
)) {
3730 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG
);
3731 error
->param_value
[1] = prop
;
3732 return CIR_DISABLED
;
3734 for (uint i
= 0; i
< lengthof(indsp
->production_rate
); i
++) {
3735 if (i
< num_cargoes
) {
3736 indsp
->production_rate
[i
] = buf
->ReadByte();
3738 indsp
->production_rate
[i
] = 0;
3744 case 0x28: { // variable size input/output production multiplier table
3745 byte num_inputs
= buf
->ReadByte();
3746 byte num_outputs
= buf
->ReadByte();
3747 if (num_inputs
> lengthof(indsp
->accepts_cargo
) || num_outputs
> lengthof(indsp
->produced_cargo
)) {
3748 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG
);
3749 error
->param_value
[1] = prop
;
3750 return CIR_DISABLED
;
3752 for (uint i
= 0; i
< lengthof(indsp
->accepts_cargo
); i
++) {
3753 for (uint j
= 0; j
< lengthof(indsp
->produced_cargo
); j
++) {
3755 if (i
< num_inputs
&& j
< num_outputs
) mult
= buf
->ReadWord();
3756 indsp
->input_cargo_multiplier
[i
][j
] = mult
;
3772 * Create a copy of the tile table so it can be freed later
3774 * @param as The AirportSpec to copy the arrays of.
3776 static void DuplicateTileTable(AirportSpec
*as
)
3778 AirportTileTable
**table_list
= MallocT
<AirportTileTable
*>(as
->num_table
);
3779 for (int i
= 0; i
< as
->num_table
; i
++) {
3781 const AirportTileTable
*it
= as
->table
[0];
3784 } while ((++it
)->ti
.x
!= -0x80);
3785 table_list
[i
] = MallocT
<AirportTileTable
>(num_tiles
);
3786 MemCpyT(table_list
[i
], as
->table
[i
], num_tiles
);
3788 as
->table
= table_list
;
3789 HangarTileTable
*depot_table
= MallocT
<HangarTileTable
>(as
->nof_depots
);
3790 MemCpyT(depot_table
, as
->depot_table
, as
->nof_depots
);
3791 as
->depot_table
= depot_table
;
3792 Direction
*rotation
= MallocT
<Direction
>(as
->num_table
);
3793 MemCpyT(rotation
, as
->rotation
, as
->num_table
);
3794 as
->rotation
= rotation
;
3798 * Define properties for airports
3799 * @param airport Local ID of the airport.
3800 * @param numinfo Number of subsequent airport IDs to change the property for.
3801 * @param prop The property to change.
3802 * @param buf The property value.
3803 * @return ChangeInfoResult.
3805 static ChangeInfoResult
AirportChangeInfo(uint airport
, int numinfo
, int prop
, ByteReader
*buf
)
3807 ChangeInfoResult ret
= CIR_SUCCESS
;
3809 if (airport
+ numinfo
> NUM_AIRPORTS_PER_GRF
) {
3810 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport
+ numinfo
, NUM_AIRPORTS_PER_GRF
);
3811 return CIR_INVALID_ID
;
3814 /* Allocate industry specs if they haven't been allocated already. */
3815 if (_cur
.grffile
->airportspec
== nullptr) {
3816 _cur
.grffile
->airportspec
= CallocT
<AirportSpec
*>(NUM_AIRPORTS_PER_GRF
);
3819 for (int i
= 0; i
< numinfo
; i
++) {
3820 AirportSpec
*as
= _cur
.grffile
->airportspec
[airport
+ i
];
3822 if (as
== nullptr && prop
!= 0x08 && prop
!= 0x09) {
3823 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport
+ i
);
3824 return CIR_INVALID_ID
;
3828 case 0x08: { // Modify original airport
3829 byte subs_id
= buf
->ReadByte();
3831 if (subs_id
== 0xFF) {
3832 /* Instead of defining a new airport, an airport id
3833 * of 0xFF disables the old airport with the current id. */
3834 AirportSpec::GetWithoutOverride(airport
+ i
)->enabled
= false;
3836 } else if (subs_id
>= NEW_AIRPORT_OFFSET
) {
3837 /* The substitute id must be one of the original airports. */
3838 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id
, airport
+ i
);
3842 AirportSpec
**spec
= &_cur
.grffile
->airportspec
[airport
+ i
];
3843 /* Allocate space for this airport.
3844 * Only need to do it once. If ever it is called again, it should not
3846 if (*spec
== nullptr) {
3847 *spec
= MallocT
<AirportSpec
>(1);
3850 memcpy(as
, AirportSpec::GetWithoutOverride(subs_id
), sizeof(*as
));
3852 as
->grf_prop
.local_id
= airport
+ i
;
3853 as
->grf_prop
.subst_id
= subs_id
;
3854 as
->grf_prop
.grffile
= _cur
.grffile
;
3855 /* override the default airport */
3856 _airport_mngr
.Add(airport
+ i
, _cur
.grffile
->grfid
, subs_id
);
3857 /* Create a copy of the original tiletable so it can be freed later. */
3858 DuplicateTileTable(as
);
3863 case 0x0A: { // Set airport layout
3865 as
->num_table
= buf
->ReadByte(); // Number of layaouts
3866 as
->rotation
= MallocT
<Direction
>(as
->num_table
);
3867 uint32 defsize
= buf
->ReadDWord(); // Total size of the definition
3868 AirportTileTable
**tile_table
= CallocT
<AirportTileTable
*>(as
->num_table
); // Table with tiles to compose the airport
3869 AirportTileTable
*att
= CallocT
<AirportTileTable
>(defsize
); // Temporary array to read the tile layouts from the GRF
3871 const AirportTileTable
*copy_from
;
3873 for (byte j
= 0; j
< as
->num_table
; j
++) {
3874 const_cast<Direction
&>(as
->rotation
[j
]) = (Direction
)buf
->ReadByte();
3875 for (int k
= 0;; k
++) {
3876 att
[k
].ti
.x
= buf
->ReadByte(); // Offsets from northermost tile
3877 att
[k
].ti
.y
= buf
->ReadByte();
3879 if (att
[k
].ti
.x
== 0 && att
[k
].ti
.y
== 0x80) {
3880 /* Not the same terminator. The one we are using is rather
3881 * x = -80, y = 0 . So, adjust it. */
3882 att
[k
].ti
.x
= -0x80;
3891 att
[k
].gfx
= buf
->ReadByte();
3893 if (att
[k
].gfx
== 0xFE) {
3894 /* Use a new tile from this GRF */
3895 int local_tile_id
= buf
->ReadWord();
3897 /* Read the ID from the _airporttile_mngr. */
3898 uint16 tempid
= _airporttile_mngr
.GetID(local_tile_id
, _cur
.grffile
->grfid
);
3900 if (tempid
== INVALID_AIRPORTTILE
) {
3901 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id
, airport
+ i
);
3903 /* Declared as been valid, can be used */
3904 att
[k
].gfx
= tempid
;
3906 } else if (att
[k
].gfx
== 0xFF) {
3907 att
[k
].ti
.x
= (int8
)GB(att
[k
].ti
.x
, 0, 8);
3908 att
[k
].ti
.y
= (int8
)GB(att
[k
].ti
.y
, 0, 8);
3911 if (as
->rotation
[j
] == DIR_E
|| as
->rotation
[j
] == DIR_W
) {
3912 as
->size_x
= max
<byte
>(as
->size_x
, att
[k
].ti
.y
+ 1);
3913 as
->size_y
= max
<byte
>(as
->size_y
, att
[k
].ti
.x
+ 1);
3915 as
->size_x
= max
<byte
>(as
->size_x
, att
[k
].ti
.x
+ 1);
3916 as
->size_y
= max
<byte
>(as
->size_y
, att
[k
].ti
.y
+ 1);
3919 tile_table
[j
] = CallocT
<AirportTileTable
>(size
);
3920 memcpy(tile_table
[j
], copy_from
, sizeof(*copy_from
) * size
);
3922 /* Install final layout construction in the airport spec */
3923 as
->table
= tile_table
;
3926 for (int i
= 0; i
< as
->num_table
; i
++) {
3927 free(tile_table
[i
]);
3937 as
->min_year
= buf
->ReadWord();
3938 as
->max_year
= buf
->ReadWord();
3939 if (as
->max_year
== 0xFFFF) as
->max_year
= MAX_YEAR
;
3943 as
->ttd_airport_type
= (TTDPAirportType
)buf
->ReadByte();
3947 as
->catchment
= Clamp(buf
->ReadByte(), 1, MAX_CATCHMENT
);
3951 as
->noise_level
= buf
->ReadByte();
3955 AddStringForMapping(buf
->ReadWord(), &as
->name
);
3958 case 0x11: // Maintenance cost factor
3959 as
->maintenance_cost
= buf
->ReadWord();
3972 * Ignore properties for objects
3973 * @param prop The property to ignore.
3974 * @param buf The property value.
3975 * @return ChangeInfoResult.
3977 static ChangeInfoResult
IgnoreObjectProperty(uint prop
, ByteReader
*buf
)
3979 ChangeInfoResult ret
= CIR_SUCCESS
;
4016 * Define properties for objects
4017 * @param id Local ID of the object.
4018 * @param numinfo Number of subsequent objectIDs to change the property for.
4019 * @param prop The property to change.
4020 * @param buf The property value.
4021 * @return ChangeInfoResult.
4023 static ChangeInfoResult
ObjectChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4025 ChangeInfoResult ret
= CIR_SUCCESS
;
4027 if (id
+ numinfo
> NUM_OBJECTS_PER_GRF
) {
4028 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id
+ numinfo
, NUM_OBJECTS_PER_GRF
);
4029 return CIR_INVALID_ID
;
4032 /* Allocate object specs if they haven't been allocated already. */
4033 if (_cur
.grffile
->objectspec
== nullptr) {
4034 _cur
.grffile
->objectspec
= CallocT
<ObjectSpec
*>(NUM_OBJECTS_PER_GRF
);
4037 for (int i
= 0; i
< numinfo
; i
++) {
4038 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[id
+ i
];
4040 if (prop
!= 0x08 && spec
== nullptr) {
4041 /* If the object property 08 is not yet set, ignore this property */
4042 ChangeInfoResult cir
= IgnoreObjectProperty(prop
, buf
);
4043 if (cir
> ret
) ret
= cir
;
4048 case 0x08: { // Class ID
4049 ObjectSpec
**ospec
= &_cur
.grffile
->objectspec
[id
+ i
];
4051 /* Allocate space for this object. */
4052 if (*ospec
== nullptr) {
4053 *ospec
= CallocT
<ObjectSpec
>(1);
4054 (*ospec
)->views
= 1; // Default for NewGRFs that don't set it.
4057 /* Swap classid because we read it in BE. */
4058 uint32 classid
= buf
->ReadDWord();
4059 (*ospec
)->cls_id
= ObjectClass::Allocate(BSWAP32(classid
));
4060 (*ospec
)->enabled
= true;
4064 case 0x09: { // Class name
4065 ObjectClass
*objclass
= ObjectClass::Get(spec
->cls_id
);
4066 AddStringForMapping(buf
->ReadWord(), &objclass
->name
);
4070 case 0x0A: // Object name
4071 AddStringForMapping(buf
->ReadWord(), &spec
->name
);
4074 case 0x0B: // Climate mask
4075 spec
->climate
= buf
->ReadByte();
4079 spec
->size
= buf
->ReadByte();
4082 case 0x0D: // Build cost multipler
4083 spec
->build_cost_multiplier
= buf
->ReadByte();
4084 spec
->clear_cost_multiplier
= spec
->build_cost_multiplier
;
4087 case 0x0E: // Introduction date
4088 spec
->introduction_date
= buf
->ReadDWord();
4091 case 0x0F: // End of life
4092 spec
->end_of_life_date
= buf
->ReadDWord();
4096 spec
->flags
= (ObjectFlags
)buf
->ReadWord();
4097 _loaded_newgrf_features
.has_2CC
|= (spec
->flags
& OBJECT_FLAG_2CC_COLOUR
) != 0;
4100 case 0x11: // Animation info
4101 spec
->animation
.frames
= buf
->ReadByte();
4102 spec
->animation
.status
= buf
->ReadByte();
4105 case 0x12: // Animation speed
4106 spec
->animation
.speed
= buf
->ReadByte();
4109 case 0x13: // Animation triggers
4110 spec
->animation
.triggers
= buf
->ReadWord();
4113 case 0x14: // Removal cost multiplier
4114 spec
->clear_cost_multiplier
= buf
->ReadByte();
4117 case 0x15: // Callback mask
4118 spec
->callback_mask
= buf
->ReadWord();
4121 case 0x16: // Building height
4122 spec
->height
= buf
->ReadByte();
4126 spec
->views
= buf
->ReadByte();
4127 if (spec
->views
!= 1 && spec
->views
!= 2 && spec
->views
!= 4) {
4128 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec
->views
, id
+ i
);
4133 case 0x18: // Amount placed on 256^2 map on map creation
4134 spec
->generate_amount
= buf
->ReadByte();
4147 * Define properties for railtypes
4148 * @param id ID of the railtype.
4149 * @param numinfo Number of subsequent IDs to change the property for.
4150 * @param prop The property to change.
4151 * @param buf The property value.
4152 * @return ChangeInfoResult.
4154 static ChangeInfoResult
RailTypeChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4156 ChangeInfoResult ret
= CIR_SUCCESS
;
4158 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
4160 if (id
+ numinfo
> RAILTYPE_END
) {
4161 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id
+ numinfo
, RAILTYPE_END
);
4162 return CIR_INVALID_ID
;
4165 for (int i
= 0; i
< numinfo
; i
++) {
4166 RailType rt
= _cur
.grffile
->railtype_map
[id
+ i
];
4167 if (rt
== INVALID_RAILTYPE
) return CIR_INVALID_ID
;
4169 RailtypeInfo
*rti
= &_railtypes
[rt
];
4172 case 0x08: // Label of rail type
4173 /* Skipped here as this is loaded during reservation stage. */
4177 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4178 uint16 str
= buf
->ReadWord();
4179 AddStringForMapping(str
, &rti
->strings
.toolbar_caption
);
4180 if (_cur
.grffile
->grf_version
< 8) {
4181 AddStringForMapping(str
, &rti
->strings
.name
);
4186 case 0x0A: // Menu text of railtype
4187 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.menu_text
);
4190 case 0x0B: // Build window caption
4191 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.build_caption
);
4194 case 0x0C: // Autoreplace text
4195 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.replace_text
);
4198 case 0x0D: // New locomotive text
4199 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.new_loco
);
4202 case 0x0E: // Compatible railtype list
4203 case 0x0F: // Powered railtype list
4204 case 0x18: // Railtype list required for date introduction
4205 case 0x19: // Introduced railtype list
4207 /* Rail type compatibility bits are added to the existing bits
4208 * to allow multiple GRFs to modify compatibility with the
4209 * default rail types. */
4210 int n
= buf
->ReadByte();
4211 for (int j
= 0; j
!= n
; j
++) {
4212 RailTypeLabel label
= buf
->ReadDWord();
4213 RailType rt
= GetRailTypeByLabel(BSWAP32(label
), false);
4214 if (rt
!= INVALID_RAILTYPE
) {
4216 case 0x0F: SetBit(rti
->powered_railtypes
, rt
); FALLTHROUGH
; // Powered implies compatible.
4217 case 0x0E: SetBit(rti
->compatible_railtypes
, rt
); break;
4218 case 0x18: SetBit(rti
->introduction_required_railtypes
, rt
); break;
4219 case 0x19: SetBit(rti
->introduces_railtypes
, rt
); break;
4226 case 0x10: // Rail Type flags
4227 rti
->flags
= (RailTypeFlags
)buf
->ReadByte();
4230 case 0x11: // Curve speed advantage
4231 rti
->curve_speed
= buf
->ReadByte();
4234 case 0x12: // Station graphic
4235 rti
->fallback_railtype
= Clamp(buf
->ReadByte(), 0, 2);
4238 case 0x13: // Construction cost factor
4239 rti
->cost_multiplier
= buf
->ReadWord();
4242 case 0x14: // Speed limit
4243 rti
->max_speed
= buf
->ReadWord();
4246 case 0x15: // Acceleration model
4247 rti
->acceleration_type
= Clamp(buf
->ReadByte(), 0, 2);
4250 case 0x16: // Map colour
4251 rti
->map_colour
= buf
->ReadByte();
4254 case 0x17: // Introduction date
4255 rti
->introduction_date
= buf
->ReadDWord();
4258 case 0x1A: // Sort order
4259 rti
->sorting_order
= buf
->ReadByte();
4262 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4263 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.name
);
4266 case 0x1C: // Maintenance cost factor
4267 rti
->maintenance_multiplier
= buf
->ReadWord();
4270 case 0x1D: // Alternate rail type label list
4271 /* Skipped here as this is loaded during reservation stage. */
4272 for (int j
= buf
->ReadByte(); j
!= 0; j
--) buf
->ReadDWord();
4284 static ChangeInfoResult
RailTypeReserveInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4286 ChangeInfoResult ret
= CIR_SUCCESS
;
4288 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
4290 if (id
+ numinfo
> RAILTYPE_END
) {
4291 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id
+ numinfo
, RAILTYPE_END
);
4292 return CIR_INVALID_ID
;
4295 for (int i
= 0; i
< numinfo
; i
++) {
4297 case 0x08: // Label of rail type
4299 RailTypeLabel rtl
= buf
->ReadDWord();
4302 RailType rt
= GetRailTypeByLabel(rtl
, false);
4303 if (rt
== INVALID_RAILTYPE
) {
4304 /* Set up new rail type */
4305 rt
= AllocateRailType(rtl
);
4308 _cur
.grffile
->railtype_map
[id
+ i
] = rt
;
4312 case 0x09: // Toolbar caption of railtype
4313 case 0x0A: // Menu text
4314 case 0x0B: // Build window caption
4315 case 0x0C: // Autoreplace text
4316 case 0x0D: // New loco
4317 case 0x13: // Construction cost
4318 case 0x14: // Speed limit
4319 case 0x1B: // Name of railtype
4320 case 0x1C: // Maintenance cost factor
4324 case 0x1D: // Alternate rail type label list
4325 if (_cur
.grffile
->railtype_map
[id
+ i
] != INVALID_RAILTYPE
) {
4326 int n
= buf
->ReadByte();
4327 for (int j
= 0; j
!= n
; j
++) {
4328 _railtypes
[_cur
.grffile
->railtype_map
[id
+ i
]].alternate_labels
.push_back(BSWAP32(buf
->ReadDWord()));
4332 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id
+ i
);
4335 case 0x0E: // Compatible railtype list
4336 case 0x0F: // Powered railtype list
4337 case 0x18: // Railtype list required for date introduction
4338 case 0x19: // Introduced railtype list
4339 for (int j
= buf
->ReadByte(); j
!= 0; j
--) buf
->ReadDWord();
4342 case 0x10: // Rail Type flags
4343 case 0x11: // Curve speed advantage
4344 case 0x12: // Station graphic
4345 case 0x15: // Acceleration model
4346 case 0x16: // Map colour
4347 case 0x1A: // Sort order
4351 case 0x17: // Introduction date
4365 * Define properties for roadtypes
4366 * @param id ID of the roadtype.
4367 * @param numinfo Number of subsequent IDs to change the property for.
4368 * @param prop The property to change.
4369 * @param buf The property value.
4370 * @return ChangeInfoResult.
4372 static ChangeInfoResult
RoadTypeChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
, RoadTramType rtt
)
4374 ChangeInfoResult ret
= CIR_SUCCESS
;
4376 extern RoadTypeInfo _roadtypes
[ROADTYPE_END
];
4377 RoadType
*type_map
= (rtt
== RTT_TRAM
) ? _cur
.grffile
->tramtype_map
: _cur
.grffile
->roadtype_map
;
4379 if (id
+ numinfo
> ROADTYPE_END
) {
4380 grfmsg(1, "RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring", id
+ numinfo
, ROADTYPE_END
);
4381 return CIR_INVALID_ID
;
4384 for (int i
= 0; i
< numinfo
; i
++) {
4385 RoadType rt
= type_map
[id
+ i
];
4386 if (rt
== INVALID_ROADTYPE
) return CIR_INVALID_ID
;
4388 RoadTypeInfo
*rti
= &_roadtypes
[rt
];
4391 case 0x08: // Label of road type
4392 /* Skipped here as this is loaded during reservation stage. */
4396 case 0x09: { // Toolbar caption of roadtype (sets name as well for backwards compatibility for grf ver < 8)
4397 uint16 str
= buf
->ReadWord();
4398 AddStringForMapping(str
, &rti
->strings
.toolbar_caption
);
4402 case 0x0A: // Menu text of roadtype
4403 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.menu_text
);
4406 case 0x0B: // Build window caption
4407 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.build_caption
);
4410 case 0x0C: // Autoreplace text
4411 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.replace_text
);
4414 case 0x0D: // New engine text
4415 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.new_engine
);
4418 case 0x0F: // Powered roadtype list
4419 case 0x18: // Roadtype list required for date introduction
4420 case 0x19: { // Introduced roadtype list
4421 /* Road type compatibility bits are added to the existing bits
4422 * to allow multiple GRFs to modify compatibility with the
4423 * default road types. */
4424 int n
= buf
->ReadByte();
4425 for (int j
= 0; j
!= n
; j
++) {
4426 RoadTypeLabel label
= buf
->ReadDWord();
4427 RoadType rt
= GetRoadTypeByLabel(BSWAP32(label
), false);
4428 if (rt
!= INVALID_ROADTYPE
) {
4430 case 0x0F: SetBit(rti
->powered_roadtypes
, rt
); break;
4431 case 0x18: SetBit(rti
->introduction_required_roadtypes
, rt
); break;
4432 case 0x19: SetBit(rti
->introduces_roadtypes
, rt
); break;
4439 case 0x10: // Road Type flags
4440 rti
->flags
= (RoadTypeFlags
)buf
->ReadByte();
4443 case 0x13: // Construction cost factor
4444 rti
->cost_multiplier
= buf
->ReadWord();
4447 case 0x14: // Speed limit
4448 rti
->max_speed
= buf
->ReadWord();
4451 case 0x16: // Map colour
4452 rti
->map_colour
= buf
->ReadByte();
4455 case 0x17: // Introduction date
4456 rti
->introduction_date
= buf
->ReadDWord();
4459 case 0x1A: // Sort order
4460 rti
->sorting_order
= buf
->ReadByte();
4463 case 0x1B: // Name of roadtype
4464 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.name
);
4467 case 0x1C: // Maintenance cost factor
4468 rti
->maintenance_multiplier
= buf
->ReadWord();
4471 case 0x1D: // Alternate road type label list
4472 /* Skipped here as this is loaded during reservation stage. */
4473 for (int j
= buf
->ReadByte(); j
!= 0; j
--) buf
->ReadDWord();
4485 static ChangeInfoResult
RoadTypeChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4487 return RoadTypeChangeInfo(id
, numinfo
, prop
, buf
, RTT_ROAD
);
4490 static ChangeInfoResult
TramTypeChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4492 return RoadTypeChangeInfo(id
, numinfo
, prop
, buf
, RTT_TRAM
);
4496 static ChangeInfoResult
RoadTypeReserveInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
, RoadTramType rtt
)
4498 ChangeInfoResult ret
= CIR_SUCCESS
;
4500 extern RoadTypeInfo _roadtypes
[ROADTYPE_END
];
4501 RoadType
*type_map
= (rtt
== RTT_TRAM
) ? _cur
.grffile
->tramtype_map
: _cur
.grffile
->roadtype_map
;
4503 if (id
+ numinfo
> ROADTYPE_END
) {
4504 grfmsg(1, "RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring", id
+ numinfo
, ROADTYPE_END
);
4505 return CIR_INVALID_ID
;
4508 for (int i
= 0; i
< numinfo
; i
++) {
4510 case 0x08: { // Label of road type
4511 RoadTypeLabel rtl
= buf
->ReadDWord();
4514 RoadType rt
= GetRoadTypeByLabel(rtl
, false);
4515 if (rt
== INVALID_ROADTYPE
) {
4516 /* Set up new road type */
4517 rt
= AllocateRoadType(rtl
, rtt
);
4518 } else if (GetRoadTramType(rt
) != rtt
) {
4519 grfmsg(1, "RoadTypeReserveInfo: Road type %u is invalid type (road/tram), ignoring", id
+ numinfo
);
4520 return CIR_INVALID_ID
;
4523 type_map
[id
+ i
] = rt
;
4526 case 0x09: // Toolbar caption of roadtype
4527 case 0x0A: // Menu text
4528 case 0x0B: // Build window caption
4529 case 0x0C: // Autoreplace text
4530 case 0x0D: // New loco
4531 case 0x13: // Construction cost
4532 case 0x14: // Speed limit
4533 case 0x1B: // Name of roadtype
4534 case 0x1C: // Maintenance cost factor
4538 case 0x1D: // Alternate road type label list
4539 if (type_map
[id
+ i
] != INVALID_ROADTYPE
) {
4540 int n
= buf
->ReadByte();
4541 for (int j
= 0; j
!= n
; j
++) {
4542 _roadtypes
[type_map
[id
+ i
]].alternate_labels
.push_back(BSWAP32(buf
->ReadDWord()));
4546 grfmsg(1, "RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set", id
+ i
);
4549 case 0x0F: // Powered roadtype list
4550 case 0x18: // Roadtype list required for date introduction
4551 case 0x19: // Introduced roadtype list
4552 for (int j
= buf
->ReadByte(); j
!= 0; j
--) buf
->ReadDWord();
4555 case 0x10: // Road Type flags
4556 case 0x16: // Map colour
4557 case 0x1A: // Sort order
4561 case 0x17: // Introduction date
4574 static ChangeInfoResult
RoadTypeReserveInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4576 return RoadTypeReserveInfo(id
, numinfo
, prop
, buf
, RTT_ROAD
);
4579 static ChangeInfoResult
TramTypeReserveInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4581 return RoadTypeReserveInfo(id
, numinfo
, prop
, buf
, RTT_TRAM
);
4584 static ChangeInfoResult
AirportTilesChangeInfo(uint airtid
, int numinfo
, int prop
, ByteReader
*buf
)
4586 ChangeInfoResult ret
= CIR_SUCCESS
;
4588 if (airtid
+ numinfo
> NUM_AIRPORTTILES_PER_GRF
) {
4589 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid
+ numinfo
, NUM_AIRPORTTILES_PER_GRF
);
4590 return CIR_INVALID_ID
;
4593 /* Allocate airport tile specs if they haven't been allocated already. */
4594 if (_cur
.grffile
->airtspec
== nullptr) {
4595 _cur
.grffile
->airtspec
= CallocT
<AirportTileSpec
*>(NUM_AIRPORTTILES_PER_GRF
);
4598 for (int i
= 0; i
< numinfo
; i
++) {
4599 AirportTileSpec
*tsp
= _cur
.grffile
->airtspec
[airtid
+ i
];
4601 if (prop
!= 0x08 && tsp
== nullptr) {
4602 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid
+ i
);
4603 return CIR_INVALID_ID
;
4607 case 0x08: { // Substitute airport tile type
4608 AirportTileSpec
**tilespec
= &_cur
.grffile
->airtspec
[airtid
+ i
];
4609 byte subs_id
= buf
->ReadByte();
4611 if (subs_id
>= NEW_AIRPORTTILE_OFFSET
) {
4612 /* The substitute id must be one of the original airport tiles. */
4613 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id
, airtid
+ i
);
4617 /* Allocate space for this airport tile. */
4618 if (*tilespec
== nullptr) {
4619 *tilespec
= CallocT
<AirportTileSpec
>(1);
4622 memcpy(tsp
, AirportTileSpec::Get(subs_id
), sizeof(AirportTileSpec
));
4623 tsp
->enabled
= true;
4625 tsp
->animation
.status
= ANIM_STATUS_NO_ANIMATION
;
4627 tsp
->grf_prop
.local_id
= airtid
+ i
;
4628 tsp
->grf_prop
.subst_id
= subs_id
;
4629 tsp
->grf_prop
.grffile
= _cur
.grffile
;
4630 _airporttile_mngr
.AddEntityID(airtid
+ i
, _cur
.grffile
->grfid
, subs_id
); // pre-reserve the tile slot
4635 case 0x09: { // Airport tile override
4636 byte override
= buf
->ReadByte();
4638 /* The airport tile being overridden must be an original airport tile. */
4639 if (override
>= NEW_AIRPORTTILE_OFFSET
) {
4640 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override
, airtid
+ i
);
4644 _airporttile_mngr
.Add(airtid
+ i
, _cur
.grffile
->grfid
, override
);
4648 case 0x0E: // Callback mask
4649 tsp
->callback_mask
= buf
->ReadByte();
4652 case 0x0F: // Animation information
4653 tsp
->animation
.frames
= buf
->ReadByte();
4654 tsp
->animation
.status
= buf
->ReadByte();
4657 case 0x10: // Animation speed
4658 tsp
->animation
.speed
= buf
->ReadByte();
4661 case 0x11: // Animation triggers
4662 tsp
->animation
.triggers
= buf
->ReadByte();
4674 static bool HandleChangeInfoResult(const char *caller
, ChangeInfoResult cir
, uint8 feature
, uint8 property
)
4677 default: NOT_REACHED();
4680 /* Error has already been printed; just stop parsing */
4687 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller
, property
, feature
);
4691 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller
, property
, feature
);
4694 case CIR_INVALID_ID
: {
4695 /* No debug message for an invalid ID, as it has already been output */
4696 GRFError
*error
= DisableGrf(cir
== CIR_INVALID_ID
? STR_NEWGRF_ERROR_INVALID_ID
: STR_NEWGRF_ERROR_UNKNOWN_PROPERTY
);
4697 if (cir
!= CIR_INVALID_ID
) error
->param_value
[1] = property
;
4704 static void FeatureChangeInfo(ByteReader
*buf
)
4706 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4709 * B num-props how many properties to change per vehicle/station
4710 * B num-info how many vehicles/stations to change
4711 * E id ID of first vehicle/station to change, if num-info is
4712 * greater than one, this one and the following
4713 * vehicles/stations will be changed
4714 * B property what property to change, depends on the feature
4715 * V new-info new bytes of info (variable size; depends on properties) */
4717 static const VCI_Handler handler
[] = {
4718 /* GSF_TRAINS */ RailVehicleChangeInfo
,
4719 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo
,
4720 /* GSF_SHIPS */ ShipVehicleChangeInfo
,
4721 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo
,
4722 /* GSF_STATIONS */ StationChangeInfo
,
4723 /* GSF_CANALS */ CanalChangeInfo
,
4724 /* GSF_BRIDGES */ BridgeChangeInfo
,
4725 /* GSF_HOUSES */ TownHouseChangeInfo
,
4726 /* GSF_GLOBALVAR */ GlobalVarChangeInfo
,
4727 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo
,
4728 /* GSF_INDUSTRIES */ IndustriesChangeInfo
,
4729 /* GSF_CARGOES */ nullptr, // Cargo is handled during reservation
4730 /* GSF_SOUNDFX */ SoundEffectChangeInfo
,
4731 /* GSF_AIRPORTS */ AirportChangeInfo
,
4732 /* GSF_SIGNALS */ nullptr,
4733 /* GSF_OBJECTS */ ObjectChangeInfo
,
4734 /* GSF_RAILTYPES */ RailTypeChangeInfo
,
4735 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo
,
4736 /* GSF_ROADTYPES */ RoadTypeChangeInfo
,
4737 /* GSF_TRAMTYPES */ TramTypeChangeInfo
,
4740 uint8 feature
= buf
->ReadByte();
4741 uint8 numprops
= buf
->ReadByte();
4742 uint numinfo
= buf
->ReadByte();
4743 uint engine
= buf
->ReadExtendedByte();
4745 if (feature
>= GSF_END
) {
4746 grfmsg(1, "FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature
);
4750 grfmsg(6, "FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d",
4751 feature
, numprops
, engine
, numinfo
);
4753 if (feature
>= lengthof(handler
) || handler
[feature
] == nullptr) {
4754 if (feature
!= GSF_CARGOES
) grfmsg(1, "FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature
);
4758 /* Mark the feature as used by the grf */
4759 SetBit(_cur
.grffile
->grf_features
, feature
);
4761 while (numprops
-- && buf
->HasData()) {
4762 uint8 prop
= buf
->ReadByte();
4764 ChangeInfoResult cir
= handler
[feature
](engine
, numinfo
, prop
, buf
);
4765 if (HandleChangeInfoResult("FeatureChangeInfo", cir
, feature
, prop
)) return;
4769 /* Action 0x00 (GLS_SAFETYSCAN) */
4770 static void SafeChangeInfo(ByteReader
*buf
)
4772 uint8 feature
= buf
->ReadByte();
4773 uint8 numprops
= buf
->ReadByte();
4774 uint numinfo
= buf
->ReadByte();
4775 buf
->ReadExtendedByte(); // id
4777 if (feature
== GSF_BRIDGES
&& numprops
== 1) {
4778 uint8 prop
= buf
->ReadByte();
4779 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4780 * is considered safe. */
4781 if (prop
== 0x0D) return;
4782 } else if (feature
== GSF_GLOBALVAR
&& numprops
== 1) {
4783 uint8 prop
= buf
->ReadByte();
4784 /* Engine ID Mappings are safe, if the source is static */
4786 bool is_safe
= true;
4787 for (uint i
= 0; i
< numinfo
; i
++) {
4788 uint32 s
= buf
->ReadDWord();
4789 buf
->ReadDWord(); // dest
4790 const GRFConfig
*grfconfig
= GetGRFConfig(s
);
4791 if (grfconfig
!= nullptr && !HasBit(grfconfig
->flags
, GCF_STATIC
)) {
4796 if (is_safe
) return;
4800 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
4802 /* Skip remainder of GRF */
4803 _cur
.skip_sprites
= -1;
4806 /* Action 0x00 (GLS_RESERVE) */
4807 static void ReserveChangeInfo(ByteReader
*buf
)
4809 uint8 feature
= buf
->ReadByte();
4811 if (feature
!= GSF_CARGOES
&& feature
!= GSF_GLOBALVAR
&& feature
!= GSF_RAILTYPES
&& feature
!= GSF_ROADTYPES
&& feature
!= GSF_TRAMTYPES
) return;
4813 uint8 numprops
= buf
->ReadByte();
4814 uint8 numinfo
= buf
->ReadByte();
4815 uint8 index
= buf
->ReadExtendedByte();
4817 while (numprops
-- && buf
->HasData()) {
4818 uint8 prop
= buf
->ReadByte();
4819 ChangeInfoResult cir
= CIR_SUCCESS
;
4822 default: NOT_REACHED();
4824 cir
= CargoChangeInfo(index
, numinfo
, prop
, buf
);
4828 cir
= GlobalVarReserveInfo(index
, numinfo
, prop
, buf
);
4832 cir
= RailTypeReserveInfo(index
, numinfo
, prop
, buf
);
4836 cir
= RoadTypeReserveInfo(index
, numinfo
, prop
, buf
);
4840 cir
= TramTypeReserveInfo(index
, numinfo
, prop
, buf
);
4844 if (HandleChangeInfoResult("ReserveChangeInfo", cir
, feature
, prop
)) return;
4849 static void NewSpriteSet(ByteReader
*buf
)
4851 /* Basic format: <01> <feature> <num-sets> <num-ent>
4852 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4854 * B feature feature to define sprites for
4855 * 0, 1, 2, 3: veh-type, 4: train stations
4856 * E first-set first sprite set to define
4857 * B num-sets number of sprite sets (extended byte in extended format)
4858 * E num-ent how many entries per sprite set
4859 * For vehicles, this is the number of different
4860 * vehicle directions in each sprite set
4861 * Set num-dirs=8, unless your sprites are symmetric.
4862 * In that case, use num-dirs=4.
4865 uint8 feature
= buf
->ReadByte();
4866 uint16 num_sets
= buf
->ReadByte();
4867 uint16 first_set
= 0;
4869 if (num_sets
== 0 && buf
->HasData(3)) {
4870 /* Extended Action1 format.
4871 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4872 first_set
= buf
->ReadExtendedByte();
4873 num_sets
= buf
->ReadExtendedByte();
4875 uint16 num_ents
= buf
->ReadExtendedByte();
4877 if (feature
>= GSF_END
) {
4878 _cur
.skip_sprites
= num_sets
* num_ents
;
4879 grfmsg(1, "NewSpriteSet: Unsupported feature 0x%02X, skipping %d sprites", feature
, _cur
.skip_sprites
);
4883 _cur
.AddSpriteSets(feature
, _cur
.spriteid
, first_set
, num_sets
, num_ents
);
4885 grfmsg(7, "New sprite set at %d of feature 0x%02X, consisting of %d sets with %d views each (total %d)",
4886 _cur
.spriteid
, feature
, num_sets
, num_ents
, num_sets
* num_ents
4889 for (int i
= 0; i
< num_sets
* num_ents
; i
++) {
4891 LoadNextSprite(_cur
.spriteid
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
4895 /* Action 0x01 (SKIP) */
4896 static void SkipAct1(ByteReader
*buf
)
4899 uint16 num_sets
= buf
->ReadByte();
4901 if (num_sets
== 0 && buf
->HasData(3)) {
4902 /* Extended Action1 format.
4903 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4904 buf
->ReadExtendedByte(); // first_set
4905 num_sets
= buf
->ReadExtendedByte();
4907 uint16 num_ents
= buf
->ReadExtendedByte();
4909 _cur
.skip_sprites
= num_sets
* num_ents
;
4911 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur
.skip_sprites
);
4914 /* Helper function to either create a callback or link to a previously
4915 * defined spritegroup. */
4916 static const SpriteGroup
*GetGroupFromGroupID(byte setid
, byte type
, uint16 groupid
)
4918 if (HasBit(groupid
, 15)) {
4919 assert(CallbackResultSpriteGroup::CanAllocateItem());
4920 return new CallbackResultSpriteGroup(groupid
, _cur
.grffile
->grf_version
>= 8);
4923 if (groupid
> MAX_SPRITEGROUP
|| _cur
.spritegroups
[groupid
] == nullptr) {
4924 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid
, type
, groupid
);
4928 return _cur
.spritegroups
[groupid
];
4932 * Helper function to either create a callback or a result sprite group.
4933 * @param feature GrfSpecFeature to define spritegroup for.
4934 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4935 * @param type Type of the currently being parsed Action2. (only for debug output)
4936 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4937 * @return Created spritegroup.
4939 static const SpriteGroup
*CreateGroupFromGroupID(byte feature
, byte setid
, byte type
, uint16 spriteid
)
4941 if (HasBit(spriteid
, 15)) {
4942 assert(CallbackResultSpriteGroup::CanAllocateItem());
4943 return new CallbackResultSpriteGroup(spriteid
, _cur
.grffile
->grf_version
>= 8);
4946 if (!_cur
.IsValidSpriteSet(feature
, spriteid
)) {
4947 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid
, type
, spriteid
);
4951 SpriteID spriteset_start
= _cur
.GetSprite(feature
, spriteid
);
4952 uint num_sprites
= _cur
.GetNumEnts(feature
, spriteid
);
4954 /* Ensure that the sprites are loeded */
4955 assert(spriteset_start
+ num_sprites
<= _cur
.spriteid
);
4957 assert(ResultSpriteGroup::CanAllocateItem());
4958 return new ResultSpriteGroup(spriteset_start
, num_sprites
);
4962 static void NewSpriteGroup(ByteReader
*buf
)
4964 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4966 * B feature see action 1
4967 * B set-id ID of this particular definition
4968 * B type/num-entries
4969 * if 80 or greater, this is a randomized or variational
4970 * list definition, see below
4971 * otherwise it specifies a number of entries, the exact
4972 * meaning depends on the feature
4973 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4974 SpriteGroup
*act_group
= nullptr;
4976 uint8 feature
= buf
->ReadByte();
4977 if (feature
>= GSF_END
) {
4978 grfmsg(1, "NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature
);
4982 uint8 setid
= buf
->ReadByte();
4983 uint8 type
= buf
->ReadByte();
4985 /* Sprite Groups are created here but they are allocated from a pool, so
4986 * we do not need to delete anything if there is an exception from the
4990 /* Deterministic Sprite Group */
4991 case 0x81: // Self scope, byte
4992 case 0x82: // Parent scope, byte
4993 case 0x85: // Self scope, word
4994 case 0x86: // Parent scope, word
4995 case 0x89: // Self scope, dword
4996 case 0x8A: // Parent scope, dword
5001 assert(DeterministicSpriteGroup::CanAllocateItem());
5002 DeterministicSpriteGroup
*group
= new DeterministicSpriteGroup();
5004 group
->var_scope
= HasBit(type
, 1) ? VSG_SCOPE_PARENT
: VSG_SCOPE_SELF
;
5006 switch (GB(type
, 2, 2)) {
5007 default: NOT_REACHED();
5008 case 0: group
->size
= DSG_SIZE_BYTE
; varsize
= 1; break;
5009 case 1: group
->size
= DSG_SIZE_WORD
; varsize
= 2; break;
5010 case 2: group
->size
= DSG_SIZE_DWORD
; varsize
= 4; break;
5013 static std::vector
<DeterministicSpriteGroupAdjust
> adjusts
;
5016 /* Loop through the var adjusts. Unfortunately we don't know how many we have
5017 * from the outset, so we shall have to keep reallocing. */
5019 /*C++17: DeterministicSpriteGroupAdjust &adjust = */ adjusts
.emplace_back();
5020 DeterministicSpriteGroupAdjust
&adjust
= adjusts
.back();
5022 /* The first var adjust doesn't have an operation specified, so we set it to add. */
5023 adjust
.operation
= adjusts
.size() == 1 ? DSGA_OP_ADD
: (DeterministicSpriteGroupAdjustOperation
)buf
->ReadByte();
5024 adjust
.variable
= buf
->ReadByte();
5025 if (adjust
.variable
== 0x7E) {
5026 /* Link subroutine group */
5027 adjust
.subroutine
= GetGroupFromGroupID(setid
, type
, buf
->ReadByte());
5029 adjust
.parameter
= IsInsideMM(adjust
.variable
, 0x60, 0x80) ? buf
->ReadByte() : 0;
5032 varadjust
= buf
->ReadByte();
5033 adjust
.shift_num
= GB(varadjust
, 0, 5);
5034 adjust
.type
= (DeterministicSpriteGroupAdjustType
)GB(varadjust
, 6, 2);
5035 adjust
.and_mask
= buf
->ReadVarSize(varsize
);
5037 if (adjust
.type
!= DSGA_TYPE_NONE
) {
5038 adjust
.add_val
= buf
->ReadVarSize(varsize
);
5039 adjust
.divmod_val
= buf
->ReadVarSize(varsize
);
5042 adjust
.divmod_val
= 0;
5045 /* Continue reading var adjusts while bit 5 is set. */
5046 } while (HasBit(varadjust
, 5));
5048 group
->num_adjusts
= (uint
)adjusts
.size();
5049 group
->adjusts
= MallocT
<DeterministicSpriteGroupAdjust
>(group
->num_adjusts
);
5050 MemCpyT(group
->adjusts
, adjusts
.data(), group
->num_adjusts
);
5052 std::vector
<DeterministicSpriteGroupRange
> ranges
;
5053 ranges
.resize(buf
->ReadByte());
5054 for (uint i
= 0; i
< ranges
.size(); i
++) {
5055 ranges
[i
].group
= GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
5056 ranges
[i
].low
= buf
->ReadVarSize(varsize
);
5057 ranges
[i
].high
= buf
->ReadVarSize(varsize
);
5060 group
->default_group
= GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
5061 group
->error_group
= ranges
.size() > 0 ? ranges
[0].group
: group
->default_group
;
5062 /* nvar == 0 is a special case -- we turn our value into a callback result */
5063 group
->calculated_result
= ranges
.size() == 0;
5065 /* Sort ranges ascending. When ranges overlap, this may required clamping or splitting them */
5066 std::vector
<uint32
> bounds
;
5067 for (uint i
= 0; i
< ranges
.size(); i
++) {
5068 bounds
.push_back(ranges
[i
].low
);
5069 if (ranges
[i
].high
!= UINT32_MAX
) bounds
.push_back(ranges
[i
].high
+ 1);
5071 std::sort(bounds
.begin(), bounds
.end());
5072 bounds
.erase(std::unique(bounds
.begin(), bounds
.end()), bounds
.end());
5074 std::vector
<const SpriteGroup
*> target
;
5075 for (uint j
= 0; j
< bounds
.size(); ++j
) {
5076 uint32 v
= bounds
[j
];
5077 const SpriteGroup
*t
= group
->default_group
;
5078 for (uint i
= 0; i
< ranges
.size(); i
++) {
5079 if (ranges
[i
].low
<= v
&& v
<= ranges
[i
].high
) {
5080 t
= ranges
[i
].group
;
5084 target
.push_back(t
);
5086 assert(target
.size() == bounds
.size());
5088 std::vector
<DeterministicSpriteGroupRange
> optimised
;
5089 for (uint j
= 0; j
< bounds
.size(); ) {
5090 if (target
[j
] != group
->default_group
) {
5091 DeterministicSpriteGroupRange r
;
5092 r
.group
= target
[j
];
5094 while (j
< bounds
.size() && target
[j
] == r
.group
) {
5097 r
.high
= j
< bounds
.size() ? bounds
[j
] - 1 : UINT32_MAX
;
5098 optimised
.push_back(r
);
5104 group
->num_ranges
= (uint
)optimised
.size(); // cast is safe, there should never be 2**31 elements here
5105 if (group
->num_ranges
> 0) {
5106 group
->ranges
= MallocT
<DeterministicSpriteGroupRange
>(group
->num_ranges
);
5107 MemCpyT(group
->ranges
, &optimised
.front(), group
->num_ranges
);
5112 /* Randomized Sprite Group */
5113 case 0x80: // Self scope
5114 case 0x83: // Parent scope
5115 case 0x84: // Relative scope
5117 assert(RandomizedSpriteGroup::CanAllocateItem());
5118 RandomizedSpriteGroup
*group
= new RandomizedSpriteGroup();
5120 group
->var_scope
= HasBit(type
, 1) ? VSG_SCOPE_PARENT
: VSG_SCOPE_SELF
;
5122 if (HasBit(type
, 2)) {
5123 if (feature
<= GSF_AIRCRAFT
) group
->var_scope
= VSG_SCOPE_RELATIVE
;
5124 group
->count
= buf
->ReadByte();
5127 uint8 triggers
= buf
->ReadByte();
5128 group
->triggers
= GB(triggers
, 0, 7);
5129 group
->cmp_mode
= HasBit(triggers
, 7) ? RSG_CMP_ALL
: RSG_CMP_ANY
;
5130 group
->lowest_randbit
= buf
->ReadByte();
5131 group
->num_groups
= buf
->ReadByte();
5132 group
->groups
= CallocT
<const SpriteGroup
*>(group
->num_groups
);
5134 for (uint i
= 0; i
< group
->num_groups
; i
++) {
5135 group
->groups
[i
] = GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
5141 /* Neither a variable or randomized sprite group... must be a real group */
5146 case GSF_ROADVEHICLES
:
5157 byte num_loaded
= type
;
5158 byte num_loading
= buf
->ReadByte();
5160 if (!_cur
.HasValidSpriteSets(feature
)) {
5161 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
5165 assert(RealSpriteGroup::CanAllocateItem());
5166 RealSpriteGroup
*group
= new RealSpriteGroup();
5169 group
->num_loaded
= num_loaded
;
5170 group
->num_loading
= num_loading
;
5171 if (num_loaded
> 0) group
->loaded
= CallocT
<const SpriteGroup
*>(num_loaded
);
5172 if (num_loading
> 0) group
->loading
= CallocT
<const SpriteGroup
*>(num_loading
);
5174 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
5175 setid
, num_loaded
, num_loading
);
5177 for (uint i
= 0; i
< num_loaded
; i
++) {
5178 uint16 spriteid
= buf
->ReadWord();
5179 group
->loaded
[i
] = CreateGroupFromGroupID(feature
, setid
, type
, spriteid
);
5180 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i
, spriteid
);
5183 for (uint i
= 0; i
< num_loading
; i
++) {
5184 uint16 spriteid
= buf
->ReadWord();
5185 group
->loading
[i
] = CreateGroupFromGroupID(feature
, setid
, type
, spriteid
);
5186 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i
, spriteid
);
5193 case GSF_AIRPORTTILES
:
5195 case GSF_INDUSTRYTILES
: {
5196 byte num_building_sprites
= max((uint8
)1, type
);
5198 assert(TileLayoutSpriteGroup::CanAllocateItem());
5199 TileLayoutSpriteGroup
*group
= new TileLayoutSpriteGroup();
5202 /* On error, bail out immediately. Temporary GRF data was already freed */
5203 if (ReadSpriteLayout(buf
, num_building_sprites
, true, feature
, false, type
== 0, &group
->dts
)) return;
5207 case GSF_INDUSTRIES
: {
5209 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type
);
5213 assert(IndustryProductionSpriteGroup::CanAllocateItem());
5214 IndustryProductionSpriteGroup
*group
= new IndustryProductionSpriteGroup();
5216 group
->version
= type
;
5218 group
->num_input
= 3;
5219 for (uint i
= 0; i
< 3; i
++) {
5220 group
->subtract_input
[i
] = (int16
)buf
->ReadWord(); // signed
5222 group
->num_output
= 2;
5223 for (uint i
= 0; i
< 2; i
++) {
5224 group
->add_output
[i
] = buf
->ReadWord(); // unsigned
5226 group
->again
= buf
->ReadByte();
5227 } else if (type
== 1) {
5228 group
->num_input
= 3;
5229 for (uint i
= 0; i
< 3; i
++) {
5230 group
->subtract_input
[i
] = buf
->ReadByte();
5232 group
->num_output
= 2;
5233 for (uint i
= 0; i
< 2; i
++) {
5234 group
->add_output
[i
] = buf
->ReadByte();
5236 group
->again
= buf
->ReadByte();
5237 } else if (type
== 2) {
5238 group
->num_input
= buf
->ReadByte();
5239 if (group
->num_input
> lengthof(group
->subtract_input
)) {
5240 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK
);
5241 error
->data
= stredup("too many inputs (max 16)");
5244 for (uint i
= 0; i
< group
->num_input
; i
++) {
5245 byte rawcargo
= buf
->ReadByte();
5246 CargoID cargo
= GetCargoTranslation(rawcargo
, _cur
.grffile
);
5247 if (cargo
== CT_INVALID
) {
5248 /* The mapped cargo is invalid. This is permitted at this point,
5249 * as long as the result is not used. Mark it invalid so this
5250 * can be tested later. */
5251 group
->version
= 0xFF;
5252 } else if (std::find(group
->cargo_input
, group
->cargo_input
+ i
, cargo
) != group
->cargo_input
+ i
) {
5253 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK
);
5254 error
->data
= stredup("duplicate input cargo");
5257 group
->cargo_input
[i
] = cargo
;
5258 group
->subtract_input
[i
] = buf
->ReadByte();
5260 group
->num_output
= buf
->ReadByte();
5261 if (group
->num_output
> lengthof(group
->add_output
)) {
5262 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK
);
5263 error
->data
= stredup("too many outputs (max 16)");
5266 for (uint i
= 0; i
< group
->num_output
; i
++) {
5267 byte rawcargo
= buf
->ReadByte();
5268 CargoID cargo
= GetCargoTranslation(rawcargo
, _cur
.grffile
);
5269 if (cargo
== CT_INVALID
) {
5270 /* Mark this result as invalid to use */
5271 group
->version
= 0xFF;
5272 } else if (std::find(group
->cargo_output
, group
->cargo_output
+ i
, cargo
) != group
->cargo_output
+ i
) {
5273 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_INDPROD_CALLBACK
);
5274 error
->data
= stredup("duplicate output cargo");
5277 group
->cargo_output
[i
] = cargo
;
5278 group
->add_output
[i
] = buf
->ReadByte();
5280 group
->again
= buf
->ReadByte();
5287 /* Loading of Tile Layout and Production Callback groups would happen here */
5288 default: grfmsg(1, "NewSpriteGroup: Unsupported feature 0x%02X, skipping", feature
);
5293 _cur
.spritegroups
[setid
] = act_group
;
5296 static CargoID
TranslateCargo(uint8 feature
, uint8 ctype
)
5298 if (feature
== GSF_OBJECTS
) {
5301 case 0xFF: return CT_PURCHASE_OBJECT
;
5303 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype
);
5307 /* Special cargo types for purchase list and stations */
5308 if (feature
== GSF_STATIONS
&& ctype
== 0xFE) return CT_DEFAULT_NA
;
5309 if (ctype
== 0xFF) return CT_PURCHASE
;
5311 if (_cur
.grffile
->cargo_list
.size() == 0) {
5312 /* No cargo table, so use bitnum values */
5314 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype
);
5318 const CargoSpec
*cs
;
5319 FOR_ALL_CARGOSPECS(cs
) {
5320 if (cs
->bitnum
== ctype
) {
5321 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype
, cs
->Index());
5326 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype
);
5330 /* Check if the cargo type is out of bounds of the cargo translation table */
5331 if (ctype
>= _cur
.grffile
->cargo_list
.size()) {
5332 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype
, (unsigned int)_cur
.grffile
->cargo_list
.size() - 1);
5336 /* Look up the cargo label from the translation table */
5337 CargoLabel cl
= _cur
.grffile
->cargo_list
[ctype
];
5339 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype
);
5343 ctype
= GetCargoIDByLabel(cl
);
5344 if (ctype
== CT_INVALID
) {
5345 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));
5349 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
);
5354 static bool IsValidGroupID(uint16 groupid
, const char *function
)
5356 if (groupid
> MAX_SPRITEGROUP
|| _cur
.spritegroups
[groupid
] == nullptr) {
5357 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function
, groupid
);
5364 static void VehicleMapSpriteGroup(ByteReader
*buf
, byte feature
, uint8 idcount
)
5366 static EngineID
*last_engines
;
5367 static uint last_engines_count
;
5368 bool wagover
= false;
5370 /* Test for 'wagon override' flag */
5371 if (HasBit(idcount
, 7)) {
5373 /* Strip off the flag */
5374 idcount
= GB(idcount
, 0, 7);
5376 if (last_engines_count
== 0) {
5377 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5381 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5382 last_engines_count
, idcount
);
5384 if (last_engines_count
!= idcount
) {
5385 last_engines
= ReallocT(last_engines
, idcount
);
5386 last_engines_count
= idcount
;
5390 EngineID
*engines
= AllocaM(EngineID
, idcount
);
5391 for (uint i
= 0; i
< idcount
; i
++) {
5392 Engine
*e
= GetNewEngine(_cur
.grffile
, (VehicleType
)feature
, buf
->ReadExtendedByte());
5394 /* No engine could be allocated?!? Deal with it. Okay,
5395 * this might look bad. Also make sure this NewGRF
5396 * gets disabled, as a half loaded one is bad. */
5397 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID
, 0, 0);
5401 engines
[i
] = e
->index
;
5402 if (!wagover
) last_engines
[i
] = engines
[i
];
5405 uint8 cidcount
= buf
->ReadByte();
5406 for (uint c
= 0; c
< cidcount
; c
++) {
5407 uint8 ctype
= buf
->ReadByte();
5408 uint16 groupid
= buf
->ReadWord();
5409 if (!IsValidGroupID(groupid
, "VehicleMapSpriteGroup")) continue;
5411 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c
, ctype
, groupid
);
5413 ctype
= TranslateCargo(feature
, ctype
);
5414 if (ctype
== CT_INVALID
) continue;
5416 for (uint i
= 0; i
< idcount
; i
++) {
5417 EngineID engine
= engines
[i
];
5419 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i
, engine
);
5422 SetWagonOverrideSprites(engine
, ctype
, _cur
.spritegroups
[groupid
], last_engines
, last_engines_count
);
5424 SetCustomEngineSprites(engine
, ctype
, _cur
.spritegroups
[groupid
]);
5429 uint16 groupid
= buf
->ReadWord();
5430 if (!IsValidGroupID(groupid
, "VehicleMapSpriteGroup")) return;
5432 grfmsg(8, "-- Default group id 0x%04X", groupid
);
5434 for (uint i
= 0; i
< idcount
; i
++) {
5435 EngineID engine
= engines
[i
];
5438 SetWagonOverrideSprites(engine
, CT_DEFAULT
, _cur
.spritegroups
[groupid
], last_engines
, last_engines_count
);
5440 SetCustomEngineSprites(engine
, CT_DEFAULT
, _cur
.spritegroups
[groupid
]);
5441 SetEngineGRF(engine
, _cur
.grffile
);
5447 static void CanalMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5449 CanalFeature
*cfs
= AllocaM(CanalFeature
, idcount
);
5450 for (uint i
= 0; i
< idcount
; i
++) {
5451 cfs
[i
] = (CanalFeature
)buf
->ReadByte();
5454 uint8 cidcount
= buf
->ReadByte();
5455 buf
->Skip(cidcount
* 3);
5457 uint16 groupid
= buf
->ReadWord();
5458 if (!IsValidGroupID(groupid
, "CanalMapSpriteGroup")) return;
5460 for (uint i
= 0; i
< idcount
; i
++) {
5461 CanalFeature cf
= cfs
[i
];
5464 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf
);
5468 _water_feature
[cf
].grffile
= _cur
.grffile
;
5469 _water_feature
[cf
].group
= _cur
.spritegroups
[groupid
];
5474 static void StationMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5476 uint8
*stations
= AllocaM(uint8
, idcount
);
5477 for (uint i
= 0; i
< idcount
; i
++) {
5478 stations
[i
] = buf
->ReadByte();
5481 uint8 cidcount
= buf
->ReadByte();
5482 for (uint c
= 0; c
< cidcount
; c
++) {
5483 uint8 ctype
= buf
->ReadByte();
5484 uint16 groupid
= buf
->ReadWord();
5485 if (!IsValidGroupID(groupid
, "StationMapSpriteGroup")) continue;
5487 ctype
= TranslateCargo(GSF_STATIONS
, ctype
);
5488 if (ctype
== CT_INVALID
) continue;
5490 for (uint i
= 0; i
< idcount
; i
++) {
5491 StationSpec
*statspec
= _cur
.grffile
->stations
== nullptr ? nullptr : _cur
.grffile
->stations
[stations
[i
]];
5493 if (statspec
== nullptr) {
5494 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations
[i
]);
5498 statspec
->grf_prop
.spritegroup
[ctype
] = _cur
.spritegroups
[groupid
];
5502 uint16 groupid
= buf
->ReadWord();
5503 if (!IsValidGroupID(groupid
, "StationMapSpriteGroup")) return;
5505 for (uint i
= 0; i
< idcount
; i
++) {
5506 StationSpec
*statspec
= _cur
.grffile
->stations
== nullptr ? nullptr : _cur
.grffile
->stations
[stations
[i
]];
5508 if (statspec
== nullptr) {
5509 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations
[i
]);
5513 if (statspec
->grf_prop
.grffile
!= nullptr) {
5514 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations
[i
]);
5518 statspec
->grf_prop
.spritegroup
[CT_DEFAULT
] = _cur
.spritegroups
[groupid
];
5519 statspec
->grf_prop
.grffile
= _cur
.grffile
;
5520 statspec
->grf_prop
.local_id
= stations
[i
];
5521 StationClass::Assign(statspec
);
5526 static void TownHouseMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5528 uint8
*houses
= AllocaM(uint8
, idcount
);
5529 for (uint i
= 0; i
< idcount
; i
++) {
5530 houses
[i
] = buf
->ReadByte();
5533 /* Skip the cargo type section, we only care about the default group */
5534 uint8 cidcount
= buf
->ReadByte();
5535 buf
->Skip(cidcount
* 3);
5537 uint16 groupid
= buf
->ReadWord();
5538 if (!IsValidGroupID(groupid
, "TownHouseMapSpriteGroup")) return;
5540 if (_cur
.grffile
->housespec
== nullptr) {
5541 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5545 for (uint i
= 0; i
< idcount
; i
++) {
5546 HouseSpec
*hs
= _cur
.grffile
->housespec
[houses
[i
]];
5548 if (hs
== nullptr) {
5549 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses
[i
]);
5553 hs
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5557 static void IndustryMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5559 uint8
*industries
= AllocaM(uint8
, idcount
);
5560 for (uint i
= 0; i
< idcount
; i
++) {
5561 industries
[i
] = buf
->ReadByte();
5564 /* Skip the cargo type section, we only care about the default group */
5565 uint8 cidcount
= buf
->ReadByte();
5566 buf
->Skip(cidcount
* 3);
5568 uint16 groupid
= buf
->ReadWord();
5569 if (!IsValidGroupID(groupid
, "IndustryMapSpriteGroup")) return;
5571 if (_cur
.grffile
->industryspec
== nullptr) {
5572 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5576 for (uint i
= 0; i
< idcount
; i
++) {
5577 IndustrySpec
*indsp
= _cur
.grffile
->industryspec
[industries
[i
]];
5579 if (indsp
== nullptr) {
5580 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries
[i
]);
5584 indsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5588 static void IndustrytileMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5590 uint8
*indtiles
= AllocaM(uint8
, idcount
);
5591 for (uint i
= 0; i
< idcount
; i
++) {
5592 indtiles
[i
] = buf
->ReadByte();
5595 /* Skip the cargo type section, we only care about the default group */
5596 uint8 cidcount
= buf
->ReadByte();
5597 buf
->Skip(cidcount
* 3);
5599 uint16 groupid
= buf
->ReadWord();
5600 if (!IsValidGroupID(groupid
, "IndustrytileMapSpriteGroup")) return;
5602 if (_cur
.grffile
->indtspec
== nullptr) {
5603 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5607 for (uint i
= 0; i
< idcount
; i
++) {
5608 IndustryTileSpec
*indtsp
= _cur
.grffile
->indtspec
[indtiles
[i
]];
5610 if (indtsp
== nullptr) {
5611 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles
[i
]);
5615 indtsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5619 static void CargoMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5621 CargoID
*cargoes
= AllocaM(CargoID
, idcount
);
5622 for (uint i
= 0; i
< idcount
; i
++) {
5623 cargoes
[i
] = buf
->ReadByte();
5626 /* Skip the cargo type section, we only care about the default group */
5627 uint8 cidcount
= buf
->ReadByte();
5628 buf
->Skip(cidcount
* 3);
5630 uint16 groupid
= buf
->ReadWord();
5631 if (!IsValidGroupID(groupid
, "CargoMapSpriteGroup")) return;
5633 for (uint i
= 0; i
< idcount
; i
++) {
5634 CargoID cid
= cargoes
[i
];
5636 if (cid
>= NUM_CARGO
) {
5637 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid
);
5641 CargoSpec
*cs
= CargoSpec::Get(cid
);
5642 cs
->grffile
= _cur
.grffile
;
5643 cs
->group
= _cur
.spritegroups
[groupid
];
5647 static void ObjectMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5649 if (_cur
.grffile
->objectspec
== nullptr) {
5650 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5654 uint8
*objects
= AllocaM(uint8
, idcount
);
5655 for (uint i
= 0; i
< idcount
; i
++) {
5656 objects
[i
] = buf
->ReadByte();
5659 uint8 cidcount
= buf
->ReadByte();
5660 for (uint c
= 0; c
< cidcount
; c
++) {
5661 uint8 ctype
= buf
->ReadByte();
5662 uint16 groupid
= buf
->ReadWord();
5663 if (!IsValidGroupID(groupid
, "ObjectMapSpriteGroup")) continue;
5665 ctype
= TranslateCargo(GSF_OBJECTS
, ctype
);
5666 if (ctype
== CT_INVALID
) continue;
5668 for (uint i
= 0; i
< idcount
; i
++) {
5669 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[objects
[i
]];
5671 if (spec
== nullptr) {
5672 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects
[i
]);
5676 spec
->grf_prop
.spritegroup
[ctype
] = _cur
.spritegroups
[groupid
];
5680 uint16 groupid
= buf
->ReadWord();
5681 if (!IsValidGroupID(groupid
, "ObjectMapSpriteGroup")) return;
5683 for (uint i
= 0; i
< idcount
; i
++) {
5684 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[objects
[i
]];
5686 if (spec
== nullptr) {
5687 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects
[i
]);
5691 if (spec
->grf_prop
.grffile
!= nullptr) {
5692 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects
[i
]);
5696 spec
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5697 spec
->grf_prop
.grffile
= _cur
.grffile
;
5698 spec
->grf_prop
.local_id
= objects
[i
];
5702 static void RailTypeMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5704 uint8
*railtypes
= AllocaM(uint8
, idcount
);
5705 for (uint i
= 0; i
< idcount
; i
++) {
5706 uint8 id
= buf
->ReadByte();
5707 railtypes
[i
] = id
< RAILTYPE_END
? _cur
.grffile
->railtype_map
[id
] : INVALID_RAILTYPE
;
5710 uint8 cidcount
= buf
->ReadByte();
5711 for (uint c
= 0; c
< cidcount
; c
++) {
5712 uint8 ctype
= buf
->ReadByte();
5713 uint16 groupid
= buf
->ReadWord();
5714 if (!IsValidGroupID(groupid
, "RailTypeMapSpriteGroup")) continue;
5716 if (ctype
>= RTSG_END
) continue;
5718 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
5719 for (uint i
= 0; i
< idcount
; i
++) {
5720 if (railtypes
[i
] != INVALID_RAILTYPE
) {
5721 RailtypeInfo
*rti
= &_railtypes
[railtypes
[i
]];
5723 rti
->grffile
[ctype
] = _cur
.grffile
;
5724 rti
->group
[ctype
] = _cur
.spritegroups
[groupid
];
5729 /* Railtypes do not use the default group. */
5733 static void RoadTypeMapSpriteGroup(ByteReader
*buf
, uint8 idcount
, RoadTramType rtt
)
5735 RoadType
*type_map
= (rtt
== RTT_TRAM
) ? _cur
.grffile
->tramtype_map
: _cur
.grffile
->roadtype_map
;
5737 uint8
*roadtypes
= AllocaM(uint8
, idcount
);
5738 for (uint i
= 0; i
< idcount
; i
++) {
5739 uint8 id
= buf
->ReadByte();
5740 roadtypes
[i
] = id
< ROADTYPE_END
? type_map
[id
] : INVALID_ROADTYPE
;
5743 uint8 cidcount
= buf
->ReadByte();
5744 for (uint c
= 0; c
< cidcount
; c
++) {
5745 uint8 ctype
= buf
->ReadByte();
5746 uint16 groupid
= buf
->ReadWord();
5747 if (!IsValidGroupID(groupid
, "RoadTypeMapSpriteGroup")) continue;
5749 if (ctype
>= ROTSG_END
) continue;
5751 extern RoadTypeInfo _roadtypes
[ROADTYPE_END
];
5752 for (uint i
= 0; i
< idcount
; i
++) {
5753 if (roadtypes
[i
] != INVALID_ROADTYPE
) {
5754 RoadTypeInfo
*rti
= &_roadtypes
[roadtypes
[i
]];
5756 rti
->grffile
[ctype
] = _cur
.grffile
;
5757 rti
->group
[ctype
] = _cur
.spritegroups
[groupid
];
5762 /* Roadtypes do not use the default group. */
5766 static void AirportMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5768 uint8
*airports
= AllocaM(uint8
, idcount
);
5769 for (uint i
= 0; i
< idcount
; i
++) {
5770 airports
[i
] = buf
->ReadByte();
5773 /* Skip the cargo type section, we only care about the default group */
5774 uint8 cidcount
= buf
->ReadByte();
5775 buf
->Skip(cidcount
* 3);
5777 uint16 groupid
= buf
->ReadWord();
5778 if (!IsValidGroupID(groupid
, "AirportMapSpriteGroup")) return;
5780 if (_cur
.grffile
->airportspec
== nullptr) {
5781 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5785 for (uint i
= 0; i
< idcount
; i
++) {
5786 AirportSpec
*as
= _cur
.grffile
->airportspec
[airports
[i
]];
5788 if (as
== nullptr) {
5789 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports
[i
]);
5793 as
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5797 static void AirportTileMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5799 uint8
*airptiles
= AllocaM(uint8
, idcount
);
5800 for (uint i
= 0; i
< idcount
; i
++) {
5801 airptiles
[i
] = buf
->ReadByte();
5804 /* Skip the cargo type section, we only care about the default group */
5805 uint8 cidcount
= buf
->ReadByte();
5806 buf
->Skip(cidcount
* 3);
5808 uint16 groupid
= buf
->ReadWord();
5809 if (!IsValidGroupID(groupid
, "AirportTileMapSpriteGroup")) return;
5811 if (_cur
.grffile
->airtspec
== nullptr) {
5812 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5816 for (uint i
= 0; i
< idcount
; i
++) {
5817 AirportTileSpec
*airtsp
= _cur
.grffile
->airtspec
[airptiles
[i
]];
5819 if (airtsp
== nullptr) {
5820 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles
[i
]);
5824 airtsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5830 static void FeatureMapSpriteGroup(ByteReader
*buf
)
5832 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5833 * id-list := [<id>] [id-list]
5834 * cargo-list := <cargo-type> <cid> [cargo-list]
5836 * B feature see action 0
5837 * B n-id bits 0-6: how many IDs this definition applies to
5838 * bit 7: if set, this is a wagon override definition (see below)
5839 * B ids the IDs for which this definition applies
5840 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5841 * can be zero, in that case the def-cid is used always
5842 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5843 * W cid cargo ID (sprite group ID) for this type of cargo
5844 * W def-cid default cargo ID (sprite group ID) */
5846 uint8 feature
= buf
->ReadByte();
5847 uint8 idcount
= buf
->ReadByte();
5849 if (feature
>= GSF_END
) {
5850 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature
);
5854 /* If idcount is zero, this is a feature callback */
5856 /* Skip number of cargo ids? */
5858 uint16 groupid
= buf
->ReadWord();
5859 if (!IsValidGroupID(groupid
, "FeatureMapSpriteGroup")) return;
5861 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature 0x%02X", feature
);
5863 AddGenericCallback(feature
, _cur
.grffile
, _cur
.spritegroups
[groupid
]);
5867 /* Mark the feature as used by the grf (generic callbacks do not count) */
5868 SetBit(_cur
.grffile
->grf_features
, feature
);
5870 grfmsg(6, "FeatureMapSpriteGroup: Feature 0x%02X, %d ids", feature
, idcount
);
5874 case GSF_ROADVEHICLES
:
5877 VehicleMapSpriteGroup(buf
, feature
, idcount
);
5881 CanalMapSpriteGroup(buf
, idcount
);
5885 StationMapSpriteGroup(buf
, idcount
);
5889 TownHouseMapSpriteGroup(buf
, idcount
);
5892 case GSF_INDUSTRIES
:
5893 IndustryMapSpriteGroup(buf
, idcount
);
5896 case GSF_INDUSTRYTILES
:
5897 IndustrytileMapSpriteGroup(buf
, idcount
);
5901 CargoMapSpriteGroup(buf
, idcount
);
5905 AirportMapSpriteGroup(buf
, idcount
);
5909 ObjectMapSpriteGroup(buf
, idcount
);
5913 RailTypeMapSpriteGroup(buf
, idcount
);
5917 RoadTypeMapSpriteGroup(buf
, idcount
, RTT_ROAD
);
5921 RoadTypeMapSpriteGroup(buf
, idcount
, RTT_TRAM
);
5924 case GSF_AIRPORTTILES
:
5925 AirportTileMapSpriteGroup(buf
, idcount
);
5929 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x%02X, skipping", feature
);
5935 static void FeatureNewName(ByteReader
*buf
)
5937 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5939 * B veh-type see action 0 (as 00..07, + 0A
5940 * But IF veh-type = 48, then generic text
5941 * B language-id If bit 6 is set, This is the extended language scheme,
5942 * with up to 64 language.
5943 * Otherwise, it is a mapping where set bits have meaning
5944 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5945 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5946 * B num-veh number of vehicles which are getting a new name
5947 * B/W offset number of the first vehicle that gets a new name
5948 * Byte : ID of vehicle to change
5949 * Word : ID of string to change/add
5950 * S data new texts, each of them zero-terminated, after
5951 * which the next name begins. */
5953 bool new_scheme
= _cur
.grffile
->grf_version
>= 7;
5955 uint8 feature
= buf
->ReadByte();
5956 if (feature
>= GSF_END
&& feature
!= 0x48) {
5957 grfmsg(1, "FeatureNewName: Unsupported feature 0x%02X, skipping", feature
);
5961 uint8 lang
= buf
->ReadByte();
5962 uint8 num
= buf
->ReadByte();
5963 bool generic
= HasBit(lang
, 7);
5966 id
= buf
->ReadWord();
5967 } else if (feature
<= GSF_AIRCRAFT
) {
5968 id
= buf
->ReadExtendedByte();
5970 id
= buf
->ReadByte();
5975 uint16 endid
= id
+ num
;
5977 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature 0x%02X) in language 0x%02X",
5978 id
, endid
, feature
, lang
);
5980 for (; id
< endid
&& buf
->HasData(); id
++) {
5981 const char *name
= buf
->ReadString();
5982 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id
, name
);
5986 case GSF_ROADVEHICLES
:
5990 Engine
*e
= GetNewEngine(_cur
.grffile
, (VehicleType
)feature
, id
, HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
));
5991 if (e
== nullptr) break;
5992 StringID string
= AddGRFString(_cur
.grffile
->grfid
, e
->index
, lang
, new_scheme
, false, name
, e
->info
.string_id
);
5993 e
->info
.string_id
= string
;
5995 AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, true, name
, STR_UNDEFINED
);
6000 if (IsInsideMM(id
, 0xD000, 0xD400) || IsInsideMM(id
, 0xD800, 0xE000)) {
6001 AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, true, name
, STR_UNDEFINED
);
6005 switch (GB(id
, 8, 8)) {
6006 case 0xC4: // Station class name
6007 if (_cur
.grffile
->stations
== nullptr || _cur
.grffile
->stations
[GB(id
, 0, 8)] == nullptr) {
6008 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id
, 0, 8));
6010 StationClassID cls_id
= _cur
.grffile
->stations
[GB(id
, 0, 8)]->cls_id
;
6011 StationClass::Get(cls_id
)->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
6015 case 0xC5: // Station name
6016 if (_cur
.grffile
->stations
== nullptr || _cur
.grffile
->stations
[GB(id
, 0, 8)] == nullptr) {
6017 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id
, 0, 8));
6019 _cur
.grffile
->stations
[GB(id
, 0, 8)]->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
6023 case 0xC7: // Airporttile name
6024 if (_cur
.grffile
->airtspec
== nullptr || _cur
.grffile
->airtspec
[GB(id
, 0, 8)] == nullptr) {
6025 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id
, 0, 8));
6027 _cur
.grffile
->airtspec
[GB(id
, 0, 8)]->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
6031 case 0xC9: // House name
6032 if (_cur
.grffile
->housespec
== nullptr || _cur
.grffile
->housespec
[GB(id
, 0, 8)] == nullptr) {
6033 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id
, 0, 8));
6035 _cur
.grffile
->housespec
[GB(id
, 0, 8)]->building_name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
6040 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id
);
6049 * Sanitize incoming sprite offsets for Action 5 graphics replacements.
6050 * @param num The number of sprites to load.
6051 * @param offset Offset from the base.
6052 * @param max_sprites The maximum number of sprites that can be loaded in this action 5.
6053 * @param name Used for error warnings.
6054 * @return The number of sprites that is going to be skipped.
6056 static uint16
SanitizeSpriteOffset(uint16
& num
, uint16 offset
, int max_sprites
, const char *name
)
6059 if (offset
>= max_sprites
) {
6060 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name
, max_sprites
);
6061 uint orig_num
= num
;
6066 if (offset
+ num
> max_sprites
) {
6067 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name
);
6068 uint orig_num
= num
;
6069 num
= max(max_sprites
- offset
, 0);
6070 return orig_num
- num
;
6077 /** The type of action 5 type. */
6078 enum Action5BlockType
{
6079 A5BLOCK_FIXED
, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
6080 A5BLOCK_ALLOW_OFFSET
, ///< Allow replacing any subset by specifiing an offset.
6081 A5BLOCK_INVALID
, ///< unknown/not-implemented type
6083 /** Information about a single action 5 type. */
6084 struct Action5Type
{
6085 Action5BlockType block_type
; ///< How is this Action5 type processed?
6086 SpriteID sprite_base
; ///< Load the sprites starting from this sprite.
6087 uint16 min_sprites
; ///< If the Action5 contains less sprites, the whole block will be ignored.
6088 uint16 max_sprites
; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
6089 const char *name
; ///< Name for error messages.
6092 /** The information about action 5 types. */
6093 static const Action5Type _action5_types
[] = {
6094 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
6095 /* 0x00 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x00" },
6096 /* 0x01 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x01" },
6097 /* 0x02 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x02" },
6098 /* 0x03 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x03" },
6099 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET
, SPR_SIGNALS_BASE
, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT
, "Signal graphics" },
6100 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ELRAIL_BASE
, 1, ELRAIL_SPRITE_COUNT
, "Rail catenary graphics" },
6101 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET
, SPR_SLOPES_BASE
, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT
, "Foundation graphics" },
6102 /* 0x07 */ { A5BLOCK_INVALID
, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
6103 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET
, SPR_CANALS_BASE
, 1, CANALS_SPRITE_COUNT
, "Canal graphics" },
6104 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ONEWAY_BASE
, 1, ONEWAY_SPRITE_COUNT
, "One way road graphics" },
6105 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET
, SPR_2CCMAP_BASE
, 1, TWOCCMAP_SPRITE_COUNT
, "2CC colour maps" },
6106 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET
, SPR_TRAMWAY_BASE
, 1, TRAMWAY_SPRITE_COUNT
, "Tramway graphics" },
6107 /* 0x0C */ { A5BLOCK_INVALID
, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
6108 /* 0x0D */ { A5BLOCK_FIXED
, SPR_SHORE_BASE
, 16, SPR_SHORE_SPRITE_COUNT
, "Shore graphics" },
6109 /* 0x0E */ { A5BLOCK_INVALID
, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
6110 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET
, SPR_TRACKS_FOR_SLOPES_BASE
, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT
, "Sloped rail track" },
6111 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AIRPORTX_BASE
, 1, AIRPORTX_SPRITE_COUNT
, "Airport graphics" },
6112 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ROADSTOP_BASE
, 1, ROADSTOP_SPRITE_COUNT
, "Road stop graphics" },
6113 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AQUEDUCT_BASE
, 1, AQUEDUCT_SPRITE_COUNT
, "Aqueduct graphics" },
6114 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AUTORAIL_BASE
, 1, AUTORAIL_SPRITE_COUNT
, "Autorail graphics" },
6115 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET
, SPR_FLAGS_BASE
, 1, FLAGS_SPRITE_COUNT
, "Flag graphics" },
6116 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET
, SPR_OPENTTD_BASE
, 1, OPENTTD_SPRITE_COUNT
, "OpenTTD GUI graphics" },
6117 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AIRPORT_PREVIEW_BASE
, 1, SPR_AIRPORT_PREVIEW_COUNT
, "Airport preview graphics" },
6118 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET
, SPR_RAILTYPE_TUNNEL_BASE
, 1, RAILTYPE_TUNNEL_BASE_COUNT
, "Railtype tunnel base" },
6119 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET
, SPR_PALETTE_BASE
, 1, PALETTE_SPRITE_COUNT
, "Palette" },
6123 static void GraphicsNew(ByteReader
*buf
)
6125 /* <05> <graphics-type> <num-sprites> <other data...>
6127 * B graphics-type What set of graphics the sprites define.
6128 * E num-sprites How many sprites are in this set?
6129 * V other data Graphics type specific data. Currently unused. */
6131 uint8 type
= buf
->ReadByte();
6132 uint16 num
= buf
->ReadExtendedByte();
6133 uint16 offset
= HasBit(type
, 7) ? buf
->ReadExtendedByte() : 0;
6134 ClrBit(type
, 7); // Clear the high bit as that only indicates whether there is an offset.
6136 if ((type
== 0x0D) && (num
== 10) && HasBit(_cur
.grfconfig
->flags
, GCF_SYSTEM
)) {
6137 /* Special not-TTDP-compatible case used in openttd.grf
6138 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
6139 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
6140 LoadNextSprite(SPR_SHORE_BASE
+ 0, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_S
6141 LoadNextSprite(SPR_SHORE_BASE
+ 5, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_W
6142 LoadNextSprite(SPR_SHORE_BASE
+ 7, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_WSE
6143 LoadNextSprite(SPR_SHORE_BASE
+ 10, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_N
6144 LoadNextSprite(SPR_SHORE_BASE
+ 11, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_NWS
6145 LoadNextSprite(SPR_SHORE_BASE
+ 13, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_ENW
6146 LoadNextSprite(SPR_SHORE_BASE
+ 14, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_SEN
6147 LoadNextSprite(SPR_SHORE_BASE
+ 15, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_E
6148 LoadNextSprite(SPR_SHORE_BASE
+ 16, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_EW
6149 LoadNextSprite(SPR_SHORE_BASE
+ 17, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_NS
6150 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_NONE
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ONLY_NEW
;
6154 /* Supported type? */
6155 if ((type
>= lengthof(_action5_types
)) || (_action5_types
[type
].block_type
== A5BLOCK_INVALID
)) {
6156 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type
, num
);
6157 _cur
.skip_sprites
= num
;
6161 const Action5Type
*action5_type
= &_action5_types
[type
];
6163 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
6164 * except for the long version of the shore type:
6165 * Ignore offset if not allowed */
6166 if ((action5_type
->block_type
!= A5BLOCK_ALLOW_OFFSET
) && (offset
!= 0)) {
6167 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type
->name
, type
);
6171 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
6172 * This does not make sense, if <offset> is allowed */
6173 if ((action5_type
->block_type
== A5BLOCK_FIXED
) && (num
< action5_type
->min_sprites
)) {
6174 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
);
6175 _cur
.skip_sprites
= num
;
6179 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extensions) */
6180 uint16 skip_num
= SanitizeSpriteOffset(num
, offset
, action5_type
->max_sprites
, action5_type
->name
);
6181 SpriteID replace
= action5_type
->sprite_base
+ offset
;
6183 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
6184 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
);
6186 if (type
== 0x0D) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_5
;
6189 static const SpriteID depot_with_track_offset
= SPR_TRAMWAY_DEPOT_WITH_TRACK
- SPR_TRAMWAY_BASE
;
6190 static const SpriteID depot_no_track_offset
= SPR_TRAMWAY_DEPOT_NO_TRACK
- SPR_TRAMWAY_BASE
;
6191 if (offset
<= depot_with_track_offset
&& offset
+ num
> depot_with_track_offset
) _loaded_newgrf_features
.tram
= TRAMWAY_REPLACE_DEPOT_WITH_TRACK
;
6192 if (offset
<= depot_no_track_offset
&& offset
+ num
> depot_no_track_offset
) _loaded_newgrf_features
.tram
= TRAMWAY_REPLACE_DEPOT_NO_TRACK
;
6195 for (; num
> 0; num
--) {
6197 LoadNextSprite(replace
== 0 ? _cur
.spriteid
++ : replace
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
6200 _cur
.skip_sprites
= skip_num
;
6203 /* Action 0x05 (SKIP) */
6204 static void SkipAct5(ByteReader
*buf
)
6206 /* Ignore type byte */
6209 /* Skip the sprites of this action */
6210 _cur
.skip_sprites
= buf
->ReadExtendedByte();
6212 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur
.skip_sprites
);
6216 * Reads a variable common to VarAction2 and Action7/9/D.
6218 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
6219 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
6221 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
6222 * @param value returns the value of the variable.
6223 * @param grffile NewGRF querying the variable
6224 * @return true iff the variable is known and the value is returned in 'value'.
6226 bool GetGlobalVariable(byte param
, uint32
*value
, const GRFFile
*grffile
)
6229 case 0x00: // current date
6230 *value
= max(_date
- DAYS_TILL_ORIGINAL_BASE_YEAR
, 0);
6233 case 0x01: // current year
6234 *value
= Clamp(_cur_year
, ORIGINAL_BASE_YEAR
, ORIGINAL_MAX_YEAR
) - ORIGINAL_BASE_YEAR
;
6237 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)
6239 ConvertDateToYMD(_date
, &ymd
);
6240 Date start_of_year
= ConvertYMDToDate(ymd
.year
, 0, 1);
6241 *value
= ymd
.month
| (ymd
.day
- 1) << 8 | (IsLeapYear(ymd
.year
) ? 1 << 15 : 0) | (_date
- start_of_year
) << 16;
6245 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
6246 *value
= _settings_game
.game_creation
.landscape
;
6249 case 0x06: // road traffic side, bit 4 clear=left, set=right
6250 *value
= _settings_game
.vehicle
.road_side
<< 4;
6253 case 0x09: // date fraction
6254 *value
= _date_fract
* 885;
6257 case 0x0A: // animation counter
6258 *value
= _tick_counter
;
6261 case 0x0B: { // TTDPatch version
6264 uint revision
= 1; // special case: 2.0.1 is 2.0.10
6266 *value
= (major
<< 24) | (minor
<< 20) | (revision
<< 16) | build
;
6270 case 0x0D: // TTD Version, 00=DOS, 01=Windows
6271 *value
= _cur
.grfconfig
->palette
& GRFP_USE_MASK
;
6274 case 0x0E: // Y-offset for train sprites
6275 *value
= _cur
.grffile
->traininfo_vehicle_pitch
;
6278 case 0x0F: // Rail track type cost factors
6280 SB(*value
, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL
)->cost_multiplier
); // normal rail
6281 if (_settings_game
.vehicle
.disable_elrails
) {
6282 /* skip elrail multiplier - disabled */
6283 SB(*value
, 8, 8, GetRailTypeInfo(RAILTYPE_MONO
)->cost_multiplier
); // monorail
6285 SB(*value
, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC
)->cost_multiplier
); // electified railway
6286 /* Skip monorail multiplier - no space in result */
6288 SB(*value
, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV
)->cost_multiplier
); // maglev
6291 case 0x11: // current rail tool type
6292 *value
= 0; // constant fake value to avoid desync
6295 case 0x12: // Game mode
6296 *value
= _game_mode
;
6299 /* case 0x13: // Tile refresh offset to left not implemented */
6300 /* case 0x14: // Tile refresh offset to right not implemented */
6301 /* case 0x15: // Tile refresh offset upwards not implemented */
6302 /* case 0x16: // Tile refresh offset downwards not implemented */
6303 /* case 0x17: // temperate snow line not implemented */
6305 case 0x1A: // Always -1
6309 case 0x1B: // Display options
6310 *value
= 0x3F; // constant fake value to avoid desync
6313 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
6317 case 0x1E: // Miscellaneous GRF features
6318 *value
= _misc_grf_features
;
6320 /* Add the local flags */
6321 assert(!HasBit(*value
, GMB_TRAIN_WIDTH_32_PIXELS
));
6322 if (_cur
.grffile
->traininfo_vehicle_width
== VEHICLEINFO_FULL_VEHICLE_WIDTH
) SetBit(*value
, GMB_TRAIN_WIDTH_32_PIXELS
);
6325 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
6327 case 0x20: { // snow line height
6328 byte snowline
= GetSnowLine();
6329 if (_settings_game
.game_creation
.landscape
== LT_ARCTIC
&& snowline
<= _settings_game
.construction
.max_heightlevel
) {
6330 *value
= Clamp(snowline
* (grffile
->grf_version
>= 8 ? 1 : TILE_HEIGHT
), 0, 0xFE);
6338 case 0x21: // OpenTTD version
6339 *value
= _openttd_newgrf_version
;
6342 case 0x22: // difficulty level
6346 case 0x23: // long format date
6350 case 0x24: // long format year
6354 default: return false;
6358 static uint32
GetParamVal(byte param
, uint32
*cond_val
)
6360 /* First handle variable common with VarAction2 */
6362 if (GetGlobalVariable(param
- 0x80, &value
, _cur
.grffile
)) return value
;
6364 /* Non-common variable */
6366 case 0x84: { // GRF loading stage
6369 if (_cur
.stage
> GLS_INIT
) SetBit(res
, 0);
6370 if (_cur
.stage
== GLS_RESERVE
) SetBit(res
, 8);
6371 if (_cur
.stage
== GLS_ACTIVATION
) SetBit(res
, 9);
6375 case 0x85: // TTDPatch flags, only for bit tests
6376 if (cond_val
== nullptr) {
6377 /* Supported in Action 0x07 and 0x09, not 0x0D */
6380 uint32 index
= *cond_val
/ 0x20;
6381 uint32 param_val
= index
< lengthof(_ttdpatch_flags
) ? _ttdpatch_flags
[index
] : 0;
6386 case 0x88: // GRF ID check
6389 /* case 0x99: Global ID offset not implemented */
6393 if (param
< 0x80) return _cur
.grffile
->GetParam(param
);
6395 /* In-game variable. */
6396 grfmsg(1, "Unsupported in-game variable 0x%02X", param
);
6402 static void CfgApply(ByteReader
*buf
)
6404 /* <06> <param-num> <param-size> <offset> ... <FF>
6406 * B param-num Number of parameter to substitute (First = "zero")
6407 * Ignored if that parameter was not specified in newgrf.cfg
6408 * B param-size How many bytes to replace. If larger than 4, the
6409 * bytes of the following parameter are used. In that
6410 * case, nothing is applied unless *all* parameters
6412 * B offset Offset into data from beginning of next sprite
6413 * to place where parameter is to be stored. */
6415 /* Preload the next sprite */
6416 size_t pos
= FioGetPos();
6417 uint32 num
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
6418 uint8 type
= FioReadByte();
6419 byte
*preload_sprite
= nullptr;
6421 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
6423 preload_sprite
= MallocT
<byte
>(num
);
6424 FioReadBlock(preload_sprite
, num
);
6427 /* Reset the file position to the start of the next sprite */
6428 FioSeekTo(pos
, SEEK_SET
);
6431 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
6432 free(preload_sprite
);
6436 GRFLocation
location(_cur
.grfconfig
->ident
.grfid
, _cur
.nfo_line
+ 1);
6437 GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.find(location
);
6438 if (it
!= _grf_line_to_action6_sprite_override
.end()) {
6439 free(preload_sprite
);
6440 preload_sprite
= _grf_line_to_action6_sprite_override
[location
];
6442 _grf_line_to_action6_sprite_override
[location
] = preload_sprite
;
6445 /* Now perform the Action 0x06 on our data. */
6454 /* Read the parameter to apply. 0xFF indicates no more data to change. */
6455 param_num
= buf
->ReadByte();
6456 if (param_num
== 0xFF) break;
6458 /* Get the size of the parameter to use. If the size covers multiple
6459 * double words, sequential parameter values are used. */
6460 param_size
= buf
->ReadByte();
6462 /* Bit 7 of param_size indicates we should add to the original value
6463 * instead of replacing it. */
6464 add_value
= HasBit(param_size
, 7);
6465 param_size
= GB(param_size
, 0, 7);
6467 /* Where to apply the data to within the pseudo sprite data. */
6468 offset
= buf
->ReadExtendedByte();
6470 /* If the parameter is a GRF parameter (not an internal variable) check
6471 * if it (and all further sequential parameters) has been defined. */
6472 if (param_num
< 0x80 && (param_num
+ (param_size
- 1) / 4) >= _cur
.grffile
->param_end
) {
6473 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num
+ (param_size
- 1) / 4));
6477 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size
, param_num
, offset
);
6480 for (i
= 0; i
< param_size
&& offset
+ i
< num
; i
++) {
6481 uint32 value
= GetParamVal(param_num
+ i
/ 4, nullptr);
6482 /* Reset carry flag for each iteration of the variable (only really
6483 * matters if param_size is greater than 4) */
6484 if (i
% 4 == 0) carry
= false;
6487 uint new_value
= preload_sprite
[offset
+ i
] + GB(value
, (i
% 4) * 8, 8) + (carry
? 1 : 0);
6488 preload_sprite
[offset
+ i
] = GB(new_value
, 0, 8);
6489 /* Check if the addition overflowed */
6490 carry
= new_value
>= 256;
6492 preload_sprite
[offset
+ i
] = GB(value
, (i
% 4) * 8, 8);
6499 * Disable a static NewGRF when it is influencing another (non-static)
6500 * NewGRF as this could cause desyncs.
6502 * We could just tell the NewGRF querying that the file doesn't exist,
6503 * but that might give unwanted results. Disabling the NewGRF gives the
6504 * best result as no NewGRF author can complain about that.
6505 * @param c The NewGRF to disable.
6507 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig
*c
)
6509 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC
, c
);
6510 error
->data
= stredup(_cur
.grfconfig
->GetName());
6515 static void SkipIf(ByteReader
*buf
)
6517 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6524 uint32 cond_val
= 0;
6528 uint8 param
= buf
->ReadByte();
6529 uint8 paramsize
= buf
->ReadByte();
6530 uint8 condtype
= buf
->ReadByte();
6533 /* Always 1 for bit tests, the given value should be ignored. */
6537 switch (paramsize
) {
6538 case 8: cond_val
= buf
->ReadDWord(); mask
= buf
->ReadDWord(); break;
6539 case 4: cond_val
= buf
->ReadDWord(); mask
= 0xFFFFFFFF; break;
6540 case 2: cond_val
= buf
->ReadWord(); mask
= 0x0000FFFF; break;
6541 case 1: cond_val
= buf
->ReadByte(); mask
= 0x000000FF; break;
6545 if (param
< 0x80 && _cur
.grffile
->param_end
<= param
) {
6546 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param
);
6550 uint32 param_val
= GetParamVal(param
, &cond_val
);
6552 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype
, param_val
, cond_val
);
6555 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6556 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6557 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6558 * So, when the condition type is one of those, the specific variable
6559 * 0x88 code is skipped, so the "general" code for the cargo
6560 * availability conditions kicks in.
6562 if (param
== 0x88 && (condtype
< 0x0B || condtype
> 0x0E)) {
6565 GRFConfig
*c
= GetGRFConfig(cond_val
, mask
);
6567 if (c
!= nullptr && HasBit(c
->flags
, GCF_STATIC
) && !HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
) && _networking
) {
6568 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c
);
6572 if (condtype
!= 10 && c
== nullptr) {
6573 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val
));
6578 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6579 case 0x06: // Is GRFID active?
6580 result
= c
->status
== GCS_ACTIVATED
;
6583 case 0x07: // Is GRFID non-active?
6584 result
= c
->status
!= GCS_ACTIVATED
;
6587 case 0x08: // GRFID is not but will be active?
6588 result
= c
->status
== GCS_INITIALISED
;
6591 case 0x09: // GRFID is or will be active?
6592 result
= c
->status
== GCS_ACTIVATED
|| c
->status
== GCS_INITIALISED
;
6595 case 0x0A: // GRFID is not nor will be active
6596 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6597 result
= c
== nullptr || c
->status
== GCS_DISABLED
|| c
->status
== GCS_NOT_FOUND
;
6600 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype
); return;
6603 /* Parameter or variable tests */
6605 case 0x00: result
= !!(param_val
& (1 << cond_val
));
6607 case 0x01: result
= !(param_val
& (1 << cond_val
));
6609 case 0x02: result
= (param_val
& mask
) == cond_val
;
6611 case 0x03: result
= (param_val
& mask
) != cond_val
;
6613 case 0x04: result
= (param_val
& mask
) < cond_val
;
6615 case 0x05: result
= (param_val
& mask
) > cond_val
;
6617 case 0x0B: result
= GetCargoIDByLabel(BSWAP32(cond_val
)) == CT_INVALID
;
6619 case 0x0C: result
= GetCargoIDByLabel(BSWAP32(cond_val
)) != CT_INVALID
;
6621 case 0x0D: result
= GetRailTypeByLabel(BSWAP32(cond_val
)) == INVALID_RAILTYPE
;
6623 case 0x0E: result
= GetRailTypeByLabel(BSWAP32(cond_val
)) != INVALID_RAILTYPE
;
6626 RoadType rt
= GetRoadTypeByLabel(BSWAP32(cond_val
));
6627 result
= rt
== INVALID_ROADTYPE
|| !RoadTypeIsRoad(rt
);
6631 RoadType rt
= GetRoadTypeByLabel(BSWAP32(cond_val
));
6632 result
= rt
!= INVALID_ROADTYPE
&& RoadTypeIsRoad(rt
);
6636 RoadType rt
= GetRoadTypeByLabel(BSWAP32(cond_val
));
6637 result
= rt
== INVALID_ROADTYPE
|| !RoadTypeIsTram(rt
);
6641 RoadType rt
= GetRoadTypeByLabel(BSWAP32(cond_val
));
6642 result
= rt
!= INVALID_ROADTYPE
&& RoadTypeIsTram(rt
);
6645 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype
); return;
6650 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6654 uint8 numsprites
= buf
->ReadByte();
6656 /* numsprites can be a GOTO label if it has been defined in the GRF
6657 * file. The jump will always be the first matching label that follows
6658 * the current nfo_line. If no matching label is found, the first matching
6659 * label in the file is used. */
6660 GRFLabel
*choice
= nullptr;
6661 for (GRFLabel
*label
= _cur
.grffile
->label
; label
!= nullptr; label
= label
->next
) {
6662 if (label
->label
!= numsprites
) continue;
6664 /* Remember a goto before the current line */
6665 if (choice
== nullptr) choice
= label
;
6666 /* If we find a label here, this is definitely good */
6667 if (label
->nfo_line
> _cur
.nfo_line
) {
6673 if (choice
!= nullptr) {
6674 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice
->label
, choice
->nfo_line
);
6675 FioSeekTo(choice
->pos
, SEEK_SET
);
6676 _cur
.nfo_line
= choice
->nfo_line
;
6680 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites
);
6681 _cur
.skip_sprites
= numsprites
;
6682 if (_cur
.skip_sprites
== 0) {
6683 /* Zero means there are no sprites to skip, so
6684 * we use -1 to indicate that all further
6685 * sprites should be skipped. */
6686 _cur
.skip_sprites
= -1;
6688 /* If an action 8 hasn't been encountered yet, disable the grf. */
6689 if (_cur
.grfconfig
->status
!= (_cur
.stage
< GLS_RESERVE
? GCS_INITIALISED
: GCS_ACTIVATED
)) {
6696 /* Action 0x08 (GLS_FILESCAN) */
6697 static void ScanInfo(ByteReader
*buf
)
6699 uint8 grf_version
= buf
->ReadByte();
6700 uint32 grfid
= buf
->ReadDWord();
6701 const char *name
= buf
->ReadString();
6703 _cur
.grfconfig
->ident
.grfid
= grfid
;
6705 if (grf_version
< 2 || grf_version
> 8) {
6706 SetBit(_cur
.grfconfig
->flags
, GCF_INVALID
);
6707 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
);
6710 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6711 if (GB(grfid
, 0, 8) == 0xFF) SetBit(_cur
.grfconfig
->flags
, GCF_SYSTEM
);
6713 AddGRFTextToList(&_cur
.grfconfig
->name
->text
, 0x7F, grfid
, false, name
);
6715 if (buf
->HasData()) {
6716 const char *info
= buf
->ReadString();
6717 AddGRFTextToList(&_cur
.grfconfig
->info
->text
, 0x7F, grfid
, true, info
);
6720 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6721 _cur
.skip_sprites
= -1;
6725 static void GRFInfo(ByteReader
*buf
)
6727 /* <08> <version> <grf-id> <name> <info>
6729 * B version newgrf version, currently 06
6730 * 4*B grf-id globally unique ID of this .grf file
6731 * S name name of this .grf set
6732 * S info string describing the set, and e.g. author and copyright */
6734 uint8 version
= buf
->ReadByte();
6735 uint32 grfid
= buf
->ReadDWord();
6736 const char *name
= buf
->ReadString();
6738 if (_cur
.stage
< GLS_RESERVE
&& _cur
.grfconfig
->status
!= GCS_UNKNOWN
) {
6739 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8
);
6743 if (_cur
.grffile
->grfid
!= grfid
) {
6744 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
));
6745 _cur
.grffile
->grfid
= grfid
;
6748 _cur
.grffile
->grf_version
= version
;
6749 _cur
.grfconfig
->status
= _cur
.stage
< GLS_RESERVE
? GCS_INITIALISED
: GCS_ACTIVATED
;
6751 /* Do swap the GRFID for displaying purposes since people expect that */
6752 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
);
6756 static void SpriteReplace(ByteReader
*buf
)
6758 /* <0A> <num-sets> <set1> [<set2> ...]
6759 * <set>: <num-sprites> <first-sprite>
6761 * B num-sets How many sets of sprites to replace.
6763 * B num-sprites How many sprites are in this set
6764 * W first-sprite First sprite number to replace */
6766 uint8 num_sets
= buf
->ReadByte();
6768 for (uint i
= 0; i
< num_sets
; i
++) {
6769 uint8 num_sprites
= buf
->ReadByte();
6770 uint16 first_sprite
= buf
->ReadWord();
6772 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6773 i
, num_sprites
, first_sprite
6776 for (uint j
= 0; j
< num_sprites
; j
++) {
6777 int load_index
= first_sprite
+ j
;
6779 LoadNextSprite(load_index
, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
); // XXX
6781 /* Shore sprites now located at different addresses.
6782 * So detect when the old ones get replaced. */
6783 if (IsInsideMM(load_index
, SPR_ORIGINALSHORE_START
, SPR_ORIGINALSHORE_END
+ 1)) {
6784 if (_loaded_newgrf_features
.shore
!= SHORE_REPLACE_ACTION_5
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_A
;
6790 /* Action 0x0A (SKIP) */
6791 static void SkipActA(ByteReader
*buf
)
6793 uint8 num_sets
= buf
->ReadByte();
6795 for (uint i
= 0; i
< num_sets
; i
++) {
6796 /* Skip the sprites this replaces */
6797 _cur
.skip_sprites
+= buf
->ReadByte();
6798 /* But ignore where they go */
6802 grfmsg(3, "SkipActA: Skipping %d sprites", _cur
.skip_sprites
);
6806 static void GRFLoadError(ByteReader
*buf
)
6808 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6810 * B severity 00: notice, continue loading grf file
6811 * 01: warning, continue loading grf file
6812 * 02: error, but continue loading grf file, and attempt
6813 * loading grf again when loading or starting next game
6814 * 03: error, abort loading and prevent loading again in
6815 * the future (only when restarting the patch)
6816 * B language-id see action 4, use 1F for built-in error messages
6817 * B message-id message to show, see below
6818 * S message for custom messages (message-id FF), text of the message
6819 * not present for built-in messages.
6820 * V data additional data for built-in (or custom) messages
6821 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6823 static const StringID msgstr
[] = {
6824 STR_NEWGRF_ERROR_VERSION_NUMBER
,
6825 STR_NEWGRF_ERROR_DOS_OR_WINDOWS
,
6826 STR_NEWGRF_ERROR_UNSET_SWITCH
,
6827 STR_NEWGRF_ERROR_INVALID_PARAMETER
,
6828 STR_NEWGRF_ERROR_LOAD_BEFORE
,
6829 STR_NEWGRF_ERROR_LOAD_AFTER
,
6830 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER
,
6833 static const StringID sevstr
[] = {
6834 STR_NEWGRF_ERROR_MSG_INFO
,
6835 STR_NEWGRF_ERROR_MSG_WARNING
,
6836 STR_NEWGRF_ERROR_MSG_ERROR
,
6837 STR_NEWGRF_ERROR_MSG_FATAL
6840 byte severity
= buf
->ReadByte();
6841 byte lang
= buf
->ReadByte();
6842 byte message_id
= buf
->ReadByte();
6844 /* Skip the error if it isn't valid for the current language. */
6845 if (!CheckGrfLangID(lang
, _cur
.grffile
->grf_version
)) return;
6847 /* Skip the error until the activation stage unless bit 7 of the severity
6849 if (!HasBit(severity
, 7) && _cur
.stage
== GLS_INIT
) {
6850 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur
.stage
);
6853 ClrBit(severity
, 7);
6855 if (severity
>= lengthof(sevstr
)) {
6856 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity
);
6858 } else if (severity
== 3) {
6859 /* This is a fatal error, so make sure the GRF is deactivated and no
6860 * more of it gets loaded. */
6863 /* Make sure we show fatal errors, instead of silly infos from before */
6864 delete _cur
.grfconfig
->error
;
6865 _cur
.grfconfig
->error
= nullptr;
6868 if (message_id
>= lengthof(msgstr
) && message_id
!= 0xFF) {
6869 grfmsg(7, "GRFLoadError: Invalid message id.");
6873 if (buf
->Remaining() <= 1) {
6874 grfmsg(7, "GRFLoadError: No message data supplied.");
6878 /* For now we can only show one message per newgrf file. */
6879 if (_cur
.grfconfig
->error
!= nullptr) return;
6881 GRFError
*error
= new GRFError(sevstr
[severity
]);
6883 if (message_id
== 0xFF) {
6884 /* This is a custom error message. */
6885 if (buf
->HasData()) {
6886 const char *message
= buf
->ReadString();
6888 error
->custom_message
= TranslateTTDPatchCodes(_cur
.grffile
->grfid
, lang
, true, message
, nullptr, SCC_RAW_STRING_POINTER
);
6890 grfmsg(7, "GRFLoadError: No custom message supplied.");
6891 error
->custom_message
= stredup("");
6894 error
->message
= msgstr
[message_id
];
6897 if (buf
->HasData()) {
6898 const char *data
= buf
->ReadString();
6900 error
->data
= TranslateTTDPatchCodes(_cur
.grffile
->grfid
, lang
, true, data
);
6902 grfmsg(7, "GRFLoadError: No message data supplied.");
6903 error
->data
= stredup("");
6906 /* Only two parameter numbers can be used in the string. */
6907 for (uint i
= 0; i
< lengthof(error
->param_value
) && buf
->HasData(); i
++) {
6908 uint param_number
= buf
->ReadByte();
6909 error
->param_value
[i
] = _cur
.grffile
->GetParam(param_number
);
6912 _cur
.grfconfig
->error
= error
;
6916 static void GRFComment(ByteReader
*buf
)
6918 /* <0C> [<ignored...>]
6920 * V ignored Anything following the 0C is ignored */
6922 if (!buf
->HasData()) return;
6924 const char *text
= buf
->ReadString();
6925 grfmsg(2, "GRFComment: %s", text
);
6928 /* Action 0x0D (GLS_SAFETYSCAN) */
6929 static void SafeParamSet(ByteReader
*buf
)
6931 uint8 target
= buf
->ReadByte();
6933 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6934 if (target
< 0x80 || target
== 0x9E) return;
6936 /* GRM could be unsafe, but as here it can only happen after other GRFs
6937 * are loaded, it should be okay. If the GRF tried to use the slots it
6938 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6939 * sprites is considered safe. */
6941 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
6943 /* Skip remainder of GRF */
6944 _cur
.skip_sprites
= -1;
6948 static uint32
GetPatchVariable(uint8 param
)
6951 /* start year - 1920 */
6952 case 0x0B: return max(_settings_game
.game_creation
.starting_year
, ORIGINAL_BASE_YEAR
) - ORIGINAL_BASE_YEAR
;
6954 /* freight trains weight factor */
6955 case 0x0E: return _settings_game
.vehicle
.freight_trains
;
6957 /* empty wagon speed increase */
6958 case 0x0F: return 0;
6960 /* plane speed factor; our patch option is reversed from TTDPatch's,
6961 * the following is good for 1x, 2x and 4x (most common?) and...
6962 * well not really for 3x. */
6964 switch (_settings_game
.vehicle
.plane_speed
) {
6973 /* 2CC colourmap base sprite */
6974 case 0x11: return SPR_2CCMAP_BASE
;
6976 /* map size: format = -MABXYSS
6977 * M : the type of map
6978 * bit 0 : set : squared map. Bit 1 is now not relevant
6979 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6980 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6981 * clear : X is the bigger edge.
6982 * A : minimum edge(log2) of the map
6983 * B : maximum edge(log2) of the map
6984 * XY : edges(log2) of each side of the map.
6985 * SS : combination of both X and Y, thus giving the size(log2) of the map
6989 byte log_X
= MapLogX() - 6; // subtraction is required to make the minimal size (64) zero based
6990 byte log_Y
= MapLogY() - 6;
6991 byte max_edge
= max(log_X
, log_Y
);
6993 if (log_X
== log_Y
) { // we have a squared map, since both edges are identical
6994 SetBit(map_bits
, 0);
6996 if (max_edge
== log_Y
) SetBit(map_bits
, 1); // edge Y been the biggest, mark it
6999 return (map_bits
<< 24) | (min(log_X
, log_Y
) << 20) | (max_edge
<< 16) |
7000 (log_X
<< 12) | (log_Y
<< 8) | (log_X
+ log_Y
);
7003 /* The maximum height of the map. */
7005 return _settings_game
.construction
.max_heightlevel
;
7007 /* Extra foundations base sprite */
7009 return SPR_SLOPES_BASE
;
7011 /* Shore base sprite */
7013 return SPR_SHORE_BASE
;
7016 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param
);
7022 static uint32
PerformGRM(uint32
*grm
, uint16 num_ids
, uint16 count
, uint8 op
, uint8 target
, const char *type
)
7028 /* Return GRFID of set that reserved ID */
7029 return grm
[_cur
.grffile
->GetParam(target
)];
7032 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
7033 if (op
== 2 || op
== 3) start
= _cur
.grffile
->GetParam(target
);
7035 for (uint i
= start
; i
< num_ids
; i
++) {
7039 if (op
== 2 || op
== 3) break;
7044 if (size
== count
) break;
7047 if (size
== count
) {
7048 /* Got the slot... */
7049 if (op
== 0 || op
== 3) {
7050 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count
, type
, start
);
7051 for (uint i
= 0; i
< count
; i
++) grm
[start
+ i
] = _cur
.grffile
->grfid
;
7056 /* Unable to allocate */
7057 if (op
!= 4 && op
!= 5) {
7058 /* Deactivate GRF */
7059 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count
, type
);
7060 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED
);
7064 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count
, type
);
7069 /** Action 0x0D: Set parameter */
7070 static void ParamSet(ByteReader
*buf
)
7072 /* <0D> <target> <operation> <source1> <source2> [<data>]
7074 * B target parameter number where result is stored
7075 * B operation operation to perform, see below
7076 * B source1 first source operand
7077 * B source2 second source operand
7078 * D data data to use in the calculation, not necessary
7079 * if both source1 and source2 refer to actual parameters
7082 * 00 Set parameter equal to source1
7083 * 01 Addition, source1 + source2
7084 * 02 Subtraction, source1 - source2
7085 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
7086 * 04 Signed multiplication, source1 * source2 (both signed)
7087 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
7088 * signed quantity; left shift if positive and right shift if
7089 * negative, source1 is unsigned)
7090 * 06 Signed bit shift, source1 by source2
7091 * (source2 like in 05, and source1 as well)
7094 uint8 target
= buf
->ReadByte();
7095 uint8 oper
= buf
->ReadByte();
7096 uint32 src1
= buf
->ReadByte();
7097 uint32 src2
= buf
->ReadByte();
7100 if (buf
->Remaining() >= 4) data
= buf
->ReadDWord();
7102 /* You can add 80 to the operation to make it apply only if the target
7103 * is not defined yet. In this respect, a parameter is taken to be
7104 * defined if any of the following applies:
7105 * - it has been set to any value in the newgrf(w).cfg parameter list
7106 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
7107 * an earlier action D */
7108 if (HasBit(oper
, 7)) {
7109 if (target
< 0x80 && target
< _cur
.grffile
->param_end
) {
7110 grfmsg(7, "ParamSet: Param %u already defined, skipping", target
);
7114 oper
= GB(oper
, 0, 7);
7118 if (GB(data
, 0, 8) == 0xFF) {
7119 if (data
== 0x0000FFFF) {
7120 /* Patch variables */
7121 src1
= GetPatchVariable(src1
);
7123 /* GRF Resource Management */
7125 uint8 feature
= GB(data
, 8, 8);
7126 uint16 count
= GB(data
, 16, 16);
7128 if (_cur
.stage
== GLS_RESERVE
) {
7129 if (feature
== 0x08) {
7130 /* General sprites */
7132 /* Check if the allocated sprites will fit below the original sprite limit */
7133 if (_cur
.spriteid
+ count
>= 16384) {
7134 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count
);
7135 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED
);
7139 /* Reserve space at the current sprite ID */
7140 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count
, _cur
.spriteid
);
7141 _grm_sprites
[GRFLocation(_cur
.grffile
->grfid
, _cur
.nfo_line
)] = _cur
.spriteid
;
7142 _cur
.spriteid
+= count
;
7145 /* Ignore GRM result during reservation */
7147 } else if (_cur
.stage
== GLS_ACTIVATION
) {
7149 case 0x00: // Trains
7150 case 0x01: // Road Vehicles
7152 case 0x03: // Aircraft
7153 if (!_settings_game
.vehicle
.dynamic_engines
) {
7154 src1
= PerformGRM(&_grm_engines
[_engine_offsets
[feature
]], _engine_counts
[feature
], count
, op
, target
, "vehicles");
7155 if (_cur
.skip_sprites
== -1) return;
7157 /* GRM does not apply for dynamic engine allocation. */
7161 src1
= _cur
.grffile
->GetParam(target
);
7171 case 0x08: // General sprites
7174 /* Return space reserved during reservation stage */
7175 src1
= _grm_sprites
[GRFLocation(_cur
.grffile
->grfid
, _cur
.nfo_line
)];
7176 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1
);
7180 src1
= _cur
.spriteid
;
7184 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op
);
7190 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
7191 src1
= PerformGRM(_grm_cargoes
, NUM_CARGO
* 2, count
, op
, target
, "cargoes");
7192 if (_cur
.skip_sprites
== -1) return;
7195 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature
); return;
7198 /* Ignore GRM during initialization */
7203 /* Read another GRF File's parameter */
7204 const GRFFile
*file
= GetFileByGRFID(data
);
7205 GRFConfig
*c
= GetGRFConfig(data
);
7206 if (c
!= nullptr && HasBit(c
->flags
, GCF_STATIC
) && !HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
) && _networking
) {
7207 /* Disable the read GRF if it is a static NewGRF. */
7208 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c
);
7210 } else if (file
== nullptr || c
== nullptr || c
->status
== GCS_DISABLED
) {
7212 } else if (src1
== 0xFE) {
7215 src1
= file
->GetParam(src1
);
7219 /* The source1 and source2 operands refer to the grf parameter number
7220 * like in action 6 and 7. In addition, they can refer to the special
7221 * variables available in action 7, or they can be FF to use the value
7222 * of <data>. If referring to parameters that are undefined, a value
7223 * of 0 is used instead. */
7224 src1
= (src1
== 0xFF) ? data
: GetParamVal(src1
, nullptr);
7225 src2
= (src2
== 0xFF) ? data
: GetParamVal(src2
, nullptr);
7247 res
= (int32
)src1
* (int32
)src2
;
7251 if ((int32
)src2
< 0) {
7252 res
= src1
>> -(int32
)src2
;
7254 res
= src1
<< (src2
& 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
7259 if ((int32
)src2
< 0) {
7260 res
= (int32
)src1
>> -(int32
)src2
;
7262 res
= (int32
)src1
<< (src2
& 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
7266 case 0x07: // Bitwise AND
7270 case 0x08: // Bitwise OR
7274 case 0x09: // Unsigned division
7282 case 0x0A: // Signed division
7286 res
= (int32
)src1
/ (int32
)src2
;
7290 case 0x0B: // Unsigned modulo
7298 case 0x0C: // Signed modulo
7302 res
= (int32
)src1
% (int32
)src2
;
7306 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper
); return;
7310 case 0x8E: // Y-Offset for train sprites
7311 _cur
.grffile
->traininfo_vehicle_pitch
= res
;
7314 case 0x8F: { // Rail track type cost factors
7315 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
7316 _railtypes
[RAILTYPE_RAIL
].cost_multiplier
= GB(res
, 0, 8);
7317 if (_settings_game
.vehicle
.disable_elrails
) {
7318 _railtypes
[RAILTYPE_ELECTRIC
].cost_multiplier
= GB(res
, 0, 8);
7319 _railtypes
[RAILTYPE_MONO
].cost_multiplier
= GB(res
, 8, 8);
7321 _railtypes
[RAILTYPE_ELECTRIC
].cost_multiplier
= GB(res
, 8, 8);
7322 _railtypes
[RAILTYPE_MONO
].cost_multiplier
= GB(res
, 16, 8);
7324 _railtypes
[RAILTYPE_MAGLEV
].cost_multiplier
= GB(res
, 16, 8);
7328 /* not implemented */
7329 case 0x93: // Tile refresh offset to left -- Intended to allow support for larger sprites, not necessary for OTTD
7330 case 0x94: // Tile refresh offset to right
7331 case 0x95: // Tile refresh offset upwards
7332 case 0x96: // Tile refresh offset downwards
7333 case 0x97: // Snow line height -- Better supported by feature 8 property 10h (snow line table) TODO: implement by filling the entire snow line table with the given value
7334 case 0x99: // Global ID offset -- Not necessary since IDs are remapped automatically
7335 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target
);
7338 case 0x9E: // Miscellaneous GRF features
7339 /* Set train list engine width */
7340 _cur
.grffile
->traininfo_vehicle_width
= HasBit(res
, GMB_TRAIN_WIDTH_32_PIXELS
) ? VEHICLEINFO_FULL_VEHICLE_WIDTH
: TRAININFO_DEFAULT_VEHICLE_WIDTH
;
7341 /* Remove the local flags from the global flags */
7342 ClrBit(res
, GMB_TRAIN_WIDTH_32_PIXELS
);
7344 /* Only copy safe bits for static grfs */
7345 if (HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
)) {
7346 uint32 safe_bits
= 0;
7347 SetBit(safe_bits
, GMB_SECOND_ROCKY_TILE_SET
);
7349 _misc_grf_features
= (_misc_grf_features
& ~safe_bits
) | (res
& safe_bits
);
7351 _misc_grf_features
= res
;
7355 case 0x9F: // locale-dependent settings
7356 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target
);
7360 if (target
< 0x80) {
7361 _cur
.grffile
->param
[target
] = res
;
7362 /* param is zeroed by default */
7363 if (target
+ 1U > _cur
.grffile
->param_end
) _cur
.grffile
->param_end
= target
+ 1;
7365 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target
);
7371 /* Action 0x0E (GLS_SAFETYSCAN) */
7372 static void SafeGRFInhibit(ByteReader
*buf
)
7374 /* <0E> <num> <grfids...>
7376 * B num Number of GRFIDs that follow
7377 * D grfids GRFIDs of the files to deactivate */
7379 uint8 num
= buf
->ReadByte();
7381 for (uint i
= 0; i
< num
; i
++) {
7382 uint32 grfid
= buf
->ReadDWord();
7384 /* GRF is unsafe it if tries to deactivate other GRFs */
7385 if (grfid
!= _cur
.grfconfig
->ident
.grfid
) {
7386 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
7388 /* Skip remainder of GRF */
7389 _cur
.skip_sprites
= -1;
7397 static void GRFInhibit(ByteReader
*buf
)
7399 /* <0E> <num> <grfids...>
7401 * B num Number of GRFIDs that follow
7402 * D grfids GRFIDs of the files to deactivate */
7404 uint8 num
= buf
->ReadByte();
7406 for (uint i
= 0; i
< num
; i
++) {
7407 uint32 grfid
= buf
->ReadDWord();
7408 GRFConfig
*file
= GetGRFConfig(grfid
);
7410 /* Unset activation flag */
7411 if (file
!= nullptr && file
!= _cur
.grfconfig
) {
7412 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file
->filename
);
7413 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED
, file
);
7414 error
->data
= stredup(_cur
.grfconfig
->GetName());
7419 /** Action 0x0F - Define Town names */
7420 static void FeatureTownName(ByteReader
*buf
)
7422 /* <0F> <id> <style-name> <num-parts> <parts>
7424 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
7425 * V style-name Name of the style (only for final definition)
7426 * B num-parts Number of parts in this definition
7427 * V parts The parts */
7429 uint32 grfid
= _cur
.grffile
->grfid
;
7431 GRFTownName
*townname
= AddGRFTownName(grfid
);
7433 byte id
= buf
->ReadByte();
7434 grfmsg(6, "FeatureTownName: definition 0x%02X", id
& 0x7F);
7436 if (HasBit(id
, 7)) {
7437 /* Final definition */
7439 bool new_scheme
= _cur
.grffile
->grf_version
>= 7;
7441 byte lang
= buf
->ReadByte();
7443 byte nb_gen
= townname
->nb_gen
;
7447 const char *name
= buf
->ReadString();
7449 char *lang_name
= TranslateTTDPatchCodes(grfid
, lang
, false, name
);
7450 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang
, lang_name
);
7453 townname
->name
[nb_gen
] = AddGRFString(grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
7455 lang
= buf
->ReadByte();
7456 } while (lang
!= 0);
7457 townname
->id
[nb_gen
] = id
;
7461 byte nb
= buf
->ReadByte();
7462 grfmsg(6, "FeatureTownName: %u parts", nb
);
7464 townname
->nbparts
[id
] = nb
;
7465 townname
->partlist
[id
] = CallocT
<NamePartList
>(nb
);
7467 for (int i
= 0; i
< nb
; i
++) {
7468 byte nbtext
= buf
->ReadByte();
7469 townname
->partlist
[id
][i
].bitstart
= buf
->ReadByte();
7470 townname
->partlist
[id
][i
].bitcount
= buf
->ReadByte();
7471 townname
->partlist
[id
][i
].maxprob
= 0;
7472 townname
->partlist
[id
][i
].partcount
= nbtext
;
7473 townname
->partlist
[id
][i
].parts
= CallocT
<NamePart
>(nbtext
);
7474 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
);
7476 for (int j
= 0; j
< nbtext
; j
++) {
7477 byte prob
= buf
->ReadByte();
7479 if (HasBit(prob
, 7)) {
7480 byte ref_id
= buf
->ReadByte();
7482 if (townname
->nbparts
[ref_id
] == 0) {
7483 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id
);
7484 DelGRFTownName(grfid
);
7485 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID
);
7489 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i
, j
, ref_id
, prob
& 0x7F);
7490 townname
->partlist
[id
][i
].parts
[j
].data
.id
= ref_id
;
7492 const char *text
= buf
->ReadString();
7493 townname
->partlist
[id
][i
].parts
[j
].data
.text
= TranslateTTDPatchCodes(grfid
, 0, false, text
);
7494 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i
, j
, townname
->partlist
[id
][i
].parts
[j
].data
.text
, prob
);
7496 townname
->partlist
[id
][i
].parts
[j
].prob
= prob
;
7497 townname
->partlist
[id
][i
].maxprob
+= GB(prob
, 0, 7);
7499 grfmsg(6, "FeatureTownName: part %d, total probability %d", i
, townname
->partlist
[id
][i
].maxprob
);
7503 /** Action 0x10 - Define goto label */
7504 static void DefineGotoLabel(ByteReader
*buf
)
7506 /* <10> <label> [<comment>]
7508 * B label The label to define
7509 * V comment Optional comment - ignored */
7511 byte nfo_label
= buf
->ReadByte();
7513 GRFLabel
*label
= MallocT
<GRFLabel
>(1);
7514 label
->label
= nfo_label
;
7515 label
->nfo_line
= _cur
.nfo_line
;
7516 label
->pos
= FioGetPos();
7517 label
->next
= nullptr;
7519 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7520 if (_cur
.grffile
->label
== nullptr) {
7521 _cur
.grffile
->label
= label
;
7523 /* Attach the label to the end of the list */
7525 for (l
= _cur
.grffile
->label
; l
->next
!= nullptr; l
= l
->next
) {}
7529 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label
->label
);
7533 * Process a sound import from another GRF file.
7534 * @param sound Destination for sound.
7536 static void ImportGRFSound(SoundEntry
*sound
)
7538 const GRFFile
*file
;
7539 uint32 grfid
= FioReadDword();
7540 SoundID sound_id
= FioReadWord();
7542 file
= GetFileByGRFID(grfid
);
7543 if (file
== nullptr || file
->sound_offset
== 0) {
7544 grfmsg(1, "ImportGRFSound: Source file not available");
7548 if (sound_id
>= file
->num_sounds
) {
7549 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id
);
7553 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id
, file
->sound_offset
+ sound_id
, grfid
);
7555 *sound
= *GetSound(file
->sound_offset
+ sound_id
);
7557 /* Reset volume and priority, which TTDPatch doesn't copy */
7558 sound
->volume
= 128;
7559 sound
->priority
= 0;
7563 * Load a sound from a file.
7564 * @param offs File offset to read sound from.
7565 * @param sound Destination for sound.
7567 static void LoadGRFSound(size_t offs
, SoundEntry
*sound
)
7569 /* Set default volume and priority */
7570 sound
->volume
= 0x80;
7571 sound
->priority
= 0;
7573 if (offs
!= SIZE_MAX
) {
7574 /* Sound is present in the NewGRF. */
7575 sound
->file_slot
= _cur
.file_index
;
7576 sound
->file_offset
= offs
;
7577 sound
->grf_container_ver
= _cur
.grf_container_ver
;
7582 static void GRFSound(ByteReader
*buf
)
7586 * W num Number of sound files that follow */
7588 uint16 num
= buf
->ReadWord();
7589 if (num
== 0) return;
7592 if (_cur
.grffile
->sound_offset
== 0) {
7593 _cur
.grffile
->sound_offset
= GetNumSounds();
7594 _cur
.grffile
->num_sounds
= num
;
7595 sound
= AllocateSound(num
);
7597 sound
= GetSound(_cur
.grffile
->sound_offset
);
7600 for (int i
= 0; i
< num
; i
++) {
7603 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7604 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7605 bool invalid
= i
>= _cur
.grffile
->num_sounds
;
7607 size_t offs
= FioGetPos();
7609 uint32 len
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
7610 byte type
= FioReadByte();
7612 if (_cur
.grf_container_ver
>= 2 && type
== 0xFD) {
7613 /* Reference to sprite section. */
7615 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7617 } else if (len
!= 4) {
7618 grfmsg(1, "GRFSound: Invalid sprite section import");
7621 uint32 id
= FioReadDword();
7622 if (_cur
.stage
== GLS_INIT
) LoadGRFSound(GetGRFSpriteOffset(id
), sound
+ i
);
7628 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7630 SkipSpriteData(type
, len
- 8);
7635 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7639 byte action
= FioReadByte();
7642 /* Allocate sound only in init stage. */
7643 if (_cur
.stage
== GLS_INIT
) {
7644 if (_cur
.grf_container_ver
>= 2) {
7645 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7647 LoadGRFSound(offs
, sound
+ i
);
7650 FioSkipBytes(len
- 1); // already read <action>
7654 if (_cur
.stage
== GLS_ACTIVATION
) {
7655 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7656 * importing sounds, so this is probably all wrong... */
7657 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7658 ImportGRFSound(sound
+ i
);
7660 FioSkipBytes(len
- 1); // already read <action>
7665 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action
);
7666 FioSkipBytes(len
- 1); // already read <action>
7672 /* Action 0x11 (SKIP) */
7673 static void SkipAct11(ByteReader
*buf
)
7677 * W num Number of sound files that follow */
7679 _cur
.skip_sprites
= buf
->ReadWord();
7681 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur
.skip_sprites
);
7685 static void LoadFontGlyph(ByteReader
*buf
)
7687 /* <12> <num_def> <font_size> <num_char> <base_char>
7689 * B num_def Number of definitions
7690 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7691 * B num_char Number of consecutive glyphs
7692 * W base_char First character index */
7694 uint8 num_def
= buf
->ReadByte();
7696 for (uint i
= 0; i
< num_def
; i
++) {
7697 FontSize size
= (FontSize
)buf
->ReadByte();
7698 uint8 num_char
= buf
->ReadByte();
7699 uint16 base_char
= buf
->ReadWord();
7701 if (size
>= FS_END
) {
7702 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size
);
7705 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char
, base_char
, size
);
7707 for (uint c
= 0; c
< num_char
; c
++) {
7708 if (size
< FS_END
) SetUnicodeGlyph(size
, base_char
+ c
, _cur
.spriteid
);
7710 LoadNextSprite(_cur
.spriteid
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
7715 /** Action 0x12 (SKIP) */
7716 static void SkipAct12(ByteReader
*buf
)
7718 /* <12> <num_def> <font_size> <num_char> <base_char>
7720 * B num_def Number of definitions
7721 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7722 * B num_char Number of consecutive glyphs
7723 * W base_char First character index */
7725 uint8 num_def
= buf
->ReadByte();
7727 for (uint i
= 0; i
< num_def
; i
++) {
7728 /* Ignore 'size' byte */
7731 /* Sum up number of characters */
7732 _cur
.skip_sprites
+= buf
->ReadByte();
7734 /* Ignore 'base_char' word */
7738 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur
.skip_sprites
);
7742 static void TranslateGRFStrings(ByteReader
*buf
)
7744 /* <13> <grfid> <num-ent> <offset> <text...>
7746 * 4*B grfid The GRFID of the file whose texts are to be translated
7747 * B num-ent Number of strings
7748 * W offset First text ID
7749 * S text... Zero-terminated strings */
7751 uint32 grfid
= buf
->ReadDWord();
7752 const GRFConfig
*c
= GetGRFConfig(grfid
);
7753 if (c
== nullptr || (c
->status
!= GCS_INITIALISED
&& c
->status
!= GCS_ACTIVATED
)) {
7754 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid
));
7758 if (c
->status
== GCS_INITIALISED
) {
7759 /* If the file is not active but will be activated later, give an error
7760 * and disable this file. */
7761 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER
);
7764 GetString(tmp
, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE
, lastof(tmp
));
7765 error
->data
= stredup(tmp
);
7770 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7771 * to be added as a generic string, thus the language id of 0x7F. For this to work
7772 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7773 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7774 * not change anything if a string has been provided specifically for this language. */
7775 byte language
= _cur
.grffile
->grf_version
>= 8 ? buf
->ReadByte() : 0x7F;
7776 byte num_strings
= buf
->ReadByte();
7777 uint16 first_id
= buf
->ReadWord();
7779 if (!((first_id
>= 0xD000 && first_id
+ num_strings
<= 0xD400) || (first_id
>= 0xD800 && first_id
+ num_strings
<= 0xE000))) {
7780 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id
, num_strings
);
7784 for (uint i
= 0; i
< num_strings
&& buf
->HasData(); i
++) {
7785 const char *string
= buf
->ReadString();
7787 if (StrEmpty(string
)) {
7788 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7792 AddGRFString(grfid
, first_id
+ i
, language
, true, true, string
, STR_UNDEFINED
);
7796 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7797 static bool ChangeGRFName(byte langid
, const char *str
)
7799 AddGRFTextToList(&_cur
.grfconfig
->name
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7803 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7804 static bool ChangeGRFDescription(byte langid
, const char *str
)
7806 AddGRFTextToList(&_cur
.grfconfig
->info
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, true, str
);
7810 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7811 static bool ChangeGRFURL(byte langid
, const char *str
)
7813 AddGRFTextToList(&_cur
.grfconfig
->url
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7817 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7818 static bool ChangeGRFNumUsedParams(size_t len
, ByteReader
*buf
)
7821 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len
);
7824 _cur
.grfconfig
->num_valid_params
= min(buf
->ReadByte(), lengthof(_cur
.grfconfig
->param
));
7829 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7830 static bool ChangeGRFPalette(size_t len
, ByteReader
*buf
)
7833 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len
);
7836 char data
= buf
->ReadByte();
7837 GRFPalette pal
= GRFP_GRF_UNSET
;
7840 case 'A': pal
= GRFP_GRF_ANY
; break;
7841 case 'W': pal
= GRFP_GRF_WINDOWS
; break;
7842 case 'D': pal
= GRFP_GRF_DOS
; break;
7844 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data
);
7847 if (pal
!= GRFP_GRF_UNSET
) {
7848 _cur
.grfconfig
->palette
&= ~GRFP_GRF_MASK
;
7849 _cur
.grfconfig
->palette
|= pal
;
7855 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7856 static bool ChangeGRFBlitter(size_t len
, ByteReader
*buf
)
7859 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len
);
7862 char data
= buf
->ReadByte();
7863 GRFPalette pal
= GRFP_BLT_UNSET
;
7865 case '8': pal
= GRFP_BLT_UNSET
; break;
7866 case '3': pal
= GRFP_BLT_32BPP
; break;
7868 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data
);
7871 _cur
.grfconfig
->palette
&= ~GRFP_BLT_MASK
;
7872 _cur
.grfconfig
->palette
|= pal
;
7877 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7878 static bool ChangeGRFVersion(size_t len
, ByteReader
*buf
)
7881 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len
);
7884 /* Set min_loadable_version as well (default to minimal compatibility) */
7885 _cur
.grfconfig
->version
= _cur
.grfconfig
->min_loadable_version
= buf
->ReadDWord();
7890 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7891 static bool ChangeGRFMinVersion(size_t len
, ByteReader
*buf
)
7894 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len
);
7897 _cur
.grfconfig
->min_loadable_version
= buf
->ReadDWord();
7898 if (_cur
.grfconfig
->version
== 0) {
7899 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7900 _cur
.grfconfig
->min_loadable_version
= 0;
7902 if (_cur
.grfconfig
->version
< _cur
.grfconfig
->min_loadable_version
) {
7903 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur
.grfconfig
->min_loadable_version
);
7904 _cur
.grfconfig
->min_loadable_version
= _cur
.grfconfig
->version
;
7910 static GRFParameterInfo
*_cur_parameter
; ///< The parameter which info is currently changed by the newgrf.
7912 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7913 static bool ChangeGRFParamName(byte langid
, const char *str
)
7915 AddGRFTextToList(&_cur_parameter
->name
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7919 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7920 static bool ChangeGRFParamDescription(byte langid
, const char *str
)
7922 AddGRFTextToList(&_cur_parameter
->desc
, langid
, _cur
.grfconfig
->ident
.grfid
, true, str
);
7926 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7927 static bool ChangeGRFParamType(size_t len
, ByteReader
*buf
)
7930 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len
);
7933 GRFParameterType type
= (GRFParameterType
)buf
->ReadByte();
7934 if (type
< PTYPE_END
) {
7935 _cur_parameter
->type
= type
;
7937 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type
);
7943 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7944 static bool ChangeGRFParamLimits(size_t len
, ByteReader
*buf
)
7946 if (_cur_parameter
->type
!= PTYPE_UINT_ENUM
) {
7947 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7949 } else if (len
!= 8) {
7950 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len
);
7953 uint32 min_value
= buf
->ReadDWord();
7954 uint32 max_value
= buf
->ReadDWord();
7955 if (min_value
<= max_value
) {
7956 _cur_parameter
->min_value
= min_value
;
7957 _cur_parameter
->max_value
= max_value
;
7959 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field");
7965 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7966 static bool ChangeGRFParamMask(size_t len
, ByteReader
*buf
)
7968 if (len
< 1 || len
> 3) {
7969 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len
);
7972 byte param_nr
= buf
->ReadByte();
7973 if (param_nr
>= lengthof(_cur
.grfconfig
->param
)) {
7974 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr
);
7977 _cur_parameter
->param_nr
= param_nr
;
7978 if (len
>= 2) _cur_parameter
->first_bit
= min(buf
->ReadByte(), 31);
7979 if (len
>= 3) _cur_parameter
->num_bit
= min(buf
->ReadByte(), 32 - _cur_parameter
->first_bit
);
7986 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7987 static bool ChangeGRFParamDefault(size_t len
, ByteReader
*buf
)
7990 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len
);
7993 _cur_parameter
->def_value
= buf
->ReadDWord();
7995 _cur
.grfconfig
->has_param_defaults
= true;
7999 typedef bool (*DataHandler
)(size_t, ByteReader
*); ///< Type of callback function for binary nodes
8000 typedef bool (*TextHandler
)(byte
, const char *str
); ///< Type of callback function for text nodes
8001 typedef bool (*BranchHandler
)(ByteReader
*); ///< Type of callback function for branch nodes
8004 * Data structure to store the allowed id/type combinations for action 14. The
8005 * data can be represented as a tree with 3 types of nodes:
8006 * 1. Branch nodes (identified by 'C' for choice).
8007 * 2. Binary leaf nodes (identified by 'B').
8008 * 3. Text leaf nodes (identified by 'T').
8010 struct AllowedSubtags
{
8011 /** Create empty subtags object used to identify the end of a list. */
8018 * Create a binary leaf node.
8019 * @param id The id for this node.
8020 * @param handler The callback function to call.
8022 AllowedSubtags(uint32 id
, DataHandler handler
) :
8026 this->handler
.data
= handler
;
8030 * Create a text leaf node.
8031 * @param id The id for this node.
8032 * @param handler The callback function to call.
8034 AllowedSubtags(uint32 id
, TextHandler handler
) :
8038 this->handler
.text
= handler
;
8042 * Create a branch node with a callback handler
8043 * @param id The id for this node.
8044 * @param handler The callback function to call.
8046 AllowedSubtags(uint32 id
, BranchHandler handler
) :
8050 this->handler
.call_handler
= true;
8051 this->handler
.u
.branch
= handler
;
8055 * Create a branch node with a list of sub-nodes.
8056 * @param id The id for this node.
8057 * @param subtags Array with all valid subtags.
8059 AllowedSubtags(uint32 id
, AllowedSubtags
*subtags
) :
8063 this->handler
.call_handler
= false;
8064 this->handler
.u
.subtags
= subtags
;
8067 uint32 id
; ///< The identifier for this node
8068 byte type
; ///< The type of the node, must be one of 'C', 'B' or 'T'.
8070 DataHandler data
; ///< Callback function for a binary node, only valid if type == 'B'.
8071 TextHandler text
; ///< Callback function for a text node, only valid if type == 'T'.
8074 BranchHandler branch
; ///< Callback function for a branch node, only valid if type == 'C' && call_handler.
8075 AllowedSubtags
*subtags
; ///< Pointer to a list of subtags, only valid if type == 'C' && !call_handler.
8077 bool call_handler
; ///< True if there is a callback function for this node, false if there is a list of subnodes.
8082 static bool SkipUnknownInfo(ByteReader
*buf
, byte type
);
8083 static bool HandleNodes(ByteReader
*buf
, AllowedSubtags
*tags
);
8086 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
8087 * of some parameter values (type uint/enum) or the names of some bits
8088 * (type bitmask). In both cases the format is the same:
8089 * Each subnode should be a text node with the value/bit number as id.
8091 static bool ChangeGRFParamValueNames(ByteReader
*buf
)
8093 byte type
= buf
->ReadByte();
8095 uint32 id
= buf
->ReadDWord();
8096 if (type
!= 'T' || id
> _cur_parameter
->max_value
) {
8097 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
8098 if (!SkipUnknownInfo(buf
, type
)) return false;
8099 type
= buf
->ReadByte();
8103 byte langid
= buf
->ReadByte();
8104 const char *name_string
= buf
->ReadString();
8106 SmallPair
<uint32
, GRFText
*> *val_name
= _cur_parameter
->value_names
.Find(id
);
8107 if (val_name
!= _cur_parameter
->value_names
.End()) {
8108 AddGRFTextToList(&val_name
->second
, langid
, _cur
.grfconfig
->ident
.grfid
, false, name_string
);
8110 GRFText
*list
= nullptr;
8111 AddGRFTextToList(&list
, langid
, _cur
.grfconfig
->ident
.grfid
, false, name_string
);
8112 _cur_parameter
->value_names
.Insert(id
, list
);
8115 type
= buf
->ReadByte();
8120 /** Action14 parameter tags */
8121 AllowedSubtags _tags_parameters
[] = {
8122 AllowedSubtags('NAME', ChangeGRFParamName
),
8123 AllowedSubtags('DESC', ChangeGRFParamDescription
),
8124 AllowedSubtags('TYPE', ChangeGRFParamType
),
8125 AllowedSubtags('LIMI', ChangeGRFParamLimits
),
8126 AllowedSubtags('MASK', ChangeGRFParamMask
),
8127 AllowedSubtags('VALU', ChangeGRFParamValueNames
),
8128 AllowedSubtags('DFLT', ChangeGRFParamDefault
),
8133 * Callback function for 'INFO'->'PARA' to set extra information about the
8134 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
8135 * the parameter number as id. The first parameter has id 0. The maximum
8136 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
8138 static bool HandleParameterInfo(ByteReader
*buf
)
8140 byte type
= buf
->ReadByte();
8142 uint32 id
= buf
->ReadDWord();
8143 if (type
!= 'C' || id
>= _cur
.grfconfig
->num_valid_params
) {
8144 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
8145 if (!SkipUnknownInfo(buf
, type
)) return false;
8146 type
= buf
->ReadByte();
8150 if (id
>= _cur
.grfconfig
->param_info
.size()) {
8151 _cur
.grfconfig
->param_info
.resize(id
+ 1);
8153 if (_cur
.grfconfig
->param_info
[id
] == nullptr) {
8154 _cur
.grfconfig
->param_info
[id
] = new GRFParameterInfo(id
);
8156 _cur_parameter
= _cur
.grfconfig
->param_info
[id
];
8157 /* Read all parameter-data and process each node. */
8158 if (!HandleNodes(buf
, _tags_parameters
)) return false;
8159 type
= buf
->ReadByte();
8164 /** Action14 tags for the INFO node */
8165 AllowedSubtags _tags_info
[] = {
8166 AllowedSubtags('NAME', ChangeGRFName
),
8167 AllowedSubtags('DESC', ChangeGRFDescription
),
8168 AllowedSubtags('URL_', ChangeGRFURL
),
8169 AllowedSubtags('NPAR', ChangeGRFNumUsedParams
),
8170 AllowedSubtags('PALS', ChangeGRFPalette
),
8171 AllowedSubtags('BLTR', ChangeGRFBlitter
),
8172 AllowedSubtags('VRSN', ChangeGRFVersion
),
8173 AllowedSubtags('MINV', ChangeGRFMinVersion
),
8174 AllowedSubtags('PARA', HandleParameterInfo
),
8178 /** Action14 root tags */
8179 AllowedSubtags _tags_root
[] = {
8180 AllowedSubtags('INFO', _tags_info
),
8186 * Try to skip the current node and all subnodes (if it's a branch node).
8187 * @param buf Buffer.
8188 * @param type The node type to skip.
8189 * @return True if we could skip the node, false if an error occurred.
8191 static bool SkipUnknownInfo(ByteReader
*buf
, byte type
)
8193 /* type and id are already read */
8196 byte new_type
= buf
->ReadByte();
8197 while (new_type
!= 0) {
8198 buf
->ReadDWord(); // skip the id
8199 if (!SkipUnknownInfo(buf
, new_type
)) return false;
8200 new_type
= buf
->ReadByte();
8206 buf
->ReadByte(); // lang
8207 buf
->ReadString(); // actual text
8211 uint16 size
= buf
->ReadWord();
8224 * Handle the nodes of an Action14
8225 * @param type Type of node.
8227 * @param buf Buffer.
8228 * @param subtags Allowed subtags.
8229 * @return Whether all tags could be handled.
8231 static bool HandleNode(byte type
, uint32 id
, ByteReader
*buf
, AllowedSubtags subtags
[])
8234 AllowedSubtags
*tag
;
8235 while ((tag
= &subtags
[i
++])->type
!= 0) {
8236 if (tag
->id
!= BSWAP32(id
) || tag
->type
!= type
) continue;
8238 default: NOT_REACHED();
8241 byte langid
= buf
->ReadByte();
8242 return tag
->handler
.text(langid
, buf
->ReadString());
8246 size_t len
= buf
->ReadWord();
8247 if (buf
->Remaining() < len
) return false;
8248 return tag
->handler
.data(len
, buf
);
8252 if (tag
->handler
.call_handler
) {
8253 return tag
->handler
.u
.branch(buf
);
8255 return HandleNodes(buf
, tag
->handler
.u
.subtags
);
8259 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type
, id
);
8260 return SkipUnknownInfo(buf
, type
);
8264 * Handle the contents of a 'C' choice of an Action14
8265 * @param buf Buffer.
8266 * @param subtags List of subtags.
8267 * @return Whether the nodes could all be handled.
8269 static bool HandleNodes(ByteReader
*buf
, AllowedSubtags subtags
[])
8271 byte type
= buf
->ReadByte();
8273 uint32 id
= buf
->ReadDWord();
8274 if (!HandleNode(type
, id
, buf
, subtags
)) return false;
8275 type
= buf
->ReadByte();
8281 * Handle Action 0x14
8282 * @param buf Buffer.
8284 static void StaticGRFInfo(ByteReader
*buf
)
8286 /* <14> <type> <id> <text/data...> */
8287 HandleNodes(buf
, _tags_root
);
8291 * Set the current NewGRF as unsafe for static use
8292 * @param buf Unused.
8293 * @note Used during safety scan on unsafe actions.
8295 static void GRFUnsafe(ByteReader
*buf
)
8297 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
8299 /* Skip remainder of GRF */
8300 _cur
.skip_sprites
= -1;
8304 /** Initialize the TTDPatch flags */
8305 static void InitializeGRFSpecial()
8307 _ttdpatch_flags
[0] = ((_settings_game
.station
.never_expire_airports
? 1 : 0) << 0x0C) // keepsmallairport
8308 | (1 << 0x0D) // newairports
8309 | (1 << 0x0E) // largestations
8310 | ((_settings_game
.construction
.max_bridge_length
> 16 ? 1 : 0) << 0x0F) // longbridges
8311 | (0 << 0x10) // loadtime
8312 | (1 << 0x12) // presignals
8313 | (1 << 0x13) // extpresignals
8314 | ((_settings_game
.vehicle
.never_expire_vehicles
? 1 : 0) << 0x16) // enginespersist
8315 | (1 << 0x1B) // multihead
8316 | (1 << 0x1D) // lowmemory
8317 | (1 << 0x1E); // generalfixes
8319 _ttdpatch_flags
[1] = ((_settings_game
.economy
.station_noise_level
? 1 : 0) << 0x07) // moreairports - based on units of noise
8320 | (1 << 0x08) // mammothtrains
8321 | (1 << 0x09) // trainrefit
8322 | (0 << 0x0B) // subsidiaries
8323 | ((_settings_game
.order
.gradual_loading
? 1 : 0) << 0x0C) // gradualloading
8324 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
8325 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
8326 | (1 << 0x14) // bridgespeedlimits
8327 | (1 << 0x16) // eternalgame
8328 | (1 << 0x17) // newtrains
8329 | (1 << 0x18) // newrvs
8330 | (1 << 0x19) // newships
8331 | (1 << 0x1A) // newplanes
8332 | ((_settings_game
.construction
.train_signal_side
== 1 ? 1 : 0) << 0x1B) // signalsontrafficside
8333 | ((_settings_game
.vehicle
.disable_elrails
? 0 : 1) << 0x1C); // electrifiedrailway
8335 _ttdpatch_flags
[2] = (1 << 0x01) // loadallgraphics - obsolote
8336 | (1 << 0x03) // semaphores
8337 | (1 << 0x0A) // newobjects
8338 | (0 << 0x0B) // enhancedgui
8339 | (0 << 0x0C) // newagerating
8340 | ((_settings_game
.construction
.build_on_slopes
? 1 : 0) << 0x0D) // buildonslopes
8341 | (1 << 0x0E) // fullloadany
8342 | (1 << 0x0F) // planespeed
8343 | (0 << 0x10) // moreindustriesperclimate - obsolete
8344 | (0 << 0x11) // moretoylandfeatures
8345 | (1 << 0x12) // newstations
8346 | (1 << 0x13) // tracktypecostdiff
8347 | (1 << 0x14) // manualconvert
8348 | ((_settings_game
.construction
.build_on_slopes
? 1 : 0) << 0x15) // buildoncoasts
8349 | (1 << 0x16) // canals
8350 | (1 << 0x17) // newstartyear
8351 | ((_settings_game
.vehicle
.freight_trains
> 1 ? 1 : 0) << 0x18) // freighttrains
8352 | (1 << 0x19) // newhouses
8353 | (1 << 0x1A) // newbridges
8354 | (1 << 0x1B) // newtownnames
8355 | (1 << 0x1C) // moreanimation
8356 | ((_settings_game
.vehicle
.wagon_speed_limits
? 1 : 0) << 0x1D) // wagonspeedlimits
8357 | (1 << 0x1E) // newshistory
8358 | (0 << 0x1F); // custombridgeheads
8360 _ttdpatch_flags
[3] = (0 << 0x00) // newcargodistribution
8361 | (1 << 0x01) // windowsnap
8362 | ((_settings_game
.economy
.allow_town_roads
|| _generating_world
? 0 : 1) << 0x02) // townbuildnoroad
8363 | (1 << 0x03) // pathbasedsignalling
8364 | (0 << 0x04) // aichoosechance
8365 | (1 << 0x05) // resolutionwidth
8366 | (1 << 0x06) // resolutionheight
8367 | (1 << 0x07) // newindustries
8368 | ((_settings_game
.order
.improved_load
? 1 : 0) << 0x08) // fifoloading
8369 | (0 << 0x09) // townroadbranchprob
8370 | (0 << 0x0A) // tempsnowline
8371 | (1 << 0x0B) // newcargo
8372 | (1 << 0x0C) // enhancemultiplayer
8373 | (1 << 0x0D) // onewayroads
8374 | (1 << 0x0E) // irregularstations
8375 | (1 << 0x0F) // statistics
8376 | (1 << 0x10) // newsounds
8377 | (1 << 0x11) // autoreplace
8378 | (1 << 0x12) // autoslope
8379 | (0 << 0x13) // followvehicle
8380 | (1 << 0x14) // trams
8381 | (0 << 0x15) // enhancetunnels
8382 | (1 << 0x16) // shortrvs
8383 | (1 << 0x17) // articulatedrvs
8384 | ((_settings_game
.vehicle
.dynamic_engines
? 1 : 0) << 0x18) // dynamic engines
8385 | (1 << 0x1E) // variablerunningcosts
8386 | (1 << 0x1F); // any switch is on
8388 _ttdpatch_flags
[4] = (1 << 0x00); // larger persistent storage
8391 /** Reset and clear all NewGRF stations */
8392 static void ResetCustomStations()
8394 for (GRFFile
* const file
: _grf_files
) {
8395 StationSpec
**&stations
= file
->stations
;
8396 if (stations
== nullptr) continue;
8397 for (uint i
= 0; i
< NUM_STATIONS_PER_GRF
; i
++) {
8398 if (stations
[i
] == nullptr) continue;
8399 StationSpec
*statspec
= stations
[i
];
8401 delete[] statspec
->renderdata
;
8403 /* Release platforms and layouts */
8404 if (!statspec
->copied_layouts
) {
8405 for (uint l
= 0; l
< statspec
->lengths
; l
++) {
8406 for (uint p
= 0; p
< statspec
->platforms
[l
]; p
++) {
8407 free(statspec
->layouts
[l
][p
]);
8409 free(statspec
->layouts
[l
]);
8411 free(statspec
->layouts
);
8412 free(statspec
->platforms
);
8415 /* Release this station */
8419 /* Free and reset the station data */
8425 /** Reset and clear all NewGRF houses */
8426 static void ResetCustomHouses()
8428 for (GRFFile
* const file
: _grf_files
) {
8429 HouseSpec
**&housespec
= file
->housespec
;
8430 if (housespec
== nullptr) continue;
8431 for (uint i
= 0; i
< NUM_HOUSES_PER_GRF
; i
++) {
8436 housespec
= nullptr;
8440 /** Reset and clear all NewGRF airports */
8441 static void ResetCustomAirports()
8443 for (GRFFile
* const file
: _grf_files
) {
8444 AirportSpec
**aslist
= file
->airportspec
;
8445 if (aslist
!= nullptr) {
8446 for (uint i
= 0; i
< NUM_AIRPORTS_PER_GRF
; i
++) {
8447 AirportSpec
*as
= aslist
[i
];
8449 if (as
!= nullptr) {
8450 /* We need to remove the tiles layouts */
8451 for (int j
= 0; j
< as
->num_table
; j
++) {
8452 /* remove the individual layouts */
8456 free(as
->depot_table
);
8463 file
->airportspec
= nullptr;
8466 AirportTileSpec
**&airporttilespec
= file
->airtspec
;
8467 if (airporttilespec
!= nullptr) {
8468 for (uint i
= 0; i
< NUM_AIRPORTTILES_PER_GRF
; i
++) {
8469 free(airporttilespec
[i
]);
8471 free(airporttilespec
);
8472 airporttilespec
= nullptr;
8477 /** Reset and clear all NewGRF industries */
8478 static void ResetCustomIndustries()
8480 for (GRFFile
* const file
: _grf_files
) {
8481 IndustrySpec
**&industryspec
= file
->industryspec
;
8482 IndustryTileSpec
**&indtspec
= file
->indtspec
;
8484 /* We are verifiying both tiles and industries specs loaded from the grf file
8485 * First, let's deal with industryspec */
8486 if (industryspec
!= nullptr) {
8487 for (uint i
= 0; i
< NUM_INDUSTRYTYPES_PER_GRF
; i
++) {
8488 IndustrySpec
*ind
= industryspec
[i
];
8493 industryspec
= nullptr;
8496 if (indtspec
== nullptr) continue;
8497 for (uint i
= 0; i
< NUM_INDUSTRYTILES_PER_GRF
; i
++) {
8506 /** Reset and clear all NewObjects */
8507 static void ResetCustomObjects()
8509 for (GRFFile
* const file
: _grf_files
) {
8510 ObjectSpec
**&objectspec
= file
->objectspec
;
8511 if (objectspec
== nullptr) continue;
8512 for (uint i
= 0; i
< NUM_OBJECTS_PER_GRF
; i
++) {
8513 free(objectspec
[i
]);
8517 objectspec
= nullptr;
8521 /** Reset and clear all NewGRFs */
8522 static void ResetNewGRF()
8524 for (GRFFile
* const file
: _grf_files
) {
8529 _cur
.grffile
= nullptr;
8532 /** Clear all NewGRF errors */
8533 static void ResetNewGRFErrors()
8535 for (GRFConfig
*c
= _grfconfig
; c
!= nullptr; c
= c
->next
) {
8536 if (!HasBit(c
->flags
, GCF_COPY
) && c
->error
!= nullptr) {
8544 * Reset all NewGRF loaded data
8546 void ResetNewGRFData()
8549 CleanUpGRFTownNames();
8551 /* Copy/reset original engine info data */
8554 /* Copy/reset original bridge info data */
8557 /* Reset rail type information */
8560 /* Copy/reset original road type info data */
8563 /* Allocate temporary refit/cargo class data */
8564 _gted
= CallocT
<GRFTempEngineData
>(Engine::GetPoolSize());
8566 /* Fill rail type label temporary data for default trains */
8567 for (const Engine
*e
: Engine::IterateType(VEH_TRAIN
)) {
8568 _gted
[e
->index
].railtypelabel
= GetRailTypeInfo(e
->u
.rail
.railtype
)->label
;
8571 /* Reset GRM reservations */
8572 memset(&_grm_engines
, 0, sizeof(_grm_engines
));
8573 memset(&_grm_cargoes
, 0, sizeof(_grm_cargoes
));
8575 /* Reset generic feature callback lists */
8576 ResetGenericCallbacks();
8578 /* Reset price base data */
8579 ResetPriceBaseMultipliers();
8581 /* Reset the curencies array */
8584 /* Reset the house array */
8585 ResetCustomHouses();
8588 /* Reset the industries structures*/
8589 ResetCustomIndustries();
8592 /* Reset the objects. */
8593 ObjectClass::Reset();
8594 ResetCustomObjects();
8597 /* Reset station classes */
8598 StationClass::Reset();
8599 ResetCustomStations();
8601 /* Reset airport-related structures */
8602 AirportClass::Reset();
8603 ResetCustomAirports();
8604 AirportSpec::ResetAirports();
8605 AirportTileSpec::ResetAirportTiles();
8607 /* Reset canal sprite groups and flags */
8608 memset(_water_feature
, 0, sizeof(_water_feature
));
8610 /* Reset the snowline table. */
8613 /* Reset NewGRF files */
8616 /* Reset NewGRF errors. */
8617 ResetNewGRFErrors();
8619 /* Set up the default cargo types */
8620 SetupCargoForClimate(_settings_game
.game_creation
.landscape
);
8622 /* Reset misc GRF features and train list display variables */
8623 _misc_grf_features
= 0;
8625 _loaded_newgrf_features
.has_2CC
= false;
8626 _loaded_newgrf_features
.used_liveries
= 1 << LS_DEFAULT
;
8627 _loaded_newgrf_features
.has_newhouses
= false;
8628 _loaded_newgrf_features
.has_newindustries
= false;
8629 _loaded_newgrf_features
.shore
= SHORE_REPLACE_NONE
;
8630 _loaded_newgrf_features
.tram
= TRAMWAY_REPLACE_DEPOT_NONE
;
8632 /* Clear all GRF overrides */
8633 _grf_id_overrides
.clear();
8635 InitializeSoundPool();
8636 _spritegroup_pool
.CleanPool();
8640 * Reset NewGRF data which is stored persistently in savegames.
8642 void ResetPersistentNewGRFData()
8644 /* Reset override managers */
8645 _engine_mngr
.ResetToDefaultMapping();
8646 _house_mngr
.ResetMapping();
8647 _industry_mngr
.ResetMapping();
8648 _industile_mngr
.ResetMapping();
8649 _airport_mngr
.ResetMapping();
8650 _airporttile_mngr
.ResetMapping();
8654 * Construct the Cargo Mapping
8655 * @note This is the reverse of a cargo translation table
8657 static void BuildCargoTranslationMap()
8659 memset(_cur
.grffile
->cargo_map
, 0xFF, sizeof(_cur
.grffile
->cargo_map
));
8661 for (CargoID c
= 0; c
< NUM_CARGO
; c
++) {
8662 const CargoSpec
*cs
= CargoSpec::Get(c
);
8663 if (!cs
->IsValid()) continue;
8665 if (_cur
.grffile
->cargo_list
.size() == 0) {
8666 /* Default translation table, so just a straight mapping to bitnum */
8667 _cur
.grffile
->cargo_map
[c
] = cs
->bitnum
;
8669 /* Check the translation table for this cargo's label */
8670 int idx
= find_index(_cur
.grffile
->cargo_list
, {cs
->label
});
8671 if (idx
>= 0) _cur
.grffile
->cargo_map
[c
] = idx
;
8677 * Prepare loading a NewGRF file with its config
8678 * @param config The NewGRF configuration struct with name, id, parameters and alike.
8680 static void InitNewGRFFile(const GRFConfig
*config
)
8682 GRFFile
*newfile
= GetFileByFilename(config
->filename
);
8683 if (newfile
!= nullptr) {
8684 /* We already loaded it once. */
8685 _cur
.grffile
= newfile
;
8689 newfile
= new GRFFile(config
);
8690 _grf_files
.push_back(_cur
.grffile
= newfile
);
8694 * Constructor for GRFFile
8695 * @param config GRFConfig to copy name, grfid and parameters from.
8697 GRFFile::GRFFile(const GRFConfig
*config
)
8699 this->filename
= stredup(config
->filename
);
8700 this->grfid
= config
->ident
.grfid
;
8702 /* Initialise local settings to defaults */
8703 this->traininfo_vehicle_pitch
= 0;
8704 this->traininfo_vehicle_width
= TRAININFO_DEFAULT_VEHICLE_WIDTH
;
8706 /* Mark price_base_multipliers as 'not set' */
8707 for (Price i
= PR_BEGIN
; i
< PR_END
; i
++) {
8708 this->price_base_multipliers
[i
] = INVALID_PRICE_MODIFIER
;
8711 /* Initialise rail type map with default rail types */
8712 memset(this->railtype_map
, INVALID_RAILTYPE
, sizeof(this->railtype_map
));
8713 this->railtype_map
[0] = RAILTYPE_RAIL
;
8714 this->railtype_map
[1] = RAILTYPE_ELECTRIC
;
8715 this->railtype_map
[2] = RAILTYPE_MONO
;
8716 this->railtype_map
[3] = RAILTYPE_MAGLEV
;
8718 /* Initialise road type map with default road types */
8719 memset(this->roadtype_map
, INVALID_ROADTYPE
, sizeof(this->roadtype_map
));
8720 this->roadtype_map
[0] = ROADTYPE_ROAD
;
8722 /* Initialise tram type map with default tram types */
8723 memset(this->tramtype_map
, INVALID_ROADTYPE
, sizeof(this->tramtype_map
));
8724 this->tramtype_map
[0] = ROADTYPE_TRAM
;
8726 /* Copy the initial parameter list
8727 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8728 assert_compile(lengthof(this->param
) == lengthof(config
->param
) && lengthof(this->param
) == 0x80);
8730 assert(config
->num_params
<= lengthof(config
->param
));
8731 this->param_end
= config
->num_params
;
8732 if (this->param_end
> 0) {
8733 MemCpyT(this->param
, config
->param
, this->param_end
);
8739 free(this->filename
);
8740 delete[] this->language_map
;
8745 * List of what cargo labels are refittable for the given the vehicle-type.
8746 * Only currently active labels are applied.
8748 static const CargoLabel _default_refitmasks_rail
[] = {
8749 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8750 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8751 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8755 static const CargoLabel _default_refitmasks_road
[] = {
8758 static const CargoLabel _default_refitmasks_ships
[] = {
8759 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8760 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8761 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8765 static const CargoLabel _default_refitmasks_aircraft
[] = {
8766 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8767 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8770 static const CargoLabel
* const _default_refitmasks
[] = {
8771 _default_refitmasks_rail
,
8772 _default_refitmasks_road
,
8773 _default_refitmasks_ships
,
8774 _default_refitmasks_aircraft
,
8779 * Precalculate refit masks from cargo classes for all vehicles.
8781 static void CalculateRefitMasks()
8783 for (Engine
*e
: Engine::Iterate()) {
8784 EngineID engine
= e
->index
;
8785 EngineInfo
*ei
= &e
->info
;
8786 bool only_defaultcargo
; ///< Set if the vehicle shall carry only the default cargo
8788 /* Did the newgrf specify any refitting? If not, use defaults. */
8789 if (_gted
[engine
].refittability
!= GRFTempEngineData::UNSET
) {
8790 CargoTypes mask
= 0;
8791 CargoTypes not_mask
= 0;
8792 CargoTypes xor_mask
= ei
->refit_mask
;
8794 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8795 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8796 only_defaultcargo
= _gted
[engine
].refittability
== GRFTempEngineData::EMPTY
;
8798 if (_gted
[engine
].cargo_allowed
!= 0) {
8799 /* Build up the list of cargo types from the set cargo classes. */
8800 const CargoSpec
*cs
;
8801 FOR_ALL_CARGOSPECS(cs
) {
8802 if (_gted
[engine
].cargo_allowed
& cs
->classes
) SetBit(mask
, cs
->Index());
8803 if (_gted
[engine
].cargo_disallowed
& cs
->classes
) SetBit(not_mask
, cs
->Index());
8807 ei
->refit_mask
= ((mask
& ~not_mask
) ^ xor_mask
) & _cargo_mask
;
8809 /* Apply explicit refit includes/excludes. */
8810 ei
->refit_mask
|= _gted
[engine
].ctt_include_mask
;
8811 ei
->refit_mask
&= ~_gted
[engine
].ctt_exclude_mask
;
8813 CargoTypes xor_mask
= 0;
8815 /* Don't apply default refit mask to wagons nor engines with no capacity */
8816 if (e
->type
!= VEH_TRAIN
|| (e
->u
.rail
.capacity
!= 0 && e
->u
.rail
.railveh_type
!= RAILVEH_WAGON
)) {
8817 const CargoLabel
*cl
= _default_refitmasks
[e
->type
];
8818 for (uint i
= 0;; i
++) {
8819 if (cl
[i
] == 0) break;
8821 CargoID cargo
= GetCargoIDByLabel(cl
[i
]);
8822 if (cargo
== CT_INVALID
) continue;
8824 SetBit(xor_mask
, cargo
);
8828 ei
->refit_mask
= xor_mask
& _cargo_mask
;
8830 /* If the mask is zero, the vehicle shall only carry the default cargo */
8831 only_defaultcargo
= (ei
->refit_mask
== 0);
8834 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8835 if (!HasBit(_cargo_mask
, ei
->cargo_type
)) ei
->cargo_type
= CT_INVALID
;
8837 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8838 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8839 if (!only_defaultcargo
&& (e
->type
!= VEH_SHIP
|| e
->u
.ship
.old_refittable
) && ei
->cargo_type
!= CT_INVALID
&& !HasBit(ei
->refit_mask
, ei
->cargo_type
)) {
8840 ei
->cargo_type
= CT_INVALID
;
8843 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8844 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8845 if (ei
->cargo_type
== CT_INVALID
&& ei
->refit_mask
!= 0) {
8846 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8847 const uint8
*cargo_map_for_first_refittable
= nullptr;
8849 const GRFFile
*file
= _gted
[engine
].defaultcargo_grf
;
8850 if (file
== nullptr) file
= e
->GetGRF();
8851 if (file
!= nullptr && file
->grf_version
>= 8 && file
->cargo_list
.size() != 0) {
8852 cargo_map_for_first_refittable
= file
->cargo_map
;
8856 if (cargo_map_for_first_refittable
!= nullptr) {
8857 /* Use first refittable cargo from cargo translation table */
8858 byte best_local_slot
= 0xFF;
8860 FOR_EACH_SET_CARGO_ID(cargo_type
, ei
->refit_mask
) {
8861 byte local_slot
= cargo_map_for_first_refittable
[cargo_type
];
8862 if (local_slot
< best_local_slot
) {
8863 best_local_slot
= local_slot
;
8864 ei
->cargo_type
= cargo_type
;
8869 if (ei
->cargo_type
== CT_INVALID
) {
8870 /* Use first refittable cargo slot */
8871 ei
->cargo_type
= (CargoID
)FindFirstBit(ei
->refit_mask
);
8874 if (ei
->cargo_type
== CT_INVALID
) ei
->climates
= 0;
8876 /* Clear refit_mask for not refittable ships */
8877 if (e
->type
== VEH_SHIP
&& !e
->u
.ship
.old_refittable
) {
8883 /** Set to use the correct action0 properties for each canal feature */
8884 static void FinaliseCanals()
8886 for (uint i
= 0; i
< CF_END
; i
++) {
8887 if (_water_feature
[i
].grffile
!= nullptr) {
8888 _water_feature
[i
].callback_mask
= _water_feature
[i
].grffile
->canal_local_properties
[i
].callback_mask
;
8889 _water_feature
[i
].flags
= _water_feature
[i
].grffile
->canal_local_properties
[i
].flags
;
8894 /** Check for invalid engines */
8895 static void FinaliseEngineArray()
8897 for (Engine
*e
: Engine::Iterate()) {
8898 if (e
->GetGRF() == nullptr) {
8899 const EngineIDMapping
&eid
= _engine_mngr
[e
->index
];
8900 if (eid
.grfid
!= INVALID_GRFID
|| eid
.internal_id
!= eid
.substitute_id
) {
8901 e
->info
.string_id
= STR_NEWGRF_INVALID_ENGINE
;
8905 if (!HasBit(e
->info
.climates
, _settings_game
.game_creation
.landscape
)) continue;
8907 /* When the train does not set property 27 (misc flags), but it
8908 * is overridden by a NewGRF graphically we want to disable the
8909 * flipping possibility. */
8910 if (e
->type
== VEH_TRAIN
&& !_gted
[e
->index
].prop27_set
&& e
->GetGRF() != nullptr && is_custom_sprite(e
->u
.rail
.image_index
)) {
8911 ClrBit(e
->info
.misc_flags
, EF_RAIL_FLIPS
);
8914 /* Skip wagons, there livery is defined via the engine */
8915 if (e
->type
!= VEH_TRAIN
|| e
->u
.rail
.railveh_type
!= RAILVEH_WAGON
) {
8916 LiveryScheme ls
= GetEngineLiveryScheme(e
->index
, INVALID_ENGINE
, nullptr);
8917 SetBit(_loaded_newgrf_features
.used_liveries
, ls
);
8918 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8920 if (e
->type
== VEH_TRAIN
) {
8921 SetBit(_loaded_newgrf_features
.used_liveries
, LS_FREIGHT_WAGON
);
8928 SetBit(_loaded_newgrf_features
.used_liveries
, LS_PASSENGER_WAGON_STEAM
+ ls
- LS_STEAM
);
8933 SetBit(_loaded_newgrf_features
.used_liveries
, LS_PASSENGER_WAGON_DIESEL
+ ls
- LS_DMU
);
8936 default: NOT_REACHED();
8943 /** Check for invalid cargoes */
8944 static void FinaliseCargoArray()
8946 for (CargoID c
= 0; c
< NUM_CARGO
; c
++) {
8947 CargoSpec
*cs
= CargoSpec::Get(c
);
8948 if (!cs
->IsValid()) {
8949 cs
->name
= cs
->name_single
= cs
->units_volume
= STR_NEWGRF_INVALID_CARGO
;
8950 cs
->quantifier
= STR_NEWGRF_INVALID_CARGO_QUANTITY
;
8951 cs
->abbrev
= STR_NEWGRF_INVALID_CARGO_ABBREV
;
8957 * Check if a given housespec is valid and disable it if it's not.
8958 * The housespecs that follow it are used to check the validity of
8960 * @param hs The housespec to check.
8961 * @param next1 The housespec that follows \c hs.
8962 * @param next2 The housespec that follows \c next1.
8963 * @param next3 The housespec that follows \c next2.
8964 * @param filename The filename of the newgrf this house was defined in.
8965 * @return Whether the given housespec is valid.
8967 static bool IsHouseSpecValid(HouseSpec
*hs
, const HouseSpec
*next1
, const HouseSpec
*next2
, const HouseSpec
*next3
, const char *filename
)
8969 if (((hs
->building_flags
& BUILDING_HAS_2_TILES
) != 0 &&
8970 (next1
== nullptr || !next1
->enabled
|| (next1
->building_flags
& BUILDING_HAS_1_TILE
) != 0)) ||
8971 ((hs
->building_flags
& BUILDING_HAS_4_TILES
) != 0 &&
8972 (next2
== nullptr || !next2
->enabled
|| (next2
->building_flags
& BUILDING_HAS_1_TILE
) != 0 ||
8973 next3
== nullptr || !next3
->enabled
|| (next3
->building_flags
& BUILDING_HAS_1_TILE
) != 0))) {
8974 hs
->enabled
= false;
8975 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
);
8979 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8980 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8981 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8982 if (((hs
->building_flags
& BUILDING_HAS_2_TILES
) != 0 && next1
->population
!= 0) ||
8983 ((hs
->building_flags
& BUILDING_HAS_4_TILES
) != 0 && (next2
->population
!= 0 || next3
->population
!= 0))) {
8984 hs
->enabled
= false;
8985 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
);
8989 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8990 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8991 if (filename
!= nullptr && (hs
->building_flags
& BUILDING_HAS_1_TILE
) != (HouseSpec::Get(hs
->grf_prop
.subst_id
)->building_flags
& BUILDING_HAS_1_TILE
)) {
8992 hs
->enabled
= false;
8993 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
);
8997 /* Make sure that additional parts of multitile houses are not available. */
8998 if ((hs
->building_flags
& BUILDING_HAS_1_TILE
) == 0 && (hs
->building_availability
& HZ_ZONALL
) != 0 && (hs
->building_availability
& HZ_CLIMALL
) != 0) {
8999 hs
->enabled
= false;
9000 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
);
9008 * Make sure there is at least one house available in the year 0 for the given
9009 * climate / housezone combination.
9010 * @param bitmask The climate and housezone to check for. Exactly one climate
9011 * bit and one housezone bit should be set.
9013 static void EnsureEarlyHouse(HouseZones bitmask
)
9015 Year min_year
= MAX_YEAR
;
9017 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
9018 HouseSpec
*hs
= HouseSpec::Get(i
);
9019 if (hs
== nullptr || !hs
->enabled
) continue;
9020 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
9021 if (hs
->min_year
< min_year
) min_year
= hs
->min_year
;
9024 if (min_year
== 0) return;
9026 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
9027 HouseSpec
*hs
= HouseSpec::Get(i
);
9028 if (hs
== nullptr || !hs
->enabled
) continue;
9029 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
9030 if (hs
->min_year
== min_year
) hs
->min_year
= 0;
9035 * Add all new houses to the house array. House properties can be set at any
9036 * time in the GRF file, so we can only add a house spec to the house array
9037 * after the file has finished loading. We also need to check the dates, due to
9038 * the TTDPatch behaviour described below that we need to emulate.
9040 static void FinaliseHouseArray()
9042 /* If there are no houses with start dates before 1930, then all houses
9043 * with start dates of 1930 have them reset to 0. This is in order to be
9044 * compatible with TTDPatch, where if no houses have start dates before
9045 * 1930 and the date is before 1930, the game pretends that this is 1930.
9046 * If there have been any houses defined with start dates before 1930 then
9047 * the dates are left alone.
9048 * On the other hand, why 1930? Just 'fix' the houses with the lowest
9049 * minimum introduction date to 0.
9051 for (GRFFile
* const file
: _grf_files
) {
9052 HouseSpec
**&housespec
= file
->housespec
;
9053 if (housespec
== nullptr) continue;
9055 for (int i
= 0; i
< NUM_HOUSES_PER_GRF
; i
++) {
9056 HouseSpec
*hs
= housespec
[i
];
9058 if (hs
== nullptr) continue;
9060 const HouseSpec
*next1
= (i
+ 1 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 1] : nullptr);
9061 const HouseSpec
*next2
= (i
+ 2 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 2] : nullptr);
9062 const HouseSpec
*next3
= (i
+ 3 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 3] : nullptr);
9064 if (!IsHouseSpecValid(hs
, next1
, next2
, next3
, file
->filename
)) continue;
9066 _house_mngr
.SetEntitySpec(hs
);
9070 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
9071 HouseSpec
*hs
= HouseSpec::Get(i
);
9072 const HouseSpec
*next1
= (i
+ 1 < NUM_HOUSES
? HouseSpec::Get(i
+ 1) : nullptr);
9073 const HouseSpec
*next2
= (i
+ 2 < NUM_HOUSES
? HouseSpec::Get(i
+ 2) : nullptr);
9074 const HouseSpec
*next3
= (i
+ 3 < NUM_HOUSES
? HouseSpec::Get(i
+ 3) : nullptr);
9076 /* We need to check all houses again to we are sure that multitile houses
9077 * did get consecutive IDs and none of the parts are missing. */
9078 if (!IsHouseSpecValid(hs
, next1
, next2
, next3
, nullptr)) {
9079 /* GetHouseNorthPart checks 3 houses that are directly before
9080 * it in the house pool. If any of those houses have multi-tile
9081 * flags set it assumes it's part of a multitile house. Since
9082 * we can have invalid houses in the pool marked as disabled, we
9083 * don't want to have them influencing valid tiles. As such set
9084 * building_flags to zero here to make sure any house following
9085 * this one in the pool is properly handled as 1x1 house. */
9086 hs
->building_flags
= TILE_NO_FLAG
;
9090 HouseZones climate_mask
= (HouseZones
)(1 << (_settings_game
.game_creation
.landscape
+ 12));
9091 EnsureEarlyHouse(HZ_ZON1
| climate_mask
);
9092 EnsureEarlyHouse(HZ_ZON2
| climate_mask
);
9093 EnsureEarlyHouse(HZ_ZON3
| climate_mask
);
9094 EnsureEarlyHouse(HZ_ZON4
| climate_mask
);
9095 EnsureEarlyHouse(HZ_ZON5
| climate_mask
);
9097 if (_settings_game
.game_creation
.landscape
== LT_ARCTIC
) {
9098 EnsureEarlyHouse(HZ_ZON1
| HZ_SUBARTC_ABOVE
);
9099 EnsureEarlyHouse(HZ_ZON2
| HZ_SUBARTC_ABOVE
);
9100 EnsureEarlyHouse(HZ_ZON3
| HZ_SUBARTC_ABOVE
);
9101 EnsureEarlyHouse(HZ_ZON4
| HZ_SUBARTC_ABOVE
);
9102 EnsureEarlyHouse(HZ_ZON5
| HZ_SUBARTC_ABOVE
);
9107 * Add all new industries to the industry array. Industry properties can be set at any
9108 * time in the GRF file, so we can only add a industry spec to the industry array
9109 * after the file has finished loading.
9111 static void FinaliseIndustriesArray()
9113 for (GRFFile
* const file
: _grf_files
) {
9114 IndustrySpec
**&industryspec
= file
->industryspec
;
9115 IndustryTileSpec
**&indtspec
= file
->indtspec
;
9116 if (industryspec
!= nullptr) {
9117 for (int i
= 0; i
< NUM_INDUSTRYTYPES_PER_GRF
; i
++) {
9118 IndustrySpec
*indsp
= industryspec
[i
];
9120 if (indsp
!= nullptr && indsp
->enabled
) {
9122 /* process the conversion of text at the end, so to be sure everything will be fine
9123 * and available. Check if it does not return undefind marker, which is a very good sign of a
9124 * substitute industry who has not changed the string been examined, thus using it as such */
9125 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->name
);
9126 if (strid
!= STR_UNDEFINED
) indsp
->name
= strid
;
9128 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->closure_text
);
9129 if (strid
!= STR_UNDEFINED
) indsp
->closure_text
= strid
;
9131 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->production_up_text
);
9132 if (strid
!= STR_UNDEFINED
) indsp
->production_up_text
= strid
;
9134 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->production_down_text
);
9135 if (strid
!= STR_UNDEFINED
) indsp
->production_down_text
= strid
;
9137 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->new_industry_text
);
9138 if (strid
!= STR_UNDEFINED
) indsp
->new_industry_text
= strid
;
9140 if (indsp
->station_name
!= STR_NULL
) {
9141 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
9142 * station's name. Don't want to lose the value, therefore, do not process. */
9143 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->station_name
);
9144 if (strid
!= STR_UNDEFINED
) indsp
->station_name
= strid
;
9147 _industry_mngr
.SetEntitySpec(indsp
);
9148 _loaded_newgrf_features
.has_newindustries
= true;
9153 if (indtspec
!= nullptr) {
9154 for (int i
= 0; i
< NUM_INDUSTRYTILES_PER_GRF
; i
++) {
9155 IndustryTileSpec
*indtsp
= indtspec
[i
];
9156 if (indtsp
!= nullptr) {
9157 _industile_mngr
.SetEntitySpec(indtsp
);
9163 for (uint j
= 0; j
< NUM_INDUSTRYTYPES
; j
++) {
9164 IndustrySpec
*indsp
= &_industry_specs
[j
];
9165 if (indsp
->enabled
&& indsp
->grf_prop
.grffile
!= nullptr) {
9166 for (uint i
= 0; i
< 3; i
++) {
9167 indsp
->conflicting
[i
] = MapNewGRFIndustryType(indsp
->conflicting
[i
], indsp
->grf_prop
.grffile
->grfid
);
9170 if (!indsp
->enabled
) {
9171 indsp
->name
= STR_NEWGRF_INVALID_INDUSTRYTYPE
;
9177 * Add all new objects to the object array. Object properties can be set at any
9178 * time in the GRF file, so we can only add an object spec to the object array
9179 * after the file has finished loading.
9181 static void FinaliseObjectsArray()
9183 for (GRFFile
* const file
: _grf_files
) {
9184 ObjectSpec
**&objectspec
= file
->objectspec
;
9185 if (objectspec
!= nullptr) {
9186 for (int i
= 0; i
< NUM_OBJECTS_PER_GRF
; i
++) {
9187 if (objectspec
[i
] != nullptr && objectspec
[i
]->grf_prop
.grffile
!= nullptr && objectspec
[i
]->enabled
) {
9188 _object_mngr
.SetEntitySpec(objectspec
[i
]);
9196 * Add all new airports to the airport array. Airport properties can be set at any
9197 * time in the GRF file, so we can only add a airport spec to the airport array
9198 * after the file has finished loading.
9200 static void FinaliseAirportsArray()
9202 for (GRFFile
* const file
: _grf_files
) {
9203 AirportSpec
**&airportspec
= file
->airportspec
;
9204 if (airportspec
!= nullptr) {
9205 for (int i
= 0; i
< NUM_AIRPORTS_PER_GRF
; i
++) {
9206 if (airportspec
[i
] != nullptr && airportspec
[i
]->enabled
) {
9207 _airport_mngr
.SetEntitySpec(airportspec
[i
]);
9212 AirportTileSpec
**&airporttilespec
= file
->airtspec
;
9213 if (airporttilespec
!= nullptr) {
9214 for (uint i
= 0; i
< NUM_AIRPORTTILES_PER_GRF
; i
++) {
9215 if (airporttilespec
[i
] != nullptr && airporttilespec
[i
]->enabled
) {
9216 _airporttile_mngr
.SetEntitySpec(airporttilespec
[i
]);
9223 /* Here we perform initial decoding of some special sprites (as are they
9224 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
9225 * partial implementation yet).
9226 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
9227 * a crafted invalid GRF file. We should tell that to the user somehow, or
9228 * better make this more robust in the future. */
9229 static void DecodeSpecialSprite(byte
*buf
, uint num
, GrfLoadingStage stage
)
9231 /* XXX: There is a difference between staged loading in TTDPatch and
9232 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
9233 * during stage 1, whilst action 3 is carried out during stage 2 (to
9234 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
9235 * IDs are valid only within a given set (action 1) block, and may be
9236 * overwritten after action 3 associates them. But overwriting happens
9237 * in an earlier stage than associating, so... We just process actions
9238 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
9240 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
9241 * is not in memory and scanning the file every time would be too expensive.
9242 * In other stages we skip action 0x10 since it's already dealt with. */
9243 static const SpecialSpriteHandler handlers
[][GLS_END
] = {
9244 /* 0x00 */ { nullptr, SafeChangeInfo
, nullptr, nullptr, ReserveChangeInfo
, FeatureChangeInfo
, },
9245 /* 0x01 */ { SkipAct1
, SkipAct1
, SkipAct1
, SkipAct1
, SkipAct1
, NewSpriteSet
, },
9246 /* 0x02 */ { nullptr, nullptr, nullptr, nullptr, nullptr, NewSpriteGroup
, },
9247 /* 0x03 */ { nullptr, GRFUnsafe
, nullptr, nullptr, nullptr, FeatureMapSpriteGroup
, },
9248 /* 0x04 */ { nullptr, nullptr, nullptr, nullptr, nullptr, FeatureNewName
, },
9249 /* 0x05 */ { SkipAct5
, SkipAct5
, SkipAct5
, SkipAct5
, SkipAct5
, GraphicsNew
, },
9250 /* 0x06 */ { nullptr, nullptr, nullptr, CfgApply
, CfgApply
, CfgApply
, },
9251 /* 0x07 */ { nullptr, nullptr, nullptr, nullptr, SkipIf
, SkipIf
, },
9252 /* 0x08 */ { ScanInfo
, nullptr, nullptr, GRFInfo
, GRFInfo
, GRFInfo
, },
9253 /* 0x09 */ { nullptr, nullptr, nullptr, SkipIf
, SkipIf
, SkipIf
, },
9254 /* 0x0A */ { SkipActA
, SkipActA
, SkipActA
, SkipActA
, SkipActA
, SpriteReplace
, },
9255 /* 0x0B */ { nullptr, nullptr, nullptr, GRFLoadError
, GRFLoadError
, GRFLoadError
, },
9256 /* 0x0C */ { nullptr, nullptr, nullptr, GRFComment
, nullptr, GRFComment
, },
9257 /* 0x0D */ { nullptr, SafeParamSet
, nullptr, ParamSet
, ParamSet
, ParamSet
, },
9258 /* 0x0E */ { nullptr, SafeGRFInhibit
, nullptr, GRFInhibit
, GRFInhibit
, GRFInhibit
, },
9259 /* 0x0F */ { nullptr, GRFUnsafe
, nullptr, FeatureTownName
, nullptr, nullptr, },
9260 /* 0x10 */ { nullptr, nullptr, DefineGotoLabel
, nullptr, nullptr, nullptr, },
9261 /* 0x11 */ { SkipAct11
, GRFUnsafe
, SkipAct11
, GRFSound
, SkipAct11
, GRFSound
, },
9262 /* 0x12 */ { SkipAct12
, SkipAct12
, SkipAct12
, SkipAct12
, SkipAct12
, LoadFontGlyph
, },
9263 /* 0x13 */ { nullptr, nullptr, nullptr, nullptr, nullptr, TranslateGRFStrings
, },
9264 /* 0x14 */ { StaticGRFInfo
, nullptr, nullptr, nullptr, nullptr, nullptr, },
9267 GRFLocation
location(_cur
.grfconfig
->ident
.grfid
, _cur
.nfo_line
);
9269 GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.find(location
);
9270 if (it
== _grf_line_to_action6_sprite_override
.end()) {
9271 /* No preloaded sprite to work with; read the
9272 * pseudo sprite content. */
9273 FioReadBlock(buf
, num
);
9275 /* Use the preloaded sprite data. */
9276 buf
= _grf_line_to_action6_sprite_override
[location
];
9277 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
9279 /* Skip the real (original) content of this action. */
9280 FioSeekTo(num
, SEEK_CUR
);
9283 ByteReader
br(buf
, buf
+ num
);
9284 ByteReader
*bufp
= &br
;
9287 byte action
= bufp
->ReadByte();
9289 if (action
== 0xFF) {
9290 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
9291 } else if (action
== 0xFE) {
9292 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
9293 } else if (action
>= lengthof(handlers
)) {
9294 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action
);
9295 } else if (handlers
[action
][stage
] == nullptr) {
9296 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action
, stage
);
9298 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action
, stage
);
9299 handlers
[action
][stage
](bufp
);
9302 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
9303 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS
);
9308 /** Signature of a container version 2 GRF. */
9309 extern const byte _grf_cont_v2_sig
[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
9312 * Get the container version of the currently opened GRF file.
9313 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
9315 byte
GetGRFContainerVersion()
9317 size_t pos
= FioGetPos();
9319 if (FioReadWord() == 0) {
9320 /* Check for GRF container version 2, which is identified by the bytes
9321 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
9322 for (uint i
= 0; i
< lengthof(_grf_cont_v2_sig
); i
++) {
9323 if (FioReadByte() != _grf_cont_v2_sig
[i
]) return 0; // Invalid format
9329 /* Container version 1 has no header, rewind to start. */
9330 FioSeekTo(pos
, SEEK_SET
);
9335 * Load a particular NewGRF.
9336 * @param config The configuration of the to be loaded NewGRF.
9337 * @param file_index The Fio index of the first NewGRF to load.
9338 * @param stage The loading stage of the NewGRF.
9339 * @param subdir The sub directory to find the NewGRF in.
9341 void LoadNewGRFFile(GRFConfig
*config
, uint file_index
, GrfLoadingStage stage
, Subdirectory subdir
)
9343 const char *filename
= config
->filename
;
9345 /* A .grf file is activated only if it was active when the game was
9346 * started. If a game is loaded, only its active .grfs will be
9347 * reactivated, unless "loadallgraphics on" is used. A .grf file is
9348 * considered active if its action 8 has been processed, i.e. its
9349 * action 8 hasn't been skipped using an action 7.
9351 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
9352 * carried out. All others are ignored, because they only need to be
9353 * processed once at initialization. */
9354 if (stage
!= GLS_FILESCAN
&& stage
!= GLS_SAFETYSCAN
&& stage
!= GLS_LABELSCAN
) {
9355 _cur
.grffile
= GetFileByFilename(filename
);
9356 if (_cur
.grffile
== nullptr) usererror("File '%s' lost in cache.\n", filename
);
9357 if (stage
== GLS_RESERVE
&& config
->status
!= GCS_INITIALISED
) return;
9358 if (stage
== GLS_ACTIVATION
&& !HasBit(config
->flags
, GCF_RESERVED
)) return;
9361 if (file_index
>= MAX_FILE_SLOTS
) {
9362 DEBUG(grf
, 0, "'%s' is not loaded as the maximum number of file slots has been reached", filename
);
9363 config
->status
= GCS_DISABLED
;
9364 config
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED
);
9368 FioOpenFile(file_index
, filename
, subdir
);
9369 _cur
.file_index
= file_index
; // XXX
9370 _palette_remap_grf
[_cur
.file_index
] = (config
->palette
& GRFP_USE_MASK
);
9372 _cur
.grfconfig
= config
;
9374 DEBUG(grf
, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename
);
9376 _cur
.grf_container_ver
= GetGRFContainerVersion();
9377 if (_cur
.grf_container_ver
== 0) {
9378 DEBUG(grf
, 7, "LoadNewGRFFile: Custom .grf has invalid format");
9382 if (stage
== GLS_INIT
|| stage
== GLS_ACTIVATION
) {
9383 /* We need the sprite offsets in the init stage for NewGRF sounds
9384 * and in the activation stage for real sprites. */
9385 ReadGRFSpriteOffsets(_cur
.grf_container_ver
);
9387 /* Skip sprite section offset if present. */
9388 if (_cur
.grf_container_ver
>= 2) FioReadDword();
9391 if (_cur
.grf_container_ver
>= 2) {
9392 /* Read compression value. */
9393 byte compression
= FioReadByte();
9394 if (compression
!= 0) {
9395 DEBUG(grf
, 7, "LoadNewGRFFile: Unsupported compression format");
9400 /* Skip the first sprite; we don't care about how many sprites this
9401 * does contain; newest TTDPatches and George's longvehicles don't
9402 * neither, apparently. */
9403 uint32 num
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
9404 if (num
== 4 && FioReadByte() == 0xFF) {
9407 DEBUG(grf
, 7, "LoadNewGRFFile: Custom .grf has invalid format");
9411 _cur
.ClearDataForNextFile();
9413 ReusableBuffer
<byte
> buf
;
9415 while ((num
= (_cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord())) != 0) {
9416 byte type
= FioReadByte();
9420 if (_cur
.skip_sprites
== 0) {
9421 DecodeSpecialSprite(buf
.Allocate(num
), num
, stage
);
9423 /* Stop all processing if we are to skip the remaining sprites */
9424 if (_cur
.skip_sprites
== -1) break;
9431 if (_cur
.skip_sprites
== 0) {
9432 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
9433 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE
);
9437 if (_cur
.grf_container_ver
>= 2 && type
== 0xFD) {
9438 /* Reference to data section. Container version >= 2 only. */
9442 SkipSpriteData(type
, num
- 8);
9446 if (_cur
.skip_sprites
> 0) _cur
.skip_sprites
--;
9451 * Relocates the old shore sprites at new positions.
9453 * 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)
9454 * 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)
9455 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
9457 static void ActivateOldShore()
9459 /* Use default graphics, if no shore sprites were loaded.
9460 * Should not happen, as the base set's extra grf should include some. */
9461 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_NONE
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_A
;
9463 if (_loaded_newgrf_features
.shore
!= SHORE_REPLACE_ACTION_5
) {
9464 DupSprite(SPR_ORIGINALSHORE_START
+ 1, SPR_SHORE_BASE
+ 1); // SLOPE_W
9465 DupSprite(SPR_ORIGINALSHORE_START
+ 2, SPR_SHORE_BASE
+ 2); // SLOPE_S
9466 DupSprite(SPR_ORIGINALSHORE_START
+ 6, SPR_SHORE_BASE
+ 3); // SLOPE_SW
9467 DupSprite(SPR_ORIGINALSHORE_START
+ 0, SPR_SHORE_BASE
+ 4); // SLOPE_E
9468 DupSprite(SPR_ORIGINALSHORE_START
+ 4, SPR_SHORE_BASE
+ 6); // SLOPE_SE
9469 DupSprite(SPR_ORIGINALSHORE_START
+ 3, SPR_SHORE_BASE
+ 8); // SLOPE_N
9470 DupSprite(SPR_ORIGINALSHORE_START
+ 7, SPR_SHORE_BASE
+ 9); // SLOPE_NW
9471 DupSprite(SPR_ORIGINALSHORE_START
+ 5, SPR_SHORE_BASE
+ 12); // SLOPE_NE
9474 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_ACTION_A
) {
9475 DupSprite(SPR_FLAT_GRASS_TILE
+ 16, SPR_SHORE_BASE
+ 0); // SLOPE_STEEP_S
9476 DupSprite(SPR_FLAT_GRASS_TILE
+ 17, SPR_SHORE_BASE
+ 5); // SLOPE_STEEP_W
9477 DupSprite(SPR_FLAT_GRASS_TILE
+ 7, SPR_SHORE_BASE
+ 7); // SLOPE_WSE
9478 DupSprite(SPR_FLAT_GRASS_TILE
+ 15, SPR_SHORE_BASE
+ 10); // SLOPE_STEEP_N
9479 DupSprite(SPR_FLAT_GRASS_TILE
+ 11, SPR_SHORE_BASE
+ 11); // SLOPE_NWS
9480 DupSprite(SPR_FLAT_GRASS_TILE
+ 13, SPR_SHORE_BASE
+ 13); // SLOPE_ENW
9481 DupSprite(SPR_FLAT_GRASS_TILE
+ 14, SPR_SHORE_BASE
+ 14); // SLOPE_SEN
9482 DupSprite(SPR_FLAT_GRASS_TILE
+ 18, SPR_SHORE_BASE
+ 15); // SLOPE_STEEP_E
9484 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
9485 * If they would be used somewhen, then these grass tiles will most like not look as needed */
9486 DupSprite(SPR_FLAT_GRASS_TILE
+ 5, SPR_SHORE_BASE
+ 16); // SLOPE_EW
9487 DupSprite(SPR_FLAT_GRASS_TILE
+ 10, SPR_SHORE_BASE
+ 17); // SLOPE_NS
9492 * Replocate the old tram depot sprites to the new position, if no new ones were loaded.
9494 static void ActivateOldTramDepot()
9496 if (_loaded_newgrf_features
.tram
== TRAMWAY_REPLACE_DEPOT_WITH_TRACK
) {
9497 DupSprite(SPR_ROAD_DEPOT
+ 0, SPR_TRAMWAY_DEPOT_NO_TRACK
+ 0); // use road depot graphics for "no tracks"
9498 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK
+ 1, SPR_TRAMWAY_DEPOT_NO_TRACK
+ 1);
9499 DupSprite(SPR_ROAD_DEPOT
+ 2, SPR_TRAMWAY_DEPOT_NO_TRACK
+ 2); // use road depot graphics for "no tracks"
9500 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK
+ 3, SPR_TRAMWAY_DEPOT_NO_TRACK
+ 3);
9501 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK
+ 4, SPR_TRAMWAY_DEPOT_NO_TRACK
+ 4);
9502 DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK
+ 5, SPR_TRAMWAY_DEPOT_NO_TRACK
+ 5);
9507 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
9509 static void FinalisePriceBaseMultipliers()
9511 extern const PriceBaseSpec _price_base_specs
[];
9512 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
9513 static const uint32 override_features
= (1 << GSF_TRAINS
) | (1 << GSF_ROADVEHICLES
) | (1 << GSF_SHIPS
) | (1 << GSF_AIRCRAFT
);
9515 /* Evaluate grf overrides */
9516 int num_grfs
= (uint
)_grf_files
.size();
9517 int *grf_overrides
= AllocaM(int, num_grfs
);
9518 for (int i
= 0; i
< num_grfs
; i
++) {
9519 grf_overrides
[i
] = -1;
9521 GRFFile
*source
= _grf_files
[i
];
9522 uint32 override
= _grf_id_overrides
[source
->grfid
];
9523 if (override
== 0) continue;
9525 GRFFile
*dest
= GetFileByGRFID(override
);
9526 if (dest
== nullptr) continue;
9528 grf_overrides
[i
] = find_index(_grf_files
, dest
);
9529 assert(grf_overrides
[i
] >= 0);
9532 /* Override features and price base multipliers of earlier loaded grfs */
9533 for (int i
= 0; i
< num_grfs
; i
++) {
9534 if (grf_overrides
[i
] < 0 || grf_overrides
[i
] >= i
) continue;
9535 GRFFile
*source
= _grf_files
[i
];
9536 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9538 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9539 source
->grf_features
|= features
;
9540 dest
->grf_features
|= features
;
9542 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9543 /* No price defined -> nothing to do */
9544 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
) || source
->price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) continue;
9545 DEBUG(grf
, 3, "'%s' overrides price base multiplier %d of '%s'", source
->filename
, p
, dest
->filename
);
9546 dest
->price_base_multipliers
[p
] = source
->price_base_multipliers
[p
];
9550 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9551 for (int i
= num_grfs
- 1; i
>= 0; i
--) {
9552 if (grf_overrides
[i
] < 0 || grf_overrides
[i
] <= i
) continue;
9553 GRFFile
*source
= _grf_files
[i
];
9554 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9556 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9557 source
->grf_features
|= features
;
9558 dest
->grf_features
|= features
;
9560 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9561 /* Already a price defined -> nothing to do */
9562 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
) || dest
->price_base_multipliers
[p
] != INVALID_PRICE_MODIFIER
) continue;
9563 DEBUG(grf
, 3, "Price base multiplier %d from '%s' propagated to '%s'", p
, source
->filename
, dest
->filename
);
9564 dest
->price_base_multipliers
[p
] = source
->price_base_multipliers
[p
];
9568 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9569 for (int i
= 0; i
< num_grfs
; i
++) {
9570 if (grf_overrides
[i
] < 0) continue;
9571 GRFFile
*source
= _grf_files
[i
];
9572 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9574 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9575 source
->grf_features
|= features
;
9576 dest
->grf_features
|= features
;
9578 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9579 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
)) continue;
9580 if (source
->price_base_multipliers
[p
] != dest
->price_base_multipliers
[p
]) {
9581 DEBUG(grf
, 3, "Price base multiplier %d from '%s' propagated to '%s'", p
, dest
->filename
, source
->filename
);
9583 source
->price_base_multipliers
[p
] = dest
->price_base_multipliers
[p
];
9587 /* Apply fallback prices for grf version < 8 */
9588 for (GRFFile
* const file
: _grf_files
) {
9589 if (file
->grf_version
>= 8) continue;
9590 PriceMultipliers
&price_base_multipliers
= file
->price_base_multipliers
;
9591 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9592 Price fallback_price
= _price_base_specs
[p
].fallback_price
;
9593 if (fallback_price
!= INVALID_PRICE
&& price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) {
9594 /* No price multiplier has been set.
9595 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9596 price_base_multipliers
[p
] = price_base_multipliers
[fallback_price
];
9601 /* Decide local/global scope of price base multipliers */
9602 for (GRFFile
* const file
: _grf_files
) {
9603 PriceMultipliers
&price_base_multipliers
= file
->price_base_multipliers
;
9604 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9605 if (price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) {
9606 /* No multiplier was set; set it to a neutral value */
9607 price_base_multipliers
[p
] = 0;
9609 if (!HasBit(file
->grf_features
, _price_base_specs
[p
].grf_feature
)) {
9610 /* The grf does not define any objects of the feature,
9611 * so it must be a difficulty setting. Apply it globally */
9612 DEBUG(grf
, 3, "'%s' sets global price base multiplier %d", file
->filename
, p
);
9613 SetPriceBaseMultiplier(p
, price_base_multipliers
[p
]);
9614 price_base_multipliers
[p
] = 0;
9616 DEBUG(grf
, 3, "'%s' sets local price base multiplier %d", file
->filename
, p
);
9623 extern void InitGRFTownGeneratorNames();
9625 /** Finish loading NewGRFs and execute needed post-processing */
9626 static void AfterLoadGRFs()
9628 for (StringIDMapping
&it
: _string_to_grf_mapping
) {
9629 *it
.target
= MapGRFStringID(it
.grfid
, it
.source
);
9631 _string_to_grf_mapping
.clear();
9633 /* Free the action 6 override sprites. */
9634 for (GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.begin(); it
!= _grf_line_to_action6_sprite_override
.end(); it
++) {
9637 _grf_line_to_action6_sprite_override
.clear();
9639 /* Polish cargoes */
9640 FinaliseCargoArray();
9642 /* Pre-calculate all refit masks after loading GRF files. */
9643 CalculateRefitMasks();
9645 /* Polish engines */
9646 FinaliseEngineArray();
9648 /* Set the actually used Canal properties */
9651 /* Add all new houses to the house array. */
9652 FinaliseHouseArray();
9654 /* Add all new industries to the industry array. */
9655 FinaliseIndustriesArray();
9657 /* Add all new objects to the object array. */
9658 FinaliseObjectsArray();
9660 InitializeSortedCargoSpecs();
9662 /* Sort the list of industry types. */
9663 SortIndustryTypes();
9665 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9666 BuildIndustriesLegend();
9668 /* Build the routemap legend, based on the available cargos */
9669 BuildLinkStatsLegend();
9671 /* Add all new airports to the airports array. */
9672 FinaliseAirportsArray();
9675 /* Update the townname generators list */
9676 InitGRFTownGeneratorNames();
9678 /* Run all queued vehicle list order changes */
9679 CommitVehicleListOrderChanges();
9681 /* Load old shore sprites in new position, if they were replaced by ActionA */
9684 /* Load old tram depot sprites in new position, if no new ones are present */
9685 ActivateOldTramDepot();
9687 /* Set up custom rail types */
9691 for (Engine
*e
: Engine::IterateType(VEH_ROAD
)) {
9692 if (_gted
[e
->index
].rv_max_speed
!= 0) {
9693 /* Set RV maximum speed from the mph/0.8 unit value */
9694 e
->u
.road
.max_speed
= _gted
[e
->index
].rv_max_speed
* 4;
9697 RoadTramType rtt
= HasBit(e
->info
.misc_flags
, EF_ROAD_TRAM
) ? RTT_TRAM
: RTT_ROAD
;
9699 const GRFFile
*file
= e
->GetGRF();
9700 if (file
== nullptr || _gted
[e
->index
].roadtramtype
== 0) {
9701 e
->u
.road
.roadtype
= (rtt
== RTT_TRAM
) ? ROADTYPE_TRAM
: ROADTYPE_ROAD
;
9705 /* Remove +1 offset. */
9706 _gted
[e
->index
].roadtramtype
--;
9708 const std::vector
<RoadTypeLabel
> *list
= (rtt
== RTT_TRAM
) ? &file
->tramtype_list
: &file
->roadtype_list
;
9709 if (_gted
[e
->index
].roadtramtype
< list
->size())
9711 RoadTypeLabel rtl
= (*list
)[_gted
[e
->index
].roadtramtype
];
9712 RoadType rt
= GetRoadTypeByLabel(rtl
);
9713 if (rt
!= INVALID_ROADTYPE
&& GetRoadTramType(rt
) == rtt
) {
9714 e
->u
.road
.roadtype
= rt
;
9719 /* Road type is not available, so disable this engine */
9720 e
->info
.climates
= 0;
9723 for (Engine
*e
: Engine::IterateType(VEH_TRAIN
)) {
9724 RailType railtype
= GetRailTypeByLabel(_gted
[e
->index
].railtypelabel
);
9725 if (railtype
== INVALID_RAILTYPE
) {
9726 /* Rail type is not available, so disable this engine */
9727 e
->info
.climates
= 0;
9729 e
->u
.rail
.railtype
= railtype
;
9733 SetYearEngineAgingStops();
9735 FinalisePriceBaseMultipliers();
9737 /* Deallocate temporary loading data */
9739 _grm_sprites
.clear();
9743 * Load all the NewGRFs.
9744 * @param load_index The offset for the first sprite to add.
9745 * @param file_index The Fio index of the first NewGRF to load.
9746 * @param num_baseset Number of NewGRFs at the front of the list to look up in the baseset dir instead of the newgrf dir.
9748 void LoadNewGRF(uint load_index
, uint file_index
, uint num_baseset
)
9750 /* In case of networking we need to "sync" the start values
9751 * so all NewGRFs are loaded equally. For this we use the
9752 * start date of the game and we set the counters, etc. to
9753 * 0 so they're the same too. */
9755 Year year
= _cur_year
;
9756 DateFract date_fract
= _date_fract
;
9757 uint16 tick_counter
= _tick_counter
;
9758 byte display_opt
= _display_opt
;
9761 _cur_year
= _settings_game
.game_creation
.starting_year
;
9762 _date
= ConvertYMDToDate(_cur_year
, 0, 1);
9768 InitializeGRFSpecial();
9773 * Reset the status of all files, so we can 'retry' to load them.
9774 * This is needed when one for example rearranges the NewGRFs in-game
9775 * and a previously disabled NewGRF becomes usable. If it would not
9776 * be reset, the NewGRF would remain disabled even though it should
9777 * have been enabled.
9779 for (GRFConfig
*c
= _grfconfig
; c
!= nullptr; c
= c
->next
) {
9780 if (c
->status
!= GCS_NOT_FOUND
) c
->status
= GCS_UNKNOWN
;
9783 _cur
.spriteid
= load_index
;
9785 /* Load newgrf sprites
9786 * in each loading stage, (try to) open each file specified in the config
9787 * and load information from it. */
9788 for (GrfLoadingStage stage
= GLS_LABELSCAN
; stage
<= GLS_ACTIVATION
; stage
++) {
9789 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9790 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9791 for (GRFConfig
*c
= _grfconfig
; c
!= nullptr; c
= c
->next
) {
9792 if (c
->status
== GCS_ACTIVATED
) c
->status
= GCS_INITIALISED
;
9795 if (stage
== GLS_RESERVE
) {
9796 static const uint32 overrides
[][2] = {
9797 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9798 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9799 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9801 for (size_t i
= 0; i
< lengthof(overrides
); i
++) {
9802 SetNewGRFOverride(BSWAP32(overrides
[i
][0]), BSWAP32(overrides
[i
][1]));
9806 uint slot
= file_index
;
9807 uint num_non_static
= 0;
9810 for (GRFConfig
*c
= _grfconfig
; c
!= nullptr; c
= c
->next
) {
9811 if (c
->status
== GCS_DISABLED
|| c
->status
== GCS_NOT_FOUND
) continue;
9812 if (stage
> GLS_INIT
&& HasBit(c
->flags
, GCF_INIT_ONLY
)) continue;
9814 Subdirectory subdir
= slot
< file_index
+ num_baseset
? BASESET_DIR
: NEWGRF_DIR
;
9815 if (!FioCheckFileExists(c
->filename
, subdir
)) {
9816 DEBUG(grf
, 0, "NewGRF file is missing '%s'; disabling", c
->filename
);
9817 c
->status
= GCS_NOT_FOUND
;
9821 if (stage
== GLS_LABELSCAN
) InitNewGRFFile(c
);
9823 if (!HasBit(c
->flags
, GCF_STATIC
) && !HasBit(c
->flags
, GCF_SYSTEM
)) {
9824 if (num_non_static
== NETWORK_MAX_GRF_COUNT
) {
9825 DEBUG(grf
, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c
->filename
);
9826 c
->status
= GCS_DISABLED
;
9827 c
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED
);
9832 LoadNewGRFFile(c
, slot
++, stage
, subdir
);
9833 if (stage
== GLS_RESERVE
) {
9834 SetBit(c
->flags
, GCF_RESERVED
);
9835 } else if (stage
== GLS_ACTIVATION
) {
9836 ClrBit(c
->flags
, GCF_RESERVED
);
9837 assert(GetFileByGRFID(c
->ident
.grfid
) == _cur
.grffile
);
9838 ClearTemporaryNewGRFData(_cur
.grffile
);
9839 BuildCargoTranslationMap();
9840 DEBUG(sprite
, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur
.spriteid
);
9841 } else if (stage
== GLS_INIT
&& HasBit(c
->flags
, GCF_INIT_ONLY
)) {
9842 /* We're not going to activate this, so free whatever data we allocated */
9843 ClearTemporaryNewGRFData(_cur
.grffile
);
9848 /* Pseudo sprite processing is finished; free temporary stuff */
9849 _cur
.ClearDataForNextFile();
9851 /* Call any functions that should be run after GRFs have been loaded. */
9854 /* Now revert back to the original situation */
9857 _date_fract
= date_fract
;
9858 _tick_counter
= tick_counter
;
9859 _display_opt
= display_opt
;