4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
10 /** @file newgrf.cpp Base of all NewGRF support. */
18 #include "fileio_func.h"
19 #include "engine_func.h"
20 #include "engine_base.h"
23 #include "newgrf_engine.h"
24 #include "newgrf_text.h"
25 #include "fontcache.h"
27 #include "landscape.h"
28 #include "newgrf_cargo.h"
29 #include "newgrf_house.h"
30 #include "newgrf_sound.h"
31 #include "newgrf_station.h"
32 #include "industrytype.h"
33 #include "newgrf_canal.h"
34 #include "newgrf_townname.h"
35 #include "newgrf_industries.h"
36 #include "newgrf_airporttiles.h"
37 #include "newgrf_airport.h"
38 #include "newgrf_object.h"
41 #include "strings_func.h"
42 #include "date_func.h"
43 #include "string_func.h"
44 #include "network/network.h"
46 #include "smallmap_gui.h"
49 #include "vehicle_func.h"
51 #include "vehicle_base.h"
53 #include "table/strings.h"
54 #include "table/build_industry.h"
56 #include "safeguards.h"
58 /* TTDPatch extended GRF format codec
59 * (c) Petr Baudis 2004 (GPL'd)
60 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
62 * Contains portions of documentation by TTDPatch team.
63 * Thanks especially to Josef Drexler for the documentation as well as a lot
64 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
65 * served as subject to the initial testing of this codec. */
67 /** List of all loaded GRF files */
68 static SmallVector
<GRFFile
*, 16> _grf_files
;
70 /** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
71 byte _misc_grf_features
= 0;
73 /** 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
74 static uint32 _ttdpatch_flags
[8];
76 /** Indicates which are the newgrf features currently loaded ingame */
77 GRFLoadedFeatures _loaded_newgrf_features
;
79 static const uint MAX_SPRITEGROUP
= UINT8_MAX
; ///< Maximum GRF-local ID for a spritegroup.
81 /** Temporary data during loading of GRFs */
82 struct GrfProcessingState
{
84 /** Definition of a single Action1 spriteset */
86 SpriteID sprite
; ///< SpriteID of the first sprite of the set.
87 uint num_sprites
; ///< Number of sprites in the set.
90 /** Currently referenceable spritesets */
91 std::map
<uint
, SpriteSet
> spritesets
[GSF_END
];
95 GrfLoadingStage stage
; ///< Current loading stage
96 SpriteID spriteid
; ///< First available SpriteID for loading realsprites.
98 /* Local state in the file */
99 uint file_index
; ///< File index of currently processed GRF file.
100 GRFFile
*grffile
; ///< Currently processed GRF file.
101 GRFConfig
*grfconfig
; ///< Config of the currently processed GRF file.
102 uint32 nfo_line
; ///< Currently processed pseudo sprite number in the GRF.
103 byte grf_container_ver
; ///< Container format of the current GRF file.
105 /* Kind of return values when processing certain actions */
106 int skip_sprites
; ///< Number of psuedo sprites to skip before processing the next one. (-1 to skip to end of file)
108 /* Currently referenceable spritegroups */
109 SpriteGroup
*spritegroups
[MAX_SPRITEGROUP
+ 1];
111 /** Clear temporary data before processing the next file in the current loading stage */
112 void ClearDataForNextFile()
115 this->skip_sprites
= 0;
117 for (uint i
= 0; i
< GSF_END
; i
++) {
118 this->spritesets
[i
].clear();
121 memset(this->spritegroups
, 0, sizeof(this->spritegroups
));
125 * Records new spritesets.
126 * @param feature GrfSpecFeature the set is defined for.
127 * @param first_sprite SpriteID of the first sprite in the set.
128 * @param first_set First spriteset to define.
129 * @param numsets Number of sets to define.
130 * @param numents Number of sprites per set to define.
132 void AddSpriteSets(byte feature
, SpriteID first_sprite
, uint first_set
, uint numsets
, uint numents
)
134 assert(feature
< GSF_END
);
135 for (uint i
= 0; i
< numsets
; i
++) {
136 SpriteSet
&set
= this->spritesets
[feature
][first_set
+ i
];
137 set
.sprite
= first_sprite
+ i
* numents
;
138 set
.num_sprites
= numents
;
143 * Check whether there are any valid spritesets for a feature.
144 * @param feature GrfSpecFeature to check.
145 * @return true if there are any valid sets.
146 * @note Spritesets with zero sprites are valid to allow callback-failures.
148 bool HasValidSpriteSets(byte feature
) const
150 assert(feature
< GSF_END
);
151 return !this->spritesets
[feature
].empty();
155 * Check whether a specific set is defined.
156 * @param feature GrfSpecFeature to check.
157 * @param set Set to check.
158 * @return true if the set is valid.
159 * @note Spritesets with zero sprites are valid to allow callback-failures.
161 bool IsValidSpriteSet(byte feature
, uint set
) const
163 assert(feature
< GSF_END
);
164 return this->spritesets
[feature
].find(set
) != this->spritesets
[feature
].end();
168 * Returns the first sprite of a spriteset.
169 * @param feature GrfSpecFeature to query.
170 * @param set Set to query.
171 * @return First sprite of the set.
173 SpriteID
GetSprite(byte feature
, uint set
) const
175 assert(IsValidSpriteSet(feature
, set
));
176 return this->spritesets
[feature
].find(set
)->second
.sprite
;
180 * Returns the number of sprites in a spriteset
181 * @param feature GrfSpecFeature to query.
182 * @param set Set to query.
183 * @return Number of sprites in the set.
185 uint
GetNumEnts(byte feature
, uint set
) const
187 assert(IsValidSpriteSet(feature
, set
));
188 return this->spritesets
[feature
].find(set
)->second
.num_sprites
;
192 static GrfProcessingState _cur
;
196 * Helper to check whether an image index is valid for a particular NewGRF vehicle.
197 * @param <T> The type of vehicle.
198 * @param image_index The image index to check.
199 * @return True iff the image index is valid, or 0xFD (use new graphics).
201 template <VehicleType T
>
202 static inline bool IsValidNewGRFImageIndex(uint8 image_index
)
204 return image_index
== 0xFD || IsValidImageIndex
<T
>(image_index
);
207 class OTTDByteReaderSignal
{ };
209 /** Class to read from a NewGRF file */
216 ByteReader(byte
*data
, byte
*end
) : data(data
), end(end
) { }
218 inline byte
ReadByte()
220 if (data
< end
) return *(data
)++;
221 throw OTTDByteReaderSignal();
226 uint16 val
= ReadByte();
227 return val
| (ReadByte() << 8);
230 uint16
ReadExtendedByte()
232 uint16 val
= ReadByte();
233 return val
== 0xFF ? ReadWord() : val
;
238 uint32 val
= ReadWord();
239 return val
| (ReadWord() << 16);
242 uint32
ReadVarSize(byte size
)
245 case 1: return ReadByte();
246 case 2: return ReadWord();
247 case 4: return ReadDWord();
254 const char *ReadString()
256 char *string
= reinterpret_cast<char *>(data
);
257 size_t string_length
= ttd_strnlen(string
, Remaining());
259 if (string_length
== Remaining()) {
260 /* String was not NUL terminated, so make sure it is now. */
261 string
[string_length
- 1] = '\0';
262 grfmsg(7, "String was not terminated with a zero byte.");
264 /* Increase the string length to include the NUL byte. */
272 inline size_t Remaining() const
277 inline bool HasData(size_t count
= 1) const
279 return data
+ count
<= end
;
287 inline void Skip(size_t len
)
290 /* It is valid to move the buffer to exactly the end of the data,
291 * as there may not be any more data read. */
292 if (data
> end
) throw OTTDByteReaderSignal();
296 typedef void (*SpecialSpriteHandler
)(ByteReader
*buf
);
298 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.
300 /** Temporary engine data used when loading only */
301 struct GRFTempEngineData
{
302 /** Summary state of refittability properties */
304 UNSET
= 0, ///< No properties assigned. Default refit masks shall be activated.
305 EMPTY
, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
306 NONEMPTY
, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
309 uint16 cargo_allowed
;
310 uint16 cargo_disallowed
;
311 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 uint32 ctt_include_mask
; ///< Cargo types always included in the refit mask.
317 uint32 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 const GRFFile
* const *end
= _grf_files
.End();
395 for (GRFFile
* const *file
= _grf_files
.Begin(); file
!= end
; file
++) {
396 if ((*file
)->grfid
== grfid
) return *file
;
402 * Obtain a NewGRF file by its filename
403 * @param filename The filename to obtain the file for.
406 static GRFFile
*GetFileByFilename(const char *filename
)
408 const GRFFile
* const *end
= _grf_files
.End();
409 for (GRFFile
* const *file
= _grf_files
.Begin(); file
!= end
; file
++) {
410 if (strcmp((*file
)->filename
, filename
) == 0) return *file
;
415 /** Reset all NewGRFData that was used only while processing data */
416 static void ClearTemporaryNewGRFData(GRFFile
*gf
)
418 /* Clear the GOTO labels used for GRF processing */
419 for (GRFLabel
*l
= gf
->label
; l
!= NULL
;) {
420 GRFLabel
*l2
= l
->next
;
429 * @param message Error message or STR_NULL.
430 * @param config GRFConfig to disable, NULL for current.
431 * @return Error message of the GRF for further customisation.
433 static GRFError
*DisableGrf(StringID message
= STR_NULL
, GRFConfig
*config
= NULL
)
436 if (config
!= NULL
) {
437 file
= GetFileByGRFID(config
->ident
.grfid
);
439 config
= _cur
.grfconfig
;
443 config
->status
= GCS_DISABLED
;
444 if (file
!= NULL
) ClearTemporaryNewGRFData(file
);
445 if (config
== _cur
.grfconfig
) _cur
.skip_sprites
= -1;
447 if (message
!= STR_NULL
) {
448 delete config
->error
;
449 config
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, message
);
450 if (config
== _cur
.grfconfig
) config
->error
->param_value
[0] = _cur
.nfo_line
;
453 return config
->error
;
457 * Information for mapping static StringIDs.
459 struct StringIDMapping
{
460 uint32 grfid
; ///< Source NewGRF.
461 StringID source
; ///< Source StringID (GRF local).
462 StringID
*target
; ///< Destination for mapping result.
464 typedef SmallVector
<StringIDMapping
, 16> StringIDMappingVector
;
465 static StringIDMappingVector _string_to_grf_mapping
;
468 * Record a static StringID for getting translated later.
469 * @param source Source StringID (GRF local).
470 * @param target Destination for the mapping result.
472 static void AddStringForMapping(StringID source
, StringID
*target
)
474 *target
= STR_UNDEFINED
;
475 StringIDMapping
*item
= _string_to_grf_mapping
.Append();
476 item
->grfid
= _cur
.grffile
->grfid
;
477 item
->source
= source
;
478 item
->target
= target
;
482 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
483 * string IDs, but only for the ones we are aware off; the rest
484 * like likely unused and will show a warning.
485 * @param str the string ID to convert
486 * @return the converted string ID
488 static StringID
TTDPStringIDToOTTDStringIDMapping(StringID str
)
490 /* StringID table for TextIDs 0x4E->0x6D */
491 static const StringID units_volume
[] = {
492 STR_ITEMS
, STR_PASSENGERS
, STR_TONS
, STR_BAGS
,
493 STR_LITERS
, STR_ITEMS
, STR_CRATES
, STR_TONS
,
494 STR_TONS
, STR_TONS
, STR_TONS
, STR_BAGS
,
495 STR_TONS
, STR_TONS
, STR_TONS
, STR_BAGS
,
496 STR_TONS
, STR_TONS
, STR_BAGS
, STR_LITERS
,
497 STR_TONS
, STR_LITERS
, STR_TONS
, STR_ITEMS
,
498 STR_BAGS
, STR_LITERS
, STR_TONS
, STR_ITEMS
,
499 STR_TONS
, STR_ITEMS
, STR_LITERS
, STR_ITEMS
502 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
503 assert(!IsInsideMM(str
, 0xD000, 0xD7FF));
505 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
506 assert_compile(stringend - stringid == end - begin); \
507 if (str >= begin && str <= end) return str + (stringid - begin)
509 /* We have some changes in our cargo strings, resulting in some missing. */
510 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING
, STR_CARGO_PLURAL_FIZZY_DRINKS
);
511 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING
, STR_CARGO_SINGULAR_FIZZY_DRINK
);
512 if (str
>= 0x004E && str
<= 0x006D) return units_volume
[str
- 0x004E];
513 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING
, STR_QUANTITY_FIZZY_DRINKS
);
514 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING
, STR_ABBREV_FIZZY_DRINKS
);
515 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE
, STR_COLOUR_WHITE
);
517 /* Map building names according to our lang file changes. There are several
518 * ranges of house ids, all of which need to be remapped to allow newgrfs
519 * to use original house names. */
520 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1
, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1
);
521 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1
, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1
);
522 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1
, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1
);
524 /* Same thing for industries */
525 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE
, STR_INDUSTRY_NAME_SUGAR_MINE
);
526 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION
, STR_NEWS_INDUSTRY_PLANTED
);
527 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL
, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES
);
528 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL
, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM
);
529 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL
, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM
);
532 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY
;
533 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED
;
534 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED
;
536 #undef TEXTID_TO_STRINGID
538 if (str
== STR_NULL
) return STR_EMPTY
;
540 DEBUG(grf
, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str
);
546 * Used when setting an object's property to map to the GRF's strings
547 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
548 * @param grfid Id of the grf file.
549 * @param str StringID that we want to have the equivalent in OoenTTD.
550 * @return The properly adjusted StringID.
552 StringID
MapGRFStringID(uint32 grfid
, StringID str
)
554 if (IsInsideMM(str
, 0xD800, 0xE000)) {
555 /* General text provided by NewGRF.
556 * In the specs this is called the 0xDCxx range (misc presistent texts),
557 * but we meanwhile extended the range to 0xD800-0xDFFF.
558 * Note: We are not involved in the "persistent" business, since we do not store
559 * any NewGRF strings in savegames. */
560 return GetGRFStringID(grfid
, str
);
561 } else if (IsInsideMM(str
, 0xD000, 0xD800)) {
562 /* Callback text provided by NewGRF.
563 * In the specs this is called the 0xD0xx range (misc graphics texts).
564 * These texts can be returned by various callbacks.
566 * Due to how TTDP implements the GRF-local- to global-textid translation
567 * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
568 * We do not care about that difference and just mask out the 0x400 bit.
571 return GetGRFStringID(grfid
, str
);
573 /* The NewGRF wants to include/reference an original TTD string.
574 * Try our best to find an equivalent one. */
575 return TTDPStringIDToOTTDStringIDMapping(str
);
579 static std::map
<uint32
, uint32
> _grf_id_overrides
;
582 * Set the override for a NewGRF
583 * @param source_grfid The grfID which wants to override another NewGRF.
584 * @param target_grfid The grfID which is being overridden.
586 static void SetNewGRFOverride(uint32 source_grfid
, uint32 target_grfid
)
588 _grf_id_overrides
[source_grfid
] = target_grfid
;
589 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid
), BSWAP32(target_grfid
));
593 * Returns the engine associated to a certain internal_id, resp. allocates it.
594 * @param file NewGRF that wants to change the engine.
595 * @param type Vehicle type.
596 * @param internal_id Engine ID inside the NewGRF.
597 * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04).
598 * @return The requested engine.
600 static Engine
*GetNewEngine(const GRFFile
*file
, VehicleType type
, uint16 internal_id
, bool static_access
= false)
602 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
603 * them use the same engine slots. */
604 uint32 scope_grfid
= INVALID_GRFID
; // If not using dynamic_engines, all newgrfs share their ID range
605 if (_settings_game
.vehicle
.dynamic_engines
) {
606 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
607 scope_grfid
= file
->grfid
;
608 uint32 override
= _grf_id_overrides
[file
->grfid
];
610 scope_grfid
= override
;
611 const GRFFile
*grf_match
= GetFileByGRFID(override
);
612 if (grf_match
== NULL
) {
613 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file
->grfid
), BSWAP32(override
));
615 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file
->grfid
), BSWAP32(override
));
619 /* Check if the engine is registered in the override manager */
620 EngineID engine
= _engine_mngr
.GetID(type
, internal_id
, scope_grfid
);
621 if (engine
!= INVALID_ENGINE
) {
622 Engine
*e
= Engine::Get(engine
);
623 if (e
->grf_prop
.grffile
== NULL
) e
->grf_prop
.grffile
= file
;
628 /* Check if there is an unreserved slot */
629 EngineID engine
= _engine_mngr
.GetID(type
, internal_id
, INVALID_GRFID
);
630 if (engine
!= INVALID_ENGINE
) {
631 Engine
*e
= Engine::Get(engine
);
633 if (e
->grf_prop
.grffile
== NULL
) {
634 e
->grf_prop
.grffile
= file
;
635 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e
->index
, BSWAP32(file
->grfid
), type
, internal_id
);
638 /* Reserve the engine slot */
639 if (!static_access
) {
640 EngineIDMapping
*eid
= _engine_mngr
.Get(engine
);
641 eid
->grfid
= scope_grfid
; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
647 if (static_access
) return NULL
;
649 if (!Engine::CanAllocateItem()) {
650 grfmsg(0, "Can't allocate any more engines");
654 size_t engine_pool_size
= Engine::GetPoolSize();
656 /* ... it's not, so create a new one based off an existing engine */
657 Engine
*e
= new Engine(type
, internal_id
);
658 e
->grf_prop
.grffile
= file
;
660 /* Reserve the engine slot */
661 assert(_engine_mngr
.Length() == e
->index
);
662 EngineIDMapping
*eid
= _engine_mngr
.Append();
664 eid
->grfid
= scope_grfid
; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
665 eid
->internal_id
= internal_id
;
666 eid
->substitute_id
= min(internal_id
, _engine_counts
[type
]); // substitute_id == _engine_counts[subtype] means "no substitute"
668 if (engine_pool_size
!= Engine::GetPoolSize()) {
669 /* Resize temporary engine data ... */
670 _gted
= ReallocT(_gted
, Engine::GetPoolSize());
672 /* and blank the new block. */
673 size_t len
= (Engine::GetPoolSize() - engine_pool_size
) * sizeof(*_gted
);
674 memset(_gted
+ engine_pool_size
, 0, len
);
676 if (type
== VEH_TRAIN
) {
677 _gted
[e
->index
].railtypelabel
= GetRailTypeInfo(e
->u
.rail
.railtype
)->label
;
680 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e
->index
, BSWAP32(file
->grfid
), type
, internal_id
);
686 * Return the ID of a new engine
687 * @param file The NewGRF file providing the engine.
688 * @param type The Vehicle type.
689 * @param internal_id NewGRF-internal ID of the engine.
690 * @return The new EngineID.
691 * @note depending on the dynamic_engine setting and a possible override
692 * property the grfID may be unique or overwriting or partially re-defining
693 * properties of an existing engine.
695 EngineID
GetNewEngineID(const GRFFile
*file
, VehicleType type
, uint16 internal_id
)
697 uint32 scope_grfid
= INVALID_GRFID
; // If not using dynamic_engines, all newgrfs share their ID range
698 if (_settings_game
.vehicle
.dynamic_engines
) {
699 scope_grfid
= file
->grfid
;
700 uint32 override
= _grf_id_overrides
[file
->grfid
];
701 if (override
!= 0) scope_grfid
= override
;
704 return _engine_mngr
.GetID(type
, internal_id
, scope_grfid
);
708 * Map the colour modifiers of TTDPatch to those that Open is using.
709 * @param grf_sprite Pointer to the structure been modified.
711 static void MapSpriteMappingRecolour(PalSpriteID
*grf_sprite
)
713 if (HasBit(grf_sprite
->pal
, 14)) {
714 ClrBit(grf_sprite
->pal
, 14);
715 SetBit(grf_sprite
->sprite
, SPRITE_MODIFIER_OPAQUE
);
718 if (HasBit(grf_sprite
->sprite
, 14)) {
719 ClrBit(grf_sprite
->sprite
, 14);
720 SetBit(grf_sprite
->sprite
, PALETTE_MODIFIER_TRANSPARENT
);
723 if (HasBit(grf_sprite
->sprite
, 15)) {
724 ClrBit(grf_sprite
->sprite
, 15);
725 SetBit(grf_sprite
->sprite
, PALETTE_MODIFIER_COLOUR
);
730 * Read a sprite and a palette from the GRF and convert them into a format
731 * suitable to OpenTTD.
732 * @param buf Input stream.
733 * @param read_flags Whether to read TileLayoutFlags.
734 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
735 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
736 * @param feature GrfSpecFeature to use spritesets from.
737 * @param [out] grf_sprite Read sprite and palette.
738 * @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
739 * @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
740 * @return Read TileLayoutFlags.
742 static TileLayoutFlags
ReadSpriteLayoutSprite(ByteReader
*buf
, bool read_flags
, bool invert_action1_flag
, bool use_cur_spritesets
, int feature
, PalSpriteID
*grf_sprite
, uint16
*max_sprite_offset
= NULL
, uint16
*max_palette_offset
= NULL
)
744 grf_sprite
->sprite
= buf
->ReadWord();
745 grf_sprite
->pal
= buf
->ReadWord();
746 TileLayoutFlags flags
= read_flags
? (TileLayoutFlags
)buf
->ReadWord() : TLF_NOTHING
;
748 MapSpriteMappingRecolour(grf_sprite
);
750 bool custom_sprite
= HasBit(grf_sprite
->pal
, 15) != invert_action1_flag
;
751 ClrBit(grf_sprite
->pal
, 15);
753 /* Use sprite from Action 1 */
754 uint index
= GB(grf_sprite
->sprite
, 0, 14);
755 if (use_cur_spritesets
&& (!_cur
.IsValidSpriteSet(feature
, index
) || _cur
.GetNumEnts(feature
, index
) == 0)) {
756 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index
);
757 grf_sprite
->sprite
= SPR_IMG_QUERY
;
758 grf_sprite
->pal
= PAL_NONE
;
760 SpriteID sprite
= use_cur_spritesets
? _cur
.GetSprite(feature
, index
) : index
;
761 if (max_sprite_offset
!= NULL
) *max_sprite_offset
= use_cur_spritesets
? _cur
.GetNumEnts(feature
, index
) : UINT16_MAX
;
762 SB(grf_sprite
->sprite
, 0, SPRITE_WIDTH
, sprite
);
763 SetBit(grf_sprite
->sprite
, SPRITE_MODIFIER_CUSTOM_SPRITE
);
765 } else if ((flags
& TLF_SPRITE_VAR10
) && !(flags
& TLF_SPRITE_REG_FLAGS
)) {
766 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
767 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
771 if (flags
& TLF_CUSTOM_PALETTE
) {
772 /* Use palette from Action 1 */
773 uint index
= GB(grf_sprite
->pal
, 0, 14);
774 if (use_cur_spritesets
&& (!_cur
.IsValidSpriteSet(feature
, index
) || _cur
.GetNumEnts(feature
, index
) == 0)) {
775 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index
);
776 grf_sprite
->pal
= PAL_NONE
;
778 SpriteID sprite
= use_cur_spritesets
? _cur
.GetSprite(feature
, index
) : index
;
779 if (max_palette_offset
!= NULL
) *max_palette_offset
= use_cur_spritesets
? _cur
.GetNumEnts(feature
, index
) : UINT16_MAX
;
780 SB(grf_sprite
->pal
, 0, SPRITE_WIDTH
, sprite
);
781 SetBit(grf_sprite
->pal
, SPRITE_MODIFIER_CUSTOM_SPRITE
);
783 } else if ((flags
& TLF_PALETTE_VAR10
) && !(flags
& TLF_PALETTE_REG_FLAGS
)) {
784 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
785 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
793 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
794 * @param buf Input stream.
795 * @param flags TileLayoutFlags to process.
796 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
797 * @param dts Sprite layout to insert data into.
798 * @param index Sprite index to process; 0 for ground sprite.
800 static void ReadSpriteLayoutRegisters(ByteReader
*buf
, TileLayoutFlags flags
, bool is_parent
, NewGRFSpriteLayout
*dts
, uint index
)
802 if (!(flags
& TLF_DRAWING_FLAGS
)) return;
804 if (dts
->registers
== NULL
) dts
->AllocateRegisters();
805 TileLayoutRegisters
®s
= const_cast<TileLayoutRegisters
&>(dts
->registers
[index
]);
806 regs
.flags
= flags
& TLF_DRAWING_FLAGS
;
808 if (flags
& TLF_DODRAW
) regs
.dodraw
= buf
->ReadByte();
809 if (flags
& TLF_SPRITE
) regs
.sprite
= buf
->ReadByte();
810 if (flags
& TLF_PALETTE
) regs
.palette
= buf
->ReadByte();
813 if (flags
& TLF_BB_XY_OFFSET
) {
814 regs
.delta
.parent
[0] = buf
->ReadByte();
815 regs
.delta
.parent
[1] = buf
->ReadByte();
817 if (flags
& TLF_BB_Z_OFFSET
) regs
.delta
.parent
[2] = buf
->ReadByte();
819 if (flags
& TLF_CHILD_X_OFFSET
) regs
.delta
.child
[0] = buf
->ReadByte();
820 if (flags
& TLF_CHILD_Y_OFFSET
) regs
.delta
.child
[1] = buf
->ReadByte();
823 if (flags
& TLF_SPRITE_VAR10
) {
824 regs
.sprite_var10
= buf
->ReadByte();
825 if (regs
.sprite_var10
> TLR_MAX_VAR10
) {
826 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs
.sprite_var10
, TLR_MAX_VAR10
);
827 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
832 if (flags
& TLF_PALETTE_VAR10
) {
833 regs
.palette_var10
= buf
->ReadByte();
834 if (regs
.palette_var10
> TLR_MAX_VAR10
) {
835 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs
.palette_var10
, TLR_MAX_VAR10
);
836 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
843 * Read a spritelayout from the GRF.
845 * @param num_building_sprites Number of building sprites to read
846 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
847 * @param feature GrfSpecFeature to use spritesets from.
848 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
849 * @param no_z_position Whether bounding boxes have no Z offset
850 * @param dts Layout container to output into
851 * @return True on error (GRF was disabled).
853 static bool ReadSpriteLayout(ByteReader
*buf
, uint num_building_sprites
, bool use_cur_spritesets
, byte feature
, bool allow_var10
, bool no_z_position
, NewGRFSpriteLayout
*dts
)
855 bool has_flags
= HasBit(num_building_sprites
, 6);
856 ClrBit(num_building_sprites
, 6);
857 TileLayoutFlags valid_flags
= TLF_KNOWN_FLAGS
;
858 if (!allow_var10
) valid_flags
&= ~TLF_VAR10_FLAGS
;
859 dts
->Allocate(num_building_sprites
); // allocate before reading groundsprite flags
861 uint16
*max_sprite_offset
= AllocaM(uint16
, num_building_sprites
+ 1);
862 uint16
*max_palette_offset
= AllocaM(uint16
, num_building_sprites
+ 1);
863 MemSetT(max_sprite_offset
, 0, num_building_sprites
+ 1);
864 MemSetT(max_palette_offset
, 0, num_building_sprites
+ 1);
867 TileLayoutFlags flags
= ReadSpriteLayoutSprite(buf
, has_flags
, false, use_cur_spritesets
, feature
, &dts
->ground
, max_sprite_offset
, max_palette_offset
);
868 if (_cur
.skip_sprites
< 0) return true;
870 if (flags
& ~(valid_flags
& ~TLF_NON_GROUND_FLAGS
)) {
871 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags
& ~(valid_flags
& ~TLF_NON_GROUND_FLAGS
));
872 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
876 ReadSpriteLayoutRegisters(buf
, flags
, false, dts
, 0);
877 if (_cur
.skip_sprites
< 0) return true;
879 for (uint i
= 0; i
< num_building_sprites
; i
++) {
880 DrawTileSeqStruct
*seq
= const_cast<DrawTileSeqStruct
*>(&dts
->seq
[i
]);
882 flags
= ReadSpriteLayoutSprite(buf
, has_flags
, false, use_cur_spritesets
, feature
, &seq
->image
, max_sprite_offset
+ i
+ 1, max_palette_offset
+ i
+ 1);
883 if (_cur
.skip_sprites
< 0) return true;
885 if (flags
& ~valid_flags
) {
886 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags
& ~valid_flags
);
887 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
891 seq
->delta_x
= buf
->ReadByte();
892 seq
->delta_y
= buf
->ReadByte();
894 if (!no_z_position
) seq
->delta_z
= buf
->ReadByte();
896 if (seq
->IsParentSprite()) {
897 seq
->size_x
= buf
->ReadByte();
898 seq
->size_y
= buf
->ReadByte();
899 seq
->size_z
= buf
->ReadByte();
902 ReadSpriteLayoutRegisters(buf
, flags
, seq
->IsParentSprite(), dts
, i
+ 1);
903 if (_cur
.skip_sprites
< 0) return true;
906 /* Check if the number of sprites per spriteset is consistent */
907 bool is_consistent
= true;
908 dts
->consistent_max_offset
= 0;
909 for (uint i
= 0; i
< num_building_sprites
+ 1; i
++) {
910 if (max_sprite_offset
[i
] > 0) {
911 if (dts
->consistent_max_offset
== 0) {
912 dts
->consistent_max_offset
= max_sprite_offset
[i
];
913 } else if (dts
->consistent_max_offset
!= max_sprite_offset
[i
]) {
914 is_consistent
= false;
918 if (max_palette_offset
[i
] > 0) {
919 if (dts
->consistent_max_offset
== 0) {
920 dts
->consistent_max_offset
= max_palette_offset
[i
];
921 } else if (dts
->consistent_max_offset
!= max_palette_offset
[i
]) {
922 is_consistent
= false;
928 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
929 assert(use_cur_spritesets
|| (is_consistent
&& (dts
->consistent_max_offset
== 0 || dts
->consistent_max_offset
== UINT16_MAX
)));
931 if (!is_consistent
|| dts
->registers
!= NULL
) {
932 dts
->consistent_max_offset
= 0;
933 if (dts
->registers
== NULL
) dts
->AllocateRegisters();
935 for (uint i
= 0; i
< num_building_sprites
+ 1; i
++) {
936 TileLayoutRegisters
®s
= const_cast<TileLayoutRegisters
&>(dts
->registers
[i
]);
937 regs
.max_sprite_offset
= max_sprite_offset
[i
];
938 regs
.max_palette_offset
= max_palette_offset
[i
];
946 * Translate the refit mask.
948 static uint32
TranslateRefitMask(uint32 refit_mask
)
952 FOR_EACH_SET_BIT(bit
, refit_mask
) {
953 CargoID cargo
= GetCargoTranslation(bit
, _cur
.grffile
, true);
954 if (cargo
!= CT_INVALID
) SetBit(result
, cargo
);
960 * Converts TTD(P) Base Price pointers into the enum used by OTTD
961 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
962 * @param base_pointer TTD(P) Base Price Pointer
963 * @param error_location Function name for grf error messages
964 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
966 static void ConvertTTDBasePrice(uint32 base_pointer
, const char *error_location
, Price
*index
)
968 /* Special value for 'none' */
969 if (base_pointer
== 0) {
970 *index
= INVALID_PRICE
;
974 static const uint32 start
= 0x4B34; ///< Position of first base price
975 static const uint32 size
= 6; ///< Size of each base price record
977 if (base_pointer
< start
|| (base_pointer
- start
) % size
!= 0 || (base_pointer
- start
) / size
>= PR_END
) {
978 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location
, base_pointer
);
982 *index
= (Price
)((base_pointer
- start
) / size
);
985 /** Possible return values for the FeatureChangeInfo functions */
986 enum ChangeInfoResult
{
987 CIR_SUCCESS
, ///< Variable was parsed and read
988 CIR_DISABLED
, ///< GRF was disabled due to error
989 CIR_UNHANDLED
, ///< Variable was parsed but unread
990 CIR_UNKNOWN
, ///< Variable is unknown
991 CIR_INVALID_ID
, ///< Attempt to modify an invalid ID
994 typedef ChangeInfoResult (*VCI_Handler
)(uint engine
, int numinfo
, int prop
, ByteReader
*buf
);
997 * Define properties common to all vehicles
998 * @param ei Engine info.
999 * @param prop The property to change.
1000 * @param buf The property value.
1001 * @return ChangeInfoResult.
1003 static ChangeInfoResult
CommonVehicleChangeInfo(EngineInfo
*ei
, int prop
, ByteReader
*buf
)
1006 case 0x00: // Introduction date
1007 ei
->base_intro
= buf
->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR
;
1010 case 0x02: // Decay speed
1011 ei
->decay_speed
= buf
->ReadByte();
1014 case 0x03: // Vehicle life
1015 ei
->lifelength
= buf
->ReadByte();
1018 case 0x04: // Model life
1019 ei
->base_life
= buf
->ReadByte();
1022 case 0x06: // Climates available
1023 ei
->climates
= buf
->ReadByte();
1026 case PROP_VEHICLE_LOAD_AMOUNT
: // 0x07 Loading speed
1027 /* Amount of cargo loaded during a vehicle's "loading tick" */
1028 ei
->load_amount
= buf
->ReadByte();
1039 * Define properties for rail vehicles
1040 * @param engine :ocal ID of the first vehicle.
1041 * @param numinfo Number of subsequent IDs to change the property for.
1042 * @param prop The property to change.
1043 * @param buf The property value.
1044 * @return ChangeInfoResult.
1046 static ChangeInfoResult
RailVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1048 ChangeInfoResult ret
= CIR_SUCCESS
;
1050 for (int i
= 0; i
< numinfo
; i
++) {
1051 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_TRAIN
, engine
+ i
);
1052 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1054 EngineInfo
*ei
= &e
->info
;
1055 RailVehicleInfo
*rvi
= &e
->u
.rail
;
1058 case 0x05: { // Track type
1059 uint8 tracktype
= buf
->ReadByte();
1061 if (tracktype
< _cur
.grffile
->railtype_list
.Length()) {
1062 _gted
[e
->index
].railtypelabel
= _cur
.grffile
->railtype_list
[tracktype
];
1066 switch (tracktype
) {
1067 case 0: _gted
[e
->index
].railtypelabel
= rvi
->engclass
>= 2 ? RAILTYPE_ELECTRIC_LABEL
: RAILTYPE_RAIL_LABEL
; break;
1068 case 1: _gted
[e
->index
].railtypelabel
= RAILTYPE_MONO_LABEL
; break;
1069 case 2: _gted
[e
->index
].railtypelabel
= RAILTYPE_MAGLEV_LABEL
; break;
1071 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype
);
1077 case 0x08: // AI passenger service
1078 /* Tells the AI that this engine is designed for
1079 * passenger services and shouldn't be used for freight. */
1080 rvi
->ai_passenger_only
= buf
->ReadByte();
1083 case PROP_TRAIN_SPEED
: { // 0x09 Speed (1 unit is 1 km-ish/h)
1084 uint16 speed
= buf
->ReadWord();
1085 if (speed
== 0xFFFF) speed
= 0;
1087 rvi
->max_speed
= speed
;
1091 case PROP_TRAIN_POWER
: // 0x0B Power
1092 rvi
->power
= buf
->ReadWord();
1094 /* Set engine / wagon state based on power */
1095 if (rvi
->power
!= 0) {
1096 if (rvi
->railveh_type
== RAILVEH_WAGON
) {
1097 rvi
->railveh_type
= RAILVEH_SINGLEHEAD
;
1100 rvi
->railveh_type
= RAILVEH_WAGON
;
1104 case PROP_TRAIN_RUNNING_COST_FACTOR
: // 0x0D Running cost factor
1105 rvi
->running_cost
= buf
->ReadByte();
1108 case 0x0E: // Running cost base
1109 ConvertTTDBasePrice(buf
->ReadDWord(), "RailVehicleChangeInfo", &rvi
->running_cost_class
);
1112 case 0x12: { // Sprite ID
1113 uint8 spriteid
= buf
->ReadByte();
1114 uint8 orig_spriteid
= spriteid
;
1116 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1117 * as an array index, so we need it to be half the original value. */
1118 if (spriteid
< 0xFD) spriteid
>>= 1;
1120 if (IsValidNewGRFImageIndex
<VEH_TRAIN
>(spriteid
)) {
1121 rvi
->image_index
= spriteid
;
1123 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1124 rvi
->image_index
= 0;
1129 case 0x13: { // Dual-headed
1130 uint8 dual
= buf
->ReadByte();
1133 rvi
->railveh_type
= RAILVEH_MULTIHEAD
;
1135 rvi
->railveh_type
= rvi
->power
== 0 ?
1136 RAILVEH_WAGON
: RAILVEH_SINGLEHEAD
;
1141 case PROP_TRAIN_CARGO_CAPACITY
: // 0x14 Cargo capacity
1142 rvi
->capacity
= buf
->ReadByte();
1145 case 0x15: { // Cargo type
1146 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1147 uint8 ctype
= buf
->ReadByte();
1149 if (ctype
== 0xFF) {
1150 /* 0xFF is specified as 'use first refittable' */
1151 ei
->cargo_type
= CT_INVALID
;
1152 } else if (_cur
.grffile
->grf_version
>= 8) {
1153 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1154 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1155 } else if (ctype
< NUM_CARGO
) {
1156 /* Use untranslated cargo. */
1157 ei
->cargo_type
= ctype
;
1159 ei
->cargo_type
= CT_INVALID
;
1160 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1165 case PROP_TRAIN_WEIGHT
: // 0x16 Weight
1166 SB(rvi
->weight
, 0, 8, buf
->ReadByte());
1169 case PROP_TRAIN_COST_FACTOR
: // 0x17 Cost factor
1170 rvi
->cost_factor
= buf
->ReadByte();
1173 case 0x18: // AI rank
1174 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1178 case 0x19: { // Engine traction type
1179 /* What do the individual numbers mean?
1180 * 0x00 .. 0x07: Steam
1181 * 0x08 .. 0x27: Diesel
1182 * 0x28 .. 0x31: Electric
1183 * 0x32 .. 0x37: Monorail
1184 * 0x38 .. 0x41: Maglev
1186 uint8 traction
= buf
->ReadByte();
1187 EngineClass engclass
;
1189 if (traction
<= 0x07) {
1190 engclass
= EC_STEAM
;
1191 } else if (traction
<= 0x27) {
1192 engclass
= EC_DIESEL
;
1193 } else if (traction
<= 0x31) {
1194 engclass
= EC_ELECTRIC
;
1195 } else if (traction
<= 0x37) {
1196 engclass
= EC_MONORAIL
;
1197 } else if (traction
<= 0x41) {
1198 engclass
= EC_MAGLEV
;
1203 if (_cur
.grffile
->railtype_list
.Length() == 0) {
1204 /* Use traction type to select between normal and electrified
1205 * rail only when no translation list is in place. */
1206 if (_gted
[e
->index
].railtypelabel
== RAILTYPE_RAIL_LABEL
&& engclass
>= EC_ELECTRIC
) _gted
[e
->index
].railtypelabel
= RAILTYPE_ELECTRIC_LABEL
;
1207 if (_gted
[e
->index
].railtypelabel
== RAILTYPE_ELECTRIC_LABEL
&& engclass
< EC_ELECTRIC
) _gted
[e
->index
].railtypelabel
= RAILTYPE_RAIL_LABEL
;
1210 rvi
->engclass
= engclass
;
1214 case 0x1A: // Alter purchase list sort order
1215 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1218 case 0x1B: // Powered wagons power bonus
1219 rvi
->pow_wag_power
= buf
->ReadWord();
1222 case 0x1C: // Refit cost
1223 ei
->refit_cost
= buf
->ReadByte();
1226 case 0x1D: { // Refit cargo
1227 uint32 mask
= buf
->ReadDWord();
1228 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1229 ei
->refit_mask
= TranslateRefitMask(mask
);
1230 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1234 case 0x1E: // Callback
1235 ei
->callback_mask
= buf
->ReadByte();
1238 case PROP_TRAIN_TRACTIVE_EFFORT
: // 0x1F Tractive effort coefficient
1239 rvi
->tractive_effort
= buf
->ReadByte();
1242 case 0x20: // Air drag
1243 rvi
->air_drag
= buf
->ReadByte();
1246 case PROP_TRAIN_SHORTEN_FACTOR
: // 0x21 Shorter vehicle
1247 rvi
->shorten_factor
= buf
->ReadByte();
1250 case 0x22: // Visual effect
1251 rvi
->visual_effect
= buf
->ReadByte();
1252 /* Avoid accidentally setting visual_effect to the default value
1253 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1254 if (rvi
->visual_effect
== VE_DEFAULT
) {
1255 assert(HasBit(rvi
->visual_effect
, VE_DISABLE_EFFECT
));
1256 SB(rvi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1260 case 0x23: // Powered wagons weight bonus
1261 rvi
->pow_wag_weight
= buf
->ReadByte();
1264 case 0x24: { // High byte of vehicle weight
1265 byte weight
= buf
->ReadByte();
1268 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight
<< 8);
1270 SB(rvi
->weight
, 8, 8, weight
);
1275 case PROP_TRAIN_USER_DATA
: // 0x25 User-defined bit mask to set when checking veh. var. 42
1276 rvi
->user_def_data
= buf
->ReadByte();
1279 case 0x26: // Retire vehicle early
1280 ei
->retire_early
= buf
->ReadByte();
1283 case 0x27: // Miscellaneous flags
1284 ei
->misc_flags
= buf
->ReadByte();
1285 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1286 _gted
[e
->index
].prop27_set
= true;
1289 case 0x28: // Cargo classes allowed
1290 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1291 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1292 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1295 case 0x29: // Cargo classes disallowed
1296 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1297 _gted
[e
->index
].UpdateRefittability(false);
1300 case 0x2A: // Long format introduction date (days since year 0)
1301 ei
->base_intro
= buf
->ReadDWord();
1304 case PROP_TRAIN_CARGO_AGE_PERIOD
: // 0x2B Cargo aging period
1305 ei
->cargo_age_period
= buf
->ReadWord();
1308 case 0x2C: // CTT refit include list
1309 case 0x2D: { // CTT refit exclude list
1310 uint8 count
= buf
->ReadByte();
1311 _gted
[e
->index
].UpdateRefittability(prop
== 0x2C && count
!= 0);
1312 if (prop
== 0x2C) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1313 uint32
&ctt
= prop
== 0x2C ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1316 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1317 if (ctype
== CT_INVALID
) continue;
1324 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1333 * Define properties for road vehicles
1334 * @param engine Local ID of the first vehicle.
1335 * @param numinfo Number of subsequent IDs to change the property for.
1336 * @param prop The property to change.
1337 * @param buf The property value.
1338 * @return ChangeInfoResult.
1340 static ChangeInfoResult
RoadVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1342 ChangeInfoResult ret
= CIR_SUCCESS
;
1344 for (int i
= 0; i
< numinfo
; i
++) {
1345 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_ROAD
, engine
+ i
);
1346 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1348 EngineInfo
*ei
= &e
->info
;
1349 RoadVehicleInfo
*rvi
= &e
->u
.road
;
1352 case 0x08: // Speed (1 unit is 0.5 kmh)
1353 rvi
->max_speed
= buf
->ReadByte();
1356 case PROP_ROADVEH_RUNNING_COST_FACTOR
: // 0x09 Running cost factor
1357 rvi
->running_cost
= buf
->ReadByte();
1360 case 0x0A: // Running cost base
1361 ConvertTTDBasePrice(buf
->ReadDWord(), "RoadVehicleChangeInfo", &rvi
->running_cost_class
);
1364 case 0x0E: { // Sprite ID
1365 uint8 spriteid
= buf
->ReadByte();
1366 uint8 orig_spriteid
= spriteid
;
1368 /* cars have different custom id in the GRF file */
1369 if (spriteid
== 0xFF) spriteid
= 0xFD;
1371 if (spriteid
< 0xFD) spriteid
>>= 1;
1373 if (IsValidNewGRFImageIndex
<VEH_ROAD
>(spriteid
)) {
1374 rvi
->image_index
= spriteid
;
1376 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1377 rvi
->image_index
= 0;
1382 case PROP_ROADVEH_CARGO_CAPACITY
: // 0x0F Cargo capacity
1383 rvi
->capacity
= buf
->ReadByte();
1386 case 0x10: { // Cargo type
1387 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1388 uint8 ctype
= buf
->ReadByte();
1390 if (ctype
== 0xFF) {
1391 /* 0xFF is specified as 'use first refittable' */
1392 ei
->cargo_type
= CT_INVALID
;
1393 } else if (_cur
.grffile
->grf_version
>= 8) {
1394 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1395 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1396 } else if (ctype
< NUM_CARGO
) {
1397 /* Use untranslated cargo. */
1398 ei
->cargo_type
= ctype
;
1400 ei
->cargo_type
= CT_INVALID
;
1401 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1406 case PROP_ROADVEH_COST_FACTOR
: // 0x11 Cost factor
1407 rvi
->cost_factor
= buf
->ReadByte();
1411 rvi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1414 case PROP_ROADVEH_POWER
: // Power in units of 10 HP.
1415 rvi
->power
= buf
->ReadByte();
1418 case PROP_ROADVEH_WEIGHT
: // Weight in units of 1/4 tons.
1419 rvi
->weight
= buf
->ReadByte();
1422 case PROP_ROADVEH_SPEED
: // Speed in mph/0.8
1423 _gted
[e
->index
].rv_max_speed
= buf
->ReadByte();
1426 case 0x16: { // Cargoes available for refitting
1427 uint32 mask
= buf
->ReadDWord();
1428 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1429 ei
->refit_mask
= TranslateRefitMask(mask
);
1430 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1434 case 0x17: // Callback mask
1435 ei
->callback_mask
= buf
->ReadByte();
1438 case PROP_ROADVEH_TRACTIVE_EFFORT
: // Tractive effort coefficient in 1/256.
1439 rvi
->tractive_effort
= buf
->ReadByte();
1442 case 0x19: // Air drag
1443 rvi
->air_drag
= buf
->ReadByte();
1446 case 0x1A: // Refit cost
1447 ei
->refit_cost
= buf
->ReadByte();
1450 case 0x1B: // Retire vehicle early
1451 ei
->retire_early
= buf
->ReadByte();
1454 case 0x1C: // Miscellaneous flags
1455 ei
->misc_flags
= buf
->ReadByte();
1456 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1459 case 0x1D: // Cargo classes allowed
1460 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1461 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1462 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1465 case 0x1E: // Cargo classes disallowed
1466 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1467 _gted
[e
->index
].UpdateRefittability(false);
1470 case 0x1F: // Long format introduction date (days since year 0)
1471 ei
->base_intro
= buf
->ReadDWord();
1474 case 0x20: // Alter purchase list sort order
1475 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1478 case 0x21: // Visual effect
1479 rvi
->visual_effect
= buf
->ReadByte();
1480 /* Avoid accidentally setting visual_effect to the default value
1481 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1482 if (rvi
->visual_effect
== VE_DEFAULT
) {
1483 assert(HasBit(rvi
->visual_effect
, VE_DISABLE_EFFECT
));
1484 SB(rvi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1488 case PROP_ROADVEH_CARGO_AGE_PERIOD
: // 0x22 Cargo aging period
1489 ei
->cargo_age_period
= buf
->ReadWord();
1492 case PROP_ROADVEH_SHORTEN_FACTOR
: // 0x23 Shorter vehicle
1493 rvi
->shorten_factor
= buf
->ReadByte();
1496 case 0x24: // CTT refit include list
1497 case 0x25: { // CTT refit exclude list
1498 uint8 count
= buf
->ReadByte();
1499 _gted
[e
->index
].UpdateRefittability(prop
== 0x24 && count
!= 0);
1500 if (prop
== 0x24) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1501 uint32
&ctt
= prop
== 0x24 ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1504 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1505 if (ctype
== CT_INVALID
) continue;
1512 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1521 * Define properties for ships
1522 * @param engine Local ID of the first vehicle.
1523 * @param numinfo Number of subsequent IDs to change the property for.
1524 * @param prop The property to change.
1525 * @param buf The property value.
1526 * @return ChangeInfoResult.
1528 static ChangeInfoResult
ShipVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1530 ChangeInfoResult ret
= CIR_SUCCESS
;
1532 for (int i
= 0; i
< numinfo
; i
++) {
1533 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_SHIP
, engine
+ i
);
1534 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1536 EngineInfo
*ei
= &e
->info
;
1537 ShipVehicleInfo
*svi
= &e
->u
.ship
;
1540 case 0x08: { // Sprite ID
1541 uint8 spriteid
= buf
->ReadByte();
1542 uint8 orig_spriteid
= spriteid
;
1544 /* ships have different custom id in the GRF file */
1545 if (spriteid
== 0xFF) spriteid
= 0xFD;
1547 if (spriteid
< 0xFD) spriteid
>>= 1;
1549 if (IsValidNewGRFImageIndex
<VEH_SHIP
>(spriteid
)) {
1550 svi
->image_index
= spriteid
;
1552 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1553 svi
->image_index
= 0;
1558 case 0x09: // Refittable
1559 svi
->old_refittable
= (buf
->ReadByte() != 0);
1562 case PROP_SHIP_COST_FACTOR
: // 0x0A Cost factor
1563 svi
->cost_factor
= buf
->ReadByte();
1566 case PROP_SHIP_SPEED
: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1567 svi
->max_speed
= buf
->ReadByte();
1570 case 0x0C: { // Cargo type
1571 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1572 uint8 ctype
= buf
->ReadByte();
1574 if (ctype
== 0xFF) {
1575 /* 0xFF is specified as 'use first refittable' */
1576 ei
->cargo_type
= CT_INVALID
;
1577 } else if (_cur
.grffile
->grf_version
>= 8) {
1578 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1579 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1580 } else if (ctype
< NUM_CARGO
) {
1581 /* Use untranslated cargo. */
1582 ei
->cargo_type
= ctype
;
1584 ei
->cargo_type
= CT_INVALID
;
1585 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1590 case PROP_SHIP_CARGO_CAPACITY
: // 0x0D Cargo capacity
1591 svi
->capacity
= buf
->ReadWord();
1594 case PROP_SHIP_RUNNING_COST_FACTOR
: // 0x0F Running cost factor
1595 svi
->running_cost
= buf
->ReadByte();
1599 svi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1602 case 0x11: { // Cargoes available for refitting
1603 uint32 mask
= buf
->ReadDWord();
1604 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1605 ei
->refit_mask
= TranslateRefitMask(mask
);
1606 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1610 case 0x12: // Callback mask
1611 ei
->callback_mask
= buf
->ReadByte();
1614 case 0x13: // Refit cost
1615 ei
->refit_cost
= buf
->ReadByte();
1618 case 0x14: // Ocean speed fraction
1619 svi
->ocean_speed_frac
= buf
->ReadByte();
1622 case 0x15: // Canal speed fraction
1623 svi
->canal_speed_frac
= buf
->ReadByte();
1626 case 0x16: // Retire vehicle early
1627 ei
->retire_early
= buf
->ReadByte();
1630 case 0x17: // Miscellaneous flags
1631 ei
->misc_flags
= buf
->ReadByte();
1632 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1635 case 0x18: // Cargo classes allowed
1636 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1637 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1638 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1641 case 0x19: // Cargo classes disallowed
1642 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1643 _gted
[e
->index
].UpdateRefittability(false);
1646 case 0x1A: // Long format introduction date (days since year 0)
1647 ei
->base_intro
= buf
->ReadDWord();
1650 case 0x1B: // Alter purchase list sort order
1651 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1654 case 0x1C: // Visual effect
1655 svi
->visual_effect
= buf
->ReadByte();
1656 /* Avoid accidentally setting visual_effect to the default value
1657 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1658 if (svi
->visual_effect
== VE_DEFAULT
) {
1659 assert(HasBit(svi
->visual_effect
, VE_DISABLE_EFFECT
));
1660 SB(svi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1664 case PROP_SHIP_CARGO_AGE_PERIOD
: // 0x1D Cargo aging period
1665 ei
->cargo_age_period
= buf
->ReadWord();
1668 case 0x1E: // CTT refit include list
1669 case 0x1F: { // CTT refit exclude list
1670 uint8 count
= buf
->ReadByte();
1671 _gted
[e
->index
].UpdateRefittability(prop
== 0x1E && count
!= 0);
1672 if (prop
== 0x1E) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1673 uint32
&ctt
= prop
== 0x1E ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1676 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1677 if (ctype
== CT_INVALID
) continue;
1684 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1693 * Define properties for aircraft
1694 * @param engine Local ID of the aircraft.
1695 * @param numinfo Number of subsequent IDs to change the property for.
1696 * @param prop The property to change.
1697 * @param buf The property value.
1698 * @return ChangeInfoResult.
1700 static ChangeInfoResult
AircraftVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1702 ChangeInfoResult ret
= CIR_SUCCESS
;
1704 for (int i
= 0; i
< numinfo
; i
++) {
1705 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_AIRCRAFT
, engine
+ i
);
1706 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1708 EngineInfo
*ei
= &e
->info
;
1709 AircraftVehicleInfo
*avi
= &e
->u
.air
;
1712 case 0x08: { // Sprite ID
1713 uint8 spriteid
= buf
->ReadByte();
1714 uint8 orig_spriteid
= spriteid
;
1716 /* aircraft have different custom id in the GRF file */
1717 if (spriteid
== 0xFF) spriteid
= 0xFD;
1719 if (spriteid
< 0xFD) spriteid
>>= 1;
1721 if (IsValidNewGRFImageIndex
<VEH_AIRCRAFT
>(spriteid
)) {
1722 avi
->image_index
= spriteid
;
1724 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1725 avi
->image_index
= 0;
1730 case 0x09: // Helicopter
1731 if (buf
->ReadByte() == 0) {
1732 avi
->subtype
= AIR_HELI
;
1734 SB(avi
->subtype
, 0, 1, 1); // AIR_CTOL
1739 SB(avi
->subtype
, 1, 1, (buf
->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1742 case PROP_AIRCRAFT_COST_FACTOR
: // 0x0B Cost factor
1743 avi
->cost_factor
= buf
->ReadByte();
1746 case PROP_AIRCRAFT_SPEED
: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1747 avi
->max_speed
= (buf
->ReadByte() * 128) / 10;
1750 case 0x0D: // Acceleration
1751 avi
->acceleration
= buf
->ReadByte();
1754 case PROP_AIRCRAFT_RUNNING_COST_FACTOR
: // 0x0E Running cost factor
1755 avi
->running_cost
= buf
->ReadByte();
1758 case PROP_AIRCRAFT_PASSENGER_CAPACITY
: // 0x0F Passenger capacity
1759 avi
->passenger_capacity
= buf
->ReadWord();
1762 case PROP_AIRCRAFT_MAIL_CAPACITY
: // 0x11 Mail capacity
1763 avi
->mail_capacity
= buf
->ReadByte();
1767 avi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1770 case 0x13: { // Cargoes available for refitting
1771 uint32 mask
= buf
->ReadDWord();
1772 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1773 ei
->refit_mask
= TranslateRefitMask(mask
);
1774 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1778 case 0x14: // Callback mask
1779 ei
->callback_mask
= buf
->ReadByte();
1782 case 0x15: // Refit cost
1783 ei
->refit_cost
= buf
->ReadByte();
1786 case 0x16: // Retire vehicle early
1787 ei
->retire_early
= buf
->ReadByte();
1790 case 0x17: // Miscellaneous flags
1791 ei
->misc_flags
= buf
->ReadByte();
1792 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1795 case 0x18: // Cargo classes allowed
1796 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1797 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1798 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1801 case 0x19: // Cargo classes disallowed
1802 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1803 _gted
[e
->index
].UpdateRefittability(false);
1806 case 0x1A: // Long format introduction date (days since year 0)
1807 ei
->base_intro
= buf
->ReadDWord();
1810 case 0x1B: // Alter purchase list sort order
1811 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1814 case PROP_AIRCRAFT_CARGO_AGE_PERIOD
: // 0x1C Cargo aging period
1815 ei
->cargo_age_period
= buf
->ReadWord();
1818 case 0x1D: // CTT refit include list
1819 case 0x1E: { // CTT refit exclude list
1820 uint8 count
= buf
->ReadByte();
1821 _gted
[e
->index
].UpdateRefittability(prop
== 0x1D && count
!= 0);
1822 if (prop
== 0x1D) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1823 uint32
&ctt
= prop
== 0x1D ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1826 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1827 if (ctype
== CT_INVALID
) continue;
1833 case PROP_AIRCRAFT_RANGE
: // 0x1F Max aircraft range
1834 avi
->max_range
= buf
->ReadWord();
1838 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1847 * Define properties for stations
1848 * @param stdid StationID of the first station tile.
1849 * @param numinfo Number of subsequent station tiles to change the property for.
1850 * @param prop The property to change.
1851 * @param buf The property value.
1852 * @return ChangeInfoResult.
1854 static ChangeInfoResult
StationChangeInfo(uint stid
, int numinfo
, int prop
, ByteReader
*buf
)
1856 ChangeInfoResult ret
= CIR_SUCCESS
;
1858 if (stid
+ numinfo
> NUM_STATIONS_PER_GRF
) {
1859 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid
+ numinfo
, NUM_STATIONS_PER_GRF
);
1860 return CIR_INVALID_ID
;
1863 /* Allocate station specs if necessary */
1864 if (_cur
.grffile
->stations
== NULL
) _cur
.grffile
->stations
= CallocT
<StationSpec
*>(NUM_STATIONS_PER_GRF
);
1866 for (int i
= 0; i
< numinfo
; i
++) {
1867 StationSpec
*statspec
= _cur
.grffile
->stations
[stid
+ i
];
1869 /* Check that the station we are modifying is defined. */
1870 if (statspec
== NULL
&& prop
!= 0x08) {
1871 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid
+ i
);
1872 return CIR_INVALID_ID
;
1876 case 0x08: { // Class ID
1877 StationSpec
**spec
= &_cur
.grffile
->stations
[stid
+ i
];
1879 /* Property 0x08 is special; it is where the station is allocated */
1880 if (*spec
== NULL
) *spec
= CallocT
<StationSpec
>(1);
1882 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1883 uint32 classid
= buf
->ReadDWord();
1884 (*spec
)->cls_id
= StationClass::Allocate(BSWAP32(classid
));
1888 case 0x09: // Define sprite layout
1889 statspec
->tiles
= buf
->ReadExtendedByte();
1890 delete[] statspec
->renderdata
; // delete earlier loaded stuff
1891 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
1893 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
1894 NewGRFSpriteLayout
*dts
= &statspec
->renderdata
[t
];
1895 dts
->consistent_max_offset
= UINT16_MAX
; // Spritesets are unknown, so no limit.
1897 if (buf
->HasData(4) && *(uint32
*)buf
->Data() == 0) {
1899 extern const DrawTileSprites _station_display_datas_rail
[8];
1900 dts
->Clone(&_station_display_datas_rail
[t
% 8]);
1904 ReadSpriteLayoutSprite(buf
, false, false, false, GSF_STATIONS
, &dts
->ground
);
1905 /* On error, bail out immediately. Temporary GRF data was already freed */
1906 if (_cur
.skip_sprites
< 0) return CIR_DISABLED
;
1908 static SmallVector
<DrawTileSeqStruct
, 8> tmp_layout
;
1911 /* no relative bounding box support */
1912 DrawTileSeqStruct
*dtss
= tmp_layout
.Append();
1915 dtss
->delta_x
= buf
->ReadByte();
1916 if (dtss
->IsTerminator()) break;
1917 dtss
->delta_y
= buf
->ReadByte();
1918 dtss
->delta_z
= buf
->ReadByte();
1919 dtss
->size_x
= buf
->ReadByte();
1920 dtss
->size_y
= buf
->ReadByte();
1921 dtss
->size_z
= buf
->ReadByte();
1923 ReadSpriteLayoutSprite(buf
, false, true, false, GSF_STATIONS
, &dtss
->image
);
1924 /* On error, bail out immediately. Temporary GRF data was already freed */
1925 if (_cur
.skip_sprites
< 0) return CIR_DISABLED
;
1927 dts
->Clone(tmp_layout
.Begin());
1931 case 0x0A: { // Copy sprite layout
1932 byte srcid
= buf
->ReadByte();
1933 const StationSpec
*srcstatspec
= _cur
.grffile
->stations
[srcid
];
1935 if (srcstatspec
== NULL
) {
1936 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid
, stid
+ i
);
1940 delete[] statspec
->renderdata
; // delete earlier loaded stuff
1942 statspec
->tiles
= srcstatspec
->tiles
;
1943 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
1944 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
1945 statspec
->renderdata
[t
].Clone(&srcstatspec
->renderdata
[t
]);
1950 case 0x0B: // Callback mask
1951 statspec
->callback_mask
= buf
->ReadByte();
1954 case 0x0C: // Disallowed number of platforms
1955 statspec
->disallowed_platforms
= buf
->ReadByte();
1958 case 0x0D: // Disallowed platform lengths
1959 statspec
->disallowed_lengths
= buf
->ReadByte();
1962 case 0x0E: // Define custom layout
1963 statspec
->copied_layouts
= false;
1965 while (buf
->HasData()) {
1966 byte length
= buf
->ReadByte();
1967 byte number
= buf
->ReadByte();
1968 StationLayout layout
;
1971 if (length
== 0 || number
== 0) break;
1973 if (length
> statspec
->lengths
) {
1974 statspec
->platforms
= ReallocT(statspec
->platforms
, length
);
1975 memset(statspec
->platforms
+ statspec
->lengths
, 0, length
- statspec
->lengths
);
1977 statspec
->layouts
= ReallocT(statspec
->layouts
, length
);
1978 memset(statspec
->layouts
+ statspec
->lengths
, 0,
1979 (length
- statspec
->lengths
) * sizeof(*statspec
->layouts
));
1981 statspec
->lengths
= length
;
1983 l
= length
- 1; // index is zero-based
1985 if (number
> statspec
->platforms
[l
]) {
1986 statspec
->layouts
[l
] = ReallocT(statspec
->layouts
[l
], number
);
1987 /* We expect NULL being 0 here, but C99 guarantees that. */
1988 memset(statspec
->layouts
[l
] + statspec
->platforms
[l
], 0,
1989 (number
- statspec
->platforms
[l
]) * sizeof(**statspec
->layouts
));
1991 statspec
->platforms
[l
] = number
;
1995 layout
= MallocT
<byte
>(length
* number
);
1997 for (l
= 0; l
< length
; l
++) {
1998 for (p
= 0; p
< number
; p
++) {
1999 layout
[l
* number
+ p
] = buf
->ReadByte();
2009 free(statspec
->layouts
[l
][p
]);
2010 statspec
->layouts
[l
][p
] = layout
;
2014 case 0x0F: { // Copy custom layout
2015 byte srcid
= buf
->ReadByte();
2016 const StationSpec
*srcstatspec
= _cur
.grffile
->stations
[srcid
];
2018 if (srcstatspec
== NULL
) {
2019 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid
, stid
+ i
);
2023 statspec
->lengths
= srcstatspec
->lengths
;
2024 statspec
->platforms
= srcstatspec
->platforms
;
2025 statspec
->layouts
= srcstatspec
->layouts
;
2026 statspec
->copied_layouts
= true;
2030 case 0x10: // Little/lots cargo threshold
2031 statspec
->cargo_threshold
= buf
->ReadWord();
2034 case 0x11: // Pylon placement
2035 statspec
->pylons
= buf
->ReadByte();
2038 case 0x12: // Cargo types for random triggers
2039 statspec
->cargo_triggers
= buf
->ReadDWord();
2040 if (_cur
.grffile
->grf_version
>= 7) {
2041 statspec
->cargo_triggers
= TranslateRefitMask(statspec
->cargo_triggers
);
2045 case 0x13: // General flags
2046 statspec
->flags
= buf
->ReadByte();
2049 case 0x14: // Overhead wire placement
2050 statspec
->wires
= buf
->ReadByte();
2053 case 0x15: // Blocked tiles
2054 statspec
->blocked
= buf
->ReadByte();
2057 case 0x16: // Animation info
2058 statspec
->animation
.frames
= buf
->ReadByte();
2059 statspec
->animation
.status
= buf
->ReadByte();
2062 case 0x17: // Animation speed
2063 statspec
->animation
.speed
= buf
->ReadByte();
2066 case 0x18: // Animation triggers
2067 statspec
->animation
.triggers
= buf
->ReadWord();
2070 case 0x1A: // Advanced sprite layout
2071 statspec
->tiles
= buf
->ReadExtendedByte();
2072 delete[] statspec
->renderdata
; // delete earlier loaded stuff
2073 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
2075 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
2076 NewGRFSpriteLayout
*dts
= &statspec
->renderdata
[t
];
2077 uint num_building_sprites
= buf
->ReadByte();
2078 /* On error, bail out immediately. Temporary GRF data was already freed */
2079 if (ReadSpriteLayout(buf
, num_building_sprites
, false, GSF_STATIONS
, true, false, dts
)) return CIR_DISABLED
;
2093 * Define properties for water features
2094 * @param id Type of the first water feature.
2095 * @param numinfo Number of subsequent water feature ids to change the property for.
2096 * @param prop The property to change.
2097 * @param buf The property value.
2098 * @return ChangeInfoResult.
2100 static ChangeInfoResult
CanalChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
2102 ChangeInfoResult ret
= CIR_SUCCESS
;
2104 if (id
+ numinfo
> CF_END
) {
2105 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id
+ numinfo
, CF_END
);
2106 return CIR_INVALID_ID
;
2109 for (int i
= 0; i
< numinfo
; i
++) {
2110 CanalProperties
*cp
= &_cur
.grffile
->canal_local_properties
[id
+ i
];
2114 cp
->callback_mask
= buf
->ReadByte();
2118 cp
->flags
= buf
->ReadByte();
2131 * Define properties for bridges
2132 * @param brid BridgeID of the bridge.
2133 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2134 * @param prop The property to change.
2135 * @param buf The property value.
2136 * @return ChangeInfoResult.
2138 static ChangeInfoResult
BridgeChangeInfo(uint brid
, int numinfo
, int prop
, ByteReader
*buf
)
2140 ChangeInfoResult ret
= CIR_SUCCESS
;
2142 if (brid
+ numinfo
> MAX_BRIDGES
) {
2143 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid
+ numinfo
, MAX_BRIDGES
);
2144 return CIR_INVALID_ID
;
2147 for (int i
= 0; i
< numinfo
; i
++) {
2148 BridgeSpec
*bridge
= &_bridge
[brid
+ i
];
2151 case 0x08: { // Year of availability
2152 /* We treat '0' as always available */
2153 byte year
= buf
->ReadByte();
2154 bridge
->avail_year
= (year
> 0 ? ORIGINAL_BASE_YEAR
+ year
: 0);
2158 case 0x09: // Minimum length
2159 bridge
->min_length
= buf
->ReadByte();
2162 case 0x0A: // Maximum length
2163 bridge
->max_length
= buf
->ReadByte();
2164 if (bridge
->max_length
> 16) bridge
->max_length
= 0xFFFF;
2167 case 0x0B: // Cost factor
2168 bridge
->price
= buf
->ReadByte();
2171 case 0x0C: // Maximum speed
2172 bridge
->speed
= buf
->ReadWord();
2175 case 0x0D: { // Bridge sprite tables
2176 byte tableid
= buf
->ReadByte();
2177 byte numtables
= buf
->ReadByte();
2179 if (bridge
->sprite_table
== NULL
) {
2180 /* Allocate memory for sprite table pointers and zero out */
2181 bridge
->sprite_table
= CallocT
<PalSpriteID
*>(7);
2184 for (; numtables
-- != 0; tableid
++) {
2185 if (tableid
>= 7) { // skip invalid data
2186 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid
);
2187 for (byte sprite
= 0; sprite
< 32; sprite
++) buf
->ReadDWord();
2191 if (bridge
->sprite_table
[tableid
] == NULL
) {
2192 bridge
->sprite_table
[tableid
] = MallocT
<PalSpriteID
>(32);
2195 for (byte sprite
= 0; sprite
< 32; sprite
++) {
2196 SpriteID image
= buf
->ReadWord();
2197 PaletteID pal
= buf
->ReadWord();
2199 bridge
->sprite_table
[tableid
][sprite
].sprite
= image
;
2200 bridge
->sprite_table
[tableid
][sprite
].pal
= pal
;
2202 MapSpriteMappingRecolour(&bridge
->sprite_table
[tableid
][sprite
]);
2208 case 0x0E: // Flags; bit 0 - disable far pillars
2209 bridge
->flags
= buf
->ReadByte();
2212 case 0x0F: // Long format year of availability (year since year 0)
2213 bridge
->avail_year
= Clamp(buf
->ReadDWord(), MIN_YEAR
, MAX_YEAR
);
2216 case 0x10: { // purchase string
2217 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2218 if (newone
!= STR_UNDEFINED
) bridge
->material
= newone
;
2222 case 0x11: // description of bridge with rails or roads
2224 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2225 if (newone
!= STR_UNDEFINED
) bridge
->transport_name
[prop
- 0x11] = newone
;
2229 case 0x13: // 16 bits cost multiplier
2230 bridge
->price
= buf
->ReadWord();
2243 * Ignore a house property
2244 * @param prop Property to read.
2245 * @param buf Property value.
2246 * @return ChangeInfoResult.
2248 static ChangeInfoResult
IgnoreTownHouseProperty(int prop
, ByteReader
*buf
)
2250 ChangeInfoResult ret
= CIR_SUCCESS
;
2287 for (uint j
= 0; j
< 4; j
++) buf
->ReadByte();
2291 byte count
= buf
->ReadByte();
2292 for (byte j
= 0; j
< count
; j
++) buf
->ReadByte();
2304 * Define properties for houses
2305 * @param hid HouseID of the house.
2306 * @param numinfo Number of subsequent houseIDs to change the property for.
2307 * @param prop The property to change.
2308 * @param buf The property value.
2309 * @return ChangeInfoResult.
2311 static ChangeInfoResult
TownHouseChangeInfo(uint hid
, int numinfo
, int prop
, ByteReader
*buf
)
2313 ChangeInfoResult ret
= CIR_SUCCESS
;
2315 if (hid
+ numinfo
> NUM_HOUSES_PER_GRF
) {
2316 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid
+ numinfo
, NUM_HOUSES_PER_GRF
);
2317 return CIR_INVALID_ID
;
2320 /* Allocate house specs if they haven't been allocated already. */
2321 if (_cur
.grffile
->housespec
== NULL
) {
2322 _cur
.grffile
->housespec
= CallocT
<HouseSpec
*>(NUM_HOUSES_PER_GRF
);
2325 for (int i
= 0; i
< numinfo
; i
++) {
2326 HouseSpec
*housespec
= _cur
.grffile
->housespec
[hid
+ i
];
2328 if (prop
!= 0x08 && housespec
== NULL
) {
2329 /* If the house property 08 is not yet set, ignore this property */
2330 ChangeInfoResult cir
= IgnoreTownHouseProperty(prop
, buf
);
2331 if (cir
> ret
) ret
= cir
;
2336 case 0x08: { // Substitute building type, and definition of a new house
2337 HouseSpec
**house
= &_cur
.grffile
->housespec
[hid
+ i
];
2338 byte subs_id
= buf
->ReadByte();
2340 if (subs_id
== 0xFF) {
2341 /* Instead of defining a new house, a substitute house id
2342 * of 0xFF disables the old house with the current id. */
2343 HouseSpec::Get(hid
+ i
)->enabled
= false;
2345 } else if (subs_id
>= NEW_HOUSE_OFFSET
) {
2346 /* The substitute id must be one of the original houses. */
2347 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id
, hid
+ i
);
2351 /* Allocate space for this house. */
2352 if (*house
== NULL
) *house
= CallocT
<HouseSpec
>(1);
2356 MemCpyT(housespec
, HouseSpec::Get(subs_id
));
2358 housespec
->enabled
= true;
2359 housespec
->grf_prop
.local_id
= hid
+ i
;
2360 housespec
->grf_prop
.subst_id
= subs_id
;
2361 housespec
->grf_prop
.grffile
= _cur
.grffile
;
2362 housespec
->random_colour
[0] = 0x04; // those 4 random colours are the base colour
2363 housespec
->random_colour
[1] = 0x08; // for all new houses
2364 housespec
->random_colour
[2] = 0x0C; // they stand for red, blue, orange and green
2365 housespec
->random_colour
[3] = 0x06;
2367 /* Make sure that the third cargo type is valid in this
2368 * climate. This can cause problems when copying the properties
2369 * of a house that accepts food, where the new house is valid
2370 * in the temperate climate. */
2371 if (!CargoSpec::Get(housespec
->accepts_cargo
[2])->IsValid()) {
2372 housespec
->cargo_acceptance
[2] = 0;
2375 _loaded_newgrf_features
.has_newhouses
= true;
2379 case 0x09: // Building flags
2380 housespec
->building_flags
= (BuildingFlags
)buf
->ReadByte();
2383 case 0x0A: { // Availability years
2384 uint16 years
= buf
->ReadWord();
2385 housespec
->min_year
= GB(years
, 0, 8) > 150 ? MAX_YEAR
: ORIGINAL_BASE_YEAR
+ GB(years
, 0, 8);
2386 housespec
->max_year
= GB(years
, 8, 8) > 150 ? MAX_YEAR
: ORIGINAL_BASE_YEAR
+ GB(years
, 8, 8);
2390 case 0x0B: // Population
2391 housespec
->population
= buf
->ReadByte();
2394 case 0x0C: // Mail generation multiplier
2395 housespec
->mail_generation
= buf
->ReadByte();
2398 case 0x0D: // Passenger acceptance
2399 case 0x0E: // Mail acceptance
2400 housespec
->cargo_acceptance
[prop
- 0x0D] = buf
->ReadByte();
2403 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2404 int8 goods
= buf
->ReadByte();
2406 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2407 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2408 CargoID cid
= (goods
>= 0) ? ((_settings_game
.game_creation
.landscape
== LT_TOYLAND
) ? CT_CANDY
: CT_GOODS
) :
2409 ((_settings_game
.game_creation
.landscape
== LT_TOYLAND
) ? CT_FIZZY_DRINKS
: CT_FOOD
);
2411 /* Make sure the cargo type is valid in this climate. */
2412 if (!CargoSpec::Get(cid
)->IsValid()) goods
= 0;
2414 housespec
->accepts_cargo
[2] = cid
;
2415 housespec
->cargo_acceptance
[2] = abs(goods
); // but we do need positive value here
2419 case 0x10: // Local authority rating decrease on removal
2420 housespec
->remove_rating_decrease
= buf
->ReadWord();
2423 case 0x11: // Removal cost multiplier
2424 housespec
->removal_cost
= buf
->ReadByte();
2427 case 0x12: // Building name ID
2428 AddStringForMapping(buf
->ReadWord(), &housespec
->building_name
);
2431 case 0x13: // Building availability mask
2432 housespec
->building_availability
= (HouseZones
)buf
->ReadWord();
2435 case 0x14: // House callback mask
2436 housespec
->callback_mask
|= buf
->ReadByte();
2439 case 0x15: { // House override byte
2440 byte override
= buf
->ReadByte();
2442 /* The house being overridden must be an original house. */
2443 if (override
>= NEW_HOUSE_OFFSET
) {
2444 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override
, hid
+ i
);
2448 _house_mngr
.Add(hid
+ i
, _cur
.grffile
->grfid
, override
);
2452 case 0x16: // Periodic refresh multiplier
2453 housespec
->processing_time
= min(buf
->ReadByte(), 63);
2456 case 0x17: // Four random colours to use
2457 for (uint j
= 0; j
< 4; j
++) housespec
->random_colour
[j
] = buf
->ReadByte();
2460 case 0x18: // Relative probability of appearing
2461 housespec
->probability
= buf
->ReadByte();
2464 case 0x19: // Extra flags
2465 housespec
->extra_flags
= (HouseExtraFlags
)buf
->ReadByte();
2468 case 0x1A: // Animation frames
2469 housespec
->animation
.frames
= buf
->ReadByte();
2470 housespec
->animation
.status
= GB(housespec
->animation
.frames
, 7, 1);
2471 SB(housespec
->animation
.frames
, 7, 1, 0);
2474 case 0x1B: // Animation speed
2475 housespec
->animation
.speed
= Clamp(buf
->ReadByte(), 2, 16);
2478 case 0x1C: // Class of the building type
2479 housespec
->class_id
= AllocateHouseClassID(buf
->ReadByte(), _cur
.grffile
->grfid
);
2482 case 0x1D: // Callback mask part 2
2483 housespec
->callback_mask
|= (buf
->ReadByte() << 8);
2486 case 0x1E: { // Accepted cargo types
2487 uint32 cargotypes
= buf
->ReadDWord();
2489 /* Check if the cargo types should not be changed */
2490 if (cargotypes
== 0xFFFFFFFF) break;
2492 for (uint j
= 0; j
< 3; j
++) {
2493 /* Get the cargo number from the 'list' */
2494 uint8 cargo_part
= GB(cargotypes
, 8 * j
, 8);
2495 CargoID cargo
= GetCargoTranslation(cargo_part
, _cur
.grffile
);
2497 if (cargo
== CT_INVALID
) {
2498 /* Disable acceptance of invalid cargo type */
2499 housespec
->cargo_acceptance
[j
] = 0;
2501 housespec
->accepts_cargo
[j
] = cargo
;
2507 case 0x1F: // Minimum life span
2508 housespec
->minimum_life
= buf
->ReadByte();
2511 case 0x20: { // Cargo acceptance watch list
2512 byte count
= buf
->ReadByte();
2513 for (byte j
= 0; j
< count
; j
++) {
2514 CargoID cargo
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
2515 if (cargo
!= CT_INVALID
) SetBit(housespec
->watched_cargoes
, cargo
);
2520 case 0x21: // long introduction year
2521 housespec
->min_year
= buf
->ReadWord();
2524 case 0x22: // long maximum year
2525 housespec
->max_year
= buf
->ReadWord();
2538 * Get the language map associated with a given NewGRF and language.
2539 * @param grfid The NewGRF to get the map for.
2540 * @param language_id The (NewGRF) language ID to get the map for.
2541 * @return The LanguageMap, or NULL if it couldn't be found.
2543 /* static */ const LanguageMap
*LanguageMap::GetLanguageMap(uint32 grfid
, uint8 language_id
)
2545 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2546 const GRFFile
*grffile
= GetFileByGRFID(grfid
);
2547 return (grffile
!= NULL
&& grffile
->language_map
!= NULL
&& language_id
< MAX_LANG
) ? &grffile
->language_map
[language_id
] : NULL
;
2551 * Load a cargo- or railtype-translation table.
2552 * @param gvid ID of the global variable. This is basically only checked for zerones.
2553 * @param numinfo Number of subsequent IDs to change the property for.
2554 * @param buf The property value.
2555 * @param [in,out] translation_table Storage location for the translation table.
2556 * @param name Name of the table for debug output.
2557 * @return ChangeInfoResult.
2559 template <typename T
>
2560 static ChangeInfoResult
LoadTranslationTable(uint gvid
, int numinfo
, ByteReader
*buf
, T
&translation_table
, const char *name
)
2563 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name
);
2564 return CIR_INVALID_ID
;
2567 translation_table
.Clear();
2568 for (int i
= 0; i
< numinfo
; i
++) {
2569 uint32 item
= buf
->ReadDWord();
2570 *translation_table
.Append() = BSWAP32(item
);
2577 * Define properties for global variables
2578 * @param gvid ID of the global variable.
2579 * @param numinfo Number of subsequent IDs to change the property for.
2580 * @param prop The property to change.
2581 * @param buf The property value.
2582 * @return ChangeInfoResult.
2584 static ChangeInfoResult
GlobalVarChangeInfo(uint gvid
, int numinfo
, int prop
, ByteReader
*buf
)
2586 /* Properties which are handled as a whole */
2588 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2589 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->cargo_list
, "Cargo");
2591 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2592 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->railtype_list
, "Rail type");
2598 /* Properties which are handled per item */
2599 ChangeInfoResult ret
= CIR_SUCCESS
;
2600 for (int i
= 0; i
< numinfo
; i
++) {
2602 case 0x08: { // Cost base factor
2603 int factor
= buf
->ReadByte();
2604 uint price
= gvid
+ i
;
2606 if (price
< PR_END
) {
2607 _cur
.grffile
->price_base_multipliers
[price
] = min
<int>(factor
- 8, MAX_PRICE_MODIFIER
);
2609 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price
);
2614 case 0x0A: { // Currency display names
2615 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2616 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2618 if ((newone
!= STR_UNDEFINED
) && (curidx
< CURRENCY_END
)) {
2619 _currency_specs
[curidx
].name
= newone
;
2624 case 0x0B: { // Currency multipliers
2625 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2626 uint32 rate
= buf
->ReadDWord();
2628 if (curidx
< CURRENCY_END
) {
2629 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2630 * which OTTD does not. For this reason, divide grf value by 1000,
2631 * to be compatible */
2632 _currency_specs
[curidx
].rate
= rate
/ 1000;
2634 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx
);
2639 case 0x0C: { // Currency options
2640 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2641 uint16 options
= buf
->ReadWord();
2643 if (curidx
< CURRENCY_END
) {
2644 _currency_specs
[curidx
].separator
[0] = GB(options
, 0, 8);
2645 _currency_specs
[curidx
].separator
[1] = '\0';
2646 /* By specifying only one bit, we prevent errors,
2647 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2648 _currency_specs
[curidx
].symbol_pos
= GB(options
, 8, 1);
2650 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx
);
2655 case 0x0D: { // Currency prefix symbol
2656 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2657 uint32 tempfix
= buf
->ReadDWord();
2659 if (curidx
< CURRENCY_END
) {
2660 memcpy(_currency_specs
[curidx
].prefix
, &tempfix
, 4);
2661 _currency_specs
[curidx
].prefix
[4] = 0;
2663 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx
);
2668 case 0x0E: { // Currency suffix symbol
2669 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2670 uint32 tempfix
= buf
->ReadDWord();
2672 if (curidx
< CURRENCY_END
) {
2673 memcpy(&_currency_specs
[curidx
].suffix
, &tempfix
, 4);
2674 _currency_specs
[curidx
].suffix
[4] = 0;
2676 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx
);
2681 case 0x0F: { // Euro introduction dates
2682 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2683 Year year_euro
= buf
->ReadWord();
2685 if (curidx
< CURRENCY_END
) {
2686 _currency_specs
[curidx
].to_euro
= year_euro
;
2688 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx
);
2693 case 0x10: // Snow line height table
2694 if (numinfo
> 1 || IsSnowLineSet()) {
2695 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo
);
2696 } else if (buf
->Remaining() < SNOW_LINE_MONTHS
* SNOW_LINE_DAYS
) {
2697 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf
->Remaining());
2699 byte table
[SNOW_LINE_MONTHS
][SNOW_LINE_DAYS
];
2701 for (uint i
= 0; i
< SNOW_LINE_MONTHS
; i
++) {
2702 for (uint j
= 0; j
< SNOW_LINE_DAYS
; j
++) {
2703 table
[i
][j
] = buf
->ReadByte();
2704 if (_cur
.grffile
->grf_version
>= 8) {
2705 if (table
[i
][j
] != 0xFF) table
[i
][j
] = table
[i
][j
] * (1 + _settings_game
.construction
.max_heightlevel
) / 256;
2707 if (table
[i
][j
] >= 128) {
2711 table
[i
][j
] = table
[i
][j
] * (1 + _settings_game
.construction
.max_heightlevel
) / 128;
2720 case 0x11: // GRF match for engine allocation
2721 /* This is loaded during the reservation stage, so just skip it here. */
2722 /* Each entry is 8 bytes. */
2726 case 0x13: // Gender translation table
2727 case 0x14: // Case translation table
2728 case 0x15: { // Plural form translation
2729 uint curidx
= gvid
+ i
; // The current index, i.e. language.
2730 const LanguageMetadata
*lang
= curidx
< MAX_LANG
? GetLanguage(curidx
) : NULL
;
2732 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx
);
2733 /* Skip over the data. */
2737 while (buf
->ReadByte() != 0) {
2744 if (_cur
.grffile
->language_map
== NULL
) _cur
.grffile
->language_map
= new LanguageMap
[MAX_LANG
];
2747 uint plural_form
= buf
->ReadByte();
2748 if (plural_form
>= LANGUAGE_MAX_PLURAL
) {
2749 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form
);
2751 _cur
.grffile
->language_map
[curidx
].plural_form
= plural_form
;
2756 byte newgrf_id
= buf
->ReadByte(); // The NewGRF (custom) identifier.
2757 while (newgrf_id
!= 0) {
2758 const char *name
= buf
->ReadString(); // The name for the OpenTTD identifier.
2760 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2761 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2762 * is just a subset of UTF8, or they need the bigger UTF8 characters
2763 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2765 size_t len
= Utf8Decode(&c
, name
);
2766 if (c
== NFO_UTF8_IDENTIFIER
) name
+= len
;
2768 LanguageMap::Mapping map
;
2769 map
.newgrf_id
= newgrf_id
;
2771 map
.openttd_id
= lang
->GetGenderIndex(name
);
2772 if (map
.openttd_id
>= MAX_NUM_GENDERS
) {
2773 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name
);
2775 *_cur
.grffile
->language_map
[curidx
].gender_map
.Append() = map
;
2778 map
.openttd_id
= lang
->GetCaseIndex(name
);
2779 if (map
.openttd_id
>= MAX_NUM_CASES
) {
2780 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name
);
2782 *_cur
.grffile
->language_map
[curidx
].case_map
.Append() = map
;
2785 newgrf_id
= buf
->ReadByte();
2799 static ChangeInfoResult
GlobalVarReserveInfo(uint gvid
, int numinfo
, int prop
, ByteReader
*buf
)
2801 /* Properties which are handled as a whole */
2803 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2804 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->cargo_list
, "Cargo");
2806 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2807 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->railtype_list
, "Rail type");
2813 /* Properties which are handled per item */
2814 ChangeInfoResult ret
= CIR_SUCCESS
;
2815 for (int i
= 0; i
< numinfo
; i
++) {
2817 case 0x08: // Cost base factor
2818 case 0x15: // Plural form translation
2822 case 0x0A: // Currency display names
2823 case 0x0C: // Currency options
2824 case 0x0F: // Euro introduction dates
2828 case 0x0B: // Currency multipliers
2829 case 0x0D: // Currency prefix symbol
2830 case 0x0E: // Currency suffix symbol
2834 case 0x10: // Snow line height table
2835 buf
->Skip(SNOW_LINE_MONTHS
* SNOW_LINE_DAYS
);
2838 case 0x11: { // GRF match for engine allocation
2839 uint32 s
= buf
->ReadDWord();
2840 uint32 t
= buf
->ReadDWord();
2841 SetNewGRFOverride(s
, t
);
2845 case 0x13: // Gender translation table
2846 case 0x14: // Case translation table
2847 while (buf
->ReadByte() != 0) {
2863 * Define properties for cargoes
2864 * @param cid Local ID of the cargo.
2865 * @param numinfo Number of subsequent IDs to change the property for.
2866 * @param prop The property to change.
2867 * @param buf The property value.
2868 * @return ChangeInfoResult.
2870 static ChangeInfoResult
CargoChangeInfo(uint cid
, int numinfo
, int prop
, ByteReader
*buf
)
2872 ChangeInfoResult ret
= CIR_SUCCESS
;
2874 if (cid
+ numinfo
> NUM_CARGO
) {
2875 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid
+ numinfo
, NUM_CARGO
- 1);
2876 return CIR_INVALID_ID
;
2879 for (int i
= 0; i
< numinfo
; i
++) {
2880 CargoSpec
*cs
= CargoSpec::Get(cid
+ i
);
2883 case 0x08: // Bit number of cargo
2884 cs
->bitnum
= buf
->ReadByte();
2885 if (cs
->IsValid()) {
2886 cs
->grffile
= _cur
.grffile
;
2887 SetBit(_cargo_mask
, cid
+ i
);
2889 ClrBit(_cargo_mask
, cid
+ i
);
2893 case 0x09: // String ID for cargo type name
2894 AddStringForMapping(buf
->ReadWord(), &cs
->name
);
2897 case 0x0A: // String for 1 unit of cargo
2898 AddStringForMapping(buf
->ReadWord(), &cs
->name_single
);
2901 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2902 case 0x1B: // String for cargo units
2903 /* String for units of cargo. This is different in OpenTTD
2904 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2905 * Property 1B is used to set OpenTTD's behaviour. */
2906 AddStringForMapping(buf
->ReadWord(), &cs
->units_volume
);
2909 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2910 case 0x1C: // String for any amount of cargo
2911 /* Strings for an amount of cargo. This is different in OpenTTD
2912 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2913 * Property 1C is used to set OpenTTD's behaviour. */
2914 AddStringForMapping(buf
->ReadWord(), &cs
->quantifier
);
2917 case 0x0D: // String for two letter cargo abbreviation
2918 AddStringForMapping(buf
->ReadWord(), &cs
->abbrev
);
2921 case 0x0E: // Sprite ID for cargo icon
2922 cs
->sprite
= buf
->ReadWord();
2925 case 0x0F: // Weight of one unit of cargo
2926 cs
->weight
= buf
->ReadByte();
2929 case 0x10: // Used for payment calculation
2930 cs
->transit_days
[0] = buf
->ReadByte();
2933 case 0x11: // Used for payment calculation
2934 cs
->transit_days
[1] = buf
->ReadByte();
2937 case 0x12: // Base cargo price
2938 cs
->initial_payment
= buf
->ReadDWord();
2941 case 0x13: // Colour for station rating bars
2942 cs
->rating_colour
= buf
->ReadByte();
2945 case 0x14: // Colour for cargo graph
2946 cs
->legend_colour
= buf
->ReadByte();
2949 case 0x15: // Freight status
2950 cs
->is_freight
= (buf
->ReadByte() != 0);
2953 case 0x16: // Cargo classes
2954 cs
->classes
= buf
->ReadWord();
2957 case 0x17: // Cargo label
2958 cs
->label
= buf
->ReadDWord();
2959 cs
->label
= BSWAP32(cs
->label
);
2962 case 0x18: { // Town growth substitute type
2963 uint8 substitute_type
= buf
->ReadByte();
2965 switch (substitute_type
) {
2966 case 0x00: cs
->town_effect
= TE_PASSENGERS
; break;
2967 case 0x02: cs
->town_effect
= TE_MAIL
; break;
2968 case 0x05: cs
->town_effect
= TE_GOODS
; break;
2969 case 0x09: cs
->town_effect
= TE_WATER
; break;
2970 case 0x0B: cs
->town_effect
= TE_FOOD
; break;
2972 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type
);
2974 case 0xFF: cs
->town_effect
= TE_NONE
; break;
2979 case 0x19: // Town growth coefficient
2980 cs
->multipliertowngrowth
= buf
->ReadWord();
2983 case 0x1A: // Bitmask of callbacks to use
2984 cs
->callback_mask
= buf
->ReadByte();
2987 case 0x1D: // Vehicle capacity muliplier
2988 cs
->multiplier
= max
<uint16
>(1u, buf
->ReadWord());
3002 * Define properties for sound effects
3003 * @param sid Local ID of the sound.
3004 * @param numinfo Number of subsequent IDs to change the property for.
3005 * @param prop The property to change.
3006 * @param buf The property value.
3007 * @return ChangeInfoResult.
3009 static ChangeInfoResult
SoundEffectChangeInfo(uint sid
, int numinfo
, int prop
, ByteReader
*buf
)
3011 ChangeInfoResult ret
= CIR_SUCCESS
;
3013 if (_cur
.grffile
->sound_offset
== 0) {
3014 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3015 return CIR_INVALID_ID
;
3018 if (sid
+ numinfo
- ORIGINAL_SAMPLE_COUNT
> _cur
.grffile
->num_sounds
) {
3019 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid
+ numinfo
, ORIGINAL_SAMPLE_COUNT
+ _cur
.grffile
->num_sounds
);
3020 return CIR_INVALID_ID
;
3023 for (int i
= 0; i
< numinfo
; i
++) {
3024 SoundEntry
*sound
= GetSound(sid
+ i
+ _cur
.grffile
->sound_offset
- ORIGINAL_SAMPLE_COUNT
);
3027 case 0x08: // Relative volume
3028 sound
->volume
= buf
->ReadByte();
3031 case 0x09: // Priority
3032 sound
->priority
= buf
->ReadByte();
3035 case 0x0A: { // Override old sound
3036 SoundID orig_sound
= buf
->ReadByte();
3038 if (orig_sound
>= ORIGINAL_SAMPLE_COUNT
) {
3039 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound
, ORIGINAL_SAMPLE_COUNT
);
3041 SoundEntry
*old_sound
= GetSound(orig_sound
);
3043 /* Literally copy the data of the new sound over the original */
3044 *old_sound
= *sound
;
3059 * Ignore an industry tile property
3060 * @param prop The property to ignore.
3061 * @param buf The property value.
3062 * @return ChangeInfoResult.
3064 static ChangeInfoResult
IgnoreIndustryTileProperty(int prop
, ByteReader
*buf
)
3066 ChangeInfoResult ret
= CIR_SUCCESS
;
3093 * Define properties for industry tiles
3094 * @param indtid Local ID of the industry tile.
3095 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3096 * @param prop The property to change.
3097 * @param buf The property value.
3098 * @return ChangeInfoResult.
3100 static ChangeInfoResult
IndustrytilesChangeInfo(uint indtid
, int numinfo
, int prop
, ByteReader
*buf
)
3102 ChangeInfoResult ret
= CIR_SUCCESS
;
3104 if (indtid
+ numinfo
> NUM_INDUSTRYTILES_PER_GRF
) {
3105 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid
+ numinfo
, NUM_INDUSTRYTILES_PER_GRF
);
3106 return CIR_INVALID_ID
;
3109 /* Allocate industry tile specs if they haven't been allocated already. */
3110 if (_cur
.grffile
->indtspec
== NULL
) {
3111 _cur
.grffile
->indtspec
= CallocT
<IndustryTileSpec
*>(NUM_INDUSTRYTILES_PER_GRF
);
3114 for (int i
= 0; i
< numinfo
; i
++) {
3115 IndustryTileSpec
*tsp
= _cur
.grffile
->indtspec
[indtid
+ i
];
3117 if (prop
!= 0x08 && tsp
== NULL
) {
3118 ChangeInfoResult cir
= IgnoreIndustryTileProperty(prop
, buf
);
3119 if (cir
> ret
) ret
= cir
;
3124 case 0x08: { // Substitute industry tile type
3125 IndustryTileSpec
**tilespec
= &_cur
.grffile
->indtspec
[indtid
+ i
];
3126 byte subs_id
= buf
->ReadByte();
3128 if (subs_id
>= NEW_INDUSTRYTILEOFFSET
) {
3129 /* The substitute id must be one of the original industry tile. */
3130 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id
, indtid
+ i
);
3134 /* Allocate space for this industry. */
3135 if (*tilespec
== NULL
) {
3136 *tilespec
= CallocT
<IndustryTileSpec
>(1);
3139 memcpy(tsp
, &_industry_tile_specs
[subs_id
], sizeof(_industry_tile_specs
[subs_id
]));
3140 tsp
->enabled
= true;
3142 /* A copied tile should not have the animation infos copied too.
3143 * The anim_state should be left untouched, though
3144 * It is up to the author to animate them himself */
3145 tsp
->anim_production
= INDUSTRYTILE_NOANIM
;
3146 tsp
->anim_next
= INDUSTRYTILE_NOANIM
;
3148 tsp
->grf_prop
.local_id
= indtid
+ i
;
3149 tsp
->grf_prop
.subst_id
= subs_id
;
3150 tsp
->grf_prop
.grffile
= _cur
.grffile
;
3151 _industile_mngr
.AddEntityID(indtid
+ i
, _cur
.grffile
->grfid
, subs_id
); // pre-reserve the tile slot
3156 case 0x09: { // Industry tile override
3157 byte ovrid
= buf
->ReadByte();
3159 /* The industry being overridden must be an original industry. */
3160 if (ovrid
>= NEW_INDUSTRYTILEOFFSET
) {
3161 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid
, indtid
+ i
);
3165 _industile_mngr
.Add(indtid
+ i
, _cur
.grffile
->grfid
, ovrid
);
3169 case 0x0A: // Tile acceptance
3172 uint16 acctp
= buf
->ReadWord();
3173 tsp
->accepts_cargo
[prop
- 0x0A] = GetCargoTranslation(GB(acctp
, 0, 8), _cur
.grffile
);
3174 tsp
->acceptance
[prop
- 0x0A] = GB(acctp
, 8, 8);
3178 case 0x0D: // Land shape flags
3179 tsp
->slopes_refused
= (Slope
)buf
->ReadByte();
3182 case 0x0E: // Callback mask
3183 tsp
->callback_mask
= buf
->ReadByte();
3186 case 0x0F: // Animation information
3187 tsp
->animation
.frames
= buf
->ReadByte();
3188 tsp
->animation
.status
= buf
->ReadByte();
3191 case 0x10: // Animation speed
3192 tsp
->animation
.speed
= buf
->ReadByte();
3195 case 0x11: // Triggers for callback 25
3196 tsp
->animation
.triggers
= buf
->ReadByte();
3199 case 0x12: // Special flags
3200 tsp
->special_flags
= (IndustryTileSpecialFlags
)buf
->ReadByte();
3213 * Ignore an industry property
3214 * @param prop The property to ignore.
3215 * @param buf The property value.
3216 * @return ChangeInfoResult.
3218 static ChangeInfoResult
IgnoreIndustryProperty(int prop
, ByteReader
*buf
)
3220 ChangeInfoResult ret
= CIR_SUCCESS
;
3258 byte num_table
= buf
->ReadByte();
3259 for (byte j
= 0; j
< num_table
; j
++) {
3260 for (uint k
= 0;; k
++) {
3261 byte x
= buf
->ReadByte();
3262 if (x
== 0xFE && k
== 0) {
3268 byte y
= buf
->ReadByte();
3269 if (x
== 0 && y
== 0x80) break;
3271 byte gfx
= buf
->ReadByte();
3272 if (gfx
== 0xFE) buf
->ReadWord();
3279 for (byte j
= 0; j
< 3; j
++) buf
->ReadByte();
3283 byte number_of_sounds
= buf
->ReadByte();
3284 for (uint8 j
= 0; j
< number_of_sounds
; j
++) {
3298 * Validate the industry layout; e.g. to prevent duplicate tiles.
3299 * @param layout The layout to check.
3300 * @param size The size of the layout.
3301 * @return True if the layout is deemed valid.
3303 static bool ValidateIndustryLayout(const IndustryTileTable
*layout
, int size
)
3305 for (int i
= 0; i
< size
- 1; i
++) {
3306 for (int j
= i
+ 1; j
< size
; j
++) {
3307 if (layout
[i
].ti
.x
== layout
[j
].ti
.x
&&
3308 layout
[i
].ti
.y
== layout
[j
].ti
.y
) {
3316 /** Clean the tile table of the IndustrySpec if it's needed. */
3317 static void CleanIndustryTileTable(IndustrySpec
*ind
)
3319 if (HasBit(ind
->cleanup_flag
, CLEAN_TILELAYOUT
) && ind
->table
!= NULL
) {
3320 for (int j
= 0; j
< ind
->num_table
; j
++) {
3321 /* remove the individual layouts */
3322 free(ind
->table
[j
]);
3324 /* remove the layouts pointers */
3331 * Define properties for industries
3332 * @param indid Local ID of the industry.
3333 * @param numinfo Number of subsequent industry IDs to change the property for.
3334 * @param prop The property to change.
3335 * @param buf The property value.
3336 * @return ChangeInfoResult.
3338 static ChangeInfoResult
IndustriesChangeInfo(uint indid
, int numinfo
, int prop
, ByteReader
*buf
)
3340 ChangeInfoResult ret
= CIR_SUCCESS
;
3342 if (indid
+ numinfo
> NUM_INDUSTRYTYPES_PER_GRF
) {
3343 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid
+ numinfo
, NUM_INDUSTRYTYPES_PER_GRF
);
3344 return CIR_INVALID_ID
;
3347 /* Allocate industry specs if they haven't been allocated already. */
3348 if (_cur
.grffile
->industryspec
== NULL
) {
3349 _cur
.grffile
->industryspec
= CallocT
<IndustrySpec
*>(NUM_INDUSTRYTYPES_PER_GRF
);
3352 for (int i
= 0; i
< numinfo
; i
++) {
3353 IndustrySpec
*indsp
= _cur
.grffile
->industryspec
[indid
+ i
];
3355 if (prop
!= 0x08 && indsp
== NULL
) {
3356 ChangeInfoResult cir
= IgnoreIndustryProperty(prop
, buf
);
3357 if (cir
> ret
) ret
= cir
;
3362 case 0x08: { // Substitute industry type
3363 IndustrySpec
**indspec
= &_cur
.grffile
->industryspec
[indid
+ i
];
3364 byte subs_id
= buf
->ReadByte();
3366 if (subs_id
== 0xFF) {
3367 /* Instead of defining a new industry, a substitute industry id
3368 * of 0xFF disables the old industry with the current id. */
3369 _industry_specs
[indid
+ i
].enabled
= false;
3371 } else if (subs_id
>= NEW_INDUSTRYOFFSET
) {
3372 /* The substitute id must be one of the original industry. */
3373 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id
, indid
+ i
);
3377 /* Allocate space for this industry.
3378 * Only need to do it once. If ever it is called again, it should not
3380 if (*indspec
== NULL
) {
3381 *indspec
= CallocT
<IndustrySpec
>(1);
3384 memcpy(indsp
, &_origin_industry_specs
[subs_id
], sizeof(_industry_specs
[subs_id
]));
3385 indsp
->enabled
= true;
3386 indsp
->grf_prop
.local_id
= indid
+ i
;
3387 indsp
->grf_prop
.subst_id
= subs_id
;
3388 indsp
->grf_prop
.grffile
= _cur
.grffile
;
3389 /* If the grf industry needs to check its surounding upon creation, it should
3390 * rely on callbacks, not on the original placement functions */
3391 indsp
->check_proc
= CHECK_NOTHING
;
3396 case 0x09: { // Industry type override
3397 byte ovrid
= buf
->ReadByte();
3399 /* The industry being overridden must be an original industry. */
3400 if (ovrid
>= NEW_INDUSTRYOFFSET
) {
3401 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid
, indid
+ i
);
3404 indsp
->grf_prop
.override
= ovrid
;
3405 _industry_mngr
.Add(indid
+ i
, _cur
.grffile
->grfid
, ovrid
);
3409 case 0x0A: { // Set industry layout(s)
3410 byte new_num_layouts
= buf
->ReadByte(); // Number of layaouts
3411 /* We read the total size in bytes, but we can't rely on the
3412 * newgrf to provide a sane value. First assume the value is
3413 * sane but later on we make sure we enlarge the array if the
3414 * newgrf contains more data. Each tile uses either 3 or 5
3415 * bytes, so to play it safe we assume 3. */
3416 uint32 def_num_tiles
= buf
->ReadDWord() / 3 + 1;
3417 IndustryTileTable
**tile_table
= CallocT
<IndustryTileTable
*>(new_num_layouts
); // Table with tiles to compose an industry
3418 IndustryTileTable
*itt
= CallocT
<IndustryTileTable
>(def_num_tiles
); // Temporary array to read the tile layouts from the GRF
3420 const IndustryTileTable
*copy_from
;
3423 for (byte j
= 0; j
< new_num_layouts
; j
++) {
3424 for (uint k
= 0;; k
++) {
3425 if (k
>= def_num_tiles
) {
3426 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid
);
3427 /* Size reported by newgrf was not big enough so enlarge the array. */
3429 itt
= ReallocT
<IndustryTileTable
>(itt
, def_num_tiles
);
3432 itt
[k
].ti
.x
= buf
->ReadByte(); // Offsets from northermost tile
3434 if (itt
[k
].ti
.x
== 0xFE && k
== 0) {
3435 /* This means we have to borrow the layout from an old industry */
3436 IndustryType type
= buf
->ReadByte(); // industry holding required layout
3437 byte laynbr
= buf
->ReadByte(); // layout number to borrow
3439 copy_from
= _origin_industry_specs
[type
].table
[laynbr
];
3440 for (size
= 1;; size
++) {
3441 if (copy_from
[size
- 1].ti
.x
== -0x80 && copy_from
[size
- 1].ti
.y
== 0) break;
3446 itt
[k
].ti
.y
= buf
->ReadByte(); // Or table definition finalisation
3448 if (itt
[k
].ti
.x
== 0 && itt
[k
].ti
.y
== 0x80) {
3449 /* Not the same terminator. The one we are using is rather
3450 x = -80, y = x . So, adjust it. */
3451 itt
[k
].ti
.x
= -0x80;
3460 itt
[k
].gfx
= buf
->ReadByte();
3462 if (itt
[k
].gfx
== 0xFE) {
3463 /* Use a new tile from this GRF */
3464 int local_tile_id
= buf
->ReadWord();
3466 /* Read the ID from the _industile_mngr. */
3467 int tempid
= _industile_mngr
.GetID(local_tile_id
, _cur
.grffile
->grfid
);
3469 if (tempid
== INVALID_INDUSTRYTILE
) {
3470 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id
, indid
);
3472 /* Declared as been valid, can be used */
3473 itt
[k
].gfx
= tempid
;
3477 } else if (itt
[k
].gfx
== 0xFF) {
3478 itt
[k
].ti
.x
= (int8
)GB(itt
[k
].ti
.x
, 0, 8);
3479 itt
[k
].ti
.y
= (int8
)GB(itt
[k
].ti
.y
, 0, 8);
3481 /* When there were only 256x256 maps, TileIndex was a uint16 and
3482 * itt[k].ti was just a TileIndexDiff that was added to it.
3483 * As such negative "x" values were shifted into the "y" position.
3484 * x = -1, y = 1 -> x = 255, y = 0
3485 * Since GRF version 8 the position is interpreted as pair of independent int8.
3486 * For GRF version < 8 we need to emulate the old shifting behaviour.
3488 if (_cur
.grffile
->grf_version
< 8 && itt
[k
].ti
.x
< 0) itt
[k
].ti
.y
+= 1;
3492 if (!ValidateIndustryLayout(copy_from
, size
)) {
3493 /* The industry layout was not valid, so skip this one. */
3494 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid
);
3498 tile_table
[j
] = CallocT
<IndustryTileTable
>(size
);
3499 memcpy(tile_table
[j
], copy_from
, sizeof(*copy_from
) * size
);
3503 for (int i
= 0; i
< new_num_layouts
; i
++) {
3504 free(tile_table
[i
]);
3511 /* Clean the tile table if it was already set by a previous prop A. */
3512 CleanIndustryTileTable(indsp
);
3513 /* Install final layout construction in the industry spec */
3514 indsp
->num_table
= new_num_layouts
;
3515 indsp
->table
= tile_table
;
3516 SetBit(indsp
->cleanup_flag
, CLEAN_TILELAYOUT
);
3521 case 0x0B: // Industry production flags
3522 indsp
->life_type
= (IndustryLifeType
)buf
->ReadByte();
3525 case 0x0C: // Industry closure message
3526 AddStringForMapping(buf
->ReadWord(), &indsp
->closure_text
);
3529 case 0x0D: // Production increase message
3530 AddStringForMapping(buf
->ReadWord(), &indsp
->production_up_text
);
3533 case 0x0E: // Production decrease message
3534 AddStringForMapping(buf
->ReadWord(), &indsp
->production_down_text
);
3537 case 0x0F: // Fund cost multiplier
3538 indsp
->cost_multiplier
= buf
->ReadByte();
3541 case 0x10: // Production cargo types
3542 for (byte j
= 0; j
< 2; j
++) {
3543 indsp
->produced_cargo
[j
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3547 case 0x11: // Acceptance cargo types
3548 for (byte j
= 0; j
< 3; j
++) {
3549 indsp
->accepts_cargo
[j
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3551 buf
->ReadByte(); // Unnused, eat it up
3554 case 0x12: // Production multipliers
3556 indsp
->production_rate
[prop
- 0x12] = buf
->ReadByte();
3559 case 0x14: // Minimal amount of cargo distributed
3560 indsp
->minimal_cargo
= buf
->ReadByte();
3563 case 0x15: { // Random sound effects
3564 indsp
->number_of_sounds
= buf
->ReadByte();
3565 uint8
*sounds
= MallocT
<uint8
>(indsp
->number_of_sounds
);
3568 for (uint8 j
= 0; j
< indsp
->number_of_sounds
; j
++) {
3569 sounds
[j
] = buf
->ReadByte();
3576 if (HasBit(indsp
->cleanup_flag
, CLEAN_RANDOMSOUNDS
)) {
3577 free(indsp
->random_sounds
);
3579 indsp
->random_sounds
= sounds
;
3580 SetBit(indsp
->cleanup_flag
, CLEAN_RANDOMSOUNDS
);
3584 case 0x16: // Conflicting industry types
3585 for (byte j
= 0; j
< 3; j
++) indsp
->conflicting
[j
] = buf
->ReadByte();
3588 case 0x17: // Probability in random game
3589 indsp
->appear_creation
[_settings_game
.game_creation
.landscape
] = buf
->ReadByte();
3592 case 0x18: // Probability during gameplay
3593 indsp
->appear_ingame
[_settings_game
.game_creation
.landscape
] = buf
->ReadByte();
3596 case 0x19: // Map colour
3597 indsp
->map_colour
= buf
->ReadByte();
3600 case 0x1A: // Special industry flags to define special behavior
3601 indsp
->behaviour
= (IndustryBehaviour
)buf
->ReadDWord();
3604 case 0x1B: // New industry text ID
3605 AddStringForMapping(buf
->ReadWord(), &indsp
->new_industry_text
);
3608 case 0x1C: // Input cargo multipliers for the three input cargo types
3611 uint32 multiples
= buf
->ReadDWord();
3612 indsp
->input_cargo_multiplier
[prop
- 0x1C][0] = GB(multiples
, 0, 16);
3613 indsp
->input_cargo_multiplier
[prop
- 0x1C][1] = GB(multiples
, 16, 16);
3617 case 0x1F: // Industry name
3618 AddStringForMapping(buf
->ReadWord(), &indsp
->name
);
3621 case 0x20: // Prospecting success chance
3622 indsp
->prospecting_chance
= buf
->ReadDWord();
3625 case 0x21: // Callback mask
3626 case 0x22: { // Callback additional mask
3627 byte aflag
= buf
->ReadByte();
3628 SB(indsp
->callback_mask
, (prop
- 0x21) * 8, 8, aflag
);
3632 case 0x23: // removal cost multiplier
3633 indsp
->removal_cost_multiplier
= buf
->ReadDWord();
3636 case 0x24: { // name for nearby station
3637 uint16 str
= buf
->ReadWord();
3639 indsp
->station_name
= STR_NULL
;
3641 AddStringForMapping(str
, &indsp
->station_name
);
3656 * Create a copy of the tile table so it can be freed later
3658 * @param as The AirportSpec to copy the arrays of.
3660 static void DuplicateTileTable(AirportSpec
*as
)
3662 AirportTileTable
**table_list
= MallocT
<AirportTileTable
*>(as
->num_table
);
3663 for (int i
= 0; i
< as
->num_table
; i
++) {
3665 const AirportTileTable
*it
= as
->table
[0];
3668 } while ((++it
)->ti
.x
!= -0x80);
3669 table_list
[i
] = MallocT
<AirportTileTable
>(num_tiles
);
3670 MemCpyT(table_list
[i
], as
->table
[i
], num_tiles
);
3672 as
->table
= table_list
;
3673 HangarTileTable
*depot_table
= MallocT
<HangarTileTable
>(as
->nof_depots
);
3674 MemCpyT(depot_table
, as
->depot_table
, as
->nof_depots
);
3675 as
->depot_table
= depot_table
;
3676 Direction
*rotation
= MallocT
<Direction
>(as
->num_table
);
3677 MemCpyT(rotation
, as
->rotation
, as
->num_table
);
3678 as
->rotation
= rotation
;
3682 * Define properties for airports
3683 * @param airport Local ID of the airport.
3684 * @param numinfo Number of subsequent airport IDs to change the property for.
3685 * @param prop The property to change.
3686 * @param buf The property value.
3687 * @return ChangeInfoResult.
3689 static ChangeInfoResult
AirportChangeInfo(uint airport
, int numinfo
, int prop
, ByteReader
*buf
)
3691 ChangeInfoResult ret
= CIR_SUCCESS
;
3693 if (airport
+ numinfo
> NUM_AIRPORTS_PER_GRF
) {
3694 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport
+ numinfo
, NUM_AIRPORTS_PER_GRF
);
3695 return CIR_INVALID_ID
;
3698 /* Allocate industry specs if they haven't been allocated already. */
3699 if (_cur
.grffile
->airportspec
== NULL
) {
3700 _cur
.grffile
->airportspec
= CallocT
<AirportSpec
*>(NUM_AIRPORTS_PER_GRF
);
3703 for (int i
= 0; i
< numinfo
; i
++) {
3704 AirportSpec
*as
= _cur
.grffile
->airportspec
[airport
+ i
];
3706 if (as
== NULL
&& prop
!= 0x08 && prop
!= 0x09) {
3707 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport
+ i
);
3708 return CIR_INVALID_ID
;
3712 case 0x08: { // Modify original airport
3713 byte subs_id
= buf
->ReadByte();
3715 if (subs_id
== 0xFF) {
3716 /* Instead of defining a new airport, an airport id
3717 * of 0xFF disables the old airport with the current id. */
3718 AirportSpec::GetWithoutOverride(airport
+ i
)->enabled
= false;
3720 } else if (subs_id
>= NEW_AIRPORT_OFFSET
) {
3721 /* The substitute id must be one of the original airports. */
3722 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id
, airport
+ i
);
3726 AirportSpec
**spec
= &_cur
.grffile
->airportspec
[airport
+ i
];
3727 /* Allocate space for this airport.
3728 * Only need to do it once. If ever it is called again, it should not
3730 if (*spec
== NULL
) {
3731 *spec
= MallocT
<AirportSpec
>(1);
3734 memcpy(as
, AirportSpec::GetWithoutOverride(subs_id
), sizeof(*as
));
3736 as
->grf_prop
.local_id
= airport
+ i
;
3737 as
->grf_prop
.subst_id
= subs_id
;
3738 as
->grf_prop
.grffile
= _cur
.grffile
;
3739 /* override the default airport */
3740 _airport_mngr
.Add(airport
+ i
, _cur
.grffile
->grfid
, subs_id
);
3741 /* Create a copy of the original tiletable so it can be freed later. */
3742 DuplicateTileTable(as
);
3747 case 0x0A: { // Set airport layout
3749 as
->num_table
= buf
->ReadByte(); // Number of layaouts
3750 as
->rotation
= MallocT
<Direction
>(as
->num_table
);
3751 uint32 defsize
= buf
->ReadDWord(); // Total size of the definition
3752 AirportTileTable
**tile_table
= CallocT
<AirportTileTable
*>(as
->num_table
); // Table with tiles to compose the airport
3753 AirportTileTable
*att
= CallocT
<AirportTileTable
>(defsize
); // Temporary array to read the tile layouts from the GRF
3755 const AirportTileTable
*copy_from
;
3757 for (byte j
= 0; j
< as
->num_table
; j
++) {
3758 const_cast<Direction
&>(as
->rotation
[j
]) = (Direction
)buf
->ReadByte();
3759 for (int k
= 0;; k
++) {
3760 att
[k
].ti
.x
= buf
->ReadByte(); // Offsets from northermost tile
3761 att
[k
].ti
.y
= buf
->ReadByte();
3763 if (att
[k
].ti
.x
== 0 && att
[k
].ti
.y
== 0x80) {
3764 /* Not the same terminator. The one we are using is rather
3765 * x = -80, y = 0 . So, adjust it. */
3766 att
[k
].ti
.x
= -0x80;
3775 att
[k
].gfx
= buf
->ReadByte();
3777 if (att
[k
].gfx
== 0xFE) {
3778 /* Use a new tile from this GRF */
3779 int local_tile_id
= buf
->ReadWord();
3781 /* Read the ID from the _airporttile_mngr. */
3782 uint16 tempid
= _airporttile_mngr
.GetID(local_tile_id
, _cur
.grffile
->grfid
);
3784 if (tempid
== INVALID_AIRPORTTILE
) {
3785 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id
, airport
+ i
);
3787 /* Declared as been valid, can be used */
3788 att
[k
].gfx
= tempid
;
3792 } else if (att
[k
].gfx
== 0xFF) {
3793 att
[k
].ti
.x
= (int8
)GB(att
[k
].ti
.x
, 0, 8);
3794 att
[k
].ti
.y
= (int8
)GB(att
[k
].ti
.y
, 0, 8);
3797 if (as
->rotation
[j
] == DIR_E
|| as
->rotation
[j
] == DIR_W
) {
3798 as
->size_x
= max
<byte
>(as
->size_x
, att
[k
].ti
.y
+ 1);
3799 as
->size_y
= max
<byte
>(as
->size_y
, att
[k
].ti
.x
+ 1);
3801 as
->size_x
= max
<byte
>(as
->size_x
, att
[k
].ti
.x
+ 1);
3802 as
->size_y
= max
<byte
>(as
->size_y
, att
[k
].ti
.y
+ 1);
3805 tile_table
[j
] = CallocT
<AirportTileTable
>(size
);
3806 memcpy(tile_table
[j
], copy_from
, sizeof(*copy_from
) * size
);
3808 /* Install final layout construction in the airport spec */
3809 as
->table
= tile_table
;
3812 for (int i
= 0; i
< as
->num_table
; i
++) {
3813 free(tile_table
[i
]);
3823 as
->min_year
= buf
->ReadWord();
3824 as
->max_year
= buf
->ReadWord();
3825 if (as
->max_year
== 0xFFFF) as
->max_year
= MAX_YEAR
;
3829 as
->ttd_airport_type
= (TTDPAirportType
)buf
->ReadByte();
3833 as
->catchment
= Clamp(buf
->ReadByte(), 1, MAX_CATCHMENT
);
3837 as
->noise_level
= buf
->ReadByte();
3841 AddStringForMapping(buf
->ReadWord(), &as
->name
);
3844 case 0x11: // Maintenance cost factor
3845 as
->maintenance_cost
= buf
->ReadWord();
3858 * Ignore properties for objects
3859 * @param prop The property to ignore.
3860 * @param buf The property value.
3861 * @return ChangeInfoResult.
3863 static ChangeInfoResult
IgnoreObjectProperty(uint prop
, ByteReader
*buf
)
3865 ChangeInfoResult ret
= CIR_SUCCESS
;
3902 * Define properties for objects
3903 * @param id Local ID of the object.
3904 * @param numinfo Number of subsequent objectIDs to change the property for.
3905 * @param prop The property to change.
3906 * @param buf The property value.
3907 * @return ChangeInfoResult.
3909 static ChangeInfoResult
ObjectChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
3911 ChangeInfoResult ret
= CIR_SUCCESS
;
3913 if (id
+ numinfo
> NUM_OBJECTS_PER_GRF
) {
3914 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id
+ numinfo
, NUM_OBJECTS_PER_GRF
);
3915 return CIR_INVALID_ID
;
3918 /* Allocate object specs if they haven't been allocated already. */
3919 if (_cur
.grffile
->objectspec
== NULL
) {
3920 _cur
.grffile
->objectspec
= CallocT
<ObjectSpec
*>(NUM_OBJECTS_PER_GRF
);
3923 for (int i
= 0; i
< numinfo
; i
++) {
3924 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[id
+ i
];
3926 if (prop
!= 0x08 && spec
== NULL
) {
3927 /* If the object property 08 is not yet set, ignore this property */
3928 ChangeInfoResult cir
= IgnoreObjectProperty(prop
, buf
);
3929 if (cir
> ret
) ret
= cir
;
3934 case 0x08: { // Class ID
3935 ObjectSpec
**ospec
= &_cur
.grffile
->objectspec
[id
+ i
];
3937 /* Allocate space for this object. */
3938 if (*ospec
== NULL
) {
3939 *ospec
= CallocT
<ObjectSpec
>(1);
3940 (*ospec
)->views
= 1; // Default for NewGRFs that don't set it.
3943 /* Swap classid because we read it in BE. */
3944 uint32 classid
= buf
->ReadDWord();
3945 (*ospec
)->cls_id
= ObjectClass::Allocate(BSWAP32(classid
));
3946 (*ospec
)->enabled
= true;
3950 case 0x09: { // Class name
3951 ObjectClass
*objclass
= ObjectClass::Get(spec
->cls_id
);
3952 AddStringForMapping(buf
->ReadWord(), &objclass
->name
);
3956 case 0x0A: // Object name
3957 AddStringForMapping(buf
->ReadWord(), &spec
->name
);
3960 case 0x0B: // Climate mask
3961 spec
->climate
= buf
->ReadByte();
3965 spec
->size
= buf
->ReadByte();
3968 case 0x0D: // Build cost multipler
3969 spec
->build_cost_multiplier
= buf
->ReadByte();
3970 spec
->clear_cost_multiplier
= spec
->build_cost_multiplier
;
3973 case 0x0E: // Introduction date
3974 spec
->introduction_date
= buf
->ReadDWord();
3977 case 0x0F: // End of life
3978 spec
->end_of_life_date
= buf
->ReadDWord();
3982 spec
->flags
= (ObjectFlags
)buf
->ReadWord();
3983 _loaded_newgrf_features
.has_2CC
|= (spec
->flags
& OBJECT_FLAG_2CC_COLOUR
) != 0;
3986 case 0x11: // Animation info
3987 spec
->animation
.frames
= buf
->ReadByte();
3988 spec
->animation
.status
= buf
->ReadByte();
3991 case 0x12: // Animation speed
3992 spec
->animation
.speed
= buf
->ReadByte();
3995 case 0x13: // Animation triggers
3996 spec
->animation
.triggers
= buf
->ReadWord();
3999 case 0x14: // Removal cost multiplier
4000 spec
->clear_cost_multiplier
= buf
->ReadByte();
4003 case 0x15: // Callback mask
4004 spec
->callback_mask
= buf
->ReadWord();
4007 case 0x16: // Building height
4008 spec
->height
= buf
->ReadByte();
4012 spec
->views
= buf
->ReadByte();
4013 if (spec
->views
!= 1 && spec
->views
!= 2 && spec
->views
!= 4) {
4014 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec
->views
, id
+ i
);
4019 case 0x18: // Amount placed on 256^2 map on map creation
4020 spec
->generate_amount
= buf
->ReadByte();
4033 * Define properties for railtypes
4034 * @param id ID of the railtype.
4035 * @param numinfo Number of subsequent IDs to change the property for.
4036 * @param prop The property to change.
4037 * @param buf The property value.
4038 * @return ChangeInfoResult.
4040 static ChangeInfoResult
RailTypeChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4042 ChangeInfoResult ret
= CIR_SUCCESS
;
4044 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
4046 if (id
+ numinfo
> RAILTYPE_END
) {
4047 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id
+ numinfo
, RAILTYPE_END
);
4048 return CIR_INVALID_ID
;
4051 for (int i
= 0; i
< numinfo
; i
++) {
4052 RailType rt
= _cur
.grffile
->railtype_map
[id
+ i
];
4053 if (rt
== INVALID_RAILTYPE
) return CIR_INVALID_ID
;
4055 RailtypeInfo
*rti
= &_railtypes
[rt
];
4058 case 0x08: // Label of rail type
4059 /* Skipped here as this is loaded during reservation stage. */
4063 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4064 uint16 str
= buf
->ReadWord();
4065 AddStringForMapping(str
, &rti
->strings
.toolbar_caption
);
4066 if (_cur
.grffile
->grf_version
< 8) {
4067 AddStringForMapping(str
, &rti
->strings
.name
);
4072 case 0x0A: // Menu text of railtype
4073 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.menu_text
);
4076 case 0x0B: // Build window caption
4077 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.build_caption
);
4080 case 0x0C: // Autoreplace text
4081 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.replace_text
);
4084 case 0x0D: // New locomotive text
4085 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.new_loco
);
4088 case 0x0E: // Compatible railtype list
4089 case 0x0F: // Powered railtype list
4090 case 0x18: // Railtype list required for date introduction
4091 case 0x19: // Introduced railtype list
4093 /* Rail type compatibility bits are added to the existing bits
4094 * to allow multiple GRFs to modify compatibility with the
4095 * default rail types. */
4096 int n
= buf
->ReadByte();
4097 for (int j
= 0; j
!= n
; j
++) {
4098 RailTypeLabel label
= buf
->ReadDWord();
4099 RailType rt
= GetRailTypeByLabel(BSWAP32(label
), false);
4100 if (rt
!= INVALID_RAILTYPE
) {
4102 case 0x0F: SetBit(rti
->powered_railtypes
, rt
); FALLTHROUGH
; // Powered implies compatible.
4103 case 0x0E: SetBit(rti
->compatible_railtypes
, rt
); break;
4104 case 0x18: SetBit(rti
->introduction_required_railtypes
, rt
); break;
4105 case 0x19: SetBit(rti
->introduces_railtypes
, rt
); break;
4112 case 0x10: // Rail Type flags
4113 rti
->flags
= (RailTypeFlags
)buf
->ReadByte();
4116 case 0x11: // Curve speed advantage
4117 rti
->curve_speed
= buf
->ReadByte();
4120 case 0x12: // Station graphic
4121 rti
->fallback_railtype
= Clamp(buf
->ReadByte(), 0, 2);
4124 case 0x13: // Construction cost factor
4125 rti
->cost_multiplier
= buf
->ReadWord();
4128 case 0x14: // Speed limit
4129 rti
->max_speed
= buf
->ReadWord();
4132 case 0x15: // Acceleration model
4133 rti
->acceleration_type
= Clamp(buf
->ReadByte(), 0, 2);
4136 case 0x16: // Map colour
4137 rti
->map_colour
= buf
->ReadByte();
4140 case 0x17: // Introduction date
4141 rti
->introduction_date
= buf
->ReadDWord();
4144 case 0x1A: // Sort order
4145 rti
->sorting_order
= buf
->ReadByte();
4148 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4149 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.name
);
4152 case 0x1C: // Maintenance cost factor
4153 rti
->maintenance_multiplier
= buf
->ReadWord();
4156 case 0x1D: // Alternate rail type label list
4157 /* Skipped here as this is loaded during reservation stage. */
4158 for (int j
= buf
->ReadByte(); j
!= 0; j
--) buf
->ReadDWord();
4170 static ChangeInfoResult
RailTypeReserveInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4172 ChangeInfoResult ret
= CIR_SUCCESS
;
4174 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
4176 if (id
+ numinfo
> RAILTYPE_END
) {
4177 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id
+ numinfo
, RAILTYPE_END
);
4178 return CIR_INVALID_ID
;
4181 for (int i
= 0; i
< numinfo
; i
++) {
4183 case 0x08: // Label of rail type
4185 RailTypeLabel rtl
= buf
->ReadDWord();
4188 RailType rt
= GetRailTypeByLabel(rtl
, false);
4189 if (rt
== INVALID_RAILTYPE
) {
4190 /* Set up new rail type */
4191 rt
= AllocateRailType(rtl
);
4194 _cur
.grffile
->railtype_map
[id
+ i
] = rt
;
4198 case 0x09: // Toolbar caption of railtype
4199 case 0x0A: // Menu text
4200 case 0x0B: // Build window caption
4201 case 0x0C: // Autoreplace text
4202 case 0x0D: // New loco
4203 case 0x13: // Construction cost
4204 case 0x14: // Speed limit
4205 case 0x1B: // Name of railtype
4206 case 0x1C: // Maintenance cost factor
4210 case 0x1D: // Alternate rail type label list
4211 if (_cur
.grffile
->railtype_map
[id
+ i
] != INVALID_RAILTYPE
) {
4212 int n
= buf
->ReadByte();
4213 for (int j
= 0; j
!= n
; j
++) {
4214 *_railtypes
[_cur
.grffile
->railtype_map
[id
+ i
]].alternate_labels
.Append() = BSWAP32(buf
->ReadDWord());
4218 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id
+ i
);
4221 case 0x0E: // Compatible railtype list
4222 case 0x0F: // Powered railtype list
4223 case 0x18: // Railtype list required for date introduction
4224 case 0x19: // Introduced railtype list
4225 for (int j
= buf
->ReadByte(); j
!= 0; j
--) buf
->ReadDWord();
4228 case 0x10: // Rail Type flags
4229 case 0x11: // Curve speed advantage
4230 case 0x12: // Station graphic
4231 case 0x15: // Acceleration model
4232 case 0x16: // Map colour
4233 case 0x1A: // Sort order
4237 case 0x17: // Introduction date
4250 static ChangeInfoResult
AirportTilesChangeInfo(uint airtid
, int numinfo
, int prop
, ByteReader
*buf
)
4252 ChangeInfoResult ret
= CIR_SUCCESS
;
4254 if (airtid
+ numinfo
> NUM_AIRPORTTILES_PER_GRF
) {
4255 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid
+ numinfo
, NUM_AIRPORTTILES_PER_GRF
);
4256 return CIR_INVALID_ID
;
4259 /* Allocate airport tile specs if they haven't been allocated already. */
4260 if (_cur
.grffile
->airtspec
== NULL
) {
4261 _cur
.grffile
->airtspec
= CallocT
<AirportTileSpec
*>(NUM_AIRPORTTILES_PER_GRF
);
4264 for (int i
= 0; i
< numinfo
; i
++) {
4265 AirportTileSpec
*tsp
= _cur
.grffile
->airtspec
[airtid
+ i
];
4267 if (prop
!= 0x08 && tsp
== NULL
) {
4268 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid
+ i
);
4269 return CIR_INVALID_ID
;
4273 case 0x08: { // Substitute airport tile type
4274 AirportTileSpec
**tilespec
= &_cur
.grffile
->airtspec
[airtid
+ i
];
4275 byte subs_id
= buf
->ReadByte();
4277 if (subs_id
>= NEW_AIRPORTTILE_OFFSET
) {
4278 /* The substitute id must be one of the original airport tiles. */
4279 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id
, airtid
+ i
);
4283 /* Allocate space for this airport tile. */
4284 if (*tilespec
== NULL
) {
4285 *tilespec
= CallocT
<AirportTileSpec
>(1);
4288 memcpy(tsp
, AirportTileSpec::Get(subs_id
), sizeof(AirportTileSpec
));
4289 tsp
->enabled
= true;
4291 tsp
->animation
.status
= ANIM_STATUS_NO_ANIMATION
;
4293 tsp
->grf_prop
.local_id
= airtid
+ i
;
4294 tsp
->grf_prop
.subst_id
= subs_id
;
4295 tsp
->grf_prop
.grffile
= _cur
.grffile
;
4296 _airporttile_mngr
.AddEntityID(airtid
+ i
, _cur
.grffile
->grfid
, subs_id
); // pre-reserve the tile slot
4301 case 0x09: { // Airport tile override
4302 byte override
= buf
->ReadByte();
4304 /* The airport tile being overridden must be an original airport tile. */
4305 if (override
>= NEW_AIRPORTTILE_OFFSET
) {
4306 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override
, airtid
+ i
);
4310 _airporttile_mngr
.Add(airtid
+ i
, _cur
.grffile
->grfid
, override
);
4314 case 0x0E: // Callback mask
4315 tsp
->callback_mask
= buf
->ReadByte();
4318 case 0x0F: // Animation information
4319 tsp
->animation
.frames
= buf
->ReadByte();
4320 tsp
->animation
.status
= buf
->ReadByte();
4323 case 0x10: // Animation speed
4324 tsp
->animation
.speed
= buf
->ReadByte();
4327 case 0x11: // Animation triggers
4328 tsp
->animation
.triggers
= buf
->ReadByte();
4340 static bool HandleChangeInfoResult(const char *caller
, ChangeInfoResult cir
, uint8 feature
, uint8 property
)
4343 default: NOT_REACHED();
4346 /* Error has already been printed; just stop parsing */
4353 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller
, property
, feature
);
4357 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller
, property
, feature
);
4360 case CIR_INVALID_ID
: {
4361 /* No debug message for an invalid ID, as it has already been output */
4362 GRFError
*error
= DisableGrf(cir
== CIR_INVALID_ID
? STR_NEWGRF_ERROR_INVALID_ID
: STR_NEWGRF_ERROR_UNKNOWN_PROPERTY
);
4363 if (cir
!= CIR_INVALID_ID
) error
->param_value
[1] = property
;
4370 static void FeatureChangeInfo(ByteReader
*buf
)
4372 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4375 * B num-props how many properties to change per vehicle/station
4376 * B num-info how many vehicles/stations to change
4377 * E id ID of first vehicle/station to change, if num-info is
4378 * greater than one, this one and the following
4379 * vehicles/stations will be changed
4380 * B property what property to change, depends on the feature
4381 * V new-info new bytes of info (variable size; depends on properties) */
4383 static const VCI_Handler handler
[] = {
4384 /* GSF_TRAINS */ RailVehicleChangeInfo
,
4385 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo
,
4386 /* GSF_SHIPS */ ShipVehicleChangeInfo
,
4387 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo
,
4388 /* GSF_STATIONS */ StationChangeInfo
,
4389 /* GSF_CANALS */ CanalChangeInfo
,
4390 /* GSF_BRIDGES */ BridgeChangeInfo
,
4391 /* GSF_HOUSES */ TownHouseChangeInfo
,
4392 /* GSF_GLOBALVAR */ GlobalVarChangeInfo
,
4393 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo
,
4394 /* GSF_INDUSTRIES */ IndustriesChangeInfo
,
4395 /* GSF_CARGOES */ NULL
, // Cargo is handled during reservation
4396 /* GSF_SOUNDFX */ SoundEffectChangeInfo
,
4397 /* GSF_AIRPORTS */ AirportChangeInfo
,
4398 /* GSF_SIGNALS */ NULL
,
4399 /* GSF_OBJECTS */ ObjectChangeInfo
,
4400 /* GSF_RAILTYPES */ RailTypeChangeInfo
,
4401 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo
,
4404 uint8 feature
= buf
->ReadByte();
4405 uint8 numprops
= buf
->ReadByte();
4406 uint numinfo
= buf
->ReadByte();
4407 uint engine
= buf
->ReadExtendedByte();
4409 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4410 feature
, numprops
, engine
, numinfo
);
4412 if (feature
>= lengthof(handler
) || handler
[feature
] == NULL
) {
4413 if (feature
!= GSF_CARGOES
) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature
);
4417 /* Mark the feature as used by the grf */
4418 SetBit(_cur
.grffile
->grf_features
, feature
);
4420 while (numprops
-- && buf
->HasData()) {
4421 uint8 prop
= buf
->ReadByte();
4423 ChangeInfoResult cir
= handler
[feature
](engine
, numinfo
, prop
, buf
);
4424 if (HandleChangeInfoResult("FeatureChangeInfo", cir
, feature
, prop
)) return;
4428 /* Action 0x00 (GLS_SAFETYSCAN) */
4429 static void SafeChangeInfo(ByteReader
*buf
)
4431 uint8 feature
= buf
->ReadByte();
4432 uint8 numprops
= buf
->ReadByte();
4433 uint numinfo
= buf
->ReadByte();
4434 buf
->ReadExtendedByte(); // id
4436 if (feature
== GSF_BRIDGES
&& numprops
== 1) {
4437 uint8 prop
= buf
->ReadByte();
4438 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4439 * is considered safe. */
4440 if (prop
== 0x0D) return;
4441 } else if (feature
== GSF_GLOBALVAR
&& numprops
== 1) {
4442 uint8 prop
= buf
->ReadByte();
4443 /* Engine ID Mappings are safe, if the source is static */
4445 bool is_safe
= true;
4446 for (uint i
= 0; i
< numinfo
; i
++) {
4447 uint32 s
= buf
->ReadDWord();
4448 buf
->ReadDWord(); // dest
4449 const GRFConfig
*grfconfig
= GetGRFConfig(s
);
4450 if (grfconfig
!= NULL
&& !HasBit(grfconfig
->flags
, GCF_STATIC
)) {
4455 if (is_safe
) return;
4459 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
4461 /* Skip remainder of GRF */
4462 _cur
.skip_sprites
= -1;
4465 /* Action 0x00 (GLS_RESERVE) */
4466 static void ReserveChangeInfo(ByteReader
*buf
)
4468 uint8 feature
= buf
->ReadByte();
4470 if (feature
!= GSF_CARGOES
&& feature
!= GSF_GLOBALVAR
&& feature
!= GSF_RAILTYPES
) return;
4472 uint8 numprops
= buf
->ReadByte();
4473 uint8 numinfo
= buf
->ReadByte();
4474 uint8 index
= buf
->ReadExtendedByte();
4476 while (numprops
-- && buf
->HasData()) {
4477 uint8 prop
= buf
->ReadByte();
4478 ChangeInfoResult cir
= CIR_SUCCESS
;
4481 default: NOT_REACHED();
4483 cir
= CargoChangeInfo(index
, numinfo
, prop
, buf
);
4487 cir
= GlobalVarReserveInfo(index
, numinfo
, prop
, buf
);
4491 cir
= RailTypeReserveInfo(index
, numinfo
, prop
, buf
);
4495 if (HandleChangeInfoResult("ReserveChangeInfo", cir
, feature
, prop
)) return;
4500 static void NewSpriteSet(ByteReader
*buf
)
4502 /* Basic format: <01> <feature> <num-sets> <num-ent>
4503 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4505 * B feature feature to define sprites for
4506 * 0, 1, 2, 3: veh-type, 4: train stations
4507 * E first-set first sprite set to define
4508 * B num-sets number of sprite sets (extended byte in extended format)
4509 * E num-ent how many entries per sprite set
4510 * For vehicles, this is the number of different
4511 * vehicle directions in each sprite set
4512 * Set num-dirs=8, unless your sprites are symmetric.
4513 * In that case, use num-dirs=4.
4516 uint8 feature
= buf
->ReadByte();
4517 uint16 num_sets
= buf
->ReadByte();
4518 uint16 first_set
= 0;
4520 if (num_sets
== 0 && buf
->HasData(3)) {
4521 /* Extended Action1 format.
4522 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4523 first_set
= buf
->ReadExtendedByte();
4524 num_sets
= buf
->ReadExtendedByte();
4526 uint16 num_ents
= buf
->ReadExtendedByte();
4528 _cur
.AddSpriteSets(feature
, _cur
.spriteid
, first_set
, num_sets
, num_ents
);
4530 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4531 _cur
.spriteid
, feature
, num_sets
, num_ents
, num_sets
* num_ents
4534 for (int i
= 0; i
< num_sets
* num_ents
; i
++) {
4536 LoadNextSprite(_cur
.spriteid
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
4540 /* Action 0x01 (SKIP) */
4541 static void SkipAct1(ByteReader
*buf
)
4544 uint16 num_sets
= buf
->ReadByte();
4546 if (num_sets
== 0 && buf
->HasData(3)) {
4547 /* Extended Action1 format.
4548 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4549 buf
->ReadExtendedByte(); // first_set
4550 num_sets
= buf
->ReadExtendedByte();
4552 uint16 num_ents
= buf
->ReadExtendedByte();
4554 _cur
.skip_sprites
= num_sets
* num_ents
;
4556 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur
.skip_sprites
);
4559 /* Helper function to either create a callback or link to a previously
4560 * defined spritegroup. */
4561 static const SpriteGroup
*GetGroupFromGroupID(byte setid
, byte type
, uint16 groupid
)
4563 if (HasBit(groupid
, 15)) {
4564 assert(CallbackResultSpriteGroup::CanAllocateItem());
4565 return new CallbackResultSpriteGroup(groupid
, _cur
.grffile
->grf_version
>= 8);
4568 if (groupid
> MAX_SPRITEGROUP
|| _cur
.spritegroups
[groupid
] == NULL
) {
4569 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid
, type
, groupid
);
4573 return _cur
.spritegroups
[groupid
];
4577 * Helper function to either create a callback or a result sprite group.
4578 * @param feature GrfSpecFeature to define spritegroup for.
4579 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4580 * @param type Type of the currently being parsed Action2. (only for debug output)
4581 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4582 * @return Created spritegroup.
4584 static const SpriteGroup
*CreateGroupFromGroupID(byte feature
, byte setid
, byte type
, uint16 spriteid
)
4586 if (HasBit(spriteid
, 15)) {
4587 assert(CallbackResultSpriteGroup::CanAllocateItem());
4588 return new CallbackResultSpriteGroup(spriteid
, _cur
.grffile
->grf_version
>= 8);
4591 if (!_cur
.IsValidSpriteSet(feature
, spriteid
)) {
4592 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid
, type
, spriteid
);
4596 SpriteID spriteset_start
= _cur
.GetSprite(feature
, spriteid
);
4597 uint num_sprites
= _cur
.GetNumEnts(feature
, spriteid
);
4599 /* Ensure that the sprites are loeded */
4600 assert(spriteset_start
+ num_sprites
<= _cur
.spriteid
);
4602 assert(ResultSpriteGroup::CanAllocateItem());
4603 return new ResultSpriteGroup(spriteset_start
, num_sprites
);
4607 static void NewSpriteGroup(ByteReader
*buf
)
4609 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4611 * B feature see action 1
4612 * B set-id ID of this particular definition
4613 * B type/num-entries
4614 * if 80 or greater, this is a randomized or variational
4615 * list definition, see below
4616 * otherwise it specifies a number of entries, the exact
4617 * meaning depends on the feature
4618 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4619 SpriteGroup
*act_group
= NULL
;
4621 uint8 feature
= buf
->ReadByte();
4622 uint8 setid
= buf
->ReadByte();
4623 uint8 type
= buf
->ReadByte();
4625 /* Sprite Groups are created here but they are allocated from a pool, so
4626 * we do not need to delete anything if there is an exception from the
4630 /* Deterministic Sprite Group */
4631 case 0x81: // Self scope, byte
4632 case 0x82: // Parent scope, byte
4633 case 0x85: // Self scope, word
4634 case 0x86: // Parent scope, word
4635 case 0x89: // Self scope, dword
4636 case 0x8A: // Parent scope, dword
4641 assert(DeterministicSpriteGroup::CanAllocateItem());
4642 DeterministicSpriteGroup
*group
= new DeterministicSpriteGroup();
4644 group
->var_scope
= HasBit(type
, 1) ? VSG_SCOPE_PARENT
: VSG_SCOPE_SELF
;
4646 switch (GB(type
, 2, 2)) {
4647 default: NOT_REACHED();
4648 case 0: group
->size
= DSG_SIZE_BYTE
; varsize
= 1; break;
4649 case 1: group
->size
= DSG_SIZE_WORD
; varsize
= 2; break;
4650 case 2: group
->size
= DSG_SIZE_DWORD
; varsize
= 4; break;
4653 static SmallVector
<DeterministicSpriteGroupAdjust
, 16> adjusts
;
4656 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4657 * from the outset, so we shall have to keep reallocing. */
4659 DeterministicSpriteGroupAdjust
*adjust
= adjusts
.Append();
4661 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4662 adjust
->operation
= adjusts
.Length() == 1 ? DSGA_OP_ADD
: (DeterministicSpriteGroupAdjustOperation
)buf
->ReadByte();
4663 adjust
->variable
= buf
->ReadByte();
4664 if (adjust
->variable
== 0x7E) {
4665 /* Link subroutine group */
4666 adjust
->subroutine
= GetGroupFromGroupID(setid
, type
, buf
->ReadByte());
4668 adjust
->parameter
= IsInsideMM(adjust
->variable
, 0x60, 0x80) ? buf
->ReadByte() : 0;
4671 varadjust
= buf
->ReadByte();
4672 adjust
->shift_num
= GB(varadjust
, 0, 5);
4673 adjust
->type
= (DeterministicSpriteGroupAdjustType
)GB(varadjust
, 6, 2);
4674 adjust
->and_mask
= buf
->ReadVarSize(varsize
);
4676 if (adjust
->type
!= DSGA_TYPE_NONE
) {
4677 adjust
->add_val
= buf
->ReadVarSize(varsize
);
4678 adjust
->divmod_val
= buf
->ReadVarSize(varsize
);
4680 adjust
->add_val
= 0;
4681 adjust
->divmod_val
= 0;
4684 /* Continue reading var adjusts while bit 5 is set. */
4685 } while (HasBit(varadjust
, 5));
4687 group
->num_adjusts
= adjusts
.Length();
4688 group
->adjusts
= MallocT
<DeterministicSpriteGroupAdjust
>(group
->num_adjusts
);
4689 MemCpyT(group
->adjusts
, adjusts
.Begin(), group
->num_adjusts
);
4691 std::vector
<DeterministicSpriteGroupRange
> ranges
;
4692 ranges
.resize(buf
->ReadByte());
4693 for (uint i
= 0; i
< ranges
.size(); i
++) {
4694 ranges
[i
].group
= GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4695 ranges
[i
].low
= buf
->ReadVarSize(varsize
);
4696 ranges
[i
].high
= buf
->ReadVarSize(varsize
);
4699 group
->default_group
= GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4700 group
->error_group
= ranges
.size() > 0 ? ranges
[0].group
: group
->default_group
;
4701 /* nvar == 0 is a special case -- we turn our value into a callback result */
4702 group
->calculated_result
= ranges
.size() == 0;
4704 /* Sort ranges ascending. When ranges overlap, this may required clamping or splitting them */
4705 std::vector
<uint32
> bounds
;
4706 for (uint i
= 0; i
< ranges
.size(); i
++) {
4707 bounds
.push_back(ranges
[i
].low
);
4708 if (ranges
[i
].high
!= UINT32_MAX
) bounds
.push_back(ranges
[i
].high
+ 1);
4710 std::sort(bounds
.begin(), bounds
.end());
4711 bounds
.erase(std::unique(bounds
.begin(), bounds
.end()), bounds
.end());
4713 std::vector
<const SpriteGroup
*> target
;
4714 for (uint j
= 0; j
< bounds
.size(); ++j
) {
4715 uint32 v
= bounds
[j
];
4716 const SpriteGroup
*t
= group
->default_group
;
4717 for (uint i
= 0; i
< ranges
.size(); i
++) {
4718 if (ranges
[i
].low
<= v
&& v
<= ranges
[i
].high
) {
4719 t
= ranges
[i
].group
;
4723 target
.push_back(t
);
4725 assert(target
.size() == bounds
.size());
4727 std::vector
<DeterministicSpriteGroupRange
> optimised
;
4728 for (uint j
= 0; j
< bounds
.size(); ) {
4729 if (target
[j
] != group
->default_group
) {
4730 DeterministicSpriteGroupRange r
;
4731 r
.group
= target
[j
];
4733 while (j
< bounds
.size() && target
[j
] == r
.group
) {
4736 r
.high
= j
< bounds
.size() ? bounds
[j
] - 1 : UINT32_MAX
;
4737 optimised
.push_back(r
);
4743 group
->num_ranges
= optimised
.size();
4744 if (group
->num_ranges
> 0) {
4745 group
->ranges
= MallocT
<DeterministicSpriteGroupRange
>(group
->num_ranges
);
4746 MemCpyT(group
->ranges
, &optimised
.front(), group
->num_ranges
);
4751 /* Randomized Sprite Group */
4752 case 0x80: // Self scope
4753 case 0x83: // Parent scope
4754 case 0x84: // Relative scope
4756 assert(RandomizedSpriteGroup::CanAllocateItem());
4757 RandomizedSpriteGroup
*group
= new RandomizedSpriteGroup();
4759 group
->var_scope
= HasBit(type
, 1) ? VSG_SCOPE_PARENT
: VSG_SCOPE_SELF
;
4761 if (HasBit(type
, 2)) {
4762 if (feature
<= GSF_AIRCRAFT
) group
->var_scope
= VSG_SCOPE_RELATIVE
;
4763 group
->count
= buf
->ReadByte();
4766 uint8 triggers
= buf
->ReadByte();
4767 group
->triggers
= GB(triggers
, 0, 7);
4768 group
->cmp_mode
= HasBit(triggers
, 7) ? RSG_CMP_ALL
: RSG_CMP_ANY
;
4769 group
->lowest_randbit
= buf
->ReadByte();
4770 group
->num_groups
= buf
->ReadByte();
4771 group
->groups
= CallocT
<const SpriteGroup
*>(group
->num_groups
);
4773 for (uint i
= 0; i
< group
->num_groups
; i
++) {
4774 group
->groups
[i
] = GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4780 /* Neither a variable or randomized sprite group... must be a real group */
4785 case GSF_ROADVEHICLES
:
4794 byte num_loaded
= type
;
4795 byte num_loading
= buf
->ReadByte();
4797 if (!_cur
.HasValidSpriteSets(feature
)) {
4798 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4802 assert(RealSpriteGroup::CanAllocateItem());
4803 RealSpriteGroup
*group
= new RealSpriteGroup();
4806 group
->num_loaded
= num_loaded
;
4807 group
->num_loading
= num_loading
;
4808 if (num_loaded
> 0) group
->loaded
= CallocT
<const SpriteGroup
*>(num_loaded
);
4809 if (num_loading
> 0) group
->loading
= CallocT
<const SpriteGroup
*>(num_loading
);
4811 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4812 setid
, num_loaded
, num_loading
);
4814 for (uint i
= 0; i
< num_loaded
; i
++) {
4815 uint16 spriteid
= buf
->ReadWord();
4816 group
->loaded
[i
] = CreateGroupFromGroupID(feature
, setid
, type
, spriteid
);
4817 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i
, spriteid
);
4820 for (uint i
= 0; i
< num_loading
; i
++) {
4821 uint16 spriteid
= buf
->ReadWord();
4822 group
->loading
[i
] = CreateGroupFromGroupID(feature
, setid
, type
, spriteid
);
4823 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i
, spriteid
);
4830 case GSF_AIRPORTTILES
:
4832 case GSF_INDUSTRYTILES
: {
4833 byte num_building_sprites
= max((uint8
)1, type
);
4835 assert(TileLayoutSpriteGroup::CanAllocateItem());
4836 TileLayoutSpriteGroup
*group
= new TileLayoutSpriteGroup();
4839 /* On error, bail out immediately. Temporary GRF data was already freed */
4840 if (ReadSpriteLayout(buf
, num_building_sprites
, true, feature
, false, type
== 0, &group
->dts
)) return;
4844 case GSF_INDUSTRIES
: {
4846 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type
);
4850 assert(IndustryProductionSpriteGroup::CanAllocateItem());
4851 IndustryProductionSpriteGroup
*group
= new IndustryProductionSpriteGroup();
4853 group
->version
= type
;
4855 for (uint i
= 0; i
< 3; i
++) {
4856 group
->subtract_input
[i
] = (int16
)buf
->ReadWord(); // signed
4858 for (uint i
= 0; i
< 2; i
++) {
4859 group
->add_output
[i
] = buf
->ReadWord(); // unsigned
4861 group
->again
= buf
->ReadByte();
4863 for (uint i
= 0; i
< 3; i
++) {
4864 group
->subtract_input
[i
] = buf
->ReadByte();
4866 for (uint i
= 0; i
< 2; i
++) {
4867 group
->add_output
[i
] = buf
->ReadByte();
4869 group
->again
= buf
->ReadByte();
4874 /* Loading of Tile Layout and Production Callback groups would happen here */
4875 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature
);
4880 _cur
.spritegroups
[setid
] = act_group
;
4883 static CargoID
TranslateCargo(uint8 feature
, uint8 ctype
)
4885 if (feature
== GSF_OBJECTS
) {
4888 case 0xFF: return CT_PURCHASE_OBJECT
;
4890 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype
);
4894 /* Special cargo types for purchase list and stations */
4895 if (feature
== GSF_STATIONS
&& ctype
== 0xFE) return CT_DEFAULT_NA
;
4896 if (ctype
== 0xFF) return CT_PURCHASE
;
4898 if (_cur
.grffile
->cargo_list
.Length() == 0) {
4899 /* No cargo table, so use bitnum values */
4901 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype
);
4905 const CargoSpec
*cs
;
4906 FOR_ALL_CARGOSPECS(cs
) {
4907 if (cs
->bitnum
== ctype
) {
4908 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype
, cs
->Index());
4913 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype
);
4917 /* Check if the cargo type is out of bounds of the cargo translation table */
4918 if (ctype
>= _cur
.grffile
->cargo_list
.Length()) {
4919 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype
, _cur
.grffile
->cargo_list
.Length() - 1);
4923 /* Look up the cargo label from the translation table */
4924 CargoLabel cl
= _cur
.grffile
->cargo_list
[ctype
];
4926 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype
);
4930 ctype
= GetCargoIDByLabel(cl
);
4931 if (ctype
== CT_INVALID
) {
4932 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));
4936 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
);
4941 static bool IsValidGroupID(uint16 groupid
, const char *function
)
4943 if (groupid
> MAX_SPRITEGROUP
|| _cur
.spritegroups
[groupid
] == NULL
) {
4944 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function
, groupid
);
4951 static void VehicleMapSpriteGroup(ByteReader
*buf
, byte feature
, uint8 idcount
)
4953 static EngineID
*last_engines
;
4954 static uint last_engines_count
;
4955 bool wagover
= false;
4957 /* Test for 'wagon override' flag */
4958 if (HasBit(idcount
, 7)) {
4960 /* Strip off the flag */
4961 idcount
= GB(idcount
, 0, 7);
4963 if (last_engines_count
== 0) {
4964 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4968 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4969 last_engines_count
, idcount
);
4971 if (last_engines_count
!= idcount
) {
4972 last_engines
= ReallocT(last_engines
, idcount
);
4973 last_engines_count
= idcount
;
4977 EngineID
*engines
= AllocaM(EngineID
, idcount
);
4978 for (uint i
= 0; i
< idcount
; i
++) {
4979 Engine
*e
= GetNewEngine(_cur
.grffile
, (VehicleType
)feature
, buf
->ReadExtendedByte());
4981 /* No engine could be allocated?!? Deal with it. Okay,
4982 * this might look bad. Also make sure this NewGRF
4983 * gets disabled, as a half loaded one is bad. */
4984 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID
, 0, 0);
4988 engines
[i
] = e
->index
;
4989 if (!wagover
) last_engines
[i
] = engines
[i
];
4992 uint8 cidcount
= buf
->ReadByte();
4993 for (uint c
= 0; c
< cidcount
; c
++) {
4994 uint8 ctype
= buf
->ReadByte();
4995 uint16 groupid
= buf
->ReadWord();
4996 if (!IsValidGroupID(groupid
, "VehicleMapSpriteGroup")) continue;
4998 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c
, ctype
, groupid
);
5000 ctype
= TranslateCargo(feature
, ctype
);
5001 if (ctype
== CT_INVALID
) continue;
5003 for (uint i
= 0; i
< idcount
; i
++) {
5004 EngineID engine
= engines
[i
];
5006 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i
, engine
);
5009 SetWagonOverrideSprites(engine
, ctype
, _cur
.spritegroups
[groupid
], last_engines
, last_engines_count
);
5011 SetCustomEngineSprites(engine
, ctype
, _cur
.spritegroups
[groupid
]);
5016 uint16 groupid
= buf
->ReadWord();
5017 if (!IsValidGroupID(groupid
, "VehicleMapSpriteGroup")) return;
5019 grfmsg(8, "-- Default group id 0x%04X", groupid
);
5021 for (uint i
= 0; i
< idcount
; i
++) {
5022 EngineID engine
= engines
[i
];
5025 SetWagonOverrideSprites(engine
, CT_DEFAULT
, _cur
.spritegroups
[groupid
], last_engines
, last_engines_count
);
5027 SetCustomEngineSprites(engine
, CT_DEFAULT
, _cur
.spritegroups
[groupid
]);
5028 SetEngineGRF(engine
, _cur
.grffile
);
5034 static void CanalMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5036 CanalFeature
*cfs
= AllocaM(CanalFeature
, idcount
);
5037 for (uint i
= 0; i
< idcount
; i
++) {
5038 cfs
[i
] = (CanalFeature
)buf
->ReadByte();
5041 uint8 cidcount
= buf
->ReadByte();
5042 buf
->Skip(cidcount
* 3);
5044 uint16 groupid
= buf
->ReadWord();
5045 if (!IsValidGroupID(groupid
, "CanalMapSpriteGroup")) return;
5047 for (uint i
= 0; i
< idcount
; i
++) {
5048 CanalFeature cf
= cfs
[i
];
5051 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf
);
5055 _water_feature
[cf
].grffile
= _cur
.grffile
;
5056 _water_feature
[cf
].group
= _cur
.spritegroups
[groupid
];
5061 static void StationMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5063 uint8
*stations
= AllocaM(uint8
, idcount
);
5064 for (uint i
= 0; i
< idcount
; i
++) {
5065 stations
[i
] = buf
->ReadByte();
5068 uint8 cidcount
= buf
->ReadByte();
5069 for (uint c
= 0; c
< cidcount
; c
++) {
5070 uint8 ctype
= buf
->ReadByte();
5071 uint16 groupid
= buf
->ReadWord();
5072 if (!IsValidGroupID(groupid
, "StationMapSpriteGroup")) continue;
5074 ctype
= TranslateCargo(GSF_STATIONS
, ctype
);
5075 if (ctype
== CT_INVALID
) continue;
5077 for (uint i
= 0; i
< idcount
; i
++) {
5078 StationSpec
*statspec
= _cur
.grffile
->stations
== NULL
? NULL
: _cur
.grffile
->stations
[stations
[i
]];
5080 if (statspec
== NULL
) {
5081 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations
[i
]);
5085 statspec
->grf_prop
.spritegroup
[ctype
] = _cur
.spritegroups
[groupid
];
5089 uint16 groupid
= buf
->ReadWord();
5090 if (!IsValidGroupID(groupid
, "StationMapSpriteGroup")) return;
5092 for (uint i
= 0; i
< idcount
; i
++) {
5093 StationSpec
*statspec
= _cur
.grffile
->stations
== NULL
? NULL
: _cur
.grffile
->stations
[stations
[i
]];
5095 if (statspec
== NULL
) {
5096 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations
[i
]);
5100 if (statspec
->grf_prop
.grffile
!= NULL
) {
5101 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations
[i
]);
5105 statspec
->grf_prop
.spritegroup
[CT_DEFAULT
] = _cur
.spritegroups
[groupid
];
5106 statspec
->grf_prop
.grffile
= _cur
.grffile
;
5107 statspec
->grf_prop
.local_id
= stations
[i
];
5108 StationClass::Assign(statspec
);
5113 static void TownHouseMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5115 uint8
*houses
= AllocaM(uint8
, idcount
);
5116 for (uint i
= 0; i
< idcount
; i
++) {
5117 houses
[i
] = buf
->ReadByte();
5120 /* Skip the cargo type section, we only care about the default group */
5121 uint8 cidcount
= buf
->ReadByte();
5122 buf
->Skip(cidcount
* 3);
5124 uint16 groupid
= buf
->ReadWord();
5125 if (!IsValidGroupID(groupid
, "TownHouseMapSpriteGroup")) return;
5127 if (_cur
.grffile
->housespec
== NULL
) {
5128 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5132 for (uint i
= 0; i
< idcount
; i
++) {
5133 HouseSpec
*hs
= _cur
.grffile
->housespec
[houses
[i
]];
5136 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses
[i
]);
5140 hs
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5144 static void IndustryMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5146 uint8
*industries
= AllocaM(uint8
, idcount
);
5147 for (uint i
= 0; i
< idcount
; i
++) {
5148 industries
[i
] = buf
->ReadByte();
5151 /* Skip the cargo type section, we only care about the default group */
5152 uint8 cidcount
= buf
->ReadByte();
5153 buf
->Skip(cidcount
* 3);
5155 uint16 groupid
= buf
->ReadWord();
5156 if (!IsValidGroupID(groupid
, "IndustryMapSpriteGroup")) return;
5158 if (_cur
.grffile
->industryspec
== NULL
) {
5159 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5163 for (uint i
= 0; i
< idcount
; i
++) {
5164 IndustrySpec
*indsp
= _cur
.grffile
->industryspec
[industries
[i
]];
5166 if (indsp
== NULL
) {
5167 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries
[i
]);
5171 indsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5175 static void IndustrytileMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5177 uint8
*indtiles
= AllocaM(uint8
, idcount
);
5178 for (uint i
= 0; i
< idcount
; i
++) {
5179 indtiles
[i
] = buf
->ReadByte();
5182 /* Skip the cargo type section, we only care about the default group */
5183 uint8 cidcount
= buf
->ReadByte();
5184 buf
->Skip(cidcount
* 3);
5186 uint16 groupid
= buf
->ReadWord();
5187 if (!IsValidGroupID(groupid
, "IndustrytileMapSpriteGroup")) return;
5189 if (_cur
.grffile
->indtspec
== NULL
) {
5190 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5194 for (uint i
= 0; i
< idcount
; i
++) {
5195 IndustryTileSpec
*indtsp
= _cur
.grffile
->indtspec
[indtiles
[i
]];
5197 if (indtsp
== NULL
) {
5198 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles
[i
]);
5202 indtsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5206 static void CargoMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5208 CargoID
*cargoes
= AllocaM(CargoID
, idcount
);
5209 for (uint i
= 0; i
< idcount
; i
++) {
5210 cargoes
[i
] = buf
->ReadByte();
5213 /* Skip the cargo type section, we only care about the default group */
5214 uint8 cidcount
= buf
->ReadByte();
5215 buf
->Skip(cidcount
* 3);
5217 uint16 groupid
= buf
->ReadWord();
5218 if (!IsValidGroupID(groupid
, "CargoMapSpriteGroup")) return;
5220 for (uint i
= 0; i
< idcount
; i
++) {
5221 CargoID cid
= cargoes
[i
];
5223 if (cid
>= NUM_CARGO
) {
5224 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid
);
5228 CargoSpec
*cs
= CargoSpec::Get(cid
);
5229 cs
->grffile
= _cur
.grffile
;
5230 cs
->group
= _cur
.spritegroups
[groupid
];
5234 static void ObjectMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5236 if (_cur
.grffile
->objectspec
== NULL
) {
5237 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5241 uint8
*objects
= AllocaM(uint8
, idcount
);
5242 for (uint i
= 0; i
< idcount
; i
++) {
5243 objects
[i
] = buf
->ReadByte();
5246 uint8 cidcount
= buf
->ReadByte();
5247 for (uint c
= 0; c
< cidcount
; c
++) {
5248 uint8 ctype
= buf
->ReadByte();
5249 uint16 groupid
= buf
->ReadWord();
5250 if (!IsValidGroupID(groupid
, "ObjectMapSpriteGroup")) continue;
5252 ctype
= TranslateCargo(GSF_OBJECTS
, ctype
);
5253 if (ctype
== CT_INVALID
) continue;
5255 for (uint i
= 0; i
< idcount
; i
++) {
5256 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[objects
[i
]];
5259 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects
[i
]);
5263 spec
->grf_prop
.spritegroup
[ctype
] = _cur
.spritegroups
[groupid
];
5267 uint16 groupid
= buf
->ReadWord();
5268 if (!IsValidGroupID(groupid
, "ObjectMapSpriteGroup")) return;
5270 for (uint i
= 0; i
< idcount
; i
++) {
5271 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[objects
[i
]];
5274 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects
[i
]);
5278 if (spec
->grf_prop
.grffile
!= NULL
) {
5279 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects
[i
]);
5283 spec
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5284 spec
->grf_prop
.grffile
= _cur
.grffile
;
5285 spec
->grf_prop
.local_id
= objects
[i
];
5289 static void RailTypeMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5291 uint8
*railtypes
= AllocaM(uint8
, idcount
);
5292 for (uint i
= 0; i
< idcount
; i
++) {
5293 railtypes
[i
] = _cur
.grffile
->railtype_map
[buf
->ReadByte()];
5296 uint8 cidcount
= buf
->ReadByte();
5297 for (uint c
= 0; c
< cidcount
; c
++) {
5298 uint8 ctype
= buf
->ReadByte();
5299 uint16 groupid
= buf
->ReadWord();
5300 if (!IsValidGroupID(groupid
, "RailTypeMapSpriteGroup")) continue;
5302 if (ctype
>= RTSG_END
) continue;
5304 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
5305 for (uint i
= 0; i
< idcount
; i
++) {
5306 if (railtypes
[i
] != INVALID_RAILTYPE
) {
5307 RailtypeInfo
*rti
= &_railtypes
[railtypes
[i
]];
5309 rti
->grffile
[ctype
] = _cur
.grffile
;
5310 rti
->group
[ctype
] = _cur
.spritegroups
[groupid
];
5315 /* Railtypes do not use the default group. */
5319 static void AirportMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5321 uint8
*airports
= AllocaM(uint8
, idcount
);
5322 for (uint i
= 0; i
< idcount
; i
++) {
5323 airports
[i
] = buf
->ReadByte();
5326 /* Skip the cargo type section, we only care about the default group */
5327 uint8 cidcount
= buf
->ReadByte();
5328 buf
->Skip(cidcount
* 3);
5330 uint16 groupid
= buf
->ReadWord();
5331 if (!IsValidGroupID(groupid
, "AirportMapSpriteGroup")) return;
5333 if (_cur
.grffile
->airportspec
== NULL
) {
5334 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5338 for (uint i
= 0; i
< idcount
; i
++) {
5339 AirportSpec
*as
= _cur
.grffile
->airportspec
[airports
[i
]];
5342 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports
[i
]);
5346 as
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5350 static void AirportTileMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5352 uint8
*airptiles
= AllocaM(uint8
, idcount
);
5353 for (uint i
= 0; i
< idcount
; i
++) {
5354 airptiles
[i
] = buf
->ReadByte();
5357 /* Skip the cargo type section, we only care about the default group */
5358 uint8 cidcount
= buf
->ReadByte();
5359 buf
->Skip(cidcount
* 3);
5361 uint16 groupid
= buf
->ReadWord();
5362 if (!IsValidGroupID(groupid
, "AirportTileMapSpriteGroup")) return;
5364 if (_cur
.grffile
->airtspec
== NULL
) {
5365 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5369 for (uint i
= 0; i
< idcount
; i
++) {
5370 AirportTileSpec
*airtsp
= _cur
.grffile
->airtspec
[airptiles
[i
]];
5372 if (airtsp
== NULL
) {
5373 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles
[i
]);
5377 airtsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5383 static void FeatureMapSpriteGroup(ByteReader
*buf
)
5385 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5386 * id-list := [<id>] [id-list]
5387 * cargo-list := <cargo-type> <cid> [cargo-list]
5389 * B feature see action 0
5390 * B n-id bits 0-6: how many IDs this definition applies to
5391 * bit 7: if set, this is a wagon override definition (see below)
5392 * B ids the IDs for which this definition applies
5393 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5394 * can be zero, in that case the def-cid is used always
5395 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5396 * W cid cargo ID (sprite group ID) for this type of cargo
5397 * W def-cid default cargo ID (sprite group ID) */
5399 uint8 feature
= buf
->ReadByte();
5400 uint8 idcount
= buf
->ReadByte();
5402 /* If idcount is zero, this is a feature callback */
5404 /* Skip number of cargo ids? */
5406 uint16 groupid
= buf
->ReadWord();
5407 if (!IsValidGroupID(groupid
, "FeatureMapSpriteGroup")) return;
5409 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature
);
5411 AddGenericCallback(feature
, _cur
.grffile
, _cur
.spritegroups
[groupid
]);
5415 /* Mark the feature as used by the grf (generic callbacks do not count) */
5416 SetBit(_cur
.grffile
->grf_features
, feature
);
5418 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature
, idcount
);
5422 case GSF_ROADVEHICLES
:
5425 VehicleMapSpriteGroup(buf
, feature
, idcount
);
5429 CanalMapSpriteGroup(buf
, idcount
);
5433 StationMapSpriteGroup(buf
, idcount
);
5437 TownHouseMapSpriteGroup(buf
, idcount
);
5440 case GSF_INDUSTRIES
:
5441 IndustryMapSpriteGroup(buf
, idcount
);
5444 case GSF_INDUSTRYTILES
:
5445 IndustrytileMapSpriteGroup(buf
, idcount
);
5449 CargoMapSpriteGroup(buf
, idcount
);
5453 AirportMapSpriteGroup(buf
, idcount
);
5457 ObjectMapSpriteGroup(buf
, idcount
);
5461 RailTypeMapSpriteGroup(buf
, idcount
);
5464 case GSF_AIRPORTTILES
:
5465 AirportTileMapSpriteGroup(buf
, idcount
);
5469 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature
);
5475 static void FeatureNewName(ByteReader
*buf
)
5477 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5479 * B veh-type see action 0 (as 00..07, + 0A
5480 * But IF veh-type = 48, then generic text
5481 * B language-id If bit 6 is set, This is the extended language scheme,
5482 * with up to 64 language.
5483 * Otherwise, it is a mapping where set bits have meaning
5484 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5485 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5486 * B num-veh number of vehicles which are getting a new name
5487 * B/W offset number of the first vehicle that gets a new name
5488 * Byte : ID of vehicle to change
5489 * Word : ID of string to change/add
5490 * S data new texts, each of them zero-terminated, after
5491 * which the next name begins. */
5493 bool new_scheme
= _cur
.grffile
->grf_version
>= 7;
5495 uint8 feature
= buf
->ReadByte();
5496 uint8 lang
= buf
->ReadByte();
5497 uint8 num
= buf
->ReadByte();
5498 bool generic
= HasBit(lang
, 7);
5501 id
= buf
->ReadWord();
5502 } else if (feature
<= GSF_AIRCRAFT
) {
5503 id
= buf
->ReadExtendedByte();
5505 id
= buf
->ReadByte();
5510 uint16 endid
= id
+ num
;
5512 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5513 id
, endid
, feature
, lang
);
5515 for (; id
< endid
&& buf
->HasData(); id
++) {
5516 const char *name
= buf
->ReadString();
5517 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id
, name
);
5521 case GSF_ROADVEHICLES
:
5525 Engine
*e
= GetNewEngine(_cur
.grffile
, (VehicleType
)feature
, id
, HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
));
5526 if (e
== NULL
) break;
5527 StringID string
= AddGRFString(_cur
.grffile
->grfid
, e
->index
, lang
, new_scheme
, false, name
, e
->info
.string_id
);
5528 e
->info
.string_id
= string
;
5530 AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, true, name
, STR_UNDEFINED
);
5535 if (IsInsideMM(id
, 0xD000, 0xD400) || IsInsideMM(id
, 0xD800, 0xE000)) {
5536 AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, true, name
, STR_UNDEFINED
);
5540 switch (GB(id
, 8, 8)) {
5541 case 0xC4: // Station class name
5542 if (_cur
.grffile
->stations
== NULL
|| _cur
.grffile
->stations
[GB(id
, 0, 8)] == NULL
) {
5543 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id
, 0, 8));
5545 StationClassID cls_id
= _cur
.grffile
->stations
[GB(id
, 0, 8)]->cls_id
;
5546 StationClass::Get(cls_id
)->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5550 case 0xC5: // Station name
5551 if (_cur
.grffile
->stations
== NULL
|| _cur
.grffile
->stations
[GB(id
, 0, 8)] == NULL
) {
5552 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id
, 0, 8));
5554 _cur
.grffile
->stations
[GB(id
, 0, 8)]->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5558 case 0xC7: // Airporttile name
5559 if (_cur
.grffile
->airtspec
== NULL
|| _cur
.grffile
->airtspec
[GB(id
, 0, 8)] == NULL
) {
5560 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id
, 0, 8));
5562 _cur
.grffile
->airtspec
[GB(id
, 0, 8)]->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5566 case 0xC9: // House name
5567 if (_cur
.grffile
->housespec
== NULL
|| _cur
.grffile
->housespec
[GB(id
, 0, 8)] == NULL
) {
5568 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id
, 0, 8));
5570 _cur
.grffile
->housespec
[GB(id
, 0, 8)]->building_name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5575 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id
);
5584 * Sanitize incoming sprite offsets for Action 5 graphics replacements.
5585 * @param num The number of sprites to load.
5586 * @param offset Offset from the base.
5587 * @param max_sprites The maximum number of sprites that can be loaded in this action 5.
5588 * @param name Used for error warnings.
5589 * @return The number of sprites that is going to be skipped.
5591 static uint16
SanitizeSpriteOffset(uint16
& num
, uint16 offset
, int max_sprites
, const char *name
)
5594 if (offset
>= max_sprites
) {
5595 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name
, max_sprites
);
5596 uint orig_num
= num
;
5601 if (offset
+ num
> max_sprites
) {
5602 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name
);
5603 uint orig_num
= num
;
5604 num
= max(max_sprites
- offset
, 0);
5605 return orig_num
- num
;
5612 /** The type of action 5 type. */
5613 enum Action5BlockType
{
5614 A5BLOCK_FIXED
, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5615 A5BLOCK_ALLOW_OFFSET
, ///< Allow replacing any subset by specifiing an offset.
5616 A5BLOCK_INVALID
, ///< unknown/not-implemented type
5618 /** Information about a single action 5 type. */
5619 struct Action5Type
{
5620 Action5BlockType block_type
; ///< How is this Action5 type processed?
5621 SpriteID sprite_base
; ///< Load the sprites starting from this sprite.
5622 uint16 min_sprites
; ///< If the Action5 contains less sprites, the whole block will be ignored.
5623 uint16 max_sprites
; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5624 const char *name
; ///< Name for error messages.
5627 /** The information about action 5 types. */
5628 static const Action5Type _action5_types
[] = {
5629 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5630 /* 0x00 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x00" },
5631 /* 0x01 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x01" },
5632 /* 0x02 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x02" },
5633 /* 0x03 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x03" },
5634 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET
, SPR_SIGNALS_BASE
, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT
, "Signal graphics" },
5635 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ELRAIL_BASE
, 1, ELRAIL_SPRITE_COUNT
, "Rail catenary graphics" },
5636 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET
, SPR_SLOPES_BASE
, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT
, "Foundation graphics" },
5637 /* 0x07 */ { A5BLOCK_INVALID
, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5638 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET
, SPR_CANALS_BASE
, 1, CANALS_SPRITE_COUNT
, "Canal graphics" },
5639 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ONEWAY_BASE
, 1, ONEWAY_SPRITE_COUNT
, "One way road graphics" },
5640 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET
, SPR_2CCMAP_BASE
, 1, TWOCCMAP_SPRITE_COUNT
, "2CC colour maps" },
5641 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET
, SPR_TRAMWAY_BASE
, 1, TRAMWAY_SPRITE_COUNT
, "Tramway graphics" },
5642 /* 0x0C */ { A5BLOCK_INVALID
, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5643 /* 0x0D */ { A5BLOCK_FIXED
, SPR_SHORE_BASE
, 16, SPR_SHORE_SPRITE_COUNT
, "Shore graphics" },
5644 /* 0x0E */ { A5BLOCK_INVALID
, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5645 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET
, SPR_TRACKS_FOR_SLOPES_BASE
, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT
, "Sloped rail track" },
5646 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AIRPORTX_BASE
, 1, AIRPORTX_SPRITE_COUNT
, "Airport graphics" },
5647 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ROADSTOP_BASE
, 1, ROADSTOP_SPRITE_COUNT
, "Road stop graphics" },
5648 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AQUEDUCT_BASE
, 1, AQUEDUCT_SPRITE_COUNT
, "Aqueduct graphics" },
5649 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AUTORAIL_BASE
, 1, AUTORAIL_SPRITE_COUNT
, "Autorail graphics" },
5650 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET
, SPR_FLAGS_BASE
, 1, FLAGS_SPRITE_COUNT
, "Flag graphics" },
5651 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET
, SPR_OPENTTD_BASE
, 1, OPENTTD_SPRITE_COUNT
, "OpenTTD GUI graphics" },
5652 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AIRPORT_PREVIEW_BASE
, 1, SPR_AIRPORT_PREVIEW_COUNT
, "Airport preview graphics" },
5653 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET
, SPR_RAILTYPE_TUNNEL_BASE
, 1, RAILTYPE_TUNNEL_BASE_COUNT
, "Railtype tunnel base" },
5654 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET
, SPR_PALETTE_BASE
, 1, PALETTE_SPRITE_COUNT
, "Palette" },
5658 static void GraphicsNew(ByteReader
*buf
)
5660 /* <05> <graphics-type> <num-sprites> <other data...>
5662 * B graphics-type What set of graphics the sprites define.
5663 * E num-sprites How many sprites are in this set?
5664 * V other data Graphics type specific data. Currently unused. */
5667 uint8 type
= buf
->ReadByte();
5668 uint16 num
= buf
->ReadExtendedByte();
5669 uint16 offset
= HasBit(type
, 7) ? buf
->ReadExtendedByte() : 0;
5670 ClrBit(type
, 7); // Clear the high bit as that only indicates whether there is an offset.
5672 if ((type
== 0x0D) && (num
== 10) && HasBit(_cur
.grfconfig
->flags
, GCF_SYSTEM
)) {
5673 /* Special not-TTDP-compatible case used in openttd.grf
5674 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5675 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5676 LoadNextSprite(SPR_SHORE_BASE
+ 0, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_S
5677 LoadNextSprite(SPR_SHORE_BASE
+ 5, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_W
5678 LoadNextSprite(SPR_SHORE_BASE
+ 7, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_WSE
5679 LoadNextSprite(SPR_SHORE_BASE
+ 10, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_N
5680 LoadNextSprite(SPR_SHORE_BASE
+ 11, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_NWS
5681 LoadNextSprite(SPR_SHORE_BASE
+ 13, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_ENW
5682 LoadNextSprite(SPR_SHORE_BASE
+ 14, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_SEN
5683 LoadNextSprite(SPR_SHORE_BASE
+ 15, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_E
5684 LoadNextSprite(SPR_SHORE_BASE
+ 16, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_EW
5685 LoadNextSprite(SPR_SHORE_BASE
+ 17, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_NS
5686 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_NONE
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ONLY_NEW
;
5690 /* Supported type? */
5691 if ((type
>= lengthof(_action5_types
)) || (_action5_types
[type
].block_type
== A5BLOCK_INVALID
)) {
5692 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type
, num
);
5693 _cur
.skip_sprites
= num
;
5697 const Action5Type
*action5_type
= &_action5_types
[type
];
5699 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5700 * except for the long version of the shore type:
5701 * Ignore offset if not allowed */
5702 if ((action5_type
->block_type
!= A5BLOCK_ALLOW_OFFSET
) && (offset
!= 0)) {
5703 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type
->name
, type
);
5707 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5708 * This does not make sense, if <offset> is allowed */
5709 if ((action5_type
->block_type
== A5BLOCK_FIXED
) && (num
< action5_type
->min_sprites
)) {
5710 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
);
5711 _cur
.skip_sprites
= num
;
5715 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5716 uint16 skip_num
= SanitizeSpriteOffset(num
, offset
, action5_type
->max_sprites
, action5_type
->name
);
5717 SpriteID replace
= action5_type
->sprite_base
+ offset
;
5719 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5720 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
);
5722 for (; num
> 0; num
--) {
5724 LoadNextSprite(replace
== 0 ? _cur
.spriteid
++ : replace
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
5727 if (type
== 0x0D) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_5
;
5729 _cur
.skip_sprites
= skip_num
;
5732 /* Action 0x05 (SKIP) */
5733 static void SkipAct5(ByteReader
*buf
)
5735 /* Ignore type byte */
5738 /* Skip the sprites of this action */
5739 _cur
.skip_sprites
= buf
->ReadExtendedByte();
5741 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur
.skip_sprites
);
5745 * Reads a variable common to VarAction2 and Action7/9/D.
5747 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5748 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5750 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5751 * @param value returns the value of the variable.
5752 * @param grffile NewGRF querying the variable
5753 * @return true iff the variable is known and the value is returned in 'value'.
5755 bool GetGlobalVariable(byte param
, uint32
*value
, const GRFFile
*grffile
)
5758 case 0x00: // current date
5759 *value
= max(_date
- DAYS_TILL_ORIGINAL_BASE_YEAR
, 0);
5762 case 0x01: // current year
5763 *value
= Clamp(_cur_year
, ORIGINAL_BASE_YEAR
, ORIGINAL_MAX_YEAR
) - ORIGINAL_BASE_YEAR
;
5766 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)
5768 ConvertDateToYMD(_date
, &ymd
);
5769 Date start_of_year
= ConvertYMDToDate(ymd
.year
, 0, 1);
5770 *value
= ymd
.month
| (ymd
.day
- 1) << 8 | (IsLeapYear(ymd
.year
) ? 1 << 15 : 0) | (_date
- start_of_year
) << 16;
5774 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5775 *value
= _settings_game
.game_creation
.landscape
;
5778 case 0x06: // road traffic side, bit 4 clear=left, set=right
5779 *value
= _settings_game
.vehicle
.road_side
<< 4;
5782 case 0x09: // date fraction
5783 *value
= _date_fract
* 885;
5786 case 0x0A: // animation counter
5787 *value
= _tick_counter
;
5790 case 0x0B: { // TTDPatch version
5793 uint revision
= 1; // special case: 2.0.1 is 2.0.10
5795 *value
= (major
<< 24) | (minor
<< 20) | (revision
<< 16) | build
;
5799 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5800 *value
= _cur
.grfconfig
->palette
& GRFP_USE_MASK
;
5803 case 0x0E: // Y-offset for train sprites
5804 *value
= _cur
.grffile
->traininfo_vehicle_pitch
;
5807 case 0x0F: // Rail track type cost factors
5809 SB(*value
, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL
)->cost_multiplier
); // normal rail
5810 if (_settings_game
.vehicle
.disable_elrails
) {
5811 /* skip elrail multiplier - disabled */
5812 SB(*value
, 8, 8, GetRailTypeInfo(RAILTYPE_MONO
)->cost_multiplier
); // monorail
5814 SB(*value
, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC
)->cost_multiplier
); // electified railway
5815 /* Skip monorail multiplier - no space in result */
5817 SB(*value
, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV
)->cost_multiplier
); // maglev
5820 case 0x11: // current rail tool type
5821 *value
= 0; // constant fake value to avoid desync
5824 case 0x12: // Game mode
5825 *value
= _game_mode
;
5828 /* case 0x13: // Tile refresh offset to left not implemented */
5829 /* case 0x14: // Tile refresh offset to right not implemented */
5830 /* case 0x15: // Tile refresh offset upwards not implemented */
5831 /* case 0x16: // Tile refresh offset downwards not implemented */
5832 /* case 0x17: // temperate snow line not implemented */
5834 case 0x1A: // Always -1
5838 case 0x1B: // Display options
5839 *value
= 0x3F; // constant fake value to avoid desync
5842 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5846 case 0x1E: // Miscellaneous GRF features
5847 *value
= _misc_grf_features
;
5849 /* Add the local flags */
5850 assert(!HasBit(*value
, GMB_TRAIN_WIDTH_32_PIXELS
));
5851 if (_cur
.grffile
->traininfo_vehicle_width
== VEHICLEINFO_FULL_VEHICLE_WIDTH
) SetBit(*value
, GMB_TRAIN_WIDTH_32_PIXELS
);
5854 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5856 case 0x20: { // snow line height
5857 byte snowline
= GetSnowLine();
5858 if (_settings_game
.game_creation
.landscape
== LT_ARCTIC
&& snowline
<= _settings_game
.construction
.max_heightlevel
) {
5859 *value
= Clamp(snowline
* (grffile
->grf_version
>= 8 ? 1 : TILE_HEIGHT
), 0, 0xFE);
5867 case 0x21: // OpenTTD version
5868 *value
= _openttd_newgrf_version
;
5871 case 0x22: // difficulty level
5875 case 0x23: // long format date
5879 case 0x24: // long format year
5883 default: return false;
5887 static uint32
GetParamVal(byte param
, uint32
*cond_val
)
5889 /* First handle variable common with VarAction2 */
5891 if (GetGlobalVariable(param
- 0x80, &value
, _cur
.grffile
)) return value
;
5893 /* Non-common variable */
5895 case 0x84: { // GRF loading stage
5898 if (_cur
.stage
> GLS_INIT
) SetBit(res
, 0);
5899 if (_cur
.stage
== GLS_RESERVE
) SetBit(res
, 8);
5900 if (_cur
.stage
== GLS_ACTIVATION
) SetBit(res
, 9);
5904 case 0x85: // TTDPatch flags, only for bit tests
5905 if (cond_val
== NULL
) {
5906 /* Supported in Action 0x07 and 0x09, not 0x0D */
5909 uint32 param_val
= _ttdpatch_flags
[*cond_val
/ 0x20];
5914 case 0x88: // GRF ID check
5917 /* case 0x99: Global ID offset not implemented */
5921 if (param
< 0x80) return _cur
.grffile
->GetParam(param
);
5923 /* In-game variable. */
5924 grfmsg(1, "Unsupported in-game variable 0x%02X", param
);
5930 static void CfgApply(ByteReader
*buf
)
5932 /* <06> <param-num> <param-size> <offset> ... <FF>
5934 * B param-num Number of parameter to substitute (First = "zero")
5935 * Ignored if that parameter was not specified in newgrf.cfg
5936 * B param-size How many bytes to replace. If larger than 4, the
5937 * bytes of the following parameter are used. In that
5938 * case, nothing is applied unless *all* parameters
5940 * B offset Offset into data from beginning of next sprite
5941 * to place where parameter is to be stored. */
5943 /* Preload the next sprite */
5944 size_t pos
= FioGetPos();
5945 uint32 num
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
5946 uint8 type
= FioReadByte();
5947 byte
*preload_sprite
= NULL
;
5949 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5951 preload_sprite
= MallocT
<byte
>(num
);
5952 FioReadBlock(preload_sprite
, num
);
5955 /* Reset the file position to the start of the next sprite */
5956 FioSeekTo(pos
, SEEK_SET
);
5959 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5960 free(preload_sprite
);
5964 GRFLocation
location(_cur
.grfconfig
->ident
.grfid
, _cur
.nfo_line
+ 1);
5965 GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.find(location
);
5966 if (it
!= _grf_line_to_action6_sprite_override
.end()) {
5967 free(preload_sprite
);
5968 preload_sprite
= _grf_line_to_action6_sprite_override
[location
];
5970 _grf_line_to_action6_sprite_override
[location
] = preload_sprite
;
5973 /* Now perform the Action 0x06 on our data. */
5982 /* Read the parameter to apply. 0xFF indicates no more data to change. */
5983 param_num
= buf
->ReadByte();
5984 if (param_num
== 0xFF) break;
5986 /* Get the size of the parameter to use. If the size covers multiple
5987 * double words, sequential parameter values are used. */
5988 param_size
= buf
->ReadByte();
5990 /* Bit 7 of param_size indicates we should add to the original value
5991 * instead of replacing it. */
5992 add_value
= HasBit(param_size
, 7);
5993 param_size
= GB(param_size
, 0, 7);
5995 /* Where to apply the data to within the pseudo sprite data. */
5996 offset
= buf
->ReadExtendedByte();
5998 /* If the parameter is a GRF parameter (not an internal variable) check
5999 * if it (and all further sequential parameters) has been defined. */
6000 if (param_num
< 0x80 && (param_num
+ (param_size
- 1) / 4) >= _cur
.grffile
->param_end
) {
6001 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num
+ (param_size
- 1) / 4));
6005 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size
, param_num
, offset
);
6008 for (i
= 0; i
< param_size
&& offset
+ i
< num
; i
++) {
6009 uint32 value
= GetParamVal(param_num
+ i
/ 4, NULL
);
6010 /* Reset carry flag for each iteration of the variable (only really
6011 * matters if param_size is greater than 4) */
6012 if (i
% 4 == 0) carry
= false;
6015 uint new_value
= preload_sprite
[offset
+ i
] + GB(value
, (i
% 4) * 8, 8) + (carry
? 1 : 0);
6016 preload_sprite
[offset
+ i
] = GB(new_value
, 0, 8);
6017 /* Check if the addition overflowed */
6018 carry
= new_value
>= 256;
6020 preload_sprite
[offset
+ i
] = GB(value
, (i
% 4) * 8, 8);
6027 * Disable a static NewGRF when it is influencing another (non-static)
6028 * NewGRF as this could cause desyncs.
6030 * We could just tell the NewGRF querying that the file doesn't exist,
6031 * but that might give unwanted results. Disabling the NewGRF gives the
6032 * best result as no NewGRF author can complain about that.
6033 * @param c The NewGRF to disable.
6035 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig
*c
)
6037 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC
, c
);
6038 error
->data
= stredup(_cur
.grfconfig
->GetName());
6043 static void SkipIf(ByteReader
*buf
)
6045 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6052 /* TODO: More params. More condition types. */
6053 uint32 cond_val
= 0;
6057 uint8 param
= buf
->ReadByte();
6058 uint8 paramsize
= buf
->ReadByte();
6059 uint8 condtype
= buf
->ReadByte();
6062 /* Always 1 for bit tests, the given value should be ignored. */
6066 switch (paramsize
) {
6067 case 8: cond_val
= buf
->ReadDWord(); mask
= buf
->ReadDWord(); break;
6068 case 4: cond_val
= buf
->ReadDWord(); mask
= 0xFFFFFFFF; break;
6069 case 2: cond_val
= buf
->ReadWord(); mask
= 0x0000FFFF; break;
6070 case 1: cond_val
= buf
->ReadByte(); mask
= 0x000000FF; break;
6074 if (param
< 0x80 && _cur
.grffile
->param_end
<= param
) {
6075 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param
);
6079 uint32 param_val
= GetParamVal(param
, &cond_val
);
6081 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype
, param_val
, cond_val
);
6084 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6085 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6086 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6087 * So, when the condition type is one of those, the specific variable
6088 * 0x88 code is skipped, so the "general" code for the cargo
6089 * availability conditions kicks in.
6091 if (param
== 0x88 && (condtype
< 0x0B || condtype
> 0x0E)) {
6094 GRFConfig
*c
= GetGRFConfig(cond_val
, mask
);
6096 if (c
!= NULL
&& HasBit(c
->flags
, GCF_STATIC
) && !HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
) && _networking
) {
6097 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c
);
6101 if (condtype
!= 10 && c
== NULL
) {
6102 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val
));
6107 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6108 case 0x06: // Is GRFID active?
6109 result
= c
->status
== GCS_ACTIVATED
;
6112 case 0x07: // Is GRFID non-active?
6113 result
= c
->status
!= GCS_ACTIVATED
;
6116 case 0x08: // GRFID is not but will be active?
6117 result
= c
->status
== GCS_INITIALISED
;
6120 case 0x09: // GRFID is or will be active?
6121 result
= c
->status
== GCS_ACTIVATED
|| c
->status
== GCS_INITIALISED
;
6124 case 0x0A: // GRFID is not nor will be active
6125 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6126 result
= c
== NULL
|| c
->status
== GCS_DISABLED
|| c
->status
== GCS_NOT_FOUND
;
6129 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype
); return;
6132 /* Parameter or variable tests */
6134 case 0x00: result
= !!(param_val
& (1 << cond_val
));
6136 case 0x01: result
= !(param_val
& (1 << cond_val
));
6138 case 0x02: result
= (param_val
& mask
) == cond_val
;
6140 case 0x03: result
= (param_val
& mask
) != cond_val
;
6142 case 0x04: result
= (param_val
& mask
) < cond_val
;
6144 case 0x05: result
= (param_val
& mask
) > cond_val
;
6146 case 0x0B: result
= GetCargoIDByLabel(BSWAP32(cond_val
)) == CT_INVALID
;
6148 case 0x0C: result
= GetCargoIDByLabel(BSWAP32(cond_val
)) != CT_INVALID
;
6150 case 0x0D: result
= GetRailTypeByLabel(BSWAP32(cond_val
)) == INVALID_RAILTYPE
;
6152 case 0x0E: result
= GetRailTypeByLabel(BSWAP32(cond_val
)) != INVALID_RAILTYPE
;
6155 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype
); return;
6160 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6164 uint8 numsprites
= buf
->ReadByte();
6166 /* numsprites can be a GOTO label if it has been defined in the GRF
6167 * file. The jump will always be the first matching label that follows
6168 * the current nfo_line. If no matching label is found, the first matching
6169 * label in the file is used. */
6170 GRFLabel
*choice
= NULL
;
6171 for (GRFLabel
*label
= _cur
.grffile
->label
; label
!= NULL
; label
= label
->next
) {
6172 if (label
->label
!= numsprites
) continue;
6174 /* Remember a goto before the current line */
6175 if (choice
== NULL
) choice
= label
;
6176 /* If we find a label here, this is definitely good */
6177 if (label
->nfo_line
> _cur
.nfo_line
) {
6183 if (choice
!= NULL
) {
6184 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice
->label
, choice
->nfo_line
);
6185 FioSeekTo(choice
->pos
, SEEK_SET
);
6186 _cur
.nfo_line
= choice
->nfo_line
;
6190 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites
);
6191 _cur
.skip_sprites
= numsprites
;
6192 if (_cur
.skip_sprites
== 0) {
6193 /* Zero means there are no sprites to skip, so
6194 * we use -1 to indicate that all further
6195 * sprites should be skipped. */
6196 _cur
.skip_sprites
= -1;
6198 /* If an action 8 hasn't been encountered yet, disable the grf. */
6199 if (_cur
.grfconfig
->status
!= (_cur
.stage
< GLS_RESERVE
? GCS_INITIALISED
: GCS_ACTIVATED
)) {
6206 /* Action 0x08 (GLS_FILESCAN) */
6207 static void ScanInfo(ByteReader
*buf
)
6209 uint8 grf_version
= buf
->ReadByte();
6210 uint32 grfid
= buf
->ReadDWord();
6211 const char *name
= buf
->ReadString();
6213 _cur
.grfconfig
->ident
.grfid
= grfid
;
6215 if (grf_version
< 2 || grf_version
> 8) {
6216 SetBit(_cur
.grfconfig
->flags
, GCF_INVALID
);
6217 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
);
6220 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6221 if (GB(grfid
, 0, 8) == 0xFF) SetBit(_cur
.grfconfig
->flags
, GCF_SYSTEM
);
6223 AddGRFTextToList(&_cur
.grfconfig
->name
->text
, 0x7F, grfid
, false, name
);
6225 if (buf
->HasData()) {
6226 const char *info
= buf
->ReadString();
6227 AddGRFTextToList(&_cur
.grfconfig
->info
->text
, 0x7F, grfid
, true, info
);
6230 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6231 _cur
.skip_sprites
= -1;
6235 static void GRFInfo(ByteReader
*buf
)
6237 /* <08> <version> <grf-id> <name> <info>
6239 * B version newgrf version, currently 06
6240 * 4*B grf-id globally unique ID of this .grf file
6241 * S name name of this .grf set
6242 * S info string describing the set, and e.g. author and copyright */
6244 uint8 version
= buf
->ReadByte();
6245 uint32 grfid
= buf
->ReadDWord();
6246 const char *name
= buf
->ReadString();
6248 if (_cur
.stage
< GLS_RESERVE
&& _cur
.grfconfig
->status
!= GCS_UNKNOWN
) {
6249 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8
);
6253 if (_cur
.grffile
->grfid
!= grfid
) {
6254 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
));
6255 _cur
.grffile
->grfid
= grfid
;
6258 _cur
.grffile
->grf_version
= version
;
6259 _cur
.grfconfig
->status
= _cur
.stage
< GLS_RESERVE
? GCS_INITIALISED
: GCS_ACTIVATED
;
6261 /* Do swap the GRFID for displaying purposes since people expect that */
6262 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
);
6266 static void SpriteReplace(ByteReader
*buf
)
6268 /* <0A> <num-sets> <set1> [<set2> ...]
6269 * <set>: <num-sprites> <first-sprite>
6271 * B num-sets How many sets of sprites to replace.
6273 * B num-sprites How many sprites are in this set
6274 * W first-sprite First sprite number to replace */
6276 uint8 num_sets
= buf
->ReadByte();
6278 for (uint i
= 0; i
< num_sets
; i
++) {
6279 uint8 num_sprites
= buf
->ReadByte();
6280 uint16 first_sprite
= buf
->ReadWord();
6282 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6283 i
, num_sprites
, first_sprite
6286 for (uint j
= 0; j
< num_sprites
; j
++) {
6287 int load_index
= first_sprite
+ j
;
6289 LoadNextSprite(load_index
, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
); // XXX
6291 /* Shore sprites now located at different addresses.
6292 * So detect when the old ones get replaced. */
6293 if (IsInsideMM(load_index
, SPR_ORIGINALSHORE_START
, SPR_ORIGINALSHORE_END
+ 1)) {
6294 if (_loaded_newgrf_features
.shore
!= SHORE_REPLACE_ACTION_5
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_A
;
6300 /* Action 0x0A (SKIP) */
6301 static void SkipActA(ByteReader
*buf
)
6303 uint8 num_sets
= buf
->ReadByte();
6305 for (uint i
= 0; i
< num_sets
; i
++) {
6306 /* Skip the sprites this replaces */
6307 _cur
.skip_sprites
+= buf
->ReadByte();
6308 /* But ignore where they go */
6312 grfmsg(3, "SkipActA: Skipping %d sprites", _cur
.skip_sprites
);
6316 static void GRFLoadError(ByteReader
*buf
)
6318 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6320 * B severity 00: notice, contine loading grf file
6321 * 01: warning, continue loading grf file
6322 * 02: error, but continue loading grf file, and attempt
6323 * loading grf again when loading or starting next game
6324 * 03: error, abort loading and prevent loading again in
6325 * the future (only when restarting the patch)
6326 * B language-id see action 4, use 1F for built-in error messages
6327 * B message-id message to show, see below
6328 * S message for custom messages (message-id FF), text of the message
6329 * not present for built-in messages.
6330 * V data additional data for built-in (or custom) messages
6331 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6333 static const StringID msgstr
[] = {
6334 STR_NEWGRF_ERROR_VERSION_NUMBER
,
6335 STR_NEWGRF_ERROR_DOS_OR_WINDOWS
,
6336 STR_NEWGRF_ERROR_UNSET_SWITCH
,
6337 STR_NEWGRF_ERROR_INVALID_PARAMETER
,
6338 STR_NEWGRF_ERROR_LOAD_BEFORE
,
6339 STR_NEWGRF_ERROR_LOAD_AFTER
,
6340 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER
,
6343 static const StringID sevstr
[] = {
6344 STR_NEWGRF_ERROR_MSG_INFO
,
6345 STR_NEWGRF_ERROR_MSG_WARNING
,
6346 STR_NEWGRF_ERROR_MSG_ERROR
,
6347 STR_NEWGRF_ERROR_MSG_FATAL
6350 byte severity
= buf
->ReadByte();
6351 byte lang
= buf
->ReadByte();
6352 byte message_id
= buf
->ReadByte();
6354 /* Skip the error if it isn't valid for the current language. */
6355 if (!CheckGrfLangID(lang
, _cur
.grffile
->grf_version
)) return;
6357 /* Skip the error until the activation stage unless bit 7 of the severity
6359 if (!HasBit(severity
, 7) && _cur
.stage
== GLS_INIT
) {
6360 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur
.stage
);
6363 ClrBit(severity
, 7);
6365 if (severity
>= lengthof(sevstr
)) {
6366 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity
);
6368 } else if (severity
== 3) {
6369 /* This is a fatal error, so make sure the GRF is deactivated and no
6370 * more of it gets loaded. */
6373 /* Make sure we show fatal errors, instead of silly infos from before */
6374 delete _cur
.grfconfig
->error
;
6375 _cur
.grfconfig
->error
= NULL
;
6378 if (message_id
>= lengthof(msgstr
) && message_id
!= 0xFF) {
6379 grfmsg(7, "GRFLoadError: Invalid message id.");
6383 if (buf
->Remaining() <= 1) {
6384 grfmsg(7, "GRFLoadError: No message data supplied.");
6388 /* For now we can only show one message per newgrf file. */
6389 if (_cur
.grfconfig
->error
!= NULL
) return;
6391 GRFError
*error
= new GRFError(sevstr
[severity
]);
6393 if (message_id
== 0xFF) {
6394 /* This is a custom error message. */
6395 if (buf
->HasData()) {
6396 const char *message
= buf
->ReadString();
6398 error
->custom_message
= TranslateTTDPatchCodes(_cur
.grffile
->grfid
, lang
, true, message
, NULL
, SCC_RAW_STRING_POINTER
);
6400 grfmsg(7, "GRFLoadError: No custom message supplied.");
6401 error
->custom_message
= stredup("");
6404 error
->message
= msgstr
[message_id
];
6407 if (buf
->HasData()) {
6408 const char *data
= buf
->ReadString();
6410 error
->data
= TranslateTTDPatchCodes(_cur
.grffile
->grfid
, lang
, true, data
);
6412 grfmsg(7, "GRFLoadError: No message data supplied.");
6413 error
->data
= stredup("");
6416 /* Only two parameter numbers can be used in the string. */
6417 for (uint i
= 0; i
< lengthof(error
->param_value
) && buf
->HasData(); i
++) {
6418 uint param_number
= buf
->ReadByte();
6419 error
->param_value
[i
] = _cur
.grffile
->GetParam(param_number
);
6422 _cur
.grfconfig
->error
= error
;
6426 static void GRFComment(ByteReader
*buf
)
6428 /* <0C> [<ignored...>]
6430 * V ignored Anything following the 0C is ignored */
6432 if (!buf
->HasData()) return;
6434 const char *text
= buf
->ReadString();
6435 grfmsg(2, "GRFComment: %s", text
);
6438 /* Action 0x0D (GLS_SAFETYSCAN) */
6439 static void SafeParamSet(ByteReader
*buf
)
6441 uint8 target
= buf
->ReadByte();
6443 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6444 if (target
< 0x80 || target
== 0x9E) return;
6446 /* GRM could be unsafe, but as here it can only happen after other GRFs
6447 * are loaded, it should be okay. If the GRF tried to use the slots it
6448 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6449 * sprites is considered safe. */
6451 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
6453 /* Skip remainder of GRF */
6454 _cur
.skip_sprites
= -1;
6458 static uint32
GetPatchVariable(uint8 param
)
6461 /* start year - 1920 */
6462 case 0x0B: return max(_settings_game
.game_creation
.starting_year
, ORIGINAL_BASE_YEAR
) - ORIGINAL_BASE_YEAR
;
6464 /* freight trains weight factor */
6465 case 0x0E: return _settings_game
.vehicle
.freight_trains
;
6467 /* empty wagon speed increase */
6468 case 0x0F: return 0;
6470 /* plane speed factor; our patch option is reversed from TTDPatch's,
6471 * the following is good for 1x, 2x and 4x (most common?) and...
6472 * well not really for 3x. */
6474 switch (_settings_game
.vehicle
.plane_speed
) {
6483 /* 2CC colourmap base sprite */
6484 case 0x11: return SPR_2CCMAP_BASE
;
6486 /* map size: format = -MABXYSS
6487 * M : the type of map
6488 * bit 0 : set : squared map. Bit 1 is now not relevant
6489 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6490 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6491 * clear : X is the bigger edge.
6492 * A : minimum edge(log2) of the map
6493 * B : maximum edge(log2) of the map
6494 * XY : edges(log2) of each side of the map.
6495 * SS : combination of both X and Y, thus giving the size(log2) of the map
6499 byte log_X
= MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6500 byte log_Y
= MapLogY() - 6;
6501 byte max_edge
= max(log_X
, log_Y
);
6503 if (log_X
== log_Y
) { // we have a squared map, since both edges are identical
6504 SetBit(map_bits
, 0);
6506 if (max_edge
== log_Y
) SetBit(map_bits
, 1); // edge Y been the biggest, mark it
6509 return (map_bits
<< 24) | (min(log_X
, log_Y
) << 20) | (max_edge
<< 16) |
6510 (log_X
<< 12) | (log_Y
<< 8) | (log_X
+ log_Y
);
6513 /* The maximum height of the map. */
6515 return _settings_game
.construction
.max_heightlevel
;
6517 /* Extra foundations base sprite */
6519 return SPR_SLOPES_BASE
;
6521 /* Shore base sprite */
6523 return SPR_SHORE_BASE
;
6526 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param
);
6532 static uint32
PerformGRM(uint32
*grm
, uint16 num_ids
, uint16 count
, uint8 op
, uint8 target
, const char *type
)
6538 /* Return GRFID of set that reserved ID */
6539 return grm
[_cur
.grffile
->GetParam(target
)];
6542 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6543 if (op
== 2 || op
== 3) start
= _cur
.grffile
->GetParam(target
);
6545 for (uint i
= start
; i
< num_ids
; i
++) {
6549 if (op
== 2 || op
== 3) break;
6554 if (size
== count
) break;
6557 if (size
== count
) {
6558 /* Got the slot... */
6559 if (op
== 0 || op
== 3) {
6560 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count
, type
, start
);
6561 for (uint i
= 0; i
< count
; i
++) grm
[start
+ i
] = _cur
.grffile
->grfid
;
6566 /* Unable to allocate */
6567 if (op
!= 4 && op
!= 5) {
6568 /* Deactivate GRF */
6569 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count
, type
);
6570 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED
);
6574 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count
, type
);
6579 /** Action 0x0D: Set parameter */
6580 static void ParamSet(ByteReader
*buf
)
6582 /* <0D> <target> <operation> <source1> <source2> [<data>]
6584 * B target parameter number where result is stored
6585 * B operation operation to perform, see below
6586 * B source1 first source operand
6587 * B source2 second source operand
6588 * D data data to use in the calculation, not necessary
6589 * if both source1 and source2 refer to actual parameters
6592 * 00 Set parameter equal to source1
6593 * 01 Addition, source1 + source2
6594 * 02 Subtraction, source1 - source2
6595 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6596 * 04 Signed multiplication, source1 * source2 (both signed)
6597 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6598 * signed quantity; left shift if positive and right shift if
6599 * negative, source1 is unsigned)
6600 * 06 Signed bit shift, source1 by source2
6601 * (source2 like in 05, and source1 as well)
6604 uint8 target
= buf
->ReadByte();
6605 uint8 oper
= buf
->ReadByte();
6606 uint32 src1
= buf
->ReadByte();
6607 uint32 src2
= buf
->ReadByte();
6610 if (buf
->Remaining() >= 4) data
= buf
->ReadDWord();
6612 /* You can add 80 to the operation to make it apply only if the target
6613 * is not defined yet. In this respect, a parameter is taken to be
6614 * defined if any of the following applies:
6615 * - it has been set to any value in the newgrf(w).cfg parameter list
6616 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6617 * an earlier action D */
6618 if (HasBit(oper
, 7)) {
6619 if (target
< 0x80 && target
< _cur
.grffile
->param_end
) {
6620 grfmsg(7, "ParamSet: Param %u already defined, skipping", target
);
6624 oper
= GB(oper
, 0, 7);
6628 if (GB(data
, 0, 8) == 0xFF) {
6629 if (data
== 0x0000FFFF) {
6630 /* Patch variables */
6631 src1
= GetPatchVariable(src1
);
6633 /* GRF Resource Management */
6635 uint8 feature
= GB(data
, 8, 8);
6636 uint16 count
= GB(data
, 16, 16);
6638 if (_cur
.stage
== GLS_RESERVE
) {
6639 if (feature
== 0x08) {
6640 /* General sprites */
6642 /* Check if the allocated sprites will fit below the original sprite limit */
6643 if (_cur
.spriteid
+ count
>= 16384) {
6644 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count
);
6645 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED
);
6649 /* Reserve space at the current sprite ID */
6650 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count
, _cur
.spriteid
);
6651 _grm_sprites
[GRFLocation(_cur
.grffile
->grfid
, _cur
.nfo_line
)] = _cur
.spriteid
;
6652 _cur
.spriteid
+= count
;
6655 /* Ignore GRM result during reservation */
6657 } else if (_cur
.stage
== GLS_ACTIVATION
) {
6659 case 0x00: // Trains
6660 case 0x01: // Road Vehicles
6662 case 0x03: // Aircraft
6663 if (!_settings_game
.vehicle
.dynamic_engines
) {
6664 src1
= PerformGRM(&_grm_engines
[_engine_offsets
[feature
]], _engine_counts
[feature
], count
, op
, target
, "vehicles");
6665 if (_cur
.skip_sprites
== -1) return;
6667 /* GRM does not apply for dynamic engine allocation. */
6671 src1
= _cur
.grffile
->GetParam(target
);
6681 case 0x08: // General sprites
6684 /* Return space reserved during reservation stage */
6685 src1
= _grm_sprites
[GRFLocation(_cur
.grffile
->grfid
, _cur
.nfo_line
)];
6686 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1
);
6690 src1
= _cur
.spriteid
;
6694 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op
);
6700 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6701 src1
= PerformGRM(_grm_cargoes
, NUM_CARGO
* 2, count
, op
, target
, "cargoes");
6702 if (_cur
.skip_sprites
== -1) return;
6705 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature
); return;
6708 /* Ignore GRM during initialization */
6713 /* Read another GRF File's parameter */
6714 const GRFFile
*file
= GetFileByGRFID(data
);
6715 GRFConfig
*c
= GetGRFConfig(data
);
6716 if (c
!= NULL
&& HasBit(c
->flags
, GCF_STATIC
) && !HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
) && _networking
) {
6717 /* Disable the read GRF if it is a static NewGRF. */
6718 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c
);
6720 } else if (file
== NULL
|| c
== NULL
|| c
->status
== GCS_DISABLED
) {
6722 } else if (src1
== 0xFE) {
6725 src1
= file
->GetParam(src1
);
6729 /* The source1 and source2 operands refer to the grf parameter number
6730 * like in action 6 and 7. In addition, they can refer to the special
6731 * variables available in action 7, or they can be FF to use the value
6732 * of <data>. If referring to parameters that are undefined, a value
6733 * of 0 is used instead. */
6734 src1
= (src1
== 0xFF) ? data
: GetParamVal(src1
, NULL
);
6735 src2
= (src2
== 0xFF) ? data
: GetParamVal(src2
, NULL
);
6738 /* TODO: You can access the parameters of another GRF file by using
6739 * source2=FE, source1=the other GRF's parameter number and data=GRF
6740 * ID. This is only valid with operation 00 (set). If the GRF ID
6741 * cannot be found, a value of 0 is used for the parameter value
6763 res
= (int32
)src1
* (int32
)src2
;
6767 if ((int32
)src2
< 0) {
6768 res
= src1
>> -(int32
)src2
;
6770 res
= src1
<< (src2
& 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6775 if ((int32
)src2
< 0) {
6776 res
= (int32
)src1
>> -(int32
)src2
;
6778 res
= (int32
)src1
<< (src2
& 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6782 case 0x07: // Bitwise AND
6786 case 0x08: // Bitwise OR
6790 case 0x09: // Unsigned division
6798 case 0x0A: // Signed divison
6802 res
= (int32
)src1
/ (int32
)src2
;
6806 case 0x0B: // Unsigned modulo
6814 case 0x0C: // Signed modulo
6818 res
= (int32
)src1
% (int32
)src2
;
6822 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper
); return;
6826 case 0x8E: // Y-Offset for train sprites
6827 _cur
.grffile
->traininfo_vehicle_pitch
= res
;
6830 case 0x8F: { // Rail track type cost factors
6831 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
6832 _railtypes
[RAILTYPE_RAIL
].cost_multiplier
= GB(res
, 0, 8);
6833 if (_settings_game
.vehicle
.disable_elrails
) {
6834 _railtypes
[RAILTYPE_ELECTRIC
].cost_multiplier
= GB(res
, 0, 8);
6835 _railtypes
[RAILTYPE_MONO
].cost_multiplier
= GB(res
, 8, 8);
6837 _railtypes
[RAILTYPE_ELECTRIC
].cost_multiplier
= GB(res
, 8, 8);
6838 _railtypes
[RAILTYPE_MONO
].cost_multiplier
= GB(res
, 16, 8);
6840 _railtypes
[RAILTYPE_MAGLEV
].cost_multiplier
= GB(res
, 16, 8);
6844 /* @todo implement */
6845 case 0x93: // Tile refresh offset to left
6846 case 0x94: // Tile refresh offset to right
6847 case 0x95: // Tile refresh offset upwards
6848 case 0x96: // Tile refresh offset downwards
6849 case 0x97: // Snow line height
6850 case 0x99: // Global ID offset
6851 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target
);
6854 case 0x9E: // Miscellaneous GRF features
6855 /* Set train list engine width */
6856 _cur
.grffile
->traininfo_vehicle_width
= HasBit(res
, GMB_TRAIN_WIDTH_32_PIXELS
) ? VEHICLEINFO_FULL_VEHICLE_WIDTH
: TRAININFO_DEFAULT_VEHICLE_WIDTH
;
6857 /* Remove the local flags from the global flags */
6858 ClrBit(res
, GMB_TRAIN_WIDTH_32_PIXELS
);
6860 /* Only copy safe bits for static grfs */
6861 if (HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
)) {
6862 uint32 safe_bits
= 0;
6863 SetBit(safe_bits
, GMB_SECOND_ROCKY_TILE_SET
);
6865 _misc_grf_features
= (_misc_grf_features
& ~safe_bits
) | (res
& safe_bits
);
6867 _misc_grf_features
= res
;
6871 case 0x9F: // locale-dependent settings
6872 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target
);
6876 if (target
< 0x80) {
6877 _cur
.grffile
->param
[target
] = res
;
6878 /* param is zeroed by default */
6879 if (target
+ 1U > _cur
.grffile
->param_end
) _cur
.grffile
->param_end
= target
+ 1;
6881 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target
);
6887 /* Action 0x0E (GLS_SAFETYSCAN) */
6888 static void SafeGRFInhibit(ByteReader
*buf
)
6890 /* <0E> <num> <grfids...>
6892 * B num Number of GRFIDs that follow
6893 * D grfids GRFIDs of the files to deactivate */
6895 uint8 num
= buf
->ReadByte();
6897 for (uint i
= 0; i
< num
; i
++) {
6898 uint32 grfid
= buf
->ReadDWord();
6900 /* GRF is unsafe it if tries to deactivate other GRFs */
6901 if (grfid
!= _cur
.grfconfig
->ident
.grfid
) {
6902 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
6904 /* Skip remainder of GRF */
6905 _cur
.skip_sprites
= -1;
6913 static void GRFInhibit(ByteReader
*buf
)
6915 /* <0E> <num> <grfids...>
6917 * B num Number of GRFIDs that follow
6918 * D grfids GRFIDs of the files to deactivate */
6920 uint8 num
= buf
->ReadByte();
6922 for (uint i
= 0; i
< num
; i
++) {
6923 uint32 grfid
= buf
->ReadDWord();
6924 GRFConfig
*file
= GetGRFConfig(grfid
);
6926 /* Unset activation flag */
6927 if (file
!= NULL
&& file
!= _cur
.grfconfig
) {
6928 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file
->filename
);
6929 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED
, file
);
6930 error
->data
= stredup(_cur
.grfconfig
->GetName());
6935 /** Action 0x0F - Define Town names */
6936 static void FeatureTownName(ByteReader
*buf
)
6938 /* <0F> <id> <style-name> <num-parts> <parts>
6940 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6941 * V style-name Name of the style (only for final definition)
6942 * B num-parts Number of parts in this definition
6943 * V parts The parts */
6945 uint32 grfid
= _cur
.grffile
->grfid
;
6947 GRFTownName
*townname
= AddGRFTownName(grfid
);
6949 byte id
= buf
->ReadByte();
6950 grfmsg(6, "FeatureTownName: definition 0x%02X", id
& 0x7F);
6952 if (HasBit(id
, 7)) {
6953 /* Final definition */
6955 bool new_scheme
= _cur
.grffile
->grf_version
>= 7;
6957 byte lang
= buf
->ReadByte();
6959 byte nb_gen
= townname
->nb_gen
;
6963 const char *name
= buf
->ReadString();
6965 char *lang_name
= TranslateTTDPatchCodes(grfid
, lang
, false, name
);
6966 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang
, lang_name
);
6969 townname
->name
[nb_gen
] = AddGRFString(grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
6971 lang
= buf
->ReadByte();
6972 } while (lang
!= 0);
6973 townname
->id
[nb_gen
] = id
;
6977 byte nb
= buf
->ReadByte();
6978 grfmsg(6, "FeatureTownName: %u parts", nb
);
6980 townname
->nbparts
[id
] = nb
;
6981 townname
->partlist
[id
] = CallocT
<NamePartList
>(nb
);
6983 for (int i
= 0; i
< nb
; i
++) {
6984 byte nbtext
= buf
->ReadByte();
6985 townname
->partlist
[id
][i
].bitstart
= buf
->ReadByte();
6986 townname
->partlist
[id
][i
].bitcount
= buf
->ReadByte();
6987 townname
->partlist
[id
][i
].maxprob
= 0;
6988 townname
->partlist
[id
][i
].partcount
= nbtext
;
6989 townname
->partlist
[id
][i
].parts
= CallocT
<NamePart
>(nbtext
);
6990 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
);
6992 for (int j
= 0; j
< nbtext
; j
++) {
6993 byte prob
= buf
->ReadByte();
6995 if (HasBit(prob
, 7)) {
6996 byte ref_id
= buf
->ReadByte();
6998 if (townname
->nbparts
[ref_id
] == 0) {
6999 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id
);
7000 DelGRFTownName(grfid
);
7001 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID
);
7005 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i
, j
, ref_id
, prob
& 0x7F);
7006 townname
->partlist
[id
][i
].parts
[j
].data
.id
= ref_id
;
7008 const char *text
= buf
->ReadString();
7009 townname
->partlist
[id
][i
].parts
[j
].data
.text
= TranslateTTDPatchCodes(grfid
, 0, false, text
);
7010 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i
, j
, townname
->partlist
[id
][i
].parts
[j
].data
.text
, prob
);
7012 townname
->partlist
[id
][i
].parts
[j
].prob
= prob
;
7013 townname
->partlist
[id
][i
].maxprob
+= GB(prob
, 0, 7);
7015 grfmsg(6, "FeatureTownName: part %d, total probability %d", i
, townname
->partlist
[id
][i
].maxprob
);
7019 /** Action 0x10 - Define goto label */
7020 static void DefineGotoLabel(ByteReader
*buf
)
7022 /* <10> <label> [<comment>]
7024 * B label The label to define
7025 * V comment Optional comment - ignored */
7027 byte nfo_label
= buf
->ReadByte();
7029 GRFLabel
*label
= MallocT
<GRFLabel
>(1);
7030 label
->label
= nfo_label
;
7031 label
->nfo_line
= _cur
.nfo_line
;
7032 label
->pos
= FioGetPos();
7035 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7036 if (_cur
.grffile
->label
== NULL
) {
7037 _cur
.grffile
->label
= label
;
7039 /* Attach the label to the end of the list */
7041 for (l
= _cur
.grffile
->label
; l
->next
!= NULL
; l
= l
->next
) {}
7045 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label
->label
);
7049 * Process a sound import from another GRF file.
7050 * @param sound Destination for sound.
7052 static void ImportGRFSound(SoundEntry
*sound
)
7054 const GRFFile
*file
;
7055 uint32 grfid
= FioReadDword();
7056 SoundID sound_id
= FioReadWord();
7058 file
= GetFileByGRFID(grfid
);
7059 if (file
== NULL
|| file
->sound_offset
== 0) {
7060 grfmsg(1, "ImportGRFSound: Source file not available");
7064 if (sound_id
>= file
->num_sounds
) {
7065 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id
);
7069 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id
, file
->sound_offset
+ sound_id
, grfid
);
7071 *sound
= *GetSound(file
->sound_offset
+ sound_id
);
7073 /* Reset volume and priority, which TTDPatch doesn't copy */
7074 sound
->volume
= 128;
7075 sound
->priority
= 0;
7079 * Load a sound from a file.
7080 * @param offs File offset to read sound from.
7081 * @param sound Destination for sound.
7083 static void LoadGRFSound(size_t offs
, SoundEntry
*sound
)
7085 /* Set default volume and priority */
7086 sound
->volume
= 0x80;
7087 sound
->priority
= 0;
7089 if (offs
!= SIZE_MAX
) {
7090 /* Sound is present in the NewGRF. */
7091 sound
->file_slot
= _cur
.file_index
;
7092 sound
->file_offset
= offs
;
7093 sound
->grf_container_ver
= _cur
.grf_container_ver
;
7098 static void GRFSound(ByteReader
*buf
)
7102 * W num Number of sound files that follow */
7104 uint16 num
= buf
->ReadWord();
7105 if (num
== 0) return;
7108 if (_cur
.grffile
->sound_offset
== 0) {
7109 _cur
.grffile
->sound_offset
= GetNumSounds();
7110 _cur
.grffile
->num_sounds
= num
;
7111 sound
= AllocateSound(num
);
7113 sound
= GetSound(_cur
.grffile
->sound_offset
);
7116 for (int i
= 0; i
< num
; i
++) {
7119 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7120 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7121 bool invalid
= i
>= _cur
.grffile
->num_sounds
;
7123 size_t offs
= FioGetPos();
7125 uint32 len
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
7126 byte type
= FioReadByte();
7128 if (_cur
.grf_container_ver
>= 2 && type
== 0xFD) {
7129 /* Reference to sprite section. */
7131 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7133 } else if (len
!= 4) {
7134 grfmsg(1, "GRFSound: Invalid sprite section import");
7137 uint32 id
= FioReadDword();
7138 if (_cur
.stage
== GLS_INIT
) LoadGRFSound(GetGRFSpriteOffset(id
), sound
+ i
);
7144 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7146 SkipSpriteData(type
, len
- 8);
7151 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7155 byte action
= FioReadByte();
7158 /* Allocate sound only in init stage. */
7159 if (_cur
.stage
== GLS_INIT
) {
7160 if (_cur
.grf_container_ver
>= 2) {
7161 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7163 LoadGRFSound(offs
, sound
+ i
);
7166 FioSkipBytes(len
- 1); // already read <action>
7170 if (_cur
.stage
== GLS_ACTIVATION
) {
7171 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7172 * importing sounds, so this is probably all wrong... */
7173 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7174 ImportGRFSound(sound
+ i
);
7176 FioSkipBytes(len
- 1); // already read <action>
7181 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action
);
7182 FioSkipBytes(len
- 1); // already read <action>
7188 /* Action 0x11 (SKIP) */
7189 static void SkipAct11(ByteReader
*buf
)
7193 * W num Number of sound files that follow */
7195 _cur
.skip_sprites
= buf
->ReadWord();
7197 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur
.skip_sprites
);
7201 static void LoadFontGlyph(ByteReader
*buf
)
7203 /* <12> <num_def> <font_size> <num_char> <base_char>
7205 * B num_def Number of definitions
7206 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7207 * B num_char Number of consecutive glyphs
7208 * W base_char First character index */
7210 uint8 num_def
= buf
->ReadByte();
7212 for (uint i
= 0; i
< num_def
; i
++) {
7213 FontSize size
= (FontSize
)buf
->ReadByte();
7214 uint8 num_char
= buf
->ReadByte();
7215 uint16 base_char
= buf
->ReadWord();
7217 if (size
>= FS_END
) {
7218 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size
);
7221 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char
, base_char
, size
);
7223 for (uint c
= 0; c
< num_char
; c
++) {
7224 if (size
< FS_END
) SetUnicodeGlyph(size
, base_char
+ c
, _cur
.spriteid
);
7226 LoadNextSprite(_cur
.spriteid
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
7231 /** Action 0x12 (SKIP) */
7232 static void SkipAct12(ByteReader
*buf
)
7234 /* <12> <num_def> <font_size> <num_char> <base_char>
7236 * B num_def Number of definitions
7237 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7238 * B num_char Number of consecutive glyphs
7239 * W base_char First character index */
7241 uint8 num_def
= buf
->ReadByte();
7243 for (uint i
= 0; i
< num_def
; i
++) {
7244 /* Ignore 'size' byte */
7247 /* Sum up number of characters */
7248 _cur
.skip_sprites
+= buf
->ReadByte();
7250 /* Ignore 'base_char' word */
7254 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur
.skip_sprites
);
7258 static void TranslateGRFStrings(ByteReader
*buf
)
7260 /* <13> <grfid> <num-ent> <offset> <text...>
7262 * 4*B grfid The GRFID of the file whose texts are to be translated
7263 * B num-ent Number of strings
7264 * W offset First text ID
7265 * S text... Zero-terminated strings */
7267 uint32 grfid
= buf
->ReadDWord();
7268 const GRFConfig
*c
= GetGRFConfig(grfid
);
7269 if (c
== NULL
|| (c
->status
!= GCS_INITIALISED
&& c
->status
!= GCS_ACTIVATED
)) {
7270 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid
));
7274 if (c
->status
== GCS_INITIALISED
) {
7275 /* If the file is not active but will be activated later, give an error
7276 * and disable this file. */
7277 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER
);
7280 GetString(tmp
, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE
, lastof(tmp
));
7281 error
->data
= stredup(tmp
);
7286 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7287 * to be added as a generic string, thus the language id of 0x7F. For this to work
7288 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7289 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7290 * not change anything if a string has been provided specifically for this language. */
7291 byte language
= _cur
.grffile
->grf_version
>= 8 ? buf
->ReadByte() : 0x7F;
7292 byte num_strings
= buf
->ReadByte();
7293 uint16 first_id
= buf
->ReadWord();
7295 if (!((first_id
>= 0xD000 && first_id
+ num_strings
<= 0xD400) || (first_id
>= 0xD800 && first_id
+ num_strings
<= 0xE000))) {
7296 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id
, num_strings
);
7300 for (uint i
= 0; i
< num_strings
&& buf
->HasData(); i
++) {
7301 const char *string
= buf
->ReadString();
7303 if (StrEmpty(string
)) {
7304 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7308 AddGRFString(grfid
, first_id
+ i
, language
, true, true, string
, STR_UNDEFINED
);
7312 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7313 static bool ChangeGRFName(byte langid
, const char *str
)
7315 AddGRFTextToList(&_cur
.grfconfig
->name
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7319 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7320 static bool ChangeGRFDescription(byte langid
, const char *str
)
7322 AddGRFTextToList(&_cur
.grfconfig
->info
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, true, str
);
7326 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7327 static bool ChangeGRFURL(byte langid
, const char *str
)
7329 AddGRFTextToList(&_cur
.grfconfig
->url
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7333 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7334 static bool ChangeGRFNumUsedParams(size_t len
, ByteReader
*buf
)
7337 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len
);
7340 _cur
.grfconfig
->num_valid_params
= min(buf
->ReadByte(), lengthof(_cur
.grfconfig
->param
));
7345 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7346 static bool ChangeGRFPalette(size_t len
, ByteReader
*buf
)
7349 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len
);
7352 char data
= buf
->ReadByte();
7353 GRFPalette pal
= GRFP_GRF_UNSET
;
7356 case 'A': pal
= GRFP_GRF_ANY
; break;
7357 case 'W': pal
= GRFP_GRF_WINDOWS
; break;
7358 case 'D': pal
= GRFP_GRF_DOS
; break;
7360 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data
);
7363 if (pal
!= GRFP_GRF_UNSET
) {
7364 _cur
.grfconfig
->palette
&= ~GRFP_GRF_MASK
;
7365 _cur
.grfconfig
->palette
|= pal
;
7371 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7372 static bool ChangeGRFBlitter(size_t len
, ByteReader
*buf
)
7375 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len
);
7378 char data
= buf
->ReadByte();
7379 GRFPalette pal
= GRFP_BLT_UNSET
;
7381 case '8': pal
= GRFP_BLT_UNSET
; break;
7382 case '3': pal
= GRFP_BLT_32BPP
; break;
7384 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data
);
7387 _cur
.grfconfig
->palette
&= ~GRFP_BLT_MASK
;
7388 _cur
.grfconfig
->palette
|= pal
;
7393 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7394 static bool ChangeGRFVersion(size_t len
, ByteReader
*buf
)
7397 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len
);
7400 /* Set min_loadable_version as well (default to minimal compatibility) */
7401 _cur
.grfconfig
->version
= _cur
.grfconfig
->min_loadable_version
= buf
->ReadDWord();
7406 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7407 static bool ChangeGRFMinVersion(size_t len
, ByteReader
*buf
)
7410 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len
);
7413 _cur
.grfconfig
->min_loadable_version
= buf
->ReadDWord();
7414 if (_cur
.grfconfig
->version
== 0) {
7415 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7416 _cur
.grfconfig
->min_loadable_version
= 0;
7418 if (_cur
.grfconfig
->version
< _cur
.grfconfig
->min_loadable_version
) {
7419 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur
.grfconfig
->min_loadable_version
);
7420 _cur
.grfconfig
->min_loadable_version
= _cur
.grfconfig
->version
;
7426 static GRFParameterInfo
*_cur_parameter
; ///< The parameter which info is currently changed by the newgrf.
7428 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7429 static bool ChangeGRFParamName(byte langid
, const char *str
)
7431 AddGRFTextToList(&_cur_parameter
->name
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7435 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7436 static bool ChangeGRFParamDescription(byte langid
, const char *str
)
7438 AddGRFTextToList(&_cur_parameter
->desc
, langid
, _cur
.grfconfig
->ident
.grfid
, true, str
);
7442 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7443 static bool ChangeGRFParamType(size_t len
, ByteReader
*buf
)
7446 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len
);
7449 GRFParameterType type
= (GRFParameterType
)buf
->ReadByte();
7450 if (type
< PTYPE_END
) {
7451 _cur_parameter
->type
= type
;
7453 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type
);
7459 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7460 static bool ChangeGRFParamLimits(size_t len
, ByteReader
*buf
)
7462 if (_cur_parameter
->type
!= PTYPE_UINT_ENUM
) {
7463 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7465 } else if (len
!= 8) {
7466 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len
);
7469 _cur_parameter
->min_value
= buf
->ReadDWord();
7470 _cur_parameter
->max_value
= buf
->ReadDWord();
7475 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7476 static bool ChangeGRFParamMask(size_t len
, ByteReader
*buf
)
7478 if (len
< 1 || len
> 3) {
7479 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len
);
7482 byte param_nr
= buf
->ReadByte();
7483 if (param_nr
>= lengthof(_cur
.grfconfig
->param
)) {
7484 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr
);
7487 _cur_parameter
->param_nr
= param_nr
;
7488 if (len
>= 2) _cur_parameter
->first_bit
= min(buf
->ReadByte(), 31);
7489 if (len
>= 3) _cur_parameter
->num_bit
= min(buf
->ReadByte(), 32 - _cur_parameter
->first_bit
);
7496 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7497 static bool ChangeGRFParamDefault(size_t len
, ByteReader
*buf
)
7500 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len
);
7503 _cur_parameter
->def_value
= buf
->ReadDWord();
7505 _cur
.grfconfig
->has_param_defaults
= true;
7509 typedef bool (*DataHandler
)(size_t, ByteReader
*); ///< Type of callback function for binary nodes
7510 typedef bool (*TextHandler
)(byte
, const char *str
); ///< Type of callback function for text nodes
7511 typedef bool (*BranchHandler
)(ByteReader
*); ///< Type of callback function for branch nodes
7514 * Data structure to store the allowed id/type combinations for action 14. The
7515 * data can be represented as a tree with 3 types of nodes:
7516 * 1. Branch nodes (identified by 'C' for choice).
7517 * 2. Binary leaf nodes (identified by 'B').
7518 * 3. Text leaf nodes (identified by 'T').
7520 struct AllowedSubtags
{
7521 /** Create empty subtags object used to identify the end of a list. */
7528 * Create a binary leaf node.
7529 * @param id The id for this node.
7530 * @param handler The callback function to call.
7532 AllowedSubtags(uint32 id
, DataHandler handler
) :
7536 this->handler
.data
= handler
;
7540 * Create a text leaf node.
7541 * @param id The id for this node.
7542 * @param handler The callback function to call.
7544 AllowedSubtags(uint32 id
, TextHandler handler
) :
7548 this->handler
.text
= handler
;
7552 * Create a branch node with a callback handler
7553 * @param id The id for this node.
7554 * @param handler The callback function to call.
7556 AllowedSubtags(uint32 id
, BranchHandler handler
) :
7560 this->handler
.call_handler
= true;
7561 this->handler
.u
.branch
= handler
;
7565 * Create a branch node with a list of sub-nodes.
7566 * @param id The id for this node.
7567 * @param subtags Array with all valid subtags.
7569 AllowedSubtags(uint32 id
, AllowedSubtags
*subtags
) :
7573 this->handler
.call_handler
= false;
7574 this->handler
.u
.subtags
= subtags
;
7577 uint32 id
; ///< The identifier for this node
7578 byte type
; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7580 DataHandler data
; ///< Callback function for a binary node, only valid if type == 'B'.
7581 TextHandler text
; ///< Callback function for a text node, only valid if type == 'T'.
7584 BranchHandler branch
; ///< Callback function for a branch node, only valid if type == 'C' && call_handler.
7585 AllowedSubtags
*subtags
; ///< Pointer to a list of subtags, only valid if type == 'C' && !call_handler.
7587 bool call_handler
; ///< True if there is a callback function for this node, false if there is a list of subnodes.
7592 static bool SkipUnknownInfo(ByteReader
*buf
, byte type
);
7593 static bool HandleNodes(ByteReader
*buf
, AllowedSubtags
*tags
);
7596 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7597 * of some parameter values (type uint/enum) or the names of some bits
7598 * (type bitmask). In both cases the format is the same:
7599 * Each subnode should be a text node with the value/bit number as id.
7601 static bool ChangeGRFParamValueNames(ByteReader
*buf
)
7603 byte type
= buf
->ReadByte();
7605 uint32 id
= buf
->ReadDWord();
7606 if (type
!= 'T' || id
> _cur_parameter
->max_value
) {
7607 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7608 if (!SkipUnknownInfo(buf
, type
)) return false;
7609 type
= buf
->ReadByte();
7613 byte langid
= buf
->ReadByte();
7614 const char *name_string
= buf
->ReadString();
7616 SmallPair
<uint32
, GRFText
*> *val_name
= _cur_parameter
->value_names
.Find(id
);
7617 if (val_name
!= _cur_parameter
->value_names
.End()) {
7618 AddGRFTextToList(&val_name
->second
, langid
, _cur
.grfconfig
->ident
.grfid
, false, name_string
);
7620 GRFText
*list
= NULL
;
7621 AddGRFTextToList(&list
, langid
, _cur
.grfconfig
->ident
.grfid
, false, name_string
);
7622 _cur_parameter
->value_names
.Insert(id
, list
);
7625 type
= buf
->ReadByte();
7630 /** Action14 parameter tags */
7631 AllowedSubtags _tags_parameters
[] = {
7632 AllowedSubtags('NAME', ChangeGRFParamName
),
7633 AllowedSubtags('DESC', ChangeGRFParamDescription
),
7634 AllowedSubtags('TYPE', ChangeGRFParamType
),
7635 AllowedSubtags('LIMI', ChangeGRFParamLimits
),
7636 AllowedSubtags('MASK', ChangeGRFParamMask
),
7637 AllowedSubtags('VALU', ChangeGRFParamValueNames
),
7638 AllowedSubtags('DFLT', ChangeGRFParamDefault
),
7643 * Callback function for 'INFO'->'PARA' to set extra information about the
7644 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7645 * the parameter number as id. The first parameter has id 0. The maximum
7646 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7648 static bool HandleParameterInfo(ByteReader
*buf
)
7650 byte type
= buf
->ReadByte();
7652 uint32 id
= buf
->ReadDWord();
7653 if (type
!= 'C' || id
>= _cur
.grfconfig
->num_valid_params
) {
7654 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7655 if (!SkipUnknownInfo(buf
, type
)) return false;
7656 type
= buf
->ReadByte();
7660 if (id
>= _cur
.grfconfig
->param_info
.Length()) {
7661 uint num_to_add
= id
- _cur
.grfconfig
->param_info
.Length() + 1;
7662 GRFParameterInfo
**newdata
= _cur
.grfconfig
->param_info
.Append(num_to_add
);
7663 MemSetT
<GRFParameterInfo
*>(newdata
, 0, num_to_add
);
7665 if (_cur
.grfconfig
->param_info
[id
] == NULL
) {
7666 _cur
.grfconfig
->param_info
[id
] = new GRFParameterInfo(id
);
7668 _cur_parameter
= _cur
.grfconfig
->param_info
[id
];
7669 /* Read all parameter-data and process each node. */
7670 if (!HandleNodes(buf
, _tags_parameters
)) return false;
7671 type
= buf
->ReadByte();
7676 /** Action14 tags for the INFO node */
7677 AllowedSubtags _tags_info
[] = {
7678 AllowedSubtags('NAME', ChangeGRFName
),
7679 AllowedSubtags('DESC', ChangeGRFDescription
),
7680 AllowedSubtags('URL_', ChangeGRFURL
),
7681 AllowedSubtags('NPAR', ChangeGRFNumUsedParams
),
7682 AllowedSubtags('PALS', ChangeGRFPalette
),
7683 AllowedSubtags('BLTR', ChangeGRFBlitter
),
7684 AllowedSubtags('VRSN', ChangeGRFVersion
),
7685 AllowedSubtags('MINV', ChangeGRFMinVersion
),
7686 AllowedSubtags('PARA', HandleParameterInfo
),
7690 /** Action14 root tags */
7691 AllowedSubtags _tags_root
[] = {
7692 AllowedSubtags('INFO', _tags_info
),
7698 * Try to skip the current node and all subnodes (if it's a branch node).
7699 * @param buf Buffer.
7700 * @param type The node type to skip.
7701 * @return True if we could skip the node, false if an error occurred.
7703 static bool SkipUnknownInfo(ByteReader
*buf
, byte type
)
7705 /* type and id are already read */
7708 byte new_type
= buf
->ReadByte();
7709 while (new_type
!= 0) {
7710 buf
->ReadDWord(); // skip the id
7711 if (!SkipUnknownInfo(buf
, new_type
)) return false;
7712 new_type
= buf
->ReadByte();
7718 buf
->ReadByte(); // lang
7719 buf
->ReadString(); // actual text
7723 uint16 size
= buf
->ReadWord();
7736 * Handle the nodes of an Action14
7737 * @param type Type of node.
7739 * @param buf Buffer.
7740 * @param subtags Allowed subtags.
7741 * @return Whether all tags could be handled.
7743 static bool HandleNode(byte type
, uint32 id
, ByteReader
*buf
, AllowedSubtags subtags
[])
7746 AllowedSubtags
*tag
;
7747 while ((tag
= &subtags
[i
++])->type
!= 0) {
7748 if (tag
->id
!= BSWAP32(id
) || tag
->type
!= type
) continue;
7750 default: NOT_REACHED();
7753 byte langid
= buf
->ReadByte();
7754 return tag
->handler
.text(langid
, buf
->ReadString());
7758 size_t len
= buf
->ReadWord();
7759 if (buf
->Remaining() < len
) return false;
7760 return tag
->handler
.data(len
, buf
);
7764 if (tag
->handler
.call_handler
) {
7765 return tag
->handler
.u
.branch(buf
);
7767 return HandleNodes(buf
, tag
->handler
.u
.subtags
);
7771 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type
, id
);
7772 return SkipUnknownInfo(buf
, type
);
7776 * Handle the contents of a 'C' choice of an Action14
7777 * @param buf Buffer.
7778 * @param subtags List of subtags.
7779 * @return Whether the nodes could all be handled.
7781 static bool HandleNodes(ByteReader
*buf
, AllowedSubtags subtags
[])
7783 byte type
= buf
->ReadByte();
7785 uint32 id
= buf
->ReadDWord();
7786 if (!HandleNode(type
, id
, buf
, subtags
)) return false;
7787 type
= buf
->ReadByte();
7793 * Handle Action 0x14
7794 * @param buf Buffer.
7796 static void StaticGRFInfo(ByteReader
*buf
)
7798 /* <14> <type> <id> <text/data...> */
7799 HandleNodes(buf
, _tags_root
);
7803 * Set the current NewGRF as unsafe for static use
7804 * @param buf Unused.
7805 * @note Used during safety scan on unsafe actions.
7807 static void GRFUnsafe(ByteReader
*buf
)
7809 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
7811 /* Skip remainder of GRF */
7812 _cur
.skip_sprites
= -1;
7816 /** Initialize the TTDPatch flags */
7817 static void InitializeGRFSpecial()
7819 _ttdpatch_flags
[0] = ((_settings_game
.station
.never_expire_airports
? 1 : 0) << 0x0C) // keepsmallairport
7820 | (1 << 0x0D) // newairports
7821 | (1 << 0x0E) // largestations
7822 | ((_settings_game
.construction
.max_bridge_length
> 16 ? 1 : 0) << 0x0F) // longbridges
7823 | (0 << 0x10) // loadtime
7824 | (1 << 0x12) // presignals
7825 | (1 << 0x13) // extpresignals
7826 | ((_settings_game
.vehicle
.never_expire_vehicles
? 1 : 0) << 0x16) // enginespersist
7827 | (1 << 0x1B) // multihead
7828 | (1 << 0x1D) // lowmemory
7829 | (1 << 0x1E); // generalfixes
7831 _ttdpatch_flags
[1] = ((_settings_game
.economy
.station_noise_level
? 1 : 0) << 0x07) // moreairports - based on units of noise
7832 | (1 << 0x08) // mammothtrains
7833 | (1 << 0x09) // trainrefit
7834 | (0 << 0x0B) // subsidiaries
7835 | ((_settings_game
.order
.gradual_loading
? 1 : 0) << 0x0C) // gradualloading
7836 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7837 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7838 | (1 << 0x14) // bridgespeedlimits
7839 | (1 << 0x16) // eternalgame
7840 | (1 << 0x17) // newtrains
7841 | (1 << 0x18) // newrvs
7842 | (1 << 0x19) // newships
7843 | (1 << 0x1A) // newplanes
7844 | ((_settings_game
.construction
.train_signal_side
== 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7845 | ((_settings_game
.vehicle
.disable_elrails
? 0 : 1) << 0x1C); // electrifiedrailway
7847 _ttdpatch_flags
[2] = (1 << 0x01) // loadallgraphics - obsolote
7848 | (1 << 0x03) // semaphores
7849 | (1 << 0x0A) // newobjects
7850 | (0 << 0x0B) // enhancedgui
7851 | (0 << 0x0C) // newagerating
7852 | ((_settings_game
.construction
.build_on_slopes
? 1 : 0) << 0x0D) // buildonslopes
7853 | (1 << 0x0E) // fullloadany
7854 | (1 << 0x0F) // planespeed
7855 | (0 << 0x10) // moreindustriesperclimate - obsolete
7856 | (0 << 0x11) // moretoylandfeatures
7857 | (1 << 0x12) // newstations
7858 | (1 << 0x13) // tracktypecostdiff
7859 | (1 << 0x14) // manualconvert
7860 | ((_settings_game
.construction
.build_on_slopes
? 1 : 0) << 0x15) // buildoncoasts
7861 | (1 << 0x16) // canals
7862 | (1 << 0x17) // newstartyear
7863 | ((_settings_game
.vehicle
.freight_trains
> 1 ? 1 : 0) << 0x18) // freighttrains
7864 | (1 << 0x19) // newhouses
7865 | (1 << 0x1A) // newbridges
7866 | (1 << 0x1B) // newtownnames
7867 | (1 << 0x1C) // moreanimation
7868 | ((_settings_game
.vehicle
.wagon_speed_limits
? 1 : 0) << 0x1D) // wagonspeedlimits
7869 | (1 << 0x1E) // newshistory
7870 | (0 << 0x1F); // custombridgeheads
7872 _ttdpatch_flags
[3] = (0 << 0x00) // newcargodistribution
7873 | (1 << 0x01) // windowsnap
7874 | ((_settings_game
.economy
.allow_town_roads
|| _generating_world
? 0 : 1) << 0x02) // townbuildnoroad
7875 | (1 << 0x03) // pathbasedsignalling
7876 | (0 << 0x04) // aichoosechance
7877 | (1 << 0x05) // resolutionwidth
7878 | (1 << 0x06) // resolutionheight
7879 | (1 << 0x07) // newindustries
7880 | ((_settings_game
.order
.improved_load
? 1 : 0) << 0x08) // fifoloading
7881 | (0 << 0x09) // townroadbranchprob
7882 | (0 << 0x0A) // tempsnowline
7883 | (1 << 0x0B) // newcargo
7884 | (1 << 0x0C) // enhancemultiplayer
7885 | (1 << 0x0D) // onewayroads
7886 | (1 << 0x0E) // irregularstations
7887 | (1 << 0x0F) // statistics
7888 | (1 << 0x10) // newsounds
7889 | (1 << 0x11) // autoreplace
7890 | (1 << 0x12) // autoslope
7891 | (0 << 0x13) // followvehicle
7892 | (1 << 0x14) // trams
7893 | (0 << 0x15) // enhancetunnels
7894 | (1 << 0x16) // shortrvs
7895 | (1 << 0x17) // articulatedrvs
7896 | ((_settings_game
.vehicle
.dynamic_engines
? 1 : 0) << 0x18) // dynamic engines
7897 | (1 << 0x1E) // variablerunningcosts
7898 | (1 << 0x1F); // any switch is on
7901 /** Reset and clear all NewGRF stations */
7902 static void ResetCustomStations()
7904 const GRFFile
* const *end
= _grf_files
.End();
7905 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7906 StationSpec
**&stations
= (*file
)->stations
;
7907 if (stations
== NULL
) continue;
7908 for (uint i
= 0; i
< NUM_STATIONS_PER_GRF
; i
++) {
7909 if (stations
[i
] == NULL
) continue;
7910 StationSpec
*statspec
= stations
[i
];
7912 delete[] statspec
->renderdata
;
7914 /* Release platforms and layouts */
7915 if (!statspec
->copied_layouts
) {
7916 for (uint l
= 0; l
< statspec
->lengths
; l
++) {
7917 for (uint p
= 0; p
< statspec
->platforms
[l
]; p
++) {
7918 free(statspec
->layouts
[l
][p
]);
7920 free(statspec
->layouts
[l
]);
7922 free(statspec
->layouts
);
7923 free(statspec
->platforms
);
7926 /* Release this station */
7930 /* Free and reset the station data */
7936 /** Reset and clear all NewGRF houses */
7937 static void ResetCustomHouses()
7939 const GRFFile
* const *end
= _grf_files
.End();
7940 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7941 HouseSpec
**&housespec
= (*file
)->housespec
;
7942 if (housespec
== NULL
) continue;
7943 for (uint i
= 0; i
< NUM_HOUSES_PER_GRF
; i
++) {
7952 /** Reset and clear all NewGRF airports */
7953 static void ResetCustomAirports()
7955 const GRFFile
* const *end
= _grf_files
.End();
7956 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7957 AirportSpec
**aslist
= (*file
)->airportspec
;
7958 if (aslist
!= NULL
) {
7959 for (uint i
= 0; i
< NUM_AIRPORTS_PER_GRF
; i
++) {
7960 AirportSpec
*as
= aslist
[i
];
7963 /* We need to remove the tiles layouts */
7964 for (int j
= 0; j
< as
->num_table
; j
++) {
7965 /* remove the individual layouts */
7969 free(as
->depot_table
);
7976 (*file
)->airportspec
= NULL
;
7979 AirportTileSpec
**&airporttilespec
= (*file
)->airtspec
;
7980 if (airporttilespec
!= NULL
) {
7981 for (uint i
= 0; i
< NUM_AIRPORTTILES_PER_GRF
; i
++) {
7982 free(airporttilespec
[i
]);
7984 free(airporttilespec
);
7985 airporttilespec
= NULL
;
7990 /** Reset and clear all NewGRF industries */
7991 static void ResetCustomIndustries()
7993 const GRFFile
* const *end
= _grf_files
.End();
7994 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7995 IndustrySpec
**&industryspec
= (*file
)->industryspec
;
7996 IndustryTileSpec
**&indtspec
= (*file
)->indtspec
;
7998 /* We are verifiying both tiles and industries specs loaded from the grf file
7999 * First, let's deal with industryspec */
8000 if (industryspec
!= NULL
) {
8001 for (uint i
= 0; i
< NUM_INDUSTRYTYPES_PER_GRF
; i
++) {
8002 IndustrySpec
*ind
= industryspec
[i
];
8003 if (ind
== NULL
) continue;
8005 /* We need to remove the sounds array */
8006 if (HasBit(ind
->cleanup_flag
, CLEAN_RANDOMSOUNDS
)) {
8007 free(ind
->random_sounds
);
8010 /* We need to remove the tiles layouts */
8011 CleanIndustryTileTable(ind
);
8017 industryspec
= NULL
;
8020 if (indtspec
== NULL
) continue;
8021 for (uint i
= 0; i
< NUM_INDUSTRYTILES_PER_GRF
; i
++) {
8030 /** Reset and clear all NewObjects */
8031 static void ResetCustomObjects()
8033 const GRFFile
* const *end
= _grf_files
.End();
8034 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8035 ObjectSpec
**&objectspec
= (*file
)->objectspec
;
8036 if (objectspec
== NULL
) continue;
8037 for (uint i
= 0; i
< NUM_OBJECTS_PER_GRF
; i
++) {
8038 free(objectspec
[i
]);
8046 /** Reset and clear all NewGRFs */
8047 static void ResetNewGRF()
8049 const GRFFile
* const *end
= _grf_files
.End();
8050 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8055 _cur
.grffile
= NULL
;
8058 /** Clear all NewGRF errors */
8059 static void ResetNewGRFErrors()
8061 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
8062 if (!HasBit(c
->flags
, GCF_COPY
) && c
->error
!= NULL
) {
8070 * Reset all NewGRF loaded data
8073 void ResetNewGRFData()
8076 CleanUpGRFTownNames();
8078 /* Copy/reset original engine info data */
8081 /* Copy/reset original bridge info data */
8084 /* Reset rail type information */
8087 /* Allocate temporary refit/cargo class data */
8088 _gted
= CallocT
<GRFTempEngineData
>(Engine::GetPoolSize());
8090 /* Fill rail type label temporary data for default trains */
8092 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_TRAIN
) {
8093 _gted
[e
->index
].railtypelabel
= GetRailTypeInfo(e
->u
.rail
.railtype
)->label
;
8096 /* Reset GRM reservations */
8097 memset(&_grm_engines
, 0, sizeof(_grm_engines
));
8098 memset(&_grm_cargoes
, 0, sizeof(_grm_cargoes
));
8100 /* Reset generic feature callback lists */
8101 ResetGenericCallbacks();
8103 /* Reset price base data */
8104 ResetPriceBaseMultipliers();
8106 /* Reset the curencies array */
8109 /* Reset the house array */
8110 ResetCustomHouses();
8113 /* Reset the industries structures*/
8114 ResetCustomIndustries();
8117 /* Reset the objects. */
8118 ObjectClass::Reset();
8119 ResetCustomObjects();
8122 /* Reset station classes */
8123 StationClass::Reset();
8124 ResetCustomStations();
8126 /* Reset airport-related structures */
8127 AirportClass::Reset();
8128 ResetCustomAirports();
8129 AirportSpec::ResetAirports();
8130 AirportTileSpec::ResetAirportTiles();
8132 /* Reset canal sprite groups and flags */
8133 memset(_water_feature
, 0, sizeof(_water_feature
));
8135 /* Reset the snowline table. */
8138 /* Reset NewGRF files */
8141 /* Reset NewGRF errors. */
8142 ResetNewGRFErrors();
8144 /* Set up the default cargo types */
8145 SetupCargoForClimate(_settings_game
.game_creation
.landscape
);
8147 /* Reset misc GRF features and train list display variables */
8148 _misc_grf_features
= 0;
8150 _loaded_newgrf_features
.has_2CC
= false;
8151 _loaded_newgrf_features
.used_liveries
= 1 << LS_DEFAULT
;
8152 _loaded_newgrf_features
.has_newhouses
= false;
8153 _loaded_newgrf_features
.has_newindustries
= false;
8154 _loaded_newgrf_features
.shore
= SHORE_REPLACE_NONE
;
8156 /* Clear all GRF overrides */
8157 _grf_id_overrides
.clear();
8159 InitializeSoundPool();
8160 _spritegroup_pool
.CleanPool();
8164 * Reset NewGRF data which is stored persistently in savegames.
8166 void ResetPersistentNewGRFData()
8168 /* Reset override managers */
8169 _engine_mngr
.ResetToDefaultMapping();
8170 _house_mngr
.ResetMapping();
8171 _industry_mngr
.ResetMapping();
8172 _industile_mngr
.ResetMapping();
8173 _airport_mngr
.ResetMapping();
8174 _airporttile_mngr
.ResetMapping();
8178 * Construct the Cargo Mapping
8179 * @note This is the reverse of a cargo translation table
8181 static void BuildCargoTranslationMap()
8183 memset(_cur
.grffile
->cargo_map
, 0xFF, sizeof(_cur
.grffile
->cargo_map
));
8185 for (CargoID c
= 0; c
< NUM_CARGO
; c
++) {
8186 const CargoSpec
*cs
= CargoSpec::Get(c
);
8187 if (!cs
->IsValid()) continue;
8189 if (_cur
.grffile
->cargo_list
.Length() == 0) {
8190 /* Default translation table, so just a straight mapping to bitnum */
8191 _cur
.grffile
->cargo_map
[c
] = cs
->bitnum
;
8193 /* Check the translation table for this cargo's label */
8194 int index
= _cur
.grffile
->cargo_list
.FindIndex(cs
->label
);
8195 if (index
>= 0) _cur
.grffile
->cargo_map
[c
] = index
;
8201 * Prepare loading a NewGRF file with its config
8202 * @param config The NewGRF configuration struct with name, id, parameters and alike.
8204 static void InitNewGRFFile(const GRFConfig
*config
)
8206 GRFFile
*newfile
= GetFileByFilename(config
->filename
);
8207 if (newfile
!= NULL
) {
8208 /* We already loaded it once. */
8209 _cur
.grffile
= newfile
;
8213 newfile
= new GRFFile(config
);
8214 *_grf_files
.Append() = _cur
.grffile
= newfile
;
8218 * Constructor for GRFFile
8219 * @param config GRFConfig to copy name, grfid and parameters from.
8221 GRFFile::GRFFile(const GRFConfig
*config
)
8223 this->filename
= stredup(config
->filename
);
8224 this->grfid
= config
->ident
.grfid
;
8226 /* Initialise local settings to defaults */
8227 this->traininfo_vehicle_pitch
= 0;
8228 this->traininfo_vehicle_width
= TRAININFO_DEFAULT_VEHICLE_WIDTH
;
8230 /* Mark price_base_multipliers as 'not set' */
8231 for (Price i
= PR_BEGIN
; i
< PR_END
; i
++) {
8232 this->price_base_multipliers
[i
] = INVALID_PRICE_MODIFIER
;
8235 /* Initialise rail type map with default rail types */
8236 memset(this->railtype_map
, INVALID_RAILTYPE
, sizeof(this->railtype_map
));
8237 this->railtype_map
[0] = RAILTYPE_RAIL
;
8238 this->railtype_map
[1] = RAILTYPE_ELECTRIC
;
8239 this->railtype_map
[2] = RAILTYPE_MONO
;
8240 this->railtype_map
[3] = RAILTYPE_MAGLEV
;
8242 /* Copy the initial parameter list
8243 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8244 assert_compile(lengthof(this->param
) == lengthof(config
->param
) && lengthof(this->param
) == 0x80);
8246 assert(config
->num_params
<= lengthof(config
->param
));
8247 this->param_end
= config
->num_params
;
8248 if (this->param_end
> 0) {
8249 MemCpyT(this->param
, config
->param
, this->param_end
);
8255 free(this->filename
);
8256 delete[] this->language_map
;
8261 * List of what cargo labels are refittable for the given the vehicle-type.
8262 * Only currently active labels are applied.
8264 static const CargoLabel _default_refitmasks_rail
[] = {
8265 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8266 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8267 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8271 static const CargoLabel _default_refitmasks_road
[] = {
8274 static const CargoLabel _default_refitmasks_ships
[] = {
8275 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8276 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8277 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8281 static const CargoLabel _default_refitmasks_aircraft
[] = {
8282 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8283 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8286 static const CargoLabel
* const _default_refitmasks
[] = {
8287 _default_refitmasks_rail
,
8288 _default_refitmasks_road
,
8289 _default_refitmasks_ships
,
8290 _default_refitmasks_aircraft
,
8295 * Precalculate refit masks from cargo classes for all vehicles.
8297 static void CalculateRefitMasks()
8301 FOR_ALL_ENGINES(e
) {
8302 EngineID engine
= e
->index
;
8303 EngineInfo
*ei
= &e
->info
;
8304 bool only_defaultcargo
; ///< Set if the vehicle shall carry only the default cargo
8306 /* Did the newgrf specify any refitting? If not, use defaults. */
8307 if (_gted
[engine
].refittability
!= GRFTempEngineData::UNSET
) {
8309 uint32 not_mask
= 0;
8310 uint32 xor_mask
= ei
->refit_mask
;
8312 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8313 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8314 only_defaultcargo
= _gted
[engine
].refittability
== GRFTempEngineData::EMPTY
;
8316 if (_gted
[engine
].cargo_allowed
!= 0) {
8317 /* Build up the list of cargo types from the set cargo classes. */
8318 const CargoSpec
*cs
;
8319 FOR_ALL_CARGOSPECS(cs
) {
8320 if (_gted
[engine
].cargo_allowed
& cs
->classes
) SetBit(mask
, cs
->Index());
8321 if (_gted
[engine
].cargo_disallowed
& cs
->classes
) SetBit(not_mask
, cs
->Index());
8325 ei
->refit_mask
= ((mask
& ~not_mask
) ^ xor_mask
) & _cargo_mask
;
8327 /* Apply explicit refit includes/excludes. */
8328 ei
->refit_mask
|= _gted
[engine
].ctt_include_mask
;
8329 ei
->refit_mask
&= ~_gted
[engine
].ctt_exclude_mask
;
8331 uint32 xor_mask
= 0;
8333 /* Don't apply default refit mask to wagons nor engines with no capacity */
8334 if (e
->type
!= VEH_TRAIN
|| (e
->u
.rail
.capacity
!= 0 && e
->u
.rail
.railveh_type
!= RAILVEH_WAGON
)) {
8335 const CargoLabel
*cl
= _default_refitmasks
[e
->type
];
8336 for (uint i
= 0;; i
++) {
8337 if (cl
[i
] == 0) break;
8339 CargoID cargo
= GetCargoIDByLabel(cl
[i
]);
8340 if (cargo
== CT_INVALID
) continue;
8342 SetBit(xor_mask
, cargo
);
8346 ei
->refit_mask
= xor_mask
& _cargo_mask
;
8348 /* If the mask is zero, the vehicle shall only carry the default cargo */
8349 only_defaultcargo
= (ei
->refit_mask
== 0);
8352 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8353 if (!HasBit(_cargo_mask
, ei
->cargo_type
)) ei
->cargo_type
= CT_INVALID
;
8355 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8356 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8357 if (!only_defaultcargo
&& (e
->type
!= VEH_SHIP
|| e
->u
.ship
.old_refittable
) && ei
->cargo_type
!= CT_INVALID
&& !HasBit(ei
->refit_mask
, ei
->cargo_type
)) {
8358 ei
->cargo_type
= CT_INVALID
;
8361 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8362 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8363 if (ei
->cargo_type
== CT_INVALID
&& ei
->refit_mask
!= 0) {
8364 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8365 const uint8
*cargo_map_for_first_refittable
= NULL
;
8367 const GRFFile
*file
= _gted
[engine
].defaultcargo_grf
;
8368 if (file
== NULL
) file
= e
->GetGRF();
8369 if (file
!= NULL
&& file
->grf_version
>= 8 && file
->cargo_list
.Length() != 0) {
8370 cargo_map_for_first_refittable
= file
->cargo_map
;
8374 if (cargo_map_for_first_refittable
!= NULL
) {
8375 /* Use first refittable cargo from cargo translation table */
8376 byte best_local_slot
= 0xFF;
8378 FOR_EACH_SET_CARGO_ID(cargo_type
, ei
->refit_mask
) {
8379 byte local_slot
= cargo_map_for_first_refittable
[cargo_type
];
8380 if (local_slot
< best_local_slot
) {
8381 best_local_slot
= local_slot
;
8382 ei
->cargo_type
= cargo_type
;
8387 if (ei
->cargo_type
== CT_INVALID
) {
8388 /* Use first refittable cargo slot */
8389 ei
->cargo_type
= (CargoID
)FindFirstBit(ei
->refit_mask
);
8392 if (ei
->cargo_type
== CT_INVALID
) ei
->climates
= 0;
8394 /* Clear refit_mask for not refittable ships */
8395 if (e
->type
== VEH_SHIP
&& !e
->u
.ship
.old_refittable
) {
8401 /** Set to use the correct action0 properties for each canal feature */
8402 static void FinaliseCanals()
8404 for (uint i
= 0; i
< CF_END
; i
++) {
8405 if (_water_feature
[i
].grffile
!= NULL
) {
8406 _water_feature
[i
].callback_mask
= _water_feature
[i
].grffile
->canal_local_properties
[i
].callback_mask
;
8407 _water_feature
[i
].flags
= _water_feature
[i
].grffile
->canal_local_properties
[i
].flags
;
8412 /** Check for invalid engines */
8413 static void FinaliseEngineArray()
8417 FOR_ALL_ENGINES(e
) {
8418 if (e
->GetGRF() == NULL
) {
8419 const EngineIDMapping
&eid
= _engine_mngr
[e
->index
];
8420 if (eid
.grfid
!= INVALID_GRFID
|| eid
.internal_id
!= eid
.substitute_id
) {
8421 e
->info
.string_id
= STR_NEWGRF_INVALID_ENGINE
;
8425 /* When the train does not set property 27 (misc flags), but it
8426 * is overridden by a NewGRF graphically we want to disable the
8427 * flipping possibility. */
8428 if (e
->type
== VEH_TRAIN
&& !_gted
[e
->index
].prop27_set
&& e
->GetGRF() != NULL
&& is_custom_sprite(e
->u
.rail
.image_index
)) {
8429 ClrBit(e
->info
.misc_flags
, EF_RAIL_FLIPS
);
8432 /* Skip wagons, there livery is defined via the engine */
8433 if (e
->type
!= VEH_TRAIN
|| e
->u
.rail
.railveh_type
!= RAILVEH_WAGON
) {
8434 LiveryScheme ls
= GetEngineLiveryScheme(e
->index
, INVALID_ENGINE
, NULL
);
8435 SetBit(_loaded_newgrf_features
.used_liveries
, ls
);
8436 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8438 if (e
->type
== VEH_TRAIN
) {
8439 SetBit(_loaded_newgrf_features
.used_liveries
, LS_FREIGHT_WAGON
);
8446 SetBit(_loaded_newgrf_features
.used_liveries
, LS_PASSENGER_WAGON_STEAM
+ ls
- LS_STEAM
);
8451 SetBit(_loaded_newgrf_features
.used_liveries
, LS_PASSENGER_WAGON_DIESEL
+ ls
- LS_DMU
);
8454 default: NOT_REACHED();
8461 /** Check for invalid cargoes */
8462 static void FinaliseCargoArray()
8464 for (CargoID c
= 0; c
< NUM_CARGO
; c
++) {
8465 CargoSpec
*cs
= CargoSpec::Get(c
);
8466 if (!cs
->IsValid()) {
8467 cs
->name
= cs
->name_single
= cs
->units_volume
= STR_NEWGRF_INVALID_CARGO
;
8468 cs
->quantifier
= STR_NEWGRF_INVALID_CARGO_QUANTITY
;
8469 cs
->abbrev
= STR_NEWGRF_INVALID_CARGO_ABBREV
;
8475 * Check if a given housespec is valid and disable it if it's not.
8476 * The housespecs that follow it are used to check the validity of
8478 * @param hs The housespec to check.
8479 * @param next1 The housespec that follows \c hs.
8480 * @param next2 The housespec that follows \c next1.
8481 * @param next3 The housespec that follows \c next2.
8482 * @param filename The filename of the newgrf this house was defined in.
8483 * @return Whether the given housespec is valid.
8485 static bool IsHouseSpecValid(HouseSpec
*hs
, const HouseSpec
*next1
, const HouseSpec
*next2
, const HouseSpec
*next3
, const char *filename
)
8487 if (((hs
->building_flags
& BUILDING_HAS_2_TILES
) != 0 &&
8488 (next1
== NULL
|| !next1
->enabled
|| (next1
->building_flags
& BUILDING_HAS_1_TILE
) != 0)) ||
8489 ((hs
->building_flags
& BUILDING_HAS_4_TILES
) != 0 &&
8490 (next2
== NULL
|| !next2
->enabled
|| (next2
->building_flags
& BUILDING_HAS_1_TILE
) != 0 ||
8491 next3
== NULL
|| !next3
->enabled
|| (next3
->building_flags
& BUILDING_HAS_1_TILE
) != 0))) {
8492 hs
->enabled
= false;
8493 if (filename
!= NULL
) DEBUG(grf
, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", filename
, hs
->grf_prop
.local_id
);
8497 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8498 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8499 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8500 if (((hs
->building_flags
& BUILDING_HAS_2_TILES
) != 0 && next1
->population
!= 0) ||
8501 ((hs
->building_flags
& BUILDING_HAS_4_TILES
) != 0 && (next2
->population
!= 0 || next3
->population
!= 0))) {
8502 hs
->enabled
= false;
8503 if (filename
!= NULL
) DEBUG(grf
, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", filename
, hs
->grf_prop
.local_id
);
8507 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8508 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8509 if (filename
!= NULL
&& (hs
->building_flags
& BUILDING_HAS_1_TILE
) != (HouseSpec::Get(hs
->grf_prop
.subst_id
)->building_flags
& BUILDING_HAS_1_TILE
)) {
8510 hs
->enabled
= false;
8511 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
);
8515 /* Make sure that additional parts of multitile houses are not available. */
8516 if ((hs
->building_flags
& BUILDING_HAS_1_TILE
) == 0 && (hs
->building_availability
& HZ_ZONALL
) != 0 && (hs
->building_availability
& HZ_CLIMALL
) != 0) {
8517 hs
->enabled
= false;
8518 if (filename
!= NULL
) DEBUG(grf
, 1, "FinaliseHouseArray: %s defines house %d without a size but marked it as available. Disabling house.", filename
, hs
->grf_prop
.local_id
);
8526 * Make sure there is at least one house available in the year 0 for the given
8527 * climate / housezone combination.
8528 * @param bitmask The climate and housezone to check for. Exactly one climate
8529 * bit and one housezone bit should be set.
8531 static void EnsureEarlyHouse(HouseZones bitmask
)
8533 Year min_year
= MAX_YEAR
;
8535 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8536 HouseSpec
*hs
= HouseSpec::Get(i
);
8537 if (hs
== NULL
|| !hs
->enabled
) continue;
8538 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
8539 if (hs
->min_year
< min_year
) min_year
= hs
->min_year
;
8542 if (min_year
== 0) return;
8544 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8545 HouseSpec
*hs
= HouseSpec::Get(i
);
8546 if (hs
== NULL
|| !hs
->enabled
) continue;
8547 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
8548 if (hs
->min_year
== min_year
) hs
->min_year
= 0;
8553 * Add all new houses to the house array. House properties can be set at any
8554 * time in the GRF file, so we can only add a house spec to the house array
8555 * after the file has finished loading. We also need to check the dates, due to
8556 * the TTDPatch behaviour described below that we need to emulate.
8558 static void FinaliseHouseArray()
8560 /* If there are no houses with start dates before 1930, then all houses
8561 * with start dates of 1930 have them reset to 0. This is in order to be
8562 * compatible with TTDPatch, where if no houses have start dates before
8563 * 1930 and the date is before 1930, the game pretends that this is 1930.
8564 * If there have been any houses defined with start dates before 1930 then
8565 * the dates are left alone.
8566 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8567 * minimum introduction date to 0.
8569 const GRFFile
* const *end
= _grf_files
.End();
8570 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8571 HouseSpec
**&housespec
= (*file
)->housespec
;
8572 if (housespec
== NULL
) continue;
8574 for (int i
= 0; i
< NUM_HOUSES_PER_GRF
; i
++) {
8575 HouseSpec
*hs
= housespec
[i
];
8577 if (hs
== NULL
) continue;
8579 const HouseSpec
*next1
= (i
+ 1 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 1] : NULL
);
8580 const HouseSpec
*next2
= (i
+ 2 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 2] : NULL
);
8581 const HouseSpec
*next3
= (i
+ 3 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 3] : NULL
);
8583 if (!IsHouseSpecValid(hs
, next1
, next2
, next3
, (*file
)->filename
)) continue;
8585 _house_mngr
.SetEntitySpec(hs
);
8589 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8590 HouseSpec
*hs
= HouseSpec::Get(i
);
8591 const HouseSpec
*next1
= (i
+ 1 < NUM_HOUSES
? HouseSpec::Get(i
+ 1) : NULL
);
8592 const HouseSpec
*next2
= (i
+ 2 < NUM_HOUSES
? HouseSpec::Get(i
+ 2) : NULL
);
8593 const HouseSpec
*next3
= (i
+ 3 < NUM_HOUSES
? HouseSpec::Get(i
+ 3) : NULL
);
8595 /* We need to check all houses again to we are sure that multitile houses
8596 * did get consecutive IDs and none of the parts are missing. */
8597 if (!IsHouseSpecValid(hs
, next1
, next2
, next3
, NULL
)) {
8598 /* GetHouseNorthPart checks 3 houses that are directly before
8599 * it in the house pool. If any of those houses have multi-tile
8600 * flags set it assumes it's part of a multitile house. Since
8601 * we can have invalid houses in the pool marked as disabled, we
8602 * don't want to have them influencing valid tiles. As such set
8603 * building_flags to zero here to make sure any house following
8604 * this one in the pool is properly handled as 1x1 house. */
8605 hs
->building_flags
= TILE_NO_FLAG
;
8609 HouseZones climate_mask
= (HouseZones
)(1 << (_settings_game
.game_creation
.landscape
+ 12));
8610 EnsureEarlyHouse(HZ_ZON1
| climate_mask
);
8611 EnsureEarlyHouse(HZ_ZON2
| climate_mask
);
8612 EnsureEarlyHouse(HZ_ZON3
| climate_mask
);
8613 EnsureEarlyHouse(HZ_ZON4
| climate_mask
);
8614 EnsureEarlyHouse(HZ_ZON5
| climate_mask
);
8616 if (_settings_game
.game_creation
.landscape
== LT_ARCTIC
) {
8617 EnsureEarlyHouse(HZ_ZON1
| HZ_SUBARTC_ABOVE
);
8618 EnsureEarlyHouse(HZ_ZON2
| HZ_SUBARTC_ABOVE
);
8619 EnsureEarlyHouse(HZ_ZON3
| HZ_SUBARTC_ABOVE
);
8620 EnsureEarlyHouse(HZ_ZON4
| HZ_SUBARTC_ABOVE
);
8621 EnsureEarlyHouse(HZ_ZON5
| HZ_SUBARTC_ABOVE
);
8626 * Add all new industries to the industry array. Industry properties can be set at any
8627 * time in the GRF file, so we can only add a industry spec to the industry array
8628 * after the file has finished loading.
8630 static void FinaliseIndustriesArray()
8632 const GRFFile
* const *end
= _grf_files
.End();
8633 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8634 IndustrySpec
**&industryspec
= (*file
)->industryspec
;
8635 IndustryTileSpec
**&indtspec
= (*file
)->indtspec
;
8636 if (industryspec
!= NULL
) {
8637 for (int i
= 0; i
< NUM_INDUSTRYTYPES_PER_GRF
; i
++) {
8638 IndustrySpec
*indsp
= industryspec
[i
];
8640 if (indsp
!= NULL
&& indsp
->enabled
) {
8642 /* process the conversion of text at the end, so to be sure everything will be fine
8643 * and available. Check if it does not return undefind marker, which is a very good sign of a
8644 * substitute industry who has not changed the string been examined, thus using it as such */
8645 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->name
);
8646 if (strid
!= STR_UNDEFINED
) indsp
->name
= strid
;
8648 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->closure_text
);
8649 if (strid
!= STR_UNDEFINED
) indsp
->closure_text
= strid
;
8651 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->production_up_text
);
8652 if (strid
!= STR_UNDEFINED
) indsp
->production_up_text
= strid
;
8654 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->production_down_text
);
8655 if (strid
!= STR_UNDEFINED
) indsp
->production_down_text
= strid
;
8657 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->new_industry_text
);
8658 if (strid
!= STR_UNDEFINED
) indsp
->new_industry_text
= strid
;
8660 if (indsp
->station_name
!= STR_NULL
) {
8661 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8662 * station's name. Don't want to lose the value, therefore, do not process. */
8663 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->station_name
);
8664 if (strid
!= STR_UNDEFINED
) indsp
->station_name
= strid
;
8667 _industry_mngr
.SetEntitySpec(indsp
);
8668 _loaded_newgrf_features
.has_newindustries
= true;
8673 if (indtspec
!= NULL
) {
8674 for (int i
= 0; i
< NUM_INDUSTRYTILES_PER_GRF
; i
++) {
8675 IndustryTileSpec
*indtsp
= indtspec
[i
];
8676 if (indtsp
!= NULL
) {
8677 _industile_mngr
.SetEntitySpec(indtsp
);
8683 for (uint j
= 0; j
< NUM_INDUSTRYTYPES
; j
++) {
8684 IndustrySpec
*indsp
= &_industry_specs
[j
];
8685 if (indsp
->enabled
&& indsp
->grf_prop
.grffile
!= NULL
) {
8686 for (uint i
= 0; i
< 3; i
++) {
8687 indsp
->conflicting
[i
] = MapNewGRFIndustryType(indsp
->conflicting
[i
], indsp
->grf_prop
.grffile
->grfid
);
8690 if (!indsp
->enabled
) {
8691 indsp
->name
= STR_NEWGRF_INVALID_INDUSTRYTYPE
;
8697 * Add all new objects to the object array. Object properties can be set at any
8698 * time in the GRF file, so we can only add an object spec to the object array
8699 * after the file has finished loading.
8701 static void FinaliseObjectsArray()
8703 const GRFFile
* const *end
= _grf_files
.End();
8704 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8705 ObjectSpec
**&objectspec
= (*file
)->objectspec
;
8706 if (objectspec
!= NULL
) {
8707 for (int i
= 0; i
< NUM_OBJECTS_PER_GRF
; i
++) {
8708 if (objectspec
[i
] != NULL
&& objectspec
[i
]->grf_prop
.grffile
!= NULL
&& objectspec
[i
]->enabled
) {
8709 _object_mngr
.SetEntitySpec(objectspec
[i
]);
8717 * Add all new airports to the airport array. Airport properties can be set at any
8718 * time in the GRF file, so we can only add a airport spec to the airport array
8719 * after the file has finished loading.
8721 static void FinaliseAirportsArray()
8723 const GRFFile
* const *end
= _grf_files
.End();
8724 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8725 AirportSpec
**&airportspec
= (*file
)->airportspec
;
8726 if (airportspec
!= NULL
) {
8727 for (int i
= 0; i
< NUM_AIRPORTS_PER_GRF
; i
++) {
8728 if (airportspec
[i
] != NULL
&& airportspec
[i
]->enabled
) {
8729 _airport_mngr
.SetEntitySpec(airportspec
[i
]);
8734 AirportTileSpec
**&airporttilespec
= (*file
)->airtspec
;
8735 if (airporttilespec
!= NULL
) {
8736 for (uint i
= 0; i
< NUM_AIRPORTTILES_PER_GRF
; i
++) {
8737 if (airporttilespec
[i
] != NULL
&& airporttilespec
[i
]->enabled
) {
8738 _airporttile_mngr
.SetEntitySpec(airporttilespec
[i
]);
8745 /* Here we perform initial decoding of some special sprites (as are they
8746 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8747 * partial implementation yet).
8748 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8749 * a crafted invalid GRF file. We should tell that to the user somehow, or
8750 * better make this more robust in the future. */
8751 static void DecodeSpecialSprite(byte
*buf
, uint num
, GrfLoadingStage stage
)
8753 /* XXX: There is a difference between staged loading in TTDPatch and
8754 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8755 * during stage 1, whilst action 3 is carried out during stage 2 (to
8756 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8757 * IDs are valid only within a given set (action 1) block, and may be
8758 * overwritten after action 3 associates them. But overwriting happens
8759 * in an earlier stage than associating, so... We just process actions
8760 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8762 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8763 * is not in memory and scanning the file every time would be too expensive.
8764 * In other stages we skip action 0x10 since it's already dealt with. */
8765 static const SpecialSpriteHandler handlers
[][GLS_END
] = {
8766 /* 0x00 */ { NULL
, SafeChangeInfo
, NULL
, NULL
, ReserveChangeInfo
, FeatureChangeInfo
, },
8767 /* 0x01 */ { SkipAct1
, SkipAct1
, SkipAct1
, SkipAct1
, SkipAct1
, NewSpriteSet
, },
8768 /* 0x02 */ { NULL
, NULL
, NULL
, NULL
, NULL
, NewSpriteGroup
, },
8769 /* 0x03 */ { NULL
, GRFUnsafe
, NULL
, NULL
, NULL
, FeatureMapSpriteGroup
, },
8770 /* 0x04 */ { NULL
, NULL
, NULL
, NULL
, NULL
, FeatureNewName
, },
8771 /* 0x05 */ { SkipAct5
, SkipAct5
, SkipAct5
, SkipAct5
, SkipAct5
, GraphicsNew
, },
8772 /* 0x06 */ { NULL
, NULL
, NULL
, CfgApply
, CfgApply
, CfgApply
, },
8773 /* 0x07 */ { NULL
, NULL
, NULL
, NULL
, SkipIf
, SkipIf
, },
8774 /* 0x08 */ { ScanInfo
, NULL
, NULL
, GRFInfo
, GRFInfo
, GRFInfo
, },
8775 /* 0x09 */ { NULL
, NULL
, NULL
, SkipIf
, SkipIf
, SkipIf
, },
8776 /* 0x0A */ { SkipActA
, SkipActA
, SkipActA
, SkipActA
, SkipActA
, SpriteReplace
, },
8777 /* 0x0B */ { NULL
, NULL
, NULL
, GRFLoadError
, GRFLoadError
, GRFLoadError
, },
8778 /* 0x0C */ { NULL
, NULL
, NULL
, GRFComment
, NULL
, GRFComment
, },
8779 /* 0x0D */ { NULL
, SafeParamSet
, NULL
, ParamSet
, ParamSet
, ParamSet
, },
8780 /* 0x0E */ { NULL
, SafeGRFInhibit
, NULL
, GRFInhibit
, GRFInhibit
, GRFInhibit
, },
8781 /* 0x0F */ { NULL
, GRFUnsafe
, NULL
, FeatureTownName
, NULL
, NULL
, },
8782 /* 0x10 */ { NULL
, NULL
, DefineGotoLabel
, NULL
, NULL
, NULL
, },
8783 /* 0x11 */ { SkipAct11
,GRFUnsafe
, SkipAct11
, GRFSound
, SkipAct11
, GRFSound
, },
8784 /* 0x12 */ { SkipAct12
, SkipAct12
, SkipAct12
, SkipAct12
, SkipAct12
, LoadFontGlyph
, },
8785 /* 0x13 */ { NULL
, NULL
, NULL
, NULL
, NULL
, TranslateGRFStrings
, },
8786 /* 0x14 */ { StaticGRFInfo
, NULL
, NULL
, NULL
, NULL
, NULL
, },
8789 GRFLocation
location(_cur
.grfconfig
->ident
.grfid
, _cur
.nfo_line
);
8791 GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.find(location
);
8792 if (it
== _grf_line_to_action6_sprite_override
.end()) {
8793 /* No preloaded sprite to work with; read the
8794 * pseudo sprite content. */
8795 FioReadBlock(buf
, num
);
8797 /* Use the preloaded sprite data. */
8798 buf
= _grf_line_to_action6_sprite_override
[location
];
8799 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8801 /* Skip the real (original) content of this action. */
8802 FioSeekTo(num
, SEEK_CUR
);
8805 ByteReader
br(buf
, buf
+ num
);
8806 ByteReader
*bufp
= &br
;
8809 byte action
= bufp
->ReadByte();
8811 if (action
== 0xFF) {
8812 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8813 } else if (action
== 0xFE) {
8814 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8815 } else if (action
>= lengthof(handlers
)) {
8816 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action
);
8817 } else if (handlers
[action
][stage
] == NULL
) {
8818 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action
, stage
);
8820 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action
, stage
);
8821 handlers
[action
][stage
](bufp
);
8824 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8825 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS
);
8830 /** Signature of a container version 2 GRF. */
8831 extern const byte _grf_cont_v2_sig
[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8834 * Get the container version of the currently opened GRF file.
8835 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
8837 byte
GetGRFContainerVersion()
8839 size_t pos
= FioGetPos();
8841 if (FioReadWord() == 0) {
8842 /* Check for GRF container version 2, which is identified by the bytes
8843 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8844 for (uint i
= 0; i
< lengthof(_grf_cont_v2_sig
); i
++) {
8845 if (FioReadByte() != _grf_cont_v2_sig
[i
]) return 0; // Invalid format
8851 /* Container version 1 has no header, rewind to start. */
8852 FioSeekTo(pos
, SEEK_SET
);
8857 * Load a particular NewGRF.
8858 * @param config The configuration of the to be loaded NewGRF.
8859 * @param file_index The Fio index of the first NewGRF to load.
8860 * @param stage The loading stage of the NewGRF.
8861 * @param subdir The sub directory to find the NewGRF in.
8863 void LoadNewGRFFile(GRFConfig
*config
, uint file_index
, GrfLoadingStage stage
, Subdirectory subdir
)
8865 const char *filename
= config
->filename
;
8867 /* A .grf file is activated only if it was active when the game was
8868 * started. If a game is loaded, only its active .grfs will be
8869 * reactivated, unless "loadallgraphics on" is used. A .grf file is
8870 * considered active if its action 8 has been processed, i.e. its
8871 * action 8 hasn't been skipped using an action 7.
8873 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
8874 * carried out. All others are ignored, because they only need to be
8875 * processed once at initialization. */
8876 if (stage
!= GLS_FILESCAN
&& stage
!= GLS_SAFETYSCAN
&& stage
!= GLS_LABELSCAN
) {
8877 _cur
.grffile
= GetFileByFilename(filename
);
8878 if (_cur
.grffile
== NULL
) usererror("File '%s' lost in cache.\n", filename
);
8879 if (stage
== GLS_RESERVE
&& config
->status
!= GCS_INITIALISED
) return;
8880 if (stage
== GLS_ACTIVATION
&& !HasBit(config
->flags
, GCF_RESERVED
)) return;
8883 if (file_index
>= MAX_FILE_SLOTS
) {
8884 DEBUG(grf
, 0, "'%s' is not loaded as the maximum number of file slots has been reached", filename
);
8885 config
->status
= GCS_DISABLED
;
8886 config
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED
);
8890 FioOpenFile(file_index
, filename
, subdir
);
8891 _cur
.file_index
= file_index
; // XXX
8892 _palette_remap_grf
[_cur
.file_index
] = (config
->palette
& GRFP_USE_MASK
);
8894 _cur
.grfconfig
= config
;
8896 DEBUG(grf
, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename
);
8898 _cur
.grf_container_ver
= GetGRFContainerVersion();
8899 if (_cur
.grf_container_ver
== 0) {
8900 DEBUG(grf
, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8904 if (stage
== GLS_INIT
|| stage
== GLS_ACTIVATION
) {
8905 /* We need the sprite offsets in the init stage for NewGRF sounds
8906 * and in the activation stage for real sprites. */
8907 ReadGRFSpriteOffsets(_cur
.grf_container_ver
);
8909 /* Skip sprite section offset if present. */
8910 if (_cur
.grf_container_ver
>= 2) FioReadDword();
8913 if (_cur
.grf_container_ver
>= 2) {
8914 /* Read compression value. */
8915 byte compression
= FioReadByte();
8916 if (compression
!= 0) {
8917 DEBUG(grf
, 7, "LoadNewGRFFile: Unsupported compression format");
8922 /* Skip the first sprite; we don't care about how many sprites this
8923 * does contain; newest TTDPatches and George's longvehicles don't
8924 * neither, apparently. */
8925 uint32 num
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
8926 if (num
== 4 && FioReadByte() == 0xFF) {
8929 DEBUG(grf
, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8933 _cur
.ClearDataForNextFile();
8935 ReusableBuffer
<byte
> buf
;
8937 while ((num
= (_cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord())) != 0) {
8938 byte type
= FioReadByte();
8942 if (_cur
.skip_sprites
== 0) {
8943 DecodeSpecialSprite(buf
.Allocate(num
), num
, stage
);
8945 /* Stop all processing if we are to skip the remaining sprites */
8946 if (_cur
.skip_sprites
== -1) break;
8953 if (_cur
.skip_sprites
== 0) {
8954 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8955 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE
);
8959 if (_cur
.grf_container_ver
>= 2 && type
== 0xFD) {
8960 /* Reference to data section. Container version >= 2 only. */
8964 SkipSpriteData(type
, num
- 8);
8968 if (_cur
.skip_sprites
> 0) _cur
.skip_sprites
--;
8973 * Relocates the old shore sprites at new positions.
8975 * 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)
8976 * 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)
8977 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
8979 static void ActivateOldShore()
8981 /* Use default graphics, if no shore sprites were loaded.
8982 * Should not happen, as the base set's extra grf should include some. */
8983 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_NONE
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_A
;
8985 if (_loaded_newgrf_features
.shore
!= SHORE_REPLACE_ACTION_5
) {
8986 DupSprite(SPR_ORIGINALSHORE_START
+ 1, SPR_SHORE_BASE
+ 1); // SLOPE_W
8987 DupSprite(SPR_ORIGINALSHORE_START
+ 2, SPR_SHORE_BASE
+ 2); // SLOPE_S
8988 DupSprite(SPR_ORIGINALSHORE_START
+ 6, SPR_SHORE_BASE
+ 3); // SLOPE_SW
8989 DupSprite(SPR_ORIGINALSHORE_START
+ 0, SPR_SHORE_BASE
+ 4); // SLOPE_E
8990 DupSprite(SPR_ORIGINALSHORE_START
+ 4, SPR_SHORE_BASE
+ 6); // SLOPE_SE
8991 DupSprite(SPR_ORIGINALSHORE_START
+ 3, SPR_SHORE_BASE
+ 8); // SLOPE_N
8992 DupSprite(SPR_ORIGINALSHORE_START
+ 7, SPR_SHORE_BASE
+ 9); // SLOPE_NW
8993 DupSprite(SPR_ORIGINALSHORE_START
+ 5, SPR_SHORE_BASE
+ 12); // SLOPE_NE
8996 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_ACTION_A
) {
8997 DupSprite(SPR_FLAT_GRASS_TILE
+ 16, SPR_SHORE_BASE
+ 0); // SLOPE_STEEP_S
8998 DupSprite(SPR_FLAT_GRASS_TILE
+ 17, SPR_SHORE_BASE
+ 5); // SLOPE_STEEP_W
8999 DupSprite(SPR_FLAT_GRASS_TILE
+ 7, SPR_SHORE_BASE
+ 7); // SLOPE_WSE
9000 DupSprite(SPR_FLAT_GRASS_TILE
+ 15, SPR_SHORE_BASE
+ 10); // SLOPE_STEEP_N
9001 DupSprite(SPR_FLAT_GRASS_TILE
+ 11, SPR_SHORE_BASE
+ 11); // SLOPE_NWS
9002 DupSprite(SPR_FLAT_GRASS_TILE
+ 13, SPR_SHORE_BASE
+ 13); // SLOPE_ENW
9003 DupSprite(SPR_FLAT_GRASS_TILE
+ 14, SPR_SHORE_BASE
+ 14); // SLOPE_SEN
9004 DupSprite(SPR_FLAT_GRASS_TILE
+ 18, SPR_SHORE_BASE
+ 15); // SLOPE_STEEP_E
9006 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
9007 * If they would be used somewhen, then these grass tiles will most like not look as needed */
9008 DupSprite(SPR_FLAT_GRASS_TILE
+ 5, SPR_SHORE_BASE
+ 16); // SLOPE_EW
9009 DupSprite(SPR_FLAT_GRASS_TILE
+ 10, SPR_SHORE_BASE
+ 17); // SLOPE_NS
9014 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
9016 static void FinalisePriceBaseMultipliers()
9018 extern const PriceBaseSpec _price_base_specs
[];
9019 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
9020 static const uint32 override_features
= (1 << GSF_TRAINS
) | (1 << GSF_ROADVEHICLES
) | (1 << GSF_SHIPS
) | (1 << GSF_AIRCRAFT
);
9022 /* Evaluate grf overrides */
9023 int num_grfs
= _grf_files
.Length();
9024 int *grf_overrides
= AllocaM(int, num_grfs
);
9025 for (int i
= 0; i
< num_grfs
; i
++) {
9026 grf_overrides
[i
] = -1;
9028 GRFFile
*source
= _grf_files
[i
];
9029 uint32 override
= _grf_id_overrides
[source
->grfid
];
9030 if (override
== 0) continue;
9032 GRFFile
*dest
= GetFileByGRFID(override
);
9033 if (dest
== NULL
) continue;
9035 grf_overrides
[i
] = _grf_files
.FindIndex(dest
);
9036 assert(grf_overrides
[i
] >= 0);
9039 /* Override features and price base multipliers of earlier loaded grfs */
9040 for (int i
= 0; i
< num_grfs
; i
++) {
9041 if (grf_overrides
[i
] < 0 || grf_overrides
[i
] >= i
) continue;
9042 GRFFile
*source
= _grf_files
[i
];
9043 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9045 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9046 source
->grf_features
|= features
;
9047 dest
->grf_features
|= features
;
9049 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9050 /* No price defined -> nothing to do */
9051 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
) || source
->price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) continue;
9052 DEBUG(grf
, 3, "'%s' overrides price base multiplier %d of '%s'", source
->filename
, p
, dest
->filename
);
9053 dest
->price_base_multipliers
[p
] = source
->price_base_multipliers
[p
];
9057 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9058 for (int i
= num_grfs
- 1; i
>= 0; i
--) {
9059 if (grf_overrides
[i
] < 0 || grf_overrides
[i
] <= i
) continue;
9060 GRFFile
*source
= _grf_files
[i
];
9061 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9063 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9064 source
->grf_features
|= features
;
9065 dest
->grf_features
|= features
;
9067 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9068 /* Already a price defined -> nothing to do */
9069 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
) || dest
->price_base_multipliers
[p
] != INVALID_PRICE_MODIFIER
) continue;
9070 DEBUG(grf
, 3, "Price base multiplier %d from '%s' propagated to '%s'", p
, source
->filename
, dest
->filename
);
9071 dest
->price_base_multipliers
[p
] = source
->price_base_multipliers
[p
];
9075 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9076 for (int i
= 0; i
< num_grfs
; i
++) {
9077 if (grf_overrides
[i
] < 0) continue;
9078 GRFFile
*source
= _grf_files
[i
];
9079 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9081 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9082 source
->grf_features
|= features
;
9083 dest
->grf_features
|= features
;
9085 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9086 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
)) continue;
9087 if (source
->price_base_multipliers
[p
] != dest
->price_base_multipliers
[p
]) {
9088 DEBUG(grf
, 3, "Price base multiplier %d from '%s' propagated to '%s'", p
, dest
->filename
, source
->filename
);
9090 source
->price_base_multipliers
[p
] = dest
->price_base_multipliers
[p
];
9094 /* Apply fallback prices for grf version < 8 */
9095 const GRFFile
* const *end
= _grf_files
.End();
9096 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
9097 if ((*file
)->grf_version
>= 8) continue;
9098 PriceMultipliers
&price_base_multipliers
= (*file
)->price_base_multipliers
;
9099 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9100 Price fallback_price
= _price_base_specs
[p
].fallback_price
;
9101 if (fallback_price
!= INVALID_PRICE
&& price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) {
9102 /* No price multiplier has been set.
9103 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9104 price_base_multipliers
[p
] = price_base_multipliers
[fallback_price
];
9109 /* Decide local/global scope of price base multipliers */
9110 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
9111 PriceMultipliers
&price_base_multipliers
= (*file
)->price_base_multipliers
;
9112 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9113 if (price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) {
9114 /* No multiplier was set; set it to a neutral value */
9115 price_base_multipliers
[p
] = 0;
9117 if (!HasBit((*file
)->grf_features
, _price_base_specs
[p
].grf_feature
)) {
9118 /* The grf does not define any objects of the feature,
9119 * so it must be a difficulty setting. Apply it globally */
9120 DEBUG(grf
, 3, "'%s' sets global price base multiplier %d", (*file
)->filename
, p
);
9121 SetPriceBaseMultiplier(p
, price_base_multipliers
[p
]);
9122 price_base_multipliers
[p
] = 0;
9124 DEBUG(grf
, 3, "'%s' sets local price base multiplier %d", (*file
)->filename
, p
);
9131 extern void InitGRFTownGeneratorNames();
9133 /** Finish loading NewGRFs and execute needed post-processing */
9134 static void AfterLoadGRFs()
9136 for (StringIDMapping
*it
= _string_to_grf_mapping
.Begin(); it
!= _string_to_grf_mapping
.End(); it
++) {
9137 *it
->target
= MapGRFStringID(it
->grfid
, it
->source
);
9139 _string_to_grf_mapping
.Clear();
9141 /* Free the action 6 override sprites. */
9142 for (GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.begin(); it
!= _grf_line_to_action6_sprite_override
.end(); it
++) {
9145 _grf_line_to_action6_sprite_override
.clear();
9147 /* Polish cargoes */
9148 FinaliseCargoArray();
9150 /* Pre-calculate all refit masks after loading GRF files. */
9151 CalculateRefitMasks();
9153 /* Polish engines */
9154 FinaliseEngineArray();
9156 /* Set the actually used Canal properties */
9159 /* Add all new houses to the house array. */
9160 FinaliseHouseArray();
9162 /* Add all new industries to the industry array. */
9163 FinaliseIndustriesArray();
9165 /* Add all new objects to the object array. */
9166 FinaliseObjectsArray();
9168 InitializeSortedCargoSpecs();
9170 /* Sort the list of industry types. */
9171 SortIndustryTypes();
9173 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9174 BuildIndustriesLegend();
9176 /* Build the routemap legend, based on the available cargos */
9177 BuildLinkStatsLegend();
9179 /* Add all new airports to the airports array. */
9180 FinaliseAirportsArray();
9183 /* Update the townname generators list */
9184 InitGRFTownGeneratorNames();
9186 /* Run all queued vehicle list order changes */
9187 CommitVehicleListOrderChanges();
9189 /* Load old shore sprites in new position, if they were replaced by ActionA */
9192 /* Set up custom rail types */
9196 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_ROAD
) {
9197 if (_gted
[e
->index
].rv_max_speed
!= 0) {
9198 /* Set RV maximum speed from the mph/0.8 unit value */
9199 e
->u
.road
.max_speed
= _gted
[e
->index
].rv_max_speed
* 4;
9203 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_TRAIN
) {
9204 RailType railtype
= GetRailTypeByLabel(_gted
[e
->index
].railtypelabel
);
9205 if (railtype
== INVALID_RAILTYPE
) {
9206 /* Rail type is not available, so disable this engine */
9207 e
->info
.climates
= 0;
9209 e
->u
.rail
.railtype
= railtype
;
9213 SetYearEngineAgingStops();
9215 FinalisePriceBaseMultipliers();
9217 /* Deallocate temporary loading data */
9219 _grm_sprites
.clear();
9223 * Load all the NewGRFs.
9224 * @param load_index The offset for the first sprite to add.
9225 * @param file_index The Fio index of the first NewGRF to load.
9226 * @param num_baseset Number of NewGRFs at the front of the list to look up in the baseset dir instead of the newgrf dir.
9228 void LoadNewGRF(uint load_index
, uint file_index
, uint num_baseset
)
9230 /* In case of networking we need to "sync" the start values
9231 * so all NewGRFs are loaded equally. For this we use the
9232 * start date of the game and we set the counters, etc. to
9233 * 0 so they're the same too. */
9235 Year year
= _cur_year
;
9236 DateFract date_fract
= _date_fract
;
9237 uint16 tick_counter
= _tick_counter
;
9238 byte display_opt
= _display_opt
;
9241 _cur_year
= _settings_game
.game_creation
.starting_year
;
9242 _date
= ConvertYMDToDate(_cur_year
, 0, 1);
9248 InitializeGRFSpecial();
9253 * Reset the status of all files, so we can 'retry' to load them.
9254 * This is needed when one for example rearranges the NewGRFs in-game
9255 * and a previously disabled NewGRF becomes useable. If it would not
9256 * be reset, the NewGRF would remain disabled even though it should
9257 * have been enabled.
9259 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9260 if (c
->status
!= GCS_NOT_FOUND
) c
->status
= GCS_UNKNOWN
;
9263 _cur
.spriteid
= load_index
;
9265 /* Load newgrf sprites
9266 * in each loading stage, (try to) open each file specified in the config
9267 * and load information from it. */
9268 for (GrfLoadingStage stage
= GLS_LABELSCAN
; stage
<= GLS_ACTIVATION
; stage
++) {
9269 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9270 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9271 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9272 if (c
->status
== GCS_ACTIVATED
) c
->status
= GCS_INITIALISED
;
9275 if (stage
== GLS_RESERVE
) {
9276 static const uint32 overrides
[][2] = {
9277 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9278 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9279 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9281 for (size_t i
= 0; i
< lengthof(overrides
); i
++) {
9282 SetNewGRFOverride(BSWAP32(overrides
[i
][0]), BSWAP32(overrides
[i
][1]));
9286 uint slot
= file_index
;
9287 uint num_non_static
= 0;
9290 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9291 if (c
->status
== GCS_DISABLED
|| c
->status
== GCS_NOT_FOUND
) continue;
9292 if (stage
> GLS_INIT
&& HasBit(c
->flags
, GCF_INIT_ONLY
)) continue;
9294 Subdirectory subdir
= slot
< file_index
+ num_baseset
? BASESET_DIR
: NEWGRF_DIR
;
9295 if (!FioCheckFileExists(c
->filename
, subdir
)) {
9296 DEBUG(grf
, 0, "NewGRF file is missing '%s'; disabling", c
->filename
);
9297 c
->status
= GCS_NOT_FOUND
;
9301 if (stage
== GLS_LABELSCAN
) InitNewGRFFile(c
);
9303 if (!HasBit(c
->flags
, GCF_STATIC
) && !HasBit(c
->flags
, GCF_SYSTEM
)) {
9304 if (num_non_static
== NETWORK_MAX_GRF_COUNT
) {
9305 DEBUG(grf
, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c
->filename
);
9306 c
->status
= GCS_DISABLED
;
9307 c
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED
);
9312 LoadNewGRFFile(c
, slot
++, stage
, subdir
);
9313 if (stage
== GLS_RESERVE
) {
9314 SetBit(c
->flags
, GCF_RESERVED
);
9315 } else if (stage
== GLS_ACTIVATION
) {
9316 ClrBit(c
->flags
, GCF_RESERVED
);
9317 assert(GetFileByGRFID(c
->ident
.grfid
) == _cur
.grffile
);
9318 ClearTemporaryNewGRFData(_cur
.grffile
);
9319 BuildCargoTranslationMap();
9320 DEBUG(sprite
, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur
.spriteid
);
9321 } else if (stage
== GLS_INIT
&& HasBit(c
->flags
, GCF_INIT_ONLY
)) {
9322 /* We're not going to activate this, so free whatever data we allocated */
9323 ClearTemporaryNewGRFData(_cur
.grffile
);
9328 /* Pseudo sprite processing is finished; free temporary stuff */
9329 _cur
.ClearDataForNextFile();
9331 /* Call any functions that should be run after GRFs have been loaded. */
9334 /* Now revert back to the original situation */
9337 _date_fract
= date_fract
;
9338 _tick_counter
= tick_counter
;
9339 _display_opt
= display_opt
;