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. */
17 #include "fileio_func.h"
18 #include "engine_func.h"
19 #include "engine_base.h"
22 #include "newgrf_engine.h"
23 #include "newgrf_text.h"
26 #include "landscape.h"
27 #include "newgrf_cargo.h"
28 #include "newgrf_house.h"
29 #include "newgrf_sound.h"
30 #include "newgrf_station.h"
31 #include "industrytype.h"
32 #include "newgrf_canal.h"
33 #include "newgrf_townname.h"
34 #include "newgrf_industries.h"
35 #include "newgrf_airporttiles.h"
36 #include "newgrf_airport.h"
37 #include "newgrf_object.h"
40 #include "strings_func.h"
41 #include "date_func.h"
43 #include "network/network.h"
45 #include "smallmap_gui.h"
48 #include "vehicle_func.h"
50 #include "vehicle_base.h"
52 #include "core/pointer.h"
54 #include "table/strings.h"
55 #include "table/build_industry.h"
57 /* TTDPatch extended GRF format codec
58 * (c) Petr Baudis 2004 (GPL'd)
59 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
61 * Contains portions of documentation by TTDPatch team.
62 * Thanks especially to Josef Drexler for the documentation as well as a lot
63 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
64 * served as subject to the initial testing of this codec. */
66 /** List of all loaded GRF files */
67 static SmallVector
<GRFFile
*, 16> _grf_files
;
69 /** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
70 byte _misc_grf_features
= 0;
72 /** 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
73 static uint32 _ttdpatch_flags
[8];
75 /** Indicates which are the newgrf features currently loaded ingame */
76 GRFLoadedFeatures _loaded_newgrf_features
;
78 static const uint MAX_SPRITEGROUP
= UINT8_MAX
; ///< Maximum GRF-local ID for a spritegroup.
80 /** Temporary data during loading of GRFs */
81 struct GrfProcessingState
{
83 /** Definition of a single Action1 spriteset */
85 SpriteID sprite
; ///< SpriteID of the first sprite of the set.
86 uint num_sprites
; ///< Number of sprites in the set.
89 /** Currently referenceable spritesets */
90 std::map
<uint
, SpriteSet
> spritesets
[GSF_END
];
94 GrfLoadingStage stage
; ///< Current loading stage
95 SpriteID spriteid
; ///< First available SpriteID for loading realsprites.
97 /* Local state in the file */
98 uint file_index
; ///< File index of currently processed GRF file.
99 GRFFile
*grffile
; ///< Currently processed GRF file.
100 GRFConfig
*grfconfig
; ///< Config of the currently processed GRF file.
101 uint32 nfo_line
; ///< Currently processed pseudo sprite number in the GRF.
102 byte grf_container_ver
; ///< Container format of the current GRF file.
104 /* Currently referenceable spritegroups */
105 SpriteGroup
*spritegroups
[MAX_SPRITEGROUP
+ 1];
107 /** Clear temporary data before processing the next file in the current loading stage */
108 void ClearDataForNextFile()
112 for (uint i
= 0; i
< GSF_END
; i
++) {
113 this->spritesets
[i
].clear();
116 memset(this->spritegroups
, 0, sizeof(this->spritegroups
));
120 * Records new spritesets.
121 * @param feature GrfSpecFeature the set is defined for.
122 * @param first_sprite SpriteID of the first sprite in the set.
123 * @param first_set First spriteset to define.
124 * @param numsets Number of sets to define.
125 * @param numents Number of sprites per set to define.
127 void AddSpriteSets(byte feature
, SpriteID first_sprite
, uint first_set
, uint numsets
, uint numents
)
129 assert(feature
< GSF_END
);
130 for (uint i
= 0; i
< numsets
; i
++) {
131 SpriteSet
&set
= this->spritesets
[feature
][first_set
+ i
];
132 set
.sprite
= first_sprite
+ i
* numents
;
133 set
.num_sprites
= numents
;
138 * Check whether there are any valid spritesets for a feature.
139 * @param feature GrfSpecFeature to check.
140 * @return true if there are any valid sets.
141 * @note Spritesets with zero sprites are valid to allow callback-failures.
143 bool HasValidSpriteSets(byte feature
) const
145 assert(feature
< GSF_END
);
146 return !this->spritesets
[feature
].empty();
150 * Check whether a specific set is defined.
151 * @param feature GrfSpecFeature to check.
152 * @param set Set to check.
153 * @return true if the set is valid.
154 * @note Spritesets with zero sprites are valid to allow callback-failures.
156 bool IsValidSpriteSet(byte feature
, uint set
) const
158 assert(feature
< GSF_END
);
159 return this->spritesets
[feature
].find(set
) != this->spritesets
[feature
].end();
163 * Returns the first sprite of a spriteset.
164 * @param feature GrfSpecFeature to query.
165 * @param set Set to query.
166 * @return First sprite of the set.
168 SpriteID
GetSprite(byte feature
, uint set
) const
170 assert(IsValidSpriteSet(feature
, set
));
171 return this->spritesets
[feature
].find(set
)->second
.sprite
;
175 * Returns the number of sprites in a spriteset
176 * @param feature GrfSpecFeature to query.
177 * @param set Set to query.
178 * @return Number of sprites in the set.
180 uint
GetNumEnts(byte feature
, uint set
) const
182 assert(IsValidSpriteSet(feature
, set
));
183 return this->spritesets
[feature
].find(set
)->second
.num_sprites
;
187 static GrfProcessingState _cur
;
191 * Helper to check whether an image index is valid for a particular NewGRF vehicle.
192 * @param <T> The type of vehicle.
193 * @param image_index The image index to check.
194 * @return True iff the image index is valid, or 0xFD (use new graphics).
196 template <VehicleType T
>
197 static inline bool IsValidNewGRFImageIndex(uint8 image_index
)
199 return image_index
== 0xFD || IsValidImageIndex
<T
>(image_index
);
202 /** Class to read from a NewGRF file */
209 ByteReader(byte
*data
, byte
*end
) : data(data
), end(end
) { }
211 class out_of_data
{ };
213 inline byte
ReadByte()
215 if (data
< end
) return *(data
)++;
221 uint16 val
= ReadByte();
222 return val
| (ReadByte() << 8);
225 uint16
ReadExtendedByte()
227 uint16 val
= ReadByte();
228 return val
== 0xFF ? ReadWord() : val
;
233 uint32 val
= ReadWord();
234 return val
| (ReadWord() << 16);
237 uint32
ReadVarSize(byte size
)
240 case 1: return ReadByte();
241 case 2: return ReadWord();
242 case 4: return ReadDWord();
249 const char *ReadString (void);
251 inline size_t Remaining() const
256 inline bool HasData(size_t count
= 1) const
258 return Remaining() >= count
;
261 uint32
PeekDWord() const
263 if (!HasData (4)) throw out_of_data();
264 return data
[0] | (data
[1] << 8) | (data
[2] << 16) | (data
[3] << 24);
267 inline void Skip(size_t len
)
270 /* It is valid to move the buffer to exactly the end of the data,
271 * as there may not be any more data read. */
272 if (data
> end
) throw out_of_data();
275 byte
*Dup (size_t len
)
277 if (!HasData (len
)) throw out_of_data();
279 byte
*p
= xmemdupt (data
, len
);
285 const char *ByteReader::ReadString (void)
287 const char *string
= reinterpret_cast<char *>(data
);
289 size_t remaining
= Remaining();
290 size_t string_length
= ttd_strnlen (string
, remaining
);
292 if (string_length
== remaining
) {
293 /* String was not NUL terminated, so make sure it is now. */
294 grfmsg(7, "String was not terminated with a zero byte.");
298 /* Increase the string length to include the NUL byte. */
300 data
+= string_length
;
306 typedef int (*SpecialSpriteHandler
) (ByteReader
*buf
);
308 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.
310 /** Temporary engine data used when loading only */
311 struct GRFTempEngineData
{
312 /** Summary state of refittability properties */
314 UNSET
= 0, ///< No properties assigned. Default refit masks shall be activated.
315 EMPTY
, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
316 NONEMPTY
, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
319 uint16 cargo_allowed
;
320 uint16 cargo_disallowed
;
321 RailTypeLabel railtypelabel
;
322 const GRFFile
*defaultcargo_grf
; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
323 Refittability refittability
; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
324 bool prop27_set
; ///< Did the NewGRF set property 27 (misc flags)?
325 uint8 rv_max_speed
; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
326 uint32 ctt_include_mask
; ///< Cargo types always included in the refit mask.
327 uint32 ctt_exclude_mask
; ///< Cargo types always excluded from the refit mask.
330 * Update the summary refittability on setting a refittability property.
331 * @param non_empty true if the GRF sets the vehicle to be refittable.
333 void UpdateRefittability(bool non_empty
)
336 this->refittability
= NONEMPTY
;
337 } else if (this->refittability
== UNSET
) {
338 this->refittability
= EMPTY
;
343 static GRFTempEngineData
*_gted
; ///< Temporary engine data used during NewGRF loading
346 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
347 * GRM for vehicles is only used if dynamic engine allocation is disabled,
348 * so 256 is the number of original engines. */
349 static uint32 _grm_engines
[256];
351 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
352 static uint32 _grm_cargoes
[NUM_CARGO
* 2];
358 GRFLocation(uint32 grfid
, uint32 nfoline
) : grfid(grfid
), nfoline(nfoline
) { }
360 bool operator<(const GRFLocation
&other
) const
362 return this->grfid
< other
.grfid
|| (this->grfid
== other
.grfid
&& this->nfoline
< other
.nfoline
);
365 bool operator == (const GRFLocation
&other
) const
367 return this->grfid
== other
.grfid
&& this->nfoline
== other
.nfoline
;
371 static std::map
<GRFLocation
, SpriteID
> _grm_sprites
;
372 typedef std::map
<GRFLocation
, ttd_unique_free_ptr
<byte
> > GRFLineToSpriteOverride
;
373 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override
;
376 * DEBUG() function dedicated to newGRF debugging messages
377 * Function is essentially the same as DEBUG(grf, severity, ...) with the
378 * addition of file:line information when parsing grf files.
379 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
380 * loading/parsing grf files, not for runtime debug messages as there
381 * is no file information available during that time.
382 * @param severity debugging severity level, see debug.h
383 * @param str message in printf() format
385 void CDECL
grfmsg(int severity
, const char *str
, ...)
391 bstrvfmt (buf
, str
, va
);
394 DEBUG(grf
, severity
, "[%s:%d] %s", _cur
.grfconfig
->filename
, _cur
.nfo_line
, buf
);
398 * Obtain a NewGRF file by its grfID
399 * @param grfid The grfID to obtain the file for
402 static GRFFile
*GetFileByGRFID(uint32 grfid
)
404 const GRFFile
* const *end
= _grf_files
.End();
405 for (GRFFile
* const *file
= _grf_files
.Begin(); file
!= end
; file
++) {
406 if ((*file
)->grfid
== grfid
) return *file
;
412 * Obtain a NewGRF file by its filename
413 * @param filename The filename to obtain the file for.
416 static GRFFile
*GetFileByFilename(const char *filename
)
418 const GRFFile
* const *end
= _grf_files
.End();
419 for (GRFFile
* const *file
= _grf_files
.Begin(); file
!= end
; file
++) {
420 if (strcmp((*file
)->filename
, filename
) == 0) return *file
;
425 /** Reset all NewGRFData that was used only while processing data */
426 static void ClearTemporaryNewGRFData(GRFFile
*gf
)
428 /* Clear the GOTO labels used for GRF processing */
429 for (GRFLabel
*l
= gf
->label
; l
!= NULL
;) {
430 GRFLabel
*l2
= l
->next
;
438 * Disable the GRF being loaded
439 * @param message Error message or STR_NULL.
440 * @return Error message of the GRF for further customisation.
442 static GRFError
*DisableCur (StringID message
= STR_NULL
)
444 GRFConfig
*config
= _cur
.grfconfig
;
446 config
->status
= GCS_DISABLED
;
447 if (_cur
.grffile
!= NULL
) ClearTemporaryNewGRFData (_cur
.grffile
);
449 if (message
!= STR_NULL
) {
450 delete config
->error
;
451 config
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, message
);
452 if (config
== _cur
.grfconfig
) config
->error
->param_value
[0] = _cur
.nfo_line
;
455 return config
->error
;
460 * @param message Error message.
461 * @param config GRFConfig to disable.
463 static void DisableGrf (StringID message
, GRFConfig
*config
)
465 assert (config
!= NULL
);
466 assert (config
!= _cur
.grfconfig
);
468 config
->status
= GCS_DISABLED
;
470 GRFFile
*file
= GetFileByGRFID (config
->ident
.grfid
);
471 if (file
!= NULL
) ClearTemporaryNewGRFData(file
);
473 delete config
->error
;
474 config
->error
= new GRFError (STR_NEWGRF_ERROR_MSG_FATAL
, message
);
475 config
->error
->data
= xstrdup (_cur
.grfconfig
->GetName());
479 * Information for mapping static StringIDs.
481 struct StringIDMapping
{
482 uint32 grfid
; ///< Source NewGRF.
483 StringID source
; ///< Source StringID (GRF local).
484 StringID
*target
; ///< Destination for mapping result.
486 typedef SmallVector
<StringIDMapping
, 16> StringIDMappingVector
;
487 static StringIDMappingVector _string_to_grf_mapping
;
490 * Record a static StringID for getting translated later.
491 * @param source Source StringID (GRF local).
492 * @param target Destination for the mapping result.
494 static void AddStringForMapping(StringID source
, StringID
*target
)
496 *target
= STR_UNDEFINED
;
497 StringIDMapping
*item
= _string_to_grf_mapping
.Append();
498 item
->grfid
= _cur
.grffile
->grfid
;
499 item
->source
= source
;
500 item
->target
= target
;
504 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
505 * string IDs, but only for the ones we are aware off; the rest
506 * like likely unused and will show a warning.
507 * @param str the string ID to convert
508 * @return the converted string ID
510 static StringID
TTDPStringIDToOTTDStringIDMapping(StringID str
)
512 /* StringID table for TextIDs 0x4E->0x6D */
513 static const StringID units_volume
[] = {
514 STR_ITEMS
, STR_PASSENGERS
, STR_TONS
, STR_BAGS
,
515 STR_LITERS
, STR_ITEMS
, STR_CRATES
, STR_TONS
,
516 STR_TONS
, STR_TONS
, STR_TONS
, STR_BAGS
,
517 STR_TONS
, STR_TONS
, STR_TONS
, STR_BAGS
,
518 STR_TONS
, STR_TONS
, STR_BAGS
, STR_LITERS
,
519 STR_TONS
, STR_LITERS
, STR_TONS
, STR_ITEMS
,
520 STR_BAGS
, STR_LITERS
, STR_TONS
, STR_ITEMS
,
521 STR_TONS
, STR_ITEMS
, STR_LITERS
, STR_ITEMS
524 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
525 assert(!IsInsideMM(str
, 0xD000, 0xD7FF));
527 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
528 assert_compile(stringend - stringid == end - begin); \
529 if (str >= begin && str <= end) return str + (stringid - begin)
531 /* We have some changes in our cargo strings, resulting in some missing. */
532 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING
, STR_CARGO_PLURAL_FIZZY_DRINKS
);
533 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING
, STR_CARGO_SINGULAR_FIZZY_DRINK
);
534 if (str
>= 0x004E && str
<= 0x006D) return units_volume
[str
- 0x004E];
535 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING
, STR_QUANTITY_FIZZY_DRINKS
);
536 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING
, STR_ABBREV_FIZZY_DRINKS
);
537 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE
, STR_COLOUR_WHITE
);
539 /* Map building names according to our lang file changes. There are several
540 * ranges of house ids, all of which need to be remapped to allow newgrfs
541 * to use original house names. */
542 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1
, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1
);
543 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1
, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1
);
544 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1
, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1
);
546 /* Same thing for industries */
547 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE
, STR_INDUSTRY_NAME_SUGAR_MINE
);
548 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION
, STR_NEWS_INDUSTRY_PLANTED
);
549 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL
, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES
);
550 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL
, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM
);
551 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL
, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM
);
554 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY
;
555 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED
;
556 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED
;
558 #undef TEXTID_TO_STRINGID
560 if (str
== STR_NULL
) return STR_EMPTY
;
562 DEBUG(grf
, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str
);
568 * Used when setting an object's property to map to the GRF's strings
569 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
570 * @param grfid Id of the grf file.
571 * @param str StringID that we want to have the equivalent in OoenTTD.
572 * @return The properly adjusted StringID.
574 StringID
MapGRFStringID(uint32 grfid
, StringID str
)
576 /* 0xD0 and 0xDC stand for all the TextIDs in the range
577 * of 0xD000 (misc graphics texts) and 0xDC00 (misc persistent texts).
578 * These strings are unique to each grf file, and thus require to be used with the
579 * grfid in which they are declared */
580 switch (GB(str
, 8, 8)) {
581 case 0xD0: case 0xD1: case 0xD2: case 0xD3:
583 return GetGRFStringID(grfid
, str
);
585 case 0xD4: case 0xD5: case 0xD6: case 0xD7:
586 /* Strings embedded via 0x81 have 0x400 added to them (no real
587 * explanation why...) */
588 return GetGRFStringID(grfid
, str
- 0x400);
593 return TTDPStringIDToOTTDStringIDMapping(str
);
596 static std::map
<uint32
, uint32
> _grf_id_overrides
;
599 * Set the override for a NewGRF
600 * @param source_grfid The grfID which wants to override another NewGRF.
601 * @param target_grfid The grfID which is being overridden.
603 static void SetNewGRFOverride(uint32 source_grfid
, uint32 target_grfid
)
605 _grf_id_overrides
[source_grfid
] = target_grfid
;
606 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid
), BSWAP32(target_grfid
));
610 * Returns the engine associated to a certain internal_id, resp. allocates it.
611 * @param file NewGRF that wants to change the engine.
612 * @param type Vehicle type.
613 * @param internal_id Engine ID inside the NewGRF.
614 * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04).
615 * @return The requested engine.
617 static Engine
*GetNewEngine(const GRFFile
*file
, VehicleType type
, uint16 internal_id
, bool static_access
= false)
619 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
620 * them use the same engine slots. */
621 uint32 scope_grfid
= INVALID_GRFID
; // If not using dynamic_engines, all newgrfs share their ID range
622 if (_settings_game
.vehicle
.dynamic_engines
) {
623 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
624 scope_grfid
= file
->grfid
;
625 uint32 override
= _grf_id_overrides
[file
->grfid
];
627 scope_grfid
= override
;
628 const GRFFile
*grf_match
= GetFileByGRFID(override
);
629 if (grf_match
== NULL
) {
630 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file
->grfid
), BSWAP32(override
));
632 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file
->grfid
), BSWAP32(override
));
636 /* Check if the engine is registered in the override manager */
637 EngineID engine
= _engine_mngr
.GetID(type
, internal_id
, scope_grfid
);
638 if (engine
!= INVALID_ENGINE
) {
639 Engine
*e
= Engine::Get(engine
);
640 if (e
->grf_prop
.grffile
== NULL
) e
->grf_prop
.grffile
= file
;
645 /* Check if there is an unreserved slot */
646 EngineID engine
= _engine_mngr
.GetID(type
, internal_id
, INVALID_GRFID
);
647 if (engine
!= INVALID_ENGINE
) {
648 Engine
*e
= Engine::Get(engine
);
650 if (e
->grf_prop
.grffile
== NULL
) {
651 e
->grf_prop
.grffile
= file
;
652 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e
->index
, BSWAP32(file
->grfid
), type
, internal_id
);
655 /* Reserve the engine slot */
656 if (!static_access
) {
657 EngineIDMapping
*eid
= _engine_mngr
.Get(engine
);
658 eid
->grfid
= scope_grfid
; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
664 if (static_access
) return NULL
;
666 if (!Engine::CanAllocateItem()) {
667 grfmsg(0, "Can't allocate any more engines");
671 size_t engine_pool_size
= Engine::GetPoolSize();
673 /* ... it's not, so create a new one based off an existing engine */
674 Engine
*e
= new Engine(type
, internal_id
);
675 e
->grf_prop
.grffile
= file
;
677 /* Reserve the engine slot */
678 assert(_engine_mngr
.Length() == e
->index
);
679 EngineIDMapping
*eid
= _engine_mngr
.Append();
681 eid
->grfid
= scope_grfid
; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
682 eid
->internal_id
= internal_id
;
683 eid
->substitute_id
= min(internal_id
, _engine_counts
[type
]); // substitute_id == _engine_counts[subtype] means "no substitute"
685 if (engine_pool_size
!= Engine::GetPoolSize()) {
686 /* Resize temporary engine data ... */
687 _gted
= xrealloct (_gted
, Engine::GetPoolSize());
689 /* and blank the new block. */
690 size_t len
= (Engine::GetPoolSize() - engine_pool_size
) * sizeof(*_gted
);
691 memset(_gted
+ engine_pool_size
, 0, len
);
693 if (type
== VEH_TRAIN
) {
694 _gted
[e
->index
].railtypelabel
= GetRailTypeInfo(e
->u
.rail
.railtype
)->label
;
697 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e
->index
, BSWAP32(file
->grfid
), type
, internal_id
);
703 * Return the ID of a new engine
704 * @param file The NewGRF file providing the engine.
705 * @param type The Vehicle type.
706 * @param internal_id NewGRF-internal ID of the engine.
707 * @return The new EngineID.
708 * @note depending on the dynamic_engine setting and a possible override
709 * property the grfID may be unique or overwriting or partially re-defining
710 * properties of an existing engine.
712 EngineID
GetNewEngineID(const GRFFile
*file
, VehicleType type
, uint16 internal_id
)
714 uint32 scope_grfid
= INVALID_GRFID
; // If not using dynamic_engines, all newgrfs share their ID range
715 if (_settings_game
.vehicle
.dynamic_engines
) {
716 scope_grfid
= file
->grfid
;
717 uint32 override
= _grf_id_overrides
[file
->grfid
];
718 if (override
!= 0) scope_grfid
= override
;
721 return _engine_mngr
.GetID(type
, internal_id
, scope_grfid
);
725 * Read a sprite and paletteD from the GRF and map the colour modifiers
726 * of TTDPatch to those that Open is using.
727 * @param buf Input stream.
728 * @param grf_sprite Pointer to the structure to read.
730 static void ReadPalSprite (ByteReader
*buf
, PalSpriteID
*grf_sprite
)
732 SpriteID sprite
= buf
->ReadWord();
733 PaletteID pal
= buf
->ReadWord();
735 if (HasBit(pal
, 14)) {
737 SetBit(sprite
, SPRITE_MODIFIER_OPAQUE
);
740 if (HasBit(sprite
, 14)) {
742 SetBit(sprite
, PALETTE_MODIFIER_TRANSPARENT
);
745 if (HasBit(sprite
, 15)) {
747 SetBit(sprite
, PALETTE_MODIFIER_COLOUR
);
750 grf_sprite
->sprite
= sprite
;
751 grf_sprite
->pal
= pal
;
755 * Read a sprite and a palette from the GRF and convert them into a format
756 * suitable to OpenTTD.
757 * @param buf Input stream.
758 * @param read_flags Whether to read TileLayoutFlags.
759 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
760 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
761 * @param feature GrfSpecFeature to use spritesets from.
762 * @param [out] grf_sprite Read sprite and palette.
763 * @param [out] pflags Read TileLayoutFlags.
764 * @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
765 * @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
766 * @return Whether reading succeeded.
768 static bool ReadSpriteLayoutSprite (ByteReader
*buf
, bool read_flags
,
769 bool invert_action1_flag
, bool use_cur_spritesets
, int feature
,
770 PalSpriteID
*grf_sprite
, TileLayoutFlags
*pflags
= NULL
,
771 uint16
*max_sprite_offset
= NULL
, uint16
*max_palette_offset
= NULL
)
773 ReadPalSprite (buf
, grf_sprite
);
775 TileLayoutFlags flags
= read_flags
? (TileLayoutFlags
)buf
->ReadWord() : TLF_NOTHING
;
776 if (pflags
!= NULL
) *pflags
= flags
;
778 bool custom_sprite
= HasBit(grf_sprite
->pal
, 15) != invert_action1_flag
;
779 ClrBit(grf_sprite
->pal
, 15);
781 /* Use sprite from Action 1 */
782 uint index
= GB(grf_sprite
->sprite
, 0, 14);
783 if (use_cur_spritesets
&& (!_cur
.IsValidSpriteSet(feature
, index
) || _cur
.GetNumEnts(feature
, index
) == 0)) {
784 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index
);
785 grf_sprite
->sprite
= SPR_IMG_QUERY
;
786 grf_sprite
->pal
= PAL_NONE
;
788 SpriteID sprite
= use_cur_spritesets
? _cur
.GetSprite(feature
, index
) : index
;
789 if (max_sprite_offset
!= NULL
) *max_sprite_offset
= use_cur_spritesets
? _cur
.GetNumEnts(feature
, index
) : UINT16_MAX
;
790 SB(grf_sprite
->sprite
, 0, SPRITE_WIDTH
, sprite
);
791 SetBit(grf_sprite
->sprite
, SPRITE_MODIFIER_CUSTOM_SPRITE
);
793 } else if ((flags
& TLF_SPRITE_VAR10
) && !(flags
& TLF_SPRITE_REG_FLAGS
)) {
794 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
795 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
799 if (flags
& TLF_CUSTOM_PALETTE
) {
800 /* Use palette from Action 1 */
801 uint index
= GB(grf_sprite
->pal
, 0, 14);
802 if (use_cur_spritesets
&& (!_cur
.IsValidSpriteSet(feature
, index
) || _cur
.GetNumEnts(feature
, index
) == 0)) {
803 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index
);
804 grf_sprite
->pal
= PAL_NONE
;
806 SpriteID sprite
= use_cur_spritesets
? _cur
.GetSprite(feature
, index
) : index
;
807 if (max_palette_offset
!= NULL
) *max_palette_offset
= use_cur_spritesets
? _cur
.GetNumEnts(feature
, index
) : UINT16_MAX
;
808 SB(grf_sprite
->pal
, 0, SPRITE_WIDTH
, sprite
);
809 SetBit(grf_sprite
->pal
, SPRITE_MODIFIER_CUSTOM_SPRITE
);
811 } else if ((flags
& TLF_PALETTE_VAR10
) && !(flags
& TLF_PALETTE_REG_FLAGS
)) {
812 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
813 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
821 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
822 * @param buf Input stream.
823 * @param flags TileLayoutFlags to process.
824 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
825 * @param dts Sprite layout to insert data into.
826 * @param index Sprite index to process; 0 for ground sprite.
827 * @return Whether reading succeeded.
829 static bool ReadSpriteLayoutRegisters (ByteReader
*buf
, TileLayoutFlags flags
,
830 bool is_parent
, NewGRFSpriteLayout
*dts
, uint index
)
832 if (!(flags
& TLF_DRAWING_FLAGS
)) return true;
834 if (dts
->registers
== NULL
) dts
->AllocateRegisters();
835 TileLayoutRegisters
®s
= const_cast<TileLayoutRegisters
&>(dts
->registers
[index
]);
836 regs
.flags
= flags
& TLF_DRAWING_FLAGS
;
838 if (flags
& TLF_DODRAW
) regs
.dodraw
= buf
->ReadByte();
839 if (flags
& TLF_SPRITE
) regs
.sprite
= buf
->ReadByte();
840 if (flags
& TLF_PALETTE
) regs
.palette
= buf
->ReadByte();
843 if (flags
& TLF_BB_XY_OFFSET
) {
844 regs
.delta
.parent
[0] = buf
->ReadByte();
845 regs
.delta
.parent
[1] = buf
->ReadByte();
847 if (flags
& TLF_BB_Z_OFFSET
) regs
.delta
.parent
[2] = buf
->ReadByte();
849 if (flags
& TLF_CHILD_X_OFFSET
) regs
.delta
.child
[0] = buf
->ReadByte();
850 if (flags
& TLF_CHILD_Y_OFFSET
) regs
.delta
.child
[1] = buf
->ReadByte();
853 if (flags
& TLF_SPRITE_VAR10
) {
854 regs
.sprite_var10
= buf
->ReadByte();
855 if (regs
.sprite_var10
> TLR_MAX_VAR10
) {
856 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs
.sprite_var10
, TLR_MAX_VAR10
);
857 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
862 if (flags
& TLF_PALETTE_VAR10
) {
863 regs
.palette_var10
= buf
->ReadByte();
864 if (regs
.palette_var10
> TLR_MAX_VAR10
) {
865 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs
.palette_var10
, TLR_MAX_VAR10
);
866 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
875 * Read a spritelayout from the GRF.
877 * @param num_building_sprites Number of building sprites to read
878 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
879 * @param feature GrfSpecFeature to use spritesets from.
880 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
881 * @param no_z_position Whether bounding boxes have no Z offset
882 * @param dts Layout container to output into
883 * @return True on error (GRF was disabled).
885 static bool ReadSpriteLayout(ByteReader
*buf
, uint num_building_sprites
, bool use_cur_spritesets
, byte feature
, bool allow_var10
, bool no_z_position
, NewGRFSpriteLayout
*dts
)
887 bool has_flags
= HasBit(num_building_sprites
, 6);
888 ClrBit(num_building_sprites
, 6);
889 TileLayoutFlags valid_flags
= TLF_KNOWN_FLAGS
;
890 if (!allow_var10
) valid_flags
&= ~TLF_VAR10_FLAGS
;
891 dts
->Allocate(num_building_sprites
); // allocate before reading groundsprite flags
893 uint16
*max_sprite_offset
= AllocaM(uint16
, num_building_sprites
+ 1);
894 uint16
*max_palette_offset
= AllocaM(uint16
, num_building_sprites
+ 1);
895 MemSetT(max_sprite_offset
, 0, num_building_sprites
+ 1);
896 MemSetT(max_palette_offset
, 0, num_building_sprites
+ 1);
899 TileLayoutFlags flags
;
900 if (!ReadSpriteLayoutSprite (buf
, has_flags
, false,
901 use_cur_spritesets
, feature
, &dts
->ground
, &flags
,
902 max_sprite_offset
, max_palette_offset
)) {
906 if (flags
& ~(valid_flags
& ~TLF_NON_GROUND_FLAGS
)) {
907 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags
& ~(valid_flags
& ~TLF_NON_GROUND_FLAGS
));
908 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
912 if (!ReadSpriteLayoutRegisters (buf
, flags
, false, dts
, 0)) {
916 for (uint i
= 0; i
< num_building_sprites
; i
++) {
917 DrawTileSeqStruct
*seq
= const_cast<DrawTileSeqStruct
*>(&dts
->seq
[i
]);
919 if (!ReadSpriteLayoutSprite (buf
, has_flags
, false,
920 use_cur_spritesets
, feature
, &seq
->image
, &flags
,
921 max_sprite_offset
+ i
+ 1, max_palette_offset
+ i
+ 1)) {
925 if (flags
& ~valid_flags
) {
926 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags
& ~valid_flags
);
927 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
931 seq
->delta_x
= buf
->ReadByte();
932 seq
->delta_y
= buf
->ReadByte();
934 if (!no_z_position
) seq
->delta_z
= buf
->ReadByte();
936 if (seq
->IsParentSprite()) {
937 seq
->size_x
= buf
->ReadByte();
938 seq
->size_y
= buf
->ReadByte();
939 seq
->size_z
= buf
->ReadByte();
942 if (!ReadSpriteLayoutRegisters (buf
, flags
, seq
->IsParentSprite(), dts
, i
+ 1)) {
947 /* Check if the number of sprites per spriteset is consistent */
948 bool is_consistent
= true;
949 dts
->consistent_max_offset
= 0;
950 for (uint i
= 0; i
< num_building_sprites
+ 1; i
++) {
951 if (max_sprite_offset
[i
] > 0) {
952 if (dts
->consistent_max_offset
== 0) {
953 dts
->consistent_max_offset
= max_sprite_offset
[i
];
954 } else if (dts
->consistent_max_offset
!= max_sprite_offset
[i
]) {
955 is_consistent
= false;
959 if (max_palette_offset
[i
] > 0) {
960 if (dts
->consistent_max_offset
== 0) {
961 dts
->consistent_max_offset
= max_palette_offset
[i
];
962 } else if (dts
->consistent_max_offset
!= max_palette_offset
[i
]) {
963 is_consistent
= false;
969 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
970 assert(use_cur_spritesets
|| (is_consistent
&& (dts
->consistent_max_offset
== 0 || dts
->consistent_max_offset
== UINT16_MAX
)));
972 if (!is_consistent
|| dts
->registers
!= NULL
) {
973 dts
->consistent_max_offset
= 0;
974 if (dts
->registers
== NULL
) dts
->AllocateRegisters();
976 for (uint i
= 0; i
< num_building_sprites
+ 1; i
++) {
977 TileLayoutRegisters
®s
= const_cast<TileLayoutRegisters
&>(dts
->registers
[i
]);
978 regs
.max_sprite_offset
= max_sprite_offset
[i
];
979 regs
.max_palette_offset
= max_palette_offset
[i
];
987 * Translate the refit mask.
989 static uint32
TranslateRefitMask(uint32 refit_mask
)
993 FOR_EACH_SET_BIT(bit
, refit_mask
) {
994 CargoID cargo
= GetCargoTranslation(bit
, _cur
.grffile
, true);
995 if (cargo
!= CT_INVALID
) SetBit(result
, cargo
);
1001 * Converts TTD(P) Base Price pointers into the enum used by OTTD
1002 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
1003 * @param base_pointer TTD(P) Base Price Pointer
1004 * @param error_location Function name for grf error messages
1005 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
1007 static void ConvertTTDBasePrice(uint32 base_pointer
, const char *error_location
, Price
*index
)
1009 /* Special value for 'none' */
1010 if (base_pointer
== 0) {
1011 *index
= INVALID_PRICE
;
1015 static const uint32 start
= 0x4B34; ///< Position of first base price
1016 static const uint32 size
= 6; ///< Size of each base price record
1018 if (base_pointer
< start
|| (base_pointer
- start
) % size
!= 0 || (base_pointer
- start
) / size
>= PR_END
) {
1019 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location
, base_pointer
);
1023 *index
= (Price
)((base_pointer
- start
) / size
);
1026 /** Possible return values for the FeatureChangeInfo functions */
1027 enum ChangeInfoResult
{
1028 CIR_SUCCESS
, ///< Variable was parsed and read
1029 CIR_DISABLED
, ///< GRF was disabled due to error
1030 CIR_UNHANDLED
, ///< Variable was parsed but unread
1031 CIR_UNKNOWN
, ///< Variable is unknown
1032 CIR_INVALID_ID
, ///< Attempt to modify an invalid ID
1035 typedef ChangeInfoResult (*VCI_Handler
)(uint engine
, int numinfo
, int prop
, ByteReader
*buf
);
1038 * Define properties common to all vehicles
1039 * @param ei Engine info.
1040 * @param prop The property to change.
1041 * @param buf The property value.
1042 * @return ChangeInfoResult.
1044 static ChangeInfoResult
CommonVehicleChangeInfo(EngineInfo
*ei
, int prop
, ByteReader
*buf
)
1047 case 0x00: // Introduction date
1048 ei
->base_intro
= buf
->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR
;
1051 case 0x02: // Decay speed
1052 ei
->decay_speed
= buf
->ReadByte();
1055 case 0x03: // Vehicle life
1056 ei
->lifelength
= buf
->ReadByte();
1059 case 0x04: // Model life
1060 ei
->base_life
= buf
->ReadByte();
1063 case 0x06: // Climates available
1064 ei
->climates
= buf
->ReadByte();
1067 case PROP_VEHICLE_LOAD_AMOUNT
: // 0x07 Loading speed
1068 /* Amount of cargo loaded during a vehicle's "loading tick" */
1069 ei
->load_amount
= buf
->ReadByte();
1080 * Define properties for rail vehicles
1081 * @param engine :ocal ID of the first vehicle.
1082 * @param numinfo Number of subsequent IDs to change the property for.
1083 * @param prop The property to change.
1084 * @param buf The property value.
1085 * @return ChangeInfoResult.
1087 static ChangeInfoResult
RailVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1089 ChangeInfoResult ret
= CIR_SUCCESS
;
1091 for (int i
= 0; i
< numinfo
; i
++) {
1092 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_TRAIN
, engine
+ i
);
1093 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1095 EngineInfo
*ei
= &e
->info
;
1096 RailVehicleInfo
*rvi
= &e
->u
.rail
;
1099 case 0x05: { // Track type
1100 uint8 tracktype
= buf
->ReadByte();
1102 if (tracktype
< _cur
.grffile
->railtype_list
.Length()) {
1103 _gted
[e
->index
].railtypelabel
= _cur
.grffile
->railtype_list
[tracktype
];
1107 switch (tracktype
) {
1108 case 0: _gted
[e
->index
].railtypelabel
= rvi
->engclass
>= 2 ? RAILTYPE_ELECTRIC_LABEL
: RAILTYPE_RAIL_LABEL
; break;
1109 case 1: _gted
[e
->index
].railtypelabel
= RAILTYPE_MONO_LABEL
; break;
1110 case 2: _gted
[e
->index
].railtypelabel
= RAILTYPE_MAGLEV_LABEL
; break;
1112 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype
);
1118 case 0x08: // AI passenger service
1119 /* Tells the AI that this engine is designed for
1120 * passenger services and shouldn't be used for freight. */
1121 rvi
->ai_passenger_only
= buf
->ReadByte();
1124 case PROP_TRAIN_SPEED
: { // 0x09 Speed (1 unit is 1 km-ish/h)
1125 uint16 speed
= buf
->ReadWord();
1126 if (speed
== 0xFFFF) speed
= 0;
1128 rvi
->max_speed
= speed
;
1132 case PROP_TRAIN_POWER
: // 0x0B Power
1133 rvi
->power
= buf
->ReadWord();
1135 /* Set engine / wagon state based on power */
1136 if (rvi
->power
!= 0) {
1137 if (rvi
->railveh_type
== RAILVEH_WAGON
) {
1138 rvi
->railveh_type
= RAILVEH_SINGLEHEAD
;
1141 rvi
->railveh_type
= RAILVEH_WAGON
;
1145 case PROP_TRAIN_RUNNING_COST_FACTOR
: // 0x0D Running cost factor
1146 rvi
->running_cost
= buf
->ReadByte();
1149 case 0x0E: // Running cost base
1150 ConvertTTDBasePrice(buf
->ReadDWord(), "RailVehicleChangeInfo", &rvi
->running_cost_class
);
1153 case 0x12: { // Sprite ID
1154 uint8 spriteid
= buf
->ReadByte();
1155 uint8 orig_spriteid
= spriteid
;
1157 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1158 * as an array index, so we need it to be half the original value. */
1159 if (spriteid
< 0xFD) spriteid
>>= 1;
1161 if (IsValidNewGRFImageIndex
<VEH_TRAIN
>(spriteid
)) {
1162 rvi
->image_index
= spriteid
;
1164 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1165 rvi
->image_index
= 0;
1170 case 0x13: { // Dual-headed
1171 uint8 dual
= buf
->ReadByte();
1174 rvi
->railveh_type
= RAILVEH_MULTIHEAD
;
1176 rvi
->railveh_type
= rvi
->power
== 0 ?
1177 RAILVEH_WAGON
: RAILVEH_SINGLEHEAD
;
1182 case PROP_TRAIN_CARGO_CAPACITY
: // 0x14 Cargo capacity
1183 rvi
->capacity
= buf
->ReadByte();
1186 case 0x15: { // Cargo type
1187 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1188 uint8 ctype
= buf
->ReadByte();
1190 if (ctype
== 0xFF) {
1191 /* 0xFF is specified as 'use first refittable' */
1192 ei
->cargo_type
= CT_INVALID
;
1193 } else if (_cur
.grffile
->grf_version
>= 8) {
1194 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1195 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1196 } else if (ctype
< NUM_CARGO
) {
1197 /* Use untranslated cargo. */
1198 ei
->cargo_type
= ctype
;
1200 ei
->cargo_type
= CT_INVALID
;
1201 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1206 case PROP_TRAIN_WEIGHT
: // 0x16 Weight
1207 SB(rvi
->weight
, 0, 8, buf
->ReadByte());
1210 case PROP_TRAIN_COST_FACTOR
: // 0x17 Cost factor
1211 rvi
->cost_factor
= buf
->ReadByte();
1214 case 0x18: // AI rank
1215 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1219 case 0x19: { // Engine traction type
1220 /* What do the individual numbers mean?
1221 * 0x00 .. 0x07: Steam
1222 * 0x08 .. 0x27: Diesel
1223 * 0x28 .. 0x31: Electric
1224 * 0x32 .. 0x37: Monorail
1225 * 0x38 .. 0x41: Maglev
1227 uint8 traction
= buf
->ReadByte();
1228 EngineClass engclass
;
1230 if (traction
<= 0x07) {
1231 engclass
= EC_STEAM
;
1232 } else if (traction
<= 0x27) {
1233 engclass
= EC_DIESEL
;
1234 } else if (traction
<= 0x31) {
1235 engclass
= EC_ELECTRIC
;
1236 } else if (traction
<= 0x37) {
1237 engclass
= EC_MONORAIL
;
1238 } else if (traction
<= 0x41) {
1239 engclass
= EC_MAGLEV
;
1244 if (_cur
.grffile
->railtype_list
.Length() == 0) {
1245 /* Use traction type to select between normal and electrified
1246 * rail only when no translation list is in place. */
1247 if (_gted
[e
->index
].railtypelabel
== RAILTYPE_RAIL_LABEL
&& engclass
>= EC_ELECTRIC
) _gted
[e
->index
].railtypelabel
= RAILTYPE_ELECTRIC_LABEL
;
1248 if (_gted
[e
->index
].railtypelabel
== RAILTYPE_ELECTRIC_LABEL
&& engclass
< EC_ELECTRIC
) _gted
[e
->index
].railtypelabel
= RAILTYPE_RAIL_LABEL
;
1251 rvi
->engclass
= engclass
;
1255 case 0x1A: // Alter purchase list sort order
1256 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1259 case 0x1B: // Powered wagons power bonus
1260 rvi
->pow_wag_power
= buf
->ReadWord();
1263 case 0x1C: // Refit cost
1264 ei
->refit_cost
= buf
->ReadByte();
1267 case 0x1D: { // Refit cargo
1268 uint32 mask
= buf
->ReadDWord();
1269 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1270 ei
->refit_mask
= TranslateRefitMask(mask
);
1271 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1275 case 0x1E: // Callback
1276 ei
->callback_mask
= buf
->ReadByte();
1279 case PROP_TRAIN_TRACTIVE_EFFORT
: // 0x1F Tractive effort coefficient
1280 rvi
->tractive_effort
= buf
->ReadByte();
1283 case 0x20: // Air drag
1284 rvi
->air_drag
= buf
->ReadByte();
1287 case PROP_TRAIN_SHORTEN_FACTOR
: // 0x21 Shorter vehicle
1288 rvi
->shorten_factor
= buf
->ReadByte();
1291 case 0x22: // Visual effect
1292 rvi
->visual_effect
= buf
->ReadByte();
1293 /* Avoid accidentally setting visual_effect to the default value
1294 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1295 if (rvi
->visual_effect
== VE_DEFAULT
) {
1296 assert(HasBit(rvi
->visual_effect
, VE_DISABLE_EFFECT
));
1297 SB(rvi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1301 case 0x23: // Powered wagons weight bonus
1302 rvi
->pow_wag_weight
= buf
->ReadByte();
1305 case 0x24: { // High byte of vehicle weight
1306 byte weight
= buf
->ReadByte();
1309 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight
<< 8);
1311 SB(rvi
->weight
, 8, 8, weight
);
1316 case PROP_TRAIN_USER_DATA
: // 0x25 User-defined bit mask to set when checking veh. var. 42
1317 rvi
->user_def_data
= buf
->ReadByte();
1320 case 0x26: // Retire vehicle early
1321 ei
->retire_early
= buf
->ReadByte();
1324 case 0x27: // Miscellaneous flags
1325 ei
->misc_flags
= buf
->ReadByte();
1326 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1327 _gted
[e
->index
].prop27_set
= true;
1330 case 0x28: // Cargo classes allowed
1331 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1332 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1333 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1336 case 0x29: // Cargo classes disallowed
1337 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1338 _gted
[e
->index
].UpdateRefittability(false);
1341 case 0x2A: // Long format introduction date (days since year 0)
1342 ei
->base_intro
= buf
->ReadDWord();
1345 case PROP_TRAIN_CARGO_AGE_PERIOD
: // 0x2B Cargo aging period
1346 ei
->cargo_age_period
= buf
->ReadWord();
1349 case 0x2C: // CTT refit include list
1350 case 0x2D: { // CTT refit exclude list
1351 uint8 count
= buf
->ReadByte();
1352 _gted
[e
->index
].UpdateRefittability(prop
== 0x2C && count
!= 0);
1353 if (prop
== 0x2C) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1354 uint32
&ctt
= prop
== 0x2C ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1357 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1358 if (ctype
== CT_INVALID
) continue;
1365 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1374 * Define properties for road vehicles
1375 * @param engine Local ID of the first vehicle.
1376 * @param numinfo Number of subsequent IDs to change the property for.
1377 * @param prop The property to change.
1378 * @param buf The property value.
1379 * @return ChangeInfoResult.
1381 static ChangeInfoResult
RoadVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1383 ChangeInfoResult ret
= CIR_SUCCESS
;
1385 for (int i
= 0; i
< numinfo
; i
++) {
1386 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_ROAD
, engine
+ i
);
1387 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1389 EngineInfo
*ei
= &e
->info
;
1390 RoadVehicleInfo
*rvi
= &e
->u
.road
;
1393 case 0x08: // Speed (1 unit is 0.5 kmh)
1394 rvi
->max_speed
= buf
->ReadByte();
1397 case PROP_ROADVEH_RUNNING_COST_FACTOR
: // 0x09 Running cost factor
1398 rvi
->running_cost
= buf
->ReadByte();
1401 case 0x0A: // Running cost base
1402 ConvertTTDBasePrice(buf
->ReadDWord(), "RoadVehicleChangeInfo", &rvi
->running_cost_class
);
1405 case 0x0E: { // Sprite ID
1406 uint8 spriteid
= buf
->ReadByte();
1407 uint8 orig_spriteid
= spriteid
;
1409 /* cars have different custom id in the GRF file */
1410 if (spriteid
== 0xFF) spriteid
= 0xFD;
1412 if (spriteid
< 0xFD) spriteid
>>= 1;
1414 if (IsValidNewGRFImageIndex
<VEH_ROAD
>(spriteid
)) {
1415 rvi
->image_index
= spriteid
;
1417 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1418 rvi
->image_index
= 0;
1423 case PROP_ROADVEH_CARGO_CAPACITY
: // 0x0F Cargo capacity
1424 rvi
->capacity
= buf
->ReadByte();
1427 case 0x10: { // Cargo type
1428 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1429 uint8 ctype
= buf
->ReadByte();
1431 if (ctype
== 0xFF) {
1432 /* 0xFF is specified as 'use first refittable' */
1433 ei
->cargo_type
= CT_INVALID
;
1434 } else if (_cur
.grffile
->grf_version
>= 8) {
1435 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1436 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1437 } else if (ctype
< NUM_CARGO
) {
1438 /* Use untranslated cargo. */
1439 ei
->cargo_type
= ctype
;
1441 ei
->cargo_type
= CT_INVALID
;
1442 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1447 case PROP_ROADVEH_COST_FACTOR
: // 0x11 Cost factor
1448 rvi
->cost_factor
= buf
->ReadByte();
1452 rvi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1455 case PROP_ROADVEH_POWER
: // Power in units of 10 HP.
1456 rvi
->power
= buf
->ReadByte();
1459 case PROP_ROADVEH_WEIGHT
: // Weight in units of 1/4 tons.
1460 rvi
->weight
= buf
->ReadByte();
1463 case PROP_ROADVEH_SPEED
: // Speed in mph/0.8
1464 _gted
[e
->index
].rv_max_speed
= buf
->ReadByte();
1467 case 0x16: { // Cargoes available for refitting
1468 uint32 mask
= buf
->ReadDWord();
1469 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1470 ei
->refit_mask
= TranslateRefitMask(mask
);
1471 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1475 case 0x17: // Callback mask
1476 ei
->callback_mask
= buf
->ReadByte();
1479 case PROP_ROADVEH_TRACTIVE_EFFORT
: // Tractive effort coefficient in 1/256.
1480 rvi
->tractive_effort
= buf
->ReadByte();
1483 case 0x19: // Air drag
1484 rvi
->air_drag
= buf
->ReadByte();
1487 case 0x1A: // Refit cost
1488 ei
->refit_cost
= buf
->ReadByte();
1491 case 0x1B: // Retire vehicle early
1492 ei
->retire_early
= buf
->ReadByte();
1495 case 0x1C: // Miscellaneous flags
1496 ei
->misc_flags
= buf
->ReadByte();
1497 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1500 case 0x1D: // Cargo classes allowed
1501 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1502 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1503 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1506 case 0x1E: // Cargo classes disallowed
1507 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1508 _gted
[e
->index
].UpdateRefittability(false);
1511 case 0x1F: // Long format introduction date (days since year 0)
1512 ei
->base_intro
= buf
->ReadDWord();
1515 case 0x20: // Alter purchase list sort order
1516 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1519 case 0x21: // Visual effect
1520 rvi
->visual_effect
= buf
->ReadByte();
1521 /* Avoid accidentally setting visual_effect to the default value
1522 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1523 if (rvi
->visual_effect
== VE_DEFAULT
) {
1524 assert(HasBit(rvi
->visual_effect
, VE_DISABLE_EFFECT
));
1525 SB(rvi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1529 case PROP_ROADVEH_CARGO_AGE_PERIOD
: // 0x22 Cargo aging period
1530 ei
->cargo_age_period
= buf
->ReadWord();
1533 case PROP_ROADVEH_SHORTEN_FACTOR
: // 0x23 Shorter vehicle
1534 rvi
->shorten_factor
= buf
->ReadByte();
1537 case 0x24: // CTT refit include list
1538 case 0x25: { // CTT refit exclude list
1539 uint8 count
= buf
->ReadByte();
1540 _gted
[e
->index
].UpdateRefittability(prop
== 0x24 && count
!= 0);
1541 if (prop
== 0x24) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1542 uint32
&ctt
= prop
== 0x24 ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1545 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1546 if (ctype
== CT_INVALID
) continue;
1553 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1562 * Define properties for ships
1563 * @param engine Local ID of the first vehicle.
1564 * @param numinfo Number of subsequent IDs to change the property for.
1565 * @param prop The property to change.
1566 * @param buf The property value.
1567 * @return ChangeInfoResult.
1569 static ChangeInfoResult
ShipVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1571 ChangeInfoResult ret
= CIR_SUCCESS
;
1573 for (int i
= 0; i
< numinfo
; i
++) {
1574 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_SHIP
, engine
+ i
);
1575 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1577 EngineInfo
*ei
= &e
->info
;
1578 ShipVehicleInfo
*svi
= &e
->u
.ship
;
1581 case 0x08: { // Sprite ID
1582 uint8 spriteid
= buf
->ReadByte();
1583 uint8 orig_spriteid
= spriteid
;
1585 /* ships have different custom id in the GRF file */
1586 if (spriteid
== 0xFF) spriteid
= 0xFD;
1588 if (spriteid
< 0xFD) spriteid
>>= 1;
1590 if (IsValidNewGRFImageIndex
<VEH_SHIP
>(spriteid
)) {
1591 svi
->image_index
= spriteid
;
1593 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1594 svi
->image_index
= 0;
1599 case 0x09: // Refittable
1600 svi
->old_refittable
= (buf
->ReadByte() != 0);
1603 case PROP_SHIP_COST_FACTOR
: // 0x0A Cost factor
1604 svi
->cost_factor
= buf
->ReadByte();
1607 case PROP_SHIP_SPEED
: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1608 svi
->max_speed
= buf
->ReadByte();
1611 case 0x0C: { // Cargo type
1612 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1613 uint8 ctype
= buf
->ReadByte();
1615 if (ctype
== 0xFF) {
1616 /* 0xFF is specified as 'use first refittable' */
1617 ei
->cargo_type
= CT_INVALID
;
1618 } else if (_cur
.grffile
->grf_version
>= 8) {
1619 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1620 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1621 } else if (ctype
< NUM_CARGO
) {
1622 /* Use untranslated cargo. */
1623 ei
->cargo_type
= ctype
;
1625 ei
->cargo_type
= CT_INVALID
;
1626 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1631 case PROP_SHIP_CARGO_CAPACITY
: // 0x0D Cargo capacity
1632 svi
->capacity
= buf
->ReadWord();
1635 case PROP_SHIP_RUNNING_COST_FACTOR
: // 0x0F Running cost factor
1636 svi
->running_cost
= buf
->ReadByte();
1640 svi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1643 case 0x11: { // Cargoes available for refitting
1644 uint32 mask
= buf
->ReadDWord();
1645 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1646 ei
->refit_mask
= TranslateRefitMask(mask
);
1647 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1651 case 0x12: // Callback mask
1652 ei
->callback_mask
= buf
->ReadByte();
1655 case 0x13: // Refit cost
1656 ei
->refit_cost
= buf
->ReadByte();
1659 case 0x14: // Ocean speed fraction
1660 svi
->ocean_speed_frac
= buf
->ReadByte();
1663 case 0x15: // Canal speed fraction
1664 svi
->canal_speed_frac
= buf
->ReadByte();
1667 case 0x16: // Retire vehicle early
1668 ei
->retire_early
= buf
->ReadByte();
1671 case 0x17: // Miscellaneous flags
1672 ei
->misc_flags
= buf
->ReadByte();
1673 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1676 case 0x18: // Cargo classes allowed
1677 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1678 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1679 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1682 case 0x19: // Cargo classes disallowed
1683 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1684 _gted
[e
->index
].UpdateRefittability(false);
1687 case 0x1A: // Long format introduction date (days since year 0)
1688 ei
->base_intro
= buf
->ReadDWord();
1691 case 0x1B: // Alter purchase list sort order
1692 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1695 case 0x1C: // Visual effect
1696 svi
->visual_effect
= buf
->ReadByte();
1697 /* Avoid accidentally setting visual_effect to the default value
1698 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1699 if (svi
->visual_effect
== VE_DEFAULT
) {
1700 assert(HasBit(svi
->visual_effect
, VE_DISABLE_EFFECT
));
1701 SB(svi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1705 case PROP_SHIP_CARGO_AGE_PERIOD
: // 0x1D Cargo aging period
1706 ei
->cargo_age_period
= buf
->ReadWord();
1709 case 0x1E: // CTT refit include list
1710 case 0x1F: { // CTT refit exclude list
1711 uint8 count
= buf
->ReadByte();
1712 _gted
[e
->index
].UpdateRefittability(prop
== 0x1E && count
!= 0);
1713 if (prop
== 0x1E) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1714 uint32
&ctt
= prop
== 0x1E ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1717 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1718 if (ctype
== CT_INVALID
) continue;
1725 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1734 * Define properties for aircraft
1735 * @param engine Local ID of the aircraft.
1736 * @param numinfo Number of subsequent IDs to change the property for.
1737 * @param prop The property to change.
1738 * @param buf The property value.
1739 * @return ChangeInfoResult.
1741 static ChangeInfoResult
AircraftVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1743 ChangeInfoResult ret
= CIR_SUCCESS
;
1745 for (int i
= 0; i
< numinfo
; i
++) {
1746 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_AIRCRAFT
, engine
+ i
);
1747 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1749 EngineInfo
*ei
= &e
->info
;
1750 AircraftVehicleInfo
*avi
= &e
->u
.air
;
1753 case 0x08: { // Sprite ID
1754 uint8 spriteid
= buf
->ReadByte();
1755 uint8 orig_spriteid
= spriteid
;
1757 /* aircraft have different custom id in the GRF file */
1758 if (spriteid
== 0xFF) spriteid
= 0xFD;
1760 if (spriteid
< 0xFD) spriteid
>>= 1;
1762 if (IsValidNewGRFImageIndex
<VEH_AIRCRAFT
>(spriteid
)) {
1763 avi
->image_index
= spriteid
;
1765 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1766 avi
->image_index
= 0;
1771 case 0x09: // Helicopter
1772 if (buf
->ReadByte() == 0) {
1773 avi
->subtype
= AIR_HELI
;
1775 SB(avi
->subtype
, 0, 1, 1); // AIR_CTOL
1780 SB(avi
->subtype
, 1, 1, (buf
->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1783 case PROP_AIRCRAFT_COST_FACTOR
: // 0x0B Cost factor
1784 avi
->cost_factor
= buf
->ReadByte();
1787 case PROP_AIRCRAFT_SPEED
: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1788 avi
->max_speed
= (buf
->ReadByte() * 128) / 10;
1791 case 0x0D: // Acceleration
1792 avi
->acceleration
= buf
->ReadByte();
1795 case PROP_AIRCRAFT_RUNNING_COST_FACTOR
: // 0x0E Running cost factor
1796 avi
->running_cost
= buf
->ReadByte();
1799 case PROP_AIRCRAFT_PASSENGER_CAPACITY
: // 0x0F Passenger capacity
1800 avi
->passenger_capacity
= buf
->ReadWord();
1803 case PROP_AIRCRAFT_MAIL_CAPACITY
: // 0x11 Mail capacity
1804 avi
->mail_capacity
= buf
->ReadByte();
1808 avi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1811 case 0x13: { // Cargoes available for refitting
1812 uint32 mask
= buf
->ReadDWord();
1813 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1814 ei
->refit_mask
= TranslateRefitMask(mask
);
1815 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1819 case 0x14: // Callback mask
1820 ei
->callback_mask
= buf
->ReadByte();
1823 case 0x15: // Refit cost
1824 ei
->refit_cost
= buf
->ReadByte();
1827 case 0x16: // Retire vehicle early
1828 ei
->retire_early
= buf
->ReadByte();
1831 case 0x17: // Miscellaneous flags
1832 ei
->misc_flags
= buf
->ReadByte();
1833 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1836 case 0x18: // Cargo classes allowed
1837 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1838 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1839 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1842 case 0x19: // Cargo classes disallowed
1843 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1844 _gted
[e
->index
].UpdateRefittability(false);
1847 case 0x1A: // Long format introduction date (days since year 0)
1848 ei
->base_intro
= buf
->ReadDWord();
1851 case 0x1B: // Alter purchase list sort order
1852 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1855 case PROP_AIRCRAFT_CARGO_AGE_PERIOD
: // 0x1C Cargo aging period
1856 ei
->cargo_age_period
= buf
->ReadWord();
1859 case 0x1D: // CTT refit include list
1860 case 0x1E: { // CTT refit exclude list
1861 uint8 count
= buf
->ReadByte();
1862 _gted
[e
->index
].UpdateRefittability(prop
== 0x1D && count
!= 0);
1863 if (prop
== 0x1D) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1864 uint32
&ctt
= prop
== 0x1D ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1867 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1868 if (ctype
== CT_INVALID
) continue;
1874 case PROP_AIRCRAFT_RANGE
: // 0x1F Max aircraft range
1875 avi
->max_range
= buf
->ReadWord();
1879 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1888 * Define properties for stations
1889 * @param stdid StationID of the first station tile.
1890 * @param numinfo Number of subsequent station tiles to change the property for.
1891 * @param prop The property to change.
1892 * @param buf The property value.
1893 * @return ChangeInfoResult.
1895 static ChangeInfoResult
StationChangeInfo(uint stid
, int numinfo
, int prop
, ByteReader
*buf
)
1897 ChangeInfoResult ret
= CIR_SUCCESS
;
1899 if (stid
+ numinfo
> NUM_STATIONS_PER_GRF
) {
1900 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid
+ numinfo
, NUM_STATIONS_PER_GRF
);
1901 return CIR_INVALID_ID
;
1904 /* Allocate station specs if necessary */
1905 if (_cur
.grffile
->stations
== NULL
) _cur
.grffile
->stations
= xcalloct
<StationSpec
*>(NUM_STATIONS_PER_GRF
);
1907 for (int i
= 0; i
< numinfo
; i
++) {
1908 StationSpec
*statspec
= _cur
.grffile
->stations
[stid
+ i
];
1910 /* Check that the station we are modifying is defined. */
1911 if (statspec
== NULL
&& prop
!= 0x08) {
1912 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid
+ i
);
1913 return CIR_INVALID_ID
;
1917 case 0x08: { // Class ID
1918 StationSpec
**spec
= &_cur
.grffile
->stations
[stid
+ i
];
1920 /* Property 0x08 is special; it is where the station is allocated */
1921 if (*spec
== NULL
) *spec
= xcalloct
<StationSpec
>();
1923 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1924 uint32 classid
= buf
->ReadDWord();
1925 (*spec
)->cls_id
= StationClass::Allocate(BSWAP32(classid
));
1929 case 0x09: // Define sprite layout
1930 statspec
->tiles
= buf
->ReadExtendedByte();
1931 delete[] statspec
->renderdata
; // delete earlier loaded stuff
1932 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
1934 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
1935 NewGRFSpriteLayout
*dts
= &statspec
->renderdata
[t
];
1936 dts
->consistent_max_offset
= UINT16_MAX
; // Spritesets are unknown, so no limit.
1938 if (buf
->HasData(4) && buf
->PeekDWord() == 0) {
1940 extern const DrawTileSprites _station_display_datas_rail
[8];
1941 dts
->Clone(&_station_display_datas_rail
[t
% 8]);
1945 /* On error, bail out immediately. Temporary GRF data was already freed */
1946 if (!ReadSpriteLayoutSprite (buf
, false, false, false, GSF_STATIONS
, &dts
->ground
)) {
1947 return CIR_DISABLED
;
1950 static SmallVector
<DrawTileSeqStruct
, 8> tmp_layout
;
1953 /* no relative bounding box support */
1954 DrawTileSeqStruct
*dtss
= tmp_layout
.Append();
1957 dtss
->delta_x
= buf
->ReadByte();
1958 if (dtss
->IsTerminator()) break;
1959 dtss
->delta_y
= buf
->ReadByte();
1960 dtss
->delta_z
= buf
->ReadByte();
1961 dtss
->size_x
= buf
->ReadByte();
1962 dtss
->size_y
= buf
->ReadByte();
1963 dtss
->size_z
= buf
->ReadByte();
1965 /* On error, bail out immediately. Temporary GRF data was already freed */
1966 if (!ReadSpriteLayoutSprite (buf
, false, true, false, GSF_STATIONS
, &dtss
->image
)) {
1967 return CIR_DISABLED
;
1970 dts
->Clone(tmp_layout
.Begin());
1974 case 0x0A: { // Copy sprite layout
1975 byte srcid
= buf
->ReadByte();
1976 const StationSpec
*srcstatspec
= _cur
.grffile
->stations
[srcid
];
1978 if (srcstatspec
== NULL
) {
1979 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid
, stid
+ i
);
1983 delete[] statspec
->renderdata
; // delete earlier loaded stuff
1985 statspec
->tiles
= srcstatspec
->tiles
;
1986 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
1987 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
1988 statspec
->renderdata
[t
].Clone(&srcstatspec
->renderdata
[t
]);
1993 case 0x0B: // Callback mask
1994 statspec
->callback_mask
= buf
->ReadByte();
1997 case 0x0C: // Disallowed number of platforms
1998 statspec
->disallowed_platforms
= buf
->ReadByte();
2001 case 0x0D: // Disallowed platform lengths
2002 statspec
->disallowed_lengths
= buf
->ReadByte();
2005 case 0x0E: // Define custom layout
2006 statspec
->copied_layouts
= false;
2008 while (buf
->HasData()) {
2009 byte length
= buf
->ReadByte();
2010 byte number
= buf
->ReadByte();
2012 if (length
== 0 || number
== 0) break;
2014 if (length
> statspec
->lengths
) {
2015 statspec
->platforms
= xrealloct (statspec
->platforms
, length
);
2016 memset(statspec
->platforms
+ statspec
->lengths
, 0, length
- statspec
->lengths
);
2018 statspec
->layouts
= xrealloct (statspec
->layouts
, length
);
2019 memset(statspec
->layouts
+ statspec
->lengths
, 0,
2020 (length
- statspec
->lengths
) * sizeof(*statspec
->layouts
));
2022 statspec
->lengths
= length
;
2025 uint l
= length
- 1; // index is zero-based
2027 if (number
> statspec
->platforms
[l
]) {
2028 statspec
->layouts
[l
] = xrealloct (statspec
->layouts
[l
], number
);
2029 /* We expect NULL being 0 here, but C99 guarantees that. */
2030 memset(statspec
->layouts
[l
] + statspec
->platforms
[l
], 0,
2031 (number
- statspec
->platforms
[l
]) * sizeof(**statspec
->layouts
));
2033 statspec
->platforms
[l
] = number
;
2036 StationLayout layout
= buf
->Dup (length
* number
);
2038 StationLayout
*p
= &statspec
->layouts
[l
][number
- 1];
2044 case 0x0F: { // Copy custom layout
2045 byte srcid
= buf
->ReadByte();
2046 const StationSpec
*srcstatspec
= _cur
.grffile
->stations
[srcid
];
2048 if (srcstatspec
== NULL
) {
2049 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid
, stid
+ i
);
2053 statspec
->lengths
= srcstatspec
->lengths
;
2054 statspec
->platforms
= srcstatspec
->platforms
;
2055 statspec
->layouts
= srcstatspec
->layouts
;
2056 statspec
->copied_layouts
= true;
2060 case 0x10: // Little/lots cargo threshold
2061 statspec
->cargo_threshold
= buf
->ReadWord();
2064 case 0x11: // Pylon placement
2065 statspec
->pylons
= buf
->ReadByte();
2068 case 0x12: // Cargo types for random triggers
2069 statspec
->cargo_triggers
= buf
->ReadDWord();
2070 if (_cur
.grffile
->grf_version
>= 7) {
2071 statspec
->cargo_triggers
= TranslateRefitMask(statspec
->cargo_triggers
);
2075 case 0x13: // General flags
2076 statspec
->flags
= buf
->ReadByte();
2079 case 0x14: // Overhead wire placement
2080 statspec
->wires
= buf
->ReadByte();
2083 case 0x15: // Blocked tiles
2084 statspec
->blocked
= buf
->ReadByte();
2087 case 0x16: // Animation info
2088 statspec
->animation
.frames
= buf
->ReadByte();
2089 statspec
->animation
.status
= buf
->ReadByte();
2092 case 0x17: // Animation speed
2093 statspec
->animation
.speed
= buf
->ReadByte();
2096 case 0x18: // Animation triggers
2097 statspec
->animation
.triggers
= buf
->ReadWord();
2100 case 0x1A: // Advanced sprite layout
2101 statspec
->tiles
= buf
->ReadExtendedByte();
2102 delete[] statspec
->renderdata
; // delete earlier loaded stuff
2103 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
2105 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
2106 NewGRFSpriteLayout
*dts
= &statspec
->renderdata
[t
];
2107 uint num_building_sprites
= buf
->ReadByte();
2108 /* On error, bail out immediately. Temporary GRF data was already freed */
2109 if (ReadSpriteLayout(buf
, num_building_sprites
, false, GSF_STATIONS
, true, false, dts
)) {
2110 return CIR_DISABLED
;
2125 * Define properties for water features
2126 * @param id Type of the first water feature.
2127 * @param numinfo Number of subsequent water feature ids to change the property for.
2128 * @param prop The property to change.
2129 * @param buf The property value.
2130 * @return ChangeInfoResult.
2132 static ChangeInfoResult
CanalChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
2134 ChangeInfoResult ret
= CIR_SUCCESS
;
2136 if (id
+ numinfo
> CF_END
) {
2137 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id
+ numinfo
, CF_END
);
2138 return CIR_INVALID_ID
;
2141 for (int i
= 0; i
< numinfo
; i
++) {
2142 CanalProperties
*cp
= &_cur
.grffile
->canal_local_properties
[id
+ i
];
2146 cp
->callback_mask
= buf
->ReadByte();
2150 cp
->flags
= buf
->ReadByte();
2163 * Define properties for bridges
2164 * @param brid BridgeID of the bridge.
2165 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2166 * @param prop The property to change.
2167 * @param buf The property value.
2168 * @return ChangeInfoResult.
2170 static ChangeInfoResult
BridgeChangeInfo(uint brid
, int numinfo
, int prop
, ByteReader
*buf
)
2172 ChangeInfoResult ret
= CIR_SUCCESS
;
2174 if (brid
+ numinfo
> MAX_BRIDGES
) {
2175 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid
+ numinfo
, MAX_BRIDGES
);
2176 return CIR_INVALID_ID
;
2179 for (int i
= 0; i
< numinfo
; i
++) {
2180 BridgeSpec
*bridge
= &_bridge
[brid
+ i
];
2183 case 0x08: { // Year of availability
2184 /* We treat '0' as always available */
2185 byte year
= buf
->ReadByte();
2186 bridge
->avail_year
= (year
> 0 ? ORIGINAL_BASE_YEAR
+ year
: 0);
2190 case 0x09: // Minimum length
2191 bridge
->min_length
= buf
->ReadByte();
2194 case 0x0A: // Maximum length
2195 bridge
->max_length
= buf
->ReadByte();
2196 if (bridge
->max_length
> 16) bridge
->max_length
= 0xFFFF;
2199 case 0x0B: // Cost factor
2200 bridge
->price
= buf
->ReadByte();
2203 case 0x0C: // Maximum speed
2204 bridge
->speed
= buf
->ReadWord();
2207 case 0x0D: { // Bridge sprite tables
2208 byte tableid
= buf
->ReadByte();
2209 byte numtables
= buf
->ReadByte();
2211 if (bridge
->sprite_table
== NULL
) {
2212 /* Allocate memory for sprite table pointers and zero out */
2213 bridge
->sprite_table
= xcalloct
<PalSpriteID
*>(7);
2216 for (; numtables
-- != 0; tableid
++) {
2217 if (tableid
>= 7) { // skip invalid data
2218 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid
);
2219 for (byte sprite
= 0; sprite
< 32; sprite
++) buf
->ReadDWord();
2223 if (bridge
->sprite_table
[tableid
] == NULL
) {
2224 bridge
->sprite_table
[tableid
] = xmalloct
<PalSpriteID
>(32);
2227 for (byte sprite
= 0; sprite
< 32; sprite
++) {
2228 ReadPalSprite (buf
, &bridge
->sprite_table
[tableid
][sprite
]);
2234 case 0x0E: // Flags; bit 0 - disable far pillars
2235 bridge
->flags
= buf
->ReadByte();
2238 case 0x0F: // Long format year of availability (year since year 0)
2239 bridge
->avail_year
= Clamp(buf
->ReadDWord(), MIN_YEAR
, MAX_YEAR
);
2242 case 0x10: { // purchase string
2243 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2244 if (newone
!= STR_UNDEFINED
) bridge
->material
= newone
;
2248 case 0x11: // description of bridge with rails or roads
2250 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2251 if (newone
!= STR_UNDEFINED
) bridge
->transport_name
[prop
- 0x11] = newone
;
2255 case 0x13: // 16 bits cost multiplier
2256 bridge
->price
= buf
->ReadWord();
2259 case 0x14: // purchase sprite
2260 bridge
->sprite
= buf
->ReadWord();
2261 bridge
->pal
= buf
->ReadWord();
2274 * Ignore a house property
2275 * @param prop Property to read.
2276 * @param buf Property value.
2277 * @return ChangeInfoResult.
2279 static ChangeInfoResult
IgnoreTownHouseProperty(int prop
, ByteReader
*buf
)
2281 ChangeInfoResult ret
= CIR_SUCCESS
;
2318 for (uint j
= 0; j
< 4; j
++) buf
->ReadByte();
2322 byte count
= buf
->ReadByte();
2323 for (byte j
= 0; j
< count
; j
++) buf
->ReadByte();
2335 * Define properties for houses
2336 * @param hid HouseID of the house.
2337 * @param numinfo Number of subsequent houseIDs to change the property for.
2338 * @param prop The property to change.
2339 * @param buf The property value.
2340 * @return ChangeInfoResult.
2342 static ChangeInfoResult
TownHouseChangeInfo(uint hid
, int numinfo
, int prop
, ByteReader
*buf
)
2344 ChangeInfoResult ret
= CIR_SUCCESS
;
2346 if (hid
+ numinfo
> NUM_HOUSES_PER_GRF
) {
2347 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid
+ numinfo
, NUM_HOUSES_PER_GRF
);
2348 return CIR_INVALID_ID
;
2351 /* Allocate house specs if they haven't been allocated already. */
2352 if (_cur
.grffile
->housespec
== NULL
) {
2353 _cur
.grffile
->housespec
= xcalloct
<HouseSpec
*>(NUM_HOUSES_PER_GRF
);
2356 for (int i
= 0; i
< numinfo
; i
++) {
2357 HouseSpec
*housespec
= _cur
.grffile
->housespec
[hid
+ i
];
2359 if (prop
!= 0x08 && housespec
== NULL
) {
2360 /* If the house property 08 is not yet set, ignore this property */
2361 ChangeInfoResult cir
= IgnoreTownHouseProperty(prop
, buf
);
2362 if (cir
> ret
) ret
= cir
;
2367 case 0x08: { // Substitute building type, and definition of a new house
2368 HouseSpec
**house
= &_cur
.grffile
->housespec
[hid
+ i
];
2369 byte subs_id
= buf
->ReadByte();
2371 if (subs_id
== 0xFF) {
2372 /* Instead of defining a new house, a substitute house id
2373 * of 0xFF disables the old house with the current id. */
2374 HouseSpec::Get(hid
+ i
)->enabled
= false;
2376 } else if (subs_id
>= NEW_HOUSE_OFFSET
) {
2377 /* The substitute id must be one of the original houses. */
2378 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id
, hid
+ i
);
2382 /* Allocate space for this house. */
2383 if (*house
== NULL
) *house
= xcalloct
<HouseSpec
>();
2387 MemCpyT(housespec
, HouseSpec::Get(subs_id
));
2389 housespec
->enabled
= true;
2390 housespec
->grf_prop
.local_id
= hid
+ i
;
2391 housespec
->grf_prop
.subst_id
= subs_id
;
2392 housespec
->grf_prop
.grffile
= _cur
.grffile
;
2393 housespec
->random_colour
[0] = 0x04; // those 4 random colours are the base colour
2394 housespec
->random_colour
[1] = 0x08; // for all new houses
2395 housespec
->random_colour
[2] = 0x0C; // they stand for red, blue, orange and green
2396 housespec
->random_colour
[3] = 0x06;
2398 /* Make sure that the third cargo type is valid in this
2399 * climate. This can cause problems when copying the properties
2400 * of a house that accepts food, where the new house is valid
2401 * in the temperate climate. */
2402 if (!CargoSpec::Get(housespec
->accepts_cargo
[2])->IsValid()) {
2403 housespec
->cargo_acceptance
[2] = 0;
2406 _loaded_newgrf_features
.has_newhouses
= true;
2410 case 0x09: // Building flags
2411 housespec
->building_flags
= (BuildingFlags
)buf
->ReadByte();
2414 case 0x0A: { // Availability years
2415 uint16 years
= buf
->ReadWord();
2416 housespec
->min_year
= GB(years
, 0, 8) > 150 ? MAX_YEAR
: ORIGINAL_BASE_YEAR
+ GB(years
, 0, 8);
2417 housespec
->max_year
= GB(years
, 8, 8) > 150 ? MAX_YEAR
: ORIGINAL_BASE_YEAR
+ GB(years
, 8, 8);
2421 case 0x0B: // Population
2422 housespec
->population
= buf
->ReadByte();
2425 case 0x0C: // Mail generation multiplier
2426 housespec
->mail_generation
= buf
->ReadByte();
2429 case 0x0D: // Passenger acceptance
2430 case 0x0E: // Mail acceptance
2431 housespec
->cargo_acceptance
[prop
- 0x0D] = buf
->ReadByte();
2434 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2435 int8 goods
= buf
->ReadByte();
2437 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2438 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2439 CargoID cid
= (goods
>= 0) ? ((_settings_game
.game_creation
.landscape
== LT_TOYLAND
) ? CT_CANDY
: CT_GOODS
) :
2440 ((_settings_game
.game_creation
.landscape
== LT_TOYLAND
) ? CT_FIZZY_DRINKS
: CT_FOOD
);
2442 /* Make sure the cargo type is valid in this climate. */
2443 if (!CargoSpec::Get(cid
)->IsValid()) goods
= 0;
2445 housespec
->accepts_cargo
[2] = cid
;
2446 housespec
->cargo_acceptance
[2] = abs(goods
); // but we do need positive value here
2450 case 0x10: // Local authority rating decrease on removal
2451 housespec
->remove_rating_decrease
= buf
->ReadWord();
2454 case 0x11: // Removal cost multiplier
2455 housespec
->removal_cost
= buf
->ReadByte();
2458 case 0x12: // Building name ID
2459 AddStringForMapping(buf
->ReadWord(), &housespec
->building_name
);
2462 case 0x13: // Building availability mask
2463 housespec
->building_availability
= (HouseZones
)buf
->ReadWord();
2466 case 0x14: // House callback mask
2467 housespec
->callback_mask
|= buf
->ReadByte();
2470 case 0x15: { // House override byte
2471 byte override
= buf
->ReadByte();
2473 /* The house being overridden must be an original house. */
2474 if (override
>= NEW_HOUSE_OFFSET
) {
2475 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override
, hid
+ i
);
2479 _house_mngr
.Add(hid
+ i
, _cur
.grffile
->grfid
, override
);
2483 case 0x16: // Periodic refresh multiplier
2484 housespec
->processing_time
= min(buf
->ReadByte(), 63);
2487 case 0x17: // Four random colours to use
2488 for (uint j
= 0; j
< 4; j
++) housespec
->random_colour
[j
] = buf
->ReadByte();
2491 case 0x18: // Relative probability of appearing
2492 housespec
->probability
= buf
->ReadByte();
2495 case 0x19: // Extra flags
2496 housespec
->extra_flags
= (HouseExtraFlags
)buf
->ReadByte();
2499 case 0x1A: // Animation frames
2500 housespec
->animation
.frames
= buf
->ReadByte();
2501 housespec
->animation
.status
= GB(housespec
->animation
.frames
, 7, 1);
2502 SB(housespec
->animation
.frames
, 7, 1, 0);
2505 case 0x1B: // Animation speed
2506 housespec
->animation
.speed
= Clamp(buf
->ReadByte(), 2, 16);
2509 case 0x1C: // Class of the building type
2510 housespec
->class_id
= AllocateHouseClassID(buf
->ReadByte(), _cur
.grffile
->grfid
);
2513 case 0x1D: // Callback mask part 2
2514 housespec
->callback_mask
|= (buf
->ReadByte() << 8);
2517 case 0x1E: { // Accepted cargo types
2518 uint32 cargotypes
= buf
->ReadDWord();
2520 /* Check if the cargo types should not be changed */
2521 if (cargotypes
== 0xFFFFFFFF) break;
2523 for (uint j
= 0; j
< 3; j
++) {
2524 /* Get the cargo number from the 'list' */
2525 uint8 cargo_part
= GB(cargotypes
, 8 * j
, 8);
2526 CargoID cargo
= GetCargoTranslation(cargo_part
, _cur
.grffile
);
2528 if (cargo
== CT_INVALID
) {
2529 /* Disable acceptance of invalid cargo type */
2530 housespec
->cargo_acceptance
[j
] = 0;
2532 housespec
->accepts_cargo
[j
] = cargo
;
2538 case 0x1F: // Minimum life span
2539 housespec
->minimum_life
= buf
->ReadByte();
2542 case 0x20: { // Cargo acceptance watch list
2543 byte count
= buf
->ReadByte();
2544 for (byte j
= 0; j
< count
; j
++) {
2545 CargoID cargo
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
2546 if (cargo
!= CT_INVALID
) SetBit(housespec
->watched_cargoes
, cargo
);
2551 case 0x21: // long introduction year
2552 housespec
->min_year
= buf
->ReadWord();
2555 case 0x22: // long maximum year
2556 housespec
->max_year
= buf
->ReadWord();
2569 * Get the language map associated with a given NewGRF and language.
2570 * @param grfid The NewGRF to get the map for.
2571 * @param language_id The (NewGRF) language ID to get the map for.
2572 * @return The LanguageMap, or NULL if it couldn't be found.
2574 /* static */ const LanguageMap
*LanguageMap::GetLanguageMap(uint32 grfid
, uint8 language_id
)
2576 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2577 const GRFFile
*grffile
= GetFileByGRFID(grfid
);
2578 return (grffile
!= NULL
&& grffile
->language_map
!= NULL
&& language_id
< MAX_LANG
) ? &grffile
->language_map
[language_id
] : NULL
;
2582 * Load a cargo- or railtype-translation table.
2583 * @param gvid ID of the global variable. This is basically only checked for zerones.
2584 * @param numinfo Number of subsequent IDs to change the property for.
2585 * @param buf The property value.
2586 * @param [in,out] translation_table Storage location for the translation table.
2587 * @param name Name of the table for debug output.
2588 * @return ChangeInfoResult.
2590 template <typename T
>
2591 static ChangeInfoResult
LoadTranslationTable(uint gvid
, int numinfo
, ByteReader
*buf
, T
&translation_table
, const char *name
)
2594 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name
);
2595 return CIR_INVALID_ID
;
2598 translation_table
.Clear();
2599 for (int i
= 0; i
< numinfo
; i
++) {
2600 uint32 item
= buf
->ReadDWord();
2601 *translation_table
.Append() = BSWAP32(item
);
2608 * Define properties for global variables
2609 * @param gvid ID of the global variable.
2610 * @param numinfo Number of subsequent IDs to change the property for.
2611 * @param prop The property to change.
2612 * @param buf The property value.
2613 * @return ChangeInfoResult.
2615 static ChangeInfoResult
GlobalVarChangeInfo(uint gvid
, int numinfo
, int prop
, ByteReader
*buf
)
2617 /* Properties which are handled as a whole */
2619 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2620 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->cargo_list
, "Cargo");
2622 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2623 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->railtype_list
, "Rail type");
2629 /* Properties which are handled per item */
2630 ChangeInfoResult ret
= CIR_SUCCESS
;
2631 for (int i
= 0; i
< numinfo
; i
++) {
2633 case 0x08: { // Cost base factor
2634 int factor
= buf
->ReadByte();
2635 uint price
= gvid
+ i
;
2637 if (price
< PR_END
) {
2638 _cur
.grffile
->price_base_multipliers
[price
] = min
<int>(factor
- 8, MAX_PRICE_MODIFIER
);
2640 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price
);
2645 case 0x0A: { // Currency display names
2646 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2647 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2649 if ((newone
!= STR_UNDEFINED
) && (curidx
< CURRENCY_END
)) {
2650 _currency_specs
[curidx
].name
= newone
;
2655 case 0x0B: { // Currency multipliers
2656 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2657 uint32 rate
= buf
->ReadDWord();
2659 if (curidx
< CURRENCY_END
) {
2660 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2661 * which OTTD does not. For this reason, divide grf value by 1000,
2662 * to be compatible */
2663 _currency_specs
[curidx
].rate
= rate
/ 1000;
2665 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx
);
2670 case 0x0C: { // Currency options
2671 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2672 uint16 options
= buf
->ReadWord();
2674 if (curidx
< CURRENCY_END
) {
2675 _currency_specs
[curidx
].separator
[0] = GB(options
, 0, 8);
2676 _currency_specs
[curidx
].separator
[1] = '\0';
2677 /* By specifying only one bit, we prevent errors,
2678 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2679 _currency_specs
[curidx
].symbol_pos
= GB(options
, 8, 1);
2681 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx
);
2686 case 0x0D: { // Currency prefix symbol
2687 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2688 uint32 tempfix
= buf
->ReadDWord();
2690 if (curidx
< CURRENCY_END
) {
2691 memcpy(_currency_specs
[curidx
].prefix
, &tempfix
, 4);
2692 _currency_specs
[curidx
].prefix
[4] = 0;
2694 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx
);
2699 case 0x0E: { // Currency suffix symbol
2700 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2701 uint32 tempfix
= buf
->ReadDWord();
2703 if (curidx
< CURRENCY_END
) {
2704 memcpy(&_currency_specs
[curidx
].suffix
, &tempfix
, 4);
2705 _currency_specs
[curidx
].suffix
[4] = 0;
2707 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx
);
2712 case 0x0F: { // Euro introduction dates
2713 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2714 Year year_euro
= buf
->ReadWord();
2716 if (curidx
< CURRENCY_END
) {
2717 _currency_specs
[curidx
].to_euro
= year_euro
;
2719 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx
);
2724 case 0x10: // Snow line height table
2725 if (numinfo
> 1 || IsSnowLineSet()) {
2726 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo
);
2727 } else if (!buf
->HasData (SNOW_LINE_MONTHS
* SNOW_LINE_DAYS
)) {
2728 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf
->Remaining());
2730 byte table
[SNOW_LINE_MONTHS
][SNOW_LINE_DAYS
];
2732 for (uint i
= 0; i
< SNOW_LINE_MONTHS
; i
++) {
2733 for (uint j
= 0; j
< SNOW_LINE_DAYS
; j
++) {
2734 table
[i
][j
] = buf
->ReadByte();
2735 if (_cur
.grffile
->grf_version
>= 8) {
2736 if (table
[i
][j
] != 0xFF) table
[i
][j
] = table
[i
][j
] * (1 + _settings_game
.construction
.max_heightlevel
) / 256;
2738 if (table
[i
][j
] >= 128) {
2742 table
[i
][j
] = table
[i
][j
] * (1 + _settings_game
.construction
.max_heightlevel
) / 128;
2751 case 0x11: // GRF match for engine allocation
2752 /* This is loaded during the reservation stage, so just skip it here. */
2753 /* Each entry is 8 bytes. */
2757 case 0x13: // Gender translation table
2758 case 0x14: // Case translation table
2759 case 0x15: { // Plural form translation
2760 uint curidx
= gvid
+ i
; // The current index, i.e. language.
2761 const LanguageMetadata
*lang
= curidx
< MAX_LANG
? GetLanguage(curidx
) : NULL
;
2763 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx
);
2764 /* Skip over the data. */
2768 while (buf
->ReadByte() != 0) {
2775 if (_cur
.grffile
->language_map
== NULL
) _cur
.grffile
->language_map
= new LanguageMap
[MAX_LANG
];
2778 uint plural_form
= buf
->ReadByte();
2779 if (plural_form
>= LANGUAGE_MAX_PLURAL
) {
2780 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form
);
2782 _cur
.grffile
->language_map
[curidx
].plural_form
= plural_form
;
2788 byte newgrf_id
= buf
->ReadByte(); // The NewGRF (custom) identifier.
2789 if (newgrf_id
== 0) break;
2791 const char *name
= buf
->ReadString(); // The name for the OpenTTD identifier.
2793 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2794 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2795 * is just a subset of UTF8, or they need the bigger UTF8 characters
2796 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2798 size_t len
= Utf8Decode(&c
, name
);
2799 if (c
== NFO_UTF8_IDENTIFIER
) name
+= len
;
2801 LanguageMap::Mapping map
;
2802 map
.newgrf_id
= newgrf_id
;
2804 map
.openttd_id
= lang
->GetGenderIndex(name
);
2805 if (map
.openttd_id
>= MAX_NUM_GENDERS
) {
2806 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name
);
2808 *_cur
.grffile
->language_map
[curidx
].gender_map
.Append() = map
;
2811 map
.openttd_id
= lang
->GetCaseIndex(name
);
2812 if (map
.openttd_id
>= MAX_NUM_CASES
) {
2813 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name
);
2815 *_cur
.grffile
->language_map
[curidx
].case_map
.Append() = map
;
2831 static ChangeInfoResult
GlobalVarReserveInfo(uint gvid
, int numinfo
, int prop
, ByteReader
*buf
)
2833 /* Properties which are handled as a whole */
2835 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2836 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->cargo_list
, "Cargo");
2838 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2839 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->railtype_list
, "Rail type");
2845 /* Properties which are handled per item */
2846 ChangeInfoResult ret
= CIR_SUCCESS
;
2847 for (int i
= 0; i
< numinfo
; i
++) {
2849 case 0x08: // Cost base factor
2850 case 0x15: // Plural form translation
2854 case 0x0A: // Currency display names
2855 case 0x0C: // Currency options
2856 case 0x0F: // Euro introduction dates
2860 case 0x0B: // Currency multipliers
2861 case 0x0D: // Currency prefix symbol
2862 case 0x0E: // Currency suffix symbol
2866 case 0x10: // Snow line height table
2867 buf
->Skip(SNOW_LINE_MONTHS
* SNOW_LINE_DAYS
);
2870 case 0x11: { // GRF match for engine allocation
2871 uint32 s
= buf
->ReadDWord();
2872 uint32 t
= buf
->ReadDWord();
2873 SetNewGRFOverride(s
, t
);
2877 case 0x13: // Gender translation table
2878 case 0x14: // Case translation table
2879 while (buf
->ReadByte() != 0) {
2895 * Define properties for cargoes
2896 * @param cid Local ID of the cargo.
2897 * @param numinfo Number of subsequent IDs to change the property for.
2898 * @param prop The property to change.
2899 * @param buf The property value.
2900 * @return ChangeInfoResult.
2902 static ChangeInfoResult
CargoChangeInfo(uint cid
, int numinfo
, int prop
, ByteReader
*buf
)
2904 ChangeInfoResult ret
= CIR_SUCCESS
;
2906 if (cid
+ numinfo
> NUM_CARGO
) {
2907 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid
+ numinfo
, NUM_CARGO
- 1);
2908 return CIR_INVALID_ID
;
2911 for (int i
= 0; i
< numinfo
; i
++) {
2912 CargoSpec
*cs
= CargoSpec::Get(cid
+ i
);
2915 case 0x08: // Bit number of cargo
2916 cs
->bitnum
= buf
->ReadByte();
2917 if (cs
->IsValid()) {
2918 cs
->grffile
= _cur
.grffile
;
2919 SetBit(_cargo_mask
, cid
+ i
);
2921 ClrBit(_cargo_mask
, cid
+ i
);
2925 case 0x09: // String ID for cargo type name
2926 AddStringForMapping(buf
->ReadWord(), &cs
->name
);
2929 case 0x0A: // String for 1 unit of cargo
2930 AddStringForMapping(buf
->ReadWord(), &cs
->name_single
);
2933 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2934 case 0x1B: // String for cargo units
2935 /* String for units of cargo. This is different in OpenTTD
2936 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2937 * Property 1B is used to set OpenTTD's behaviour. */
2938 AddStringForMapping(buf
->ReadWord(), &cs
->units_volume
);
2941 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2942 case 0x1C: // String for any amount of cargo
2943 /* Strings for an amount of cargo. This is different in OpenTTD
2944 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2945 * Property 1C is used to set OpenTTD's behaviour. */
2946 AddStringForMapping(buf
->ReadWord(), &cs
->quantifier
);
2949 case 0x0D: // String for two letter cargo abbreviation
2950 AddStringForMapping(buf
->ReadWord(), &cs
->abbrev
);
2953 case 0x0E: // Sprite ID for cargo icon
2954 cs
->sprite
= buf
->ReadWord();
2957 case 0x0F: // Weight of one unit of cargo
2958 cs
->weight
= buf
->ReadByte();
2961 case 0x10: // Used for payment calculation
2962 cs
->transit_days
[0] = buf
->ReadByte();
2965 case 0x11: // Used for payment calculation
2966 cs
->transit_days
[1] = buf
->ReadByte();
2969 case 0x12: // Base cargo price
2970 cs
->initial_payment
= buf
->ReadDWord();
2973 case 0x13: // Colour for station rating bars
2974 cs
->rating_colour
= buf
->ReadByte();
2977 case 0x14: // Colour for cargo graph
2978 cs
->legend_colour
= buf
->ReadByte();
2981 case 0x15: // Freight status
2982 cs
->is_freight
= (buf
->ReadByte() != 0);
2985 case 0x16: // Cargo classes
2986 cs
->classes
= buf
->ReadWord();
2989 case 0x17: // Cargo label
2990 cs
->label
= buf
->ReadDWord();
2991 cs
->label
= BSWAP32(cs
->label
);
2994 case 0x18: { // Town growth substitute type
2995 uint8 substitute_type
= buf
->ReadByte();
2997 switch (substitute_type
) {
2998 case 0x00: cs
->town_effect
= TE_PASSENGERS
; break;
2999 case 0x02: cs
->town_effect
= TE_MAIL
; break;
3000 case 0x05: cs
->town_effect
= TE_GOODS
; break;
3001 case 0x09: cs
->town_effect
= TE_WATER
; break;
3002 case 0x0B: cs
->town_effect
= TE_FOOD
; break;
3004 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type
);
3006 case 0xFF: cs
->town_effect
= TE_NONE
; break;
3011 case 0x19: // Town growth coefficient
3012 cs
->multipliertowngrowth
= buf
->ReadWord();
3015 case 0x1A: // Bitmask of callbacks to use
3016 cs
->callback_mask
= buf
->ReadByte();
3019 case 0x1D: // Vehicle capacity muliplier
3020 cs
->multiplier
= max
<uint16
>(1u, buf
->ReadWord());
3034 * Define properties for sound effects
3035 * @param sid Local ID of the sound.
3036 * @param numinfo Number of subsequent IDs to change the property for.
3037 * @param prop The property to change.
3038 * @param buf The property value.
3039 * @return ChangeInfoResult.
3041 static ChangeInfoResult
SoundEffectChangeInfo(uint sid
, int numinfo
, int prop
, ByteReader
*buf
)
3043 ChangeInfoResult ret
= CIR_SUCCESS
;
3045 if (_cur
.grffile
->sound_offset
== 0) {
3046 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3047 return CIR_INVALID_ID
;
3050 if (sid
+ numinfo
- ORIGINAL_SAMPLE_COUNT
> _cur
.grffile
->num_sounds
) {
3051 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid
+ numinfo
, ORIGINAL_SAMPLE_COUNT
+ _cur
.grffile
->num_sounds
);
3052 return CIR_INVALID_ID
;
3055 for (int i
= 0; i
< numinfo
; i
++) {
3056 SoundEntry
*sound
= GetSound(sid
+ i
+ _cur
.grffile
->sound_offset
- ORIGINAL_SAMPLE_COUNT
);
3059 case 0x08: // Relative volume
3060 sound
->volume
= buf
->ReadByte();
3063 case 0x09: // Priority
3064 sound
->priority
= buf
->ReadByte();
3067 case 0x0A: { // Override old sound
3068 SoundID orig_sound
= buf
->ReadByte();
3070 if (orig_sound
>= ORIGINAL_SAMPLE_COUNT
) {
3071 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound
, ORIGINAL_SAMPLE_COUNT
);
3073 SoundEntry
*old_sound
= GetSound(orig_sound
);
3075 /* Literally copy the data of the new sound over the original */
3076 *old_sound
= *sound
;
3091 * Ignore an industry tile property
3092 * @param prop The property to ignore.
3093 * @param buf The property value.
3094 * @return ChangeInfoResult.
3096 static ChangeInfoResult
IgnoreIndustryTileProperty(int prop
, ByteReader
*buf
)
3098 ChangeInfoResult ret
= CIR_SUCCESS
;
3125 * Define properties for industry tiles
3126 * @param indtid Local ID of the industry tile.
3127 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3128 * @param prop The property to change.
3129 * @param buf The property value.
3130 * @return ChangeInfoResult.
3132 static ChangeInfoResult
IndustrytilesChangeInfo(uint indtid
, int numinfo
, int prop
, ByteReader
*buf
)
3134 ChangeInfoResult ret
= CIR_SUCCESS
;
3136 if (indtid
+ numinfo
> NUM_INDUSTRYTILES_PER_GRF
) {
3137 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid
+ numinfo
, NUM_INDUSTRYTILES_PER_GRF
);
3138 return CIR_INVALID_ID
;
3141 /* Allocate industry tile specs if they haven't been allocated already. */
3142 if (_cur
.grffile
->indtspec
== NULL
) {
3143 _cur
.grffile
->indtspec
= xcalloct
<IndustryTileSpec
*>(NUM_INDUSTRYTILES_PER_GRF
);
3146 for (int i
= 0; i
< numinfo
; i
++) {
3147 IndustryTileSpec
*tsp
= _cur
.grffile
->indtspec
[indtid
+ i
];
3149 if (prop
!= 0x08 && tsp
== NULL
) {
3150 ChangeInfoResult cir
= IgnoreIndustryTileProperty(prop
, buf
);
3151 if (cir
> ret
) ret
= cir
;
3156 case 0x08: { // Substitute industry tile type
3157 byte subs_id
= buf
->ReadByte();
3159 if (subs_id
>= NEW_INDUSTRYTILEOFFSET
) {
3160 /* The substitute id must be one of the original industry tile. */
3161 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id
, indtid
+ i
);
3165 /* Allocate space for this industry. */
3167 tsp
= xmemdupt (&_industry_tile_specs
[subs_id
]);
3168 _cur
.grffile
->indtspec
[indtid
+ i
] = tsp
;
3170 tsp
->enabled
= true;
3172 /* A copied tile should not have the animation infos copied too.
3173 * The anim_state should be left untouched, though
3174 * It is up to the author to animate them himself */
3175 tsp
->anim_production
= INDUSTRYTILE_NOANIM
;
3176 tsp
->anim_next
= INDUSTRYTILE_NOANIM
;
3178 tsp
->grf_prop
.local_id
= indtid
+ i
;
3179 tsp
->grf_prop
.subst_id
= subs_id
;
3180 tsp
->grf_prop
.grffile
= _cur
.grffile
;
3181 _industile_mngr
.AddEntityID(indtid
+ i
, _cur
.grffile
->grfid
, subs_id
); // pre-reserve the tile slot
3186 case 0x09: { // Industry tile override
3187 byte ovrid
= buf
->ReadByte();
3189 /* The industry being overridden must be an original industry. */
3190 if (ovrid
>= NEW_INDUSTRYTILEOFFSET
) {
3191 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid
, indtid
+ i
);
3195 _industile_mngr
.Add(indtid
+ i
, _cur
.grffile
->grfid
, ovrid
);
3199 case 0x0A: // Tile acceptance
3202 uint16 acctp
= buf
->ReadWord();
3203 tsp
->accepts_cargo
[prop
- 0x0A] = GetCargoTranslation(GB(acctp
, 0, 8), _cur
.grffile
);
3204 tsp
->acceptance
[prop
- 0x0A] = GB(acctp
, 8, 8);
3208 case 0x0D: // Land shape flags
3209 tsp
->slopes_refused
= (Slope
)buf
->ReadByte();
3212 case 0x0E: // Callback mask
3213 tsp
->callback_mask
= buf
->ReadByte();
3216 case 0x0F: // Animation information
3217 tsp
->animation
.frames
= buf
->ReadByte();
3218 tsp
->animation
.status
= buf
->ReadByte();
3221 case 0x10: // Animation speed
3222 tsp
->animation
.speed
= buf
->ReadByte();
3225 case 0x11: // Triggers for callback 25
3226 tsp
->animation
.triggers
= buf
->ReadByte();
3229 case 0x12: // Special flags
3230 tsp
->special_flags
= (IndustryTileSpecialFlags
)buf
->ReadByte();
3243 * Ignore an industry property
3244 * @param prop The property to ignore.
3245 * @param buf The property value.
3246 * @return ChangeInfoResult.
3248 static ChangeInfoResult
IgnoreIndustryProperty(int prop
, ByteReader
*buf
)
3250 ChangeInfoResult ret
= CIR_SUCCESS
;
3288 byte num_table
= buf
->ReadByte();
3289 for (byte j
= 0; j
< num_table
; j
++) {
3290 for (uint k
= 0;; k
++) {
3291 byte x
= buf
->ReadByte();
3292 if (x
== 0xFE && k
== 0) {
3298 byte y
= buf
->ReadByte();
3299 if (x
== 0 && y
== 0x80) break;
3301 byte gfx
= buf
->ReadByte();
3302 if (gfx
== 0xFE) buf
->ReadWord();
3309 for (byte j
= 0; j
< 3; j
++) buf
->ReadByte();
3313 byte number_of_sounds
= buf
->ReadByte();
3314 for (uint8 j
= 0; j
< number_of_sounds
; j
++) {
3328 * Validate the industry layout; e.g. to prevent duplicate tiles.
3329 * @param layout The layout to check.
3330 * @param size The size of the layout.
3331 * @return True if the layout is deemed valid.
3333 static bool ValidateIndustryLayout(const IndustryTileTable
*layout
, int size
)
3335 for (int i
= 0; i
< size
- 1; i
++) {
3336 for (int j
= i
+ 1; j
< size
; j
++) {
3337 if (layout
[i
].ti
.x
== layout
[j
].ti
.x
&&
3338 layout
[i
].ti
.y
== layout
[j
].ti
.y
) {
3346 /** Clean the tile table of the IndustrySpec if it's needed. */
3347 static void CleanIndustryTileTable(IndustrySpec
*ind
)
3349 if (HasBit(ind
->cleanup_flag
, CLEAN_TILELAYOUT
) && ind
->table
!= NULL
) {
3350 for (int j
= 0; j
< ind
->num_table
; j
++) {
3351 /* remove the individual layouts */
3352 free(ind
->table
[j
]);
3354 /* remove the layouts pointers */
3361 * Define properties for industries
3362 * @param indid Local ID of the industry.
3363 * @param numinfo Number of subsequent industry IDs to change the property for.
3364 * @param prop The property to change.
3365 * @param buf The property value.
3366 * @return ChangeInfoResult.
3368 static ChangeInfoResult
IndustriesChangeInfo(uint indid
, int numinfo
, int prop
, ByteReader
*buf
)
3370 ChangeInfoResult ret
= CIR_SUCCESS
;
3372 if (indid
+ numinfo
> NUM_INDUSTRYTYPES_PER_GRF
) {
3373 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid
+ numinfo
, NUM_INDUSTRYTYPES_PER_GRF
);
3374 return CIR_INVALID_ID
;
3377 /* Allocate industry specs if they haven't been allocated already. */
3378 if (_cur
.grffile
->industryspec
== NULL
) {
3379 _cur
.grffile
->industryspec
= xcalloct
<IndustrySpec
*>(NUM_INDUSTRYTYPES_PER_GRF
);
3382 for (int i
= 0; i
< numinfo
; i
++) {
3383 IndustrySpec
*indsp
= _cur
.grffile
->industryspec
[indid
+ i
];
3385 if (prop
!= 0x08 && indsp
== NULL
) {
3386 ChangeInfoResult cir
= IgnoreIndustryProperty(prop
, buf
);
3387 if (cir
> ret
) ret
= cir
;
3392 case 0x08: { // Substitute industry type
3393 byte subs_id
= buf
->ReadByte();
3395 if (subs_id
== 0xFF) {
3396 /* Instead of defining a new industry, a substitute industry id
3397 * of 0xFF disables the old industry with the current id. */
3398 _industry_specs
[indid
+ i
].enabled
= false;
3400 } else if (subs_id
>= NEW_INDUSTRYOFFSET
) {
3401 /* The substitute id must be one of the original industry. */
3402 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id
, indid
+ i
);
3406 /* Allocate space for this industry.
3407 * Only need to do it once. If ever it is called again, it should not
3409 if (indsp
== NULL
) {
3410 indsp
= xmemdupt (&_origin_industry_specs
[subs_id
]);
3411 _cur
.grffile
->industryspec
[indid
+ i
] = indsp
;
3413 indsp
->enabled
= true;
3414 indsp
->grf_prop
.local_id
= indid
+ i
;
3415 indsp
->grf_prop
.subst_id
= subs_id
;
3416 indsp
->grf_prop
.grffile
= _cur
.grffile
;
3417 /* If the grf industry needs to check its surounding upon creation, it should
3418 * rely on callbacks, not on the original placement functions */
3419 indsp
->check_proc
= CHECK_NOTHING
;
3424 case 0x09: { // Industry type override
3425 byte ovrid
= buf
->ReadByte();
3427 /* The industry being overridden must be an original industry. */
3428 if (ovrid
>= NEW_INDUSTRYOFFSET
) {
3429 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid
, indid
+ i
);
3432 indsp
->grf_prop
.override
= ovrid
;
3433 _industry_mngr
.Add(indid
+ i
, _cur
.grffile
->grfid
, ovrid
);
3437 case 0x0A: { // Set industry layout(s)
3438 byte new_num_layouts
= buf
->ReadByte(); // Number of layaouts
3439 /* We read the total size in bytes, but we can't rely on the
3440 * newgrf to provide a sane value. First assume the value is
3441 * sane but later on we make sure we enlarge the array if the
3442 * newgrf contains more data. Each tile uses either 3 or 5
3443 * bytes, so to play it safe we assume 3. */
3444 uint32 def_num_tiles
= buf
->ReadDWord() / 3 + 1;
3445 IndustryTileTable
**tile_table
= xcalloct
<IndustryTileTable
*>(new_num_layouts
); // Table with tiles to compose an industry
3446 IndustryTileTable
*itt
= xcalloct
<IndustryTileTable
>(def_num_tiles
); // Temporary array to read the tile layouts from the GRF
3448 const IndustryTileTable
*copy_from
;
3451 for (byte j
= 0; j
< new_num_layouts
; j
++) {
3452 for (uint k
= 0;; k
++) {
3453 if (k
>= def_num_tiles
) {
3454 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid
);
3455 /* Size reported by newgrf was not big enough so enlarge the array. */
3457 itt
= xrealloct
<IndustryTileTable
>(itt
, def_num_tiles
);
3460 itt
[k
].ti
.x
= buf
->ReadByte(); // Offsets from northermost tile
3462 if (itt
[k
].ti
.x
== 0xFE && k
== 0) {
3463 /* This means we have to borrow the layout from an old industry */
3464 IndustryType type
= buf
->ReadByte(); // industry holding required layout
3465 byte laynbr
= buf
->ReadByte(); // layout number to borrow
3467 copy_from
= _origin_industry_specs
[type
].table
[laynbr
];
3468 for (size
= 1;; size
++) {
3469 if (copy_from
[size
- 1].ti
.x
== -0x80 && copy_from
[size
- 1].ti
.y
== 0) break;
3474 itt
[k
].ti
.y
= buf
->ReadByte(); // Or table definition finalisation
3476 if (itt
[k
].ti
.x
== 0 && itt
[k
].ti
.y
== 0x80) {
3477 /* Not the same terminator. The one we are using is rather
3478 x = -80, y = x . So, adjust it. */
3479 itt
[k
].ti
.x
= -0x80;
3488 itt
[k
].gfx
= buf
->ReadByte();
3490 if (itt
[k
].gfx
== 0xFE) {
3491 /* Use a new tile from this GRF */
3492 int local_tile_id
= buf
->ReadWord();
3494 /* Read the ID from the _industile_mngr. */
3495 int tempid
= _industile_mngr
.GetID(local_tile_id
, _cur
.grffile
->grfid
);
3497 if (tempid
== INVALID_INDUSTRYTILE
) {
3498 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id
, indid
);
3500 /* Declared as been valid, can be used */
3501 itt
[k
].gfx
= tempid
;
3505 } else if (itt
[k
].gfx
== 0xFF) {
3506 itt
[k
].ti
.x
= (int8
)GB(itt
[k
].ti
.x
, 0, 8);
3507 itt
[k
].ti
.y
= (int8
)GB(itt
[k
].ti
.y
, 0, 8);
3509 /* When there were only 256x256 maps, TileIndex was a uint16 and
3510 * itt[k].ti was just a TileIndexDiff that was added to it.
3511 * As such negative "x" values were shifted into the "y" position.
3512 * x = -1, y = 1 -> x = 255, y = 0
3513 * Since GRF version 8 the position is interpreted as pair of independent int8.
3514 * For GRF version < 8 we need to emulate the old shifting behaviour.
3516 if (_cur
.grffile
->grf_version
< 8 && itt
[k
].ti
.x
< 0) itt
[k
].ti
.y
+= 1;
3520 if (!ValidateIndustryLayout(copy_from
, size
)) {
3521 /* The industry layout was not valid, so skip this one. */
3522 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid
);
3526 tile_table
[j
] = xmemdupt (copy_from
, size
);
3530 for (int i
= 0; i
< new_num_layouts
; i
++) {
3531 free(tile_table
[i
]);
3538 /* Clean the tile table if it was already set by a previous prop A. */
3539 CleanIndustryTileTable(indsp
);
3540 /* Install final layout construction in the industry spec */
3541 indsp
->num_table
= new_num_layouts
;
3542 indsp
->table
= tile_table
;
3543 SetBit(indsp
->cleanup_flag
, CLEAN_TILELAYOUT
);
3548 case 0x0B: // Industry production flags
3549 indsp
->life_type
= (IndustryLifeType
)buf
->ReadByte();
3552 case 0x0C: // Industry closure message
3553 AddStringForMapping(buf
->ReadWord(), &indsp
->closure_text
);
3556 case 0x0D: // Production increase message
3557 AddStringForMapping(buf
->ReadWord(), &indsp
->production_up_text
);
3560 case 0x0E: // Production decrease message
3561 AddStringForMapping(buf
->ReadWord(), &indsp
->production_down_text
);
3564 case 0x0F: // Fund cost multiplier
3565 indsp
->cost_multiplier
= buf
->ReadByte();
3568 case 0x10: // Production cargo types
3569 for (byte j
= 0; j
< 2; j
++) {
3570 indsp
->produced_cargo
[j
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3574 case 0x11: // Acceptance cargo types
3575 for (byte j
= 0; j
< 3; j
++) {
3576 indsp
->accepts_cargo
[j
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3578 buf
->ReadByte(); // Unnused, eat it up
3581 case 0x12: // Production multipliers
3583 indsp
->production_rate
[prop
- 0x12] = buf
->ReadByte();
3586 case 0x14: // Minimal amount of cargo distributed
3587 indsp
->minimal_cargo
= buf
->ReadByte();
3590 case 0x15: { // Random sound effects
3591 indsp
->number_of_sounds
= buf
->ReadByte();
3592 uint8
*sounds
= buf
->Dup (indsp
->number_of_sounds
);
3594 if (HasBit(indsp
->cleanup_flag
, CLEAN_RANDOMSOUNDS
)) {
3595 free(indsp
->random_sounds
);
3597 indsp
->random_sounds
= sounds
;
3598 SetBit(indsp
->cleanup_flag
, CLEAN_RANDOMSOUNDS
);
3602 case 0x16: // Conflicting industry types
3603 for (byte j
= 0; j
< 3; j
++) indsp
->conflicting
[j
] = buf
->ReadByte();
3606 case 0x17: // Probability in random game
3607 indsp
->appear_creation
[_settings_game
.game_creation
.landscape
] = buf
->ReadByte();
3610 case 0x18: // Probability during gameplay
3611 indsp
->appear_ingame
[_settings_game
.game_creation
.landscape
] = buf
->ReadByte();
3614 case 0x19: // Map colour
3615 indsp
->map_colour
= buf
->ReadByte();
3618 case 0x1A: // Special industry flags to define special behavior
3619 indsp
->behaviour
= (IndustryBehaviour
)buf
->ReadDWord();
3622 case 0x1B: // New industry text ID
3623 AddStringForMapping(buf
->ReadWord(), &indsp
->new_industry_text
);
3626 case 0x1C: // Input cargo multipliers for the three input cargo types
3629 uint32 multiples
= buf
->ReadDWord();
3630 indsp
->input_cargo_multiplier
[prop
- 0x1C][0] = GB(multiples
, 0, 16);
3631 indsp
->input_cargo_multiplier
[prop
- 0x1C][1] = GB(multiples
, 16, 16);
3635 case 0x1F: // Industry name
3636 AddStringForMapping(buf
->ReadWord(), &indsp
->name
);
3639 case 0x20: // Prospecting success chance
3640 indsp
->prospecting_chance
= buf
->ReadDWord();
3643 case 0x21: // Callback mask
3644 case 0x22: { // Callback additional mask
3645 byte aflag
= buf
->ReadByte();
3646 SB(indsp
->callback_mask
, (prop
- 0x21) * 8, 8, aflag
);
3650 case 0x23: // removal cost multiplier
3651 indsp
->removal_cost_multiplier
= buf
->ReadDWord();
3654 case 0x24: { // name for nearby station
3655 uint16 str
= buf
->ReadWord();
3657 indsp
->station_name
= STR_NULL
;
3659 AddStringForMapping(str
, &indsp
->station_name
);
3674 * Clone an AirportSpec.
3675 * @param src The AirportSpec to clone.
3676 * @return A fresh copy of the AirportSpec
3678 static AirportSpec
*CloneAirportSpec (const AirportSpec
*src
)
3680 AirportSpec
*as
= xmemdupt (src
);
3682 AirportTileTable
**table_list
= xmalloct
<AirportTileTable
*> (src
->num_table
);
3683 for (uint i
= 0; i
< src
->num_table
; i
++) {
3685 const AirportTileTable
*it
= src
->table
[i
];
3688 } while ((++it
)->ti
.x
!= -0x80);
3689 table_list
[i
] = xmemdupt (src
->table
[i
], num_tiles
);
3691 as
->table
= table_list
;
3693 as
->depot_table
= xmemdupt (src
->depot_table
, src
->nof_depots
);
3699 * Define properties for airports
3700 * @param airport Local ID of the airport.
3701 * @param numinfo Number of subsequent airport IDs to change the property for.
3702 * @param prop The property to change.
3703 * @param buf The property value.
3704 * @return ChangeInfoResult.
3706 static ChangeInfoResult
AirportChangeInfo(uint airport
, int numinfo
, int prop
, ByteReader
*buf
)
3708 ChangeInfoResult ret
= CIR_SUCCESS
;
3710 if (airport
+ numinfo
> NUM_AIRPORTS_PER_GRF
) {
3711 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport
+ numinfo
, NUM_AIRPORTS_PER_GRF
);
3712 return CIR_INVALID_ID
;
3715 /* Allocate industry specs if they haven't been allocated already. */
3716 if (_cur
.grffile
->airportspec
== NULL
) {
3717 _cur
.grffile
->airportspec
= xcalloct
<AirportSpec
*>(NUM_AIRPORTS_PER_GRF
);
3720 for (int i
= 0; i
< numinfo
; i
++) {
3721 AirportSpec
*as
= _cur
.grffile
->airportspec
[airport
+ i
];
3723 if (as
== NULL
&& prop
!= 0x08 && prop
!= 0x09) {
3724 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport
+ i
);
3725 return CIR_INVALID_ID
;
3729 case 0x08: { // Modify original airport
3730 byte subs_id
= buf
->ReadByte();
3732 if (subs_id
== 0xFF) {
3733 /* Instead of defining a new airport, an airport id
3734 * of 0xFF disables the old airport with the current id. */
3735 AirportSpec::GetWithoutOverride(airport
+ i
)->enabled
= false;
3737 } else if (subs_id
>= NEW_AIRPORT_OFFSET
) {
3738 /* The substitute id must be one of the original airports. */
3739 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id
, airport
+ i
);
3743 /* Allocate space for this airport.
3744 * Only need to do it once. If ever it is called again, it should not
3747 as
= CloneAirportSpec (AirportSpec::GetWithoutOverride(subs_id
));
3748 _cur
.grffile
->airportspec
[airport
+ i
] = as
;
3751 as
->grf_prop
.local_id
= airport
+ i
;
3752 as
->grf_prop
.subst_id
= subs_id
;
3753 as
->grf_prop
.grffile
= _cur
.grffile
;
3754 /* override the default airport */
3755 _airport_mngr
.Add(airport
+ i
, _cur
.grffile
->grfid
, subs_id
);
3760 case 0x0A: { // Set airport layout
3761 as
->num_table
= buf
->ReadByte(); // Number of layaouts
3762 as
->rotation
= xmalloct
<Direction
>(as
->num_table
);
3763 uint32 defsize
= buf
->ReadDWord(); // Total size of the definition
3764 AirportTileTable
**tile_table
= xcalloct
<AirportTileTable
*>(as
->num_table
); // Table with tiles to compose the airport
3765 AirportTileTable
*att
= xcalloct
<AirportTileTable
>(defsize
); // Temporary array to read the tile layouts from the GRF
3767 const AirportTileTable
*copy_from
;
3769 for (byte j
= 0; j
< as
->num_table
; j
++) {
3770 as
->rotation
[j
] = (Direction
)buf
->ReadByte();
3771 for (int k
= 0;; k
++) {
3772 att
[k
].ti
.x
= buf
->ReadByte(); // Offsets from northermost tile
3773 att
[k
].ti
.y
= buf
->ReadByte();
3775 if (att
[k
].ti
.x
== 0 && att
[k
].ti
.y
== 0x80) {
3776 /* Not the same terminator. The one we are using is rather
3777 * x = -80, y = 0 . So, adjust it. */
3778 att
[k
].ti
.x
= -0x80;
3787 att
[k
].gfx
= buf
->ReadByte();
3789 if (att
[k
].gfx
== 0xFE) {
3790 /* Use a new tile from this GRF */
3791 int local_tile_id
= buf
->ReadWord();
3793 /* Read the ID from the _airporttile_mngr. */
3794 uint16 tempid
= _airporttile_mngr
.GetID(local_tile_id
, _cur
.grffile
->grfid
);
3796 if (tempid
== INVALID_AIRPORTTILE
) {
3797 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id
, airport
+ i
);
3799 /* Declared as been valid, can be used */
3800 att
[k
].gfx
= tempid
;
3804 } else if (att
[k
].gfx
== 0xFF) {
3805 att
[k
].ti
.x
= (int8
)GB(att
[k
].ti
.x
, 0, 8);
3806 att
[k
].ti
.y
= (int8
)GB(att
[k
].ti
.y
, 0, 8);
3809 if (as
->rotation
[j
] == DIR_E
|| as
->rotation
[j
] == DIR_W
) {
3810 as
->size_x
= max
<byte
>(as
->size_x
, att
[k
].ti
.y
+ 1);
3811 as
->size_y
= max
<byte
>(as
->size_y
, att
[k
].ti
.x
+ 1);
3813 as
->size_x
= max
<byte
>(as
->size_x
, att
[k
].ti
.x
+ 1);
3814 as
->size_y
= max
<byte
>(as
->size_y
, att
[k
].ti
.y
+ 1);
3817 tile_table
[j
] = xmemdupt (copy_from
, size
);
3819 /* Install final layout construction in the airport spec */
3820 as
->table
= tile_table
;
3823 for (int i
= 0; i
< as
->num_table
; i
++) {
3824 free(tile_table
[i
]);
3834 as
->min_year
= buf
->ReadWord();
3835 as
->max_year
= buf
->ReadWord();
3836 if (as
->max_year
== 0xFFFF) as
->max_year
= MAX_YEAR
;
3840 as
->ttd_airport_type
= (TTDPAirportType
)buf
->ReadByte();
3844 as
->catchment
= Clamp(buf
->ReadByte(), 1, MAX_CATCHMENT
);
3848 as
->noise_level
= buf
->ReadByte();
3852 AddStringForMapping(buf
->ReadWord(), &as
->name
);
3855 case 0x11: // Maintenance cost factor
3856 as
->maintenance_cost
= buf
->ReadWord();
3869 * Ignore properties for objects
3870 * @param prop The property to ignore.
3871 * @param buf The property value.
3872 * @return ChangeInfoResult.
3874 static ChangeInfoResult
IgnoreObjectProperty(uint prop
, ByteReader
*buf
)
3876 ChangeInfoResult ret
= CIR_SUCCESS
;
3913 * Define properties for objects
3914 * @param id Local ID of the object.
3915 * @param numinfo Number of subsequent objectIDs to change the property for.
3916 * @param prop The property to change.
3917 * @param buf The property value.
3918 * @return ChangeInfoResult.
3920 static ChangeInfoResult
ObjectChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
3922 ChangeInfoResult ret
= CIR_SUCCESS
;
3924 if (id
+ numinfo
> NUM_OBJECTS_PER_GRF
) {
3925 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id
+ numinfo
, NUM_OBJECTS_PER_GRF
);
3926 return CIR_INVALID_ID
;
3929 /* Allocate object specs if they haven't been allocated already. */
3930 if (_cur
.grffile
->objectspec
== NULL
) {
3931 _cur
.grffile
->objectspec
= xcalloct
<ObjectSpec
*>(NUM_OBJECTS_PER_GRF
);
3934 for (int i
= 0; i
< numinfo
; i
++) {
3935 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[id
+ i
];
3937 if (prop
!= 0x08 && spec
== NULL
) {
3938 /* If the object property 08 is not yet set, ignore this property */
3939 ChangeInfoResult cir
= IgnoreObjectProperty(prop
, buf
);
3940 if (cir
> ret
) ret
= cir
;
3945 case 0x08: { // Class ID
3946 ObjectSpec
**ospec
= &_cur
.grffile
->objectspec
[id
+ i
];
3948 /* Allocate space for this object. */
3949 if (*ospec
== NULL
) {
3950 *ospec
= xcalloct
<ObjectSpec
>();
3951 (*ospec
)->views
= 1; // Default for NewGRFs that don't set it.
3954 /* Swap classid because we read it in BE. */
3955 uint32 classid
= buf
->ReadDWord();
3956 (*ospec
)->cls_id
= ObjectClass::Allocate(BSWAP32(classid
));
3957 (*ospec
)->enabled
= true;
3961 case 0x09: { // Class name
3962 ObjectClass
*objclass
= ObjectClass::Get(spec
->cls_id
);
3963 AddStringForMapping(buf
->ReadWord(), &objclass
->name
);
3967 case 0x0A: // Object name
3968 AddStringForMapping(buf
->ReadWord(), &spec
->name
);
3971 case 0x0B: // Climate mask
3972 spec
->climate
= buf
->ReadByte();
3976 spec
->size
= buf
->ReadByte();
3979 case 0x0D: // Build cost multipler
3980 spec
->build_cost_multiplier
= buf
->ReadByte();
3981 spec
->clear_cost_multiplier
= spec
->build_cost_multiplier
;
3984 case 0x0E: // Introduction date
3985 spec
->introduction_date
= buf
->ReadDWord();
3988 case 0x0F: // End of life
3989 spec
->end_of_life_date
= buf
->ReadDWord();
3993 spec
->flags
= (ObjectFlags
)buf
->ReadWord();
3994 _loaded_newgrf_features
.has_2CC
|= (spec
->flags
& OBJECT_FLAG_2CC_COLOUR
) != 0;
3997 case 0x11: // Animation info
3998 spec
->animation
.frames
= buf
->ReadByte();
3999 spec
->animation
.status
= buf
->ReadByte();
4002 case 0x12: // Animation speed
4003 spec
->animation
.speed
= buf
->ReadByte();
4006 case 0x13: // Animation triggers
4007 spec
->animation
.triggers
= buf
->ReadWord();
4010 case 0x14: // Removal cost multiplier
4011 spec
->clear_cost_multiplier
= buf
->ReadByte();
4014 case 0x15: // Callback mask
4015 spec
->callback_mask
= buf
->ReadWord();
4018 case 0x16: // Building height
4019 spec
->height
= buf
->ReadByte();
4023 spec
->views
= buf
->ReadByte();
4024 if (spec
->views
!= 1 && spec
->views
!= 2 && spec
->views
!= 4) {
4025 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec
->views
, id
+ i
);
4030 case 0x18: // Amount placed on 256^2 map on map creation
4031 spec
->generate_amount
= buf
->ReadByte();
4044 * Define properties for railtypes
4045 * @param id ID of the railtype.
4046 * @param numinfo Number of subsequent IDs to change the property for.
4047 * @param prop The property to change.
4048 * @param buf The property value.
4049 * @return ChangeInfoResult.
4051 static ChangeInfoResult
RailTypeChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4053 ChangeInfoResult ret
= CIR_SUCCESS
;
4055 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
4057 if (id
+ numinfo
> RAILTYPE_END
) {
4058 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id
+ numinfo
, RAILTYPE_END
);
4059 return CIR_INVALID_ID
;
4062 for (int i
= 0; i
< numinfo
; i
++) {
4063 RailType rt
= _cur
.grffile
->railtype_map
[id
+ i
];
4064 if (rt
== INVALID_RAILTYPE
) return CIR_INVALID_ID
;
4066 RailtypeInfo
*rti
= &_railtypes
[rt
];
4069 case 0x08: // Label of rail type
4070 /* Skipped here as this is loaded during reservation stage. */
4074 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4075 uint16 str
= buf
->ReadWord();
4076 AddStringForMapping(str
, &rti
->strings
.toolbar_caption
);
4077 if (_cur
.grffile
->grf_version
< 8) {
4078 AddStringForMapping(str
, &rti
->strings
.name
);
4083 case 0x0A: // Menu text of railtype
4084 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.menu_text
);
4087 case 0x0B: // Build window caption
4088 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.build_caption
);
4091 case 0x0C: // Autoreplace text
4092 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.replace_text
);
4095 case 0x0D: // New locomotive text
4096 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.new_loco
);
4099 case 0x0E: // Compatible railtype list
4100 case 0x0F: // Powered railtype list
4101 case 0x18: // Railtype list required for date introduction
4102 case 0x19: // Introduced railtype list
4104 /* Rail type compatibility bits are added to the existing bits
4105 * to allow multiple GRFs to modify compatibility with the
4106 * default rail types. */
4107 int n
= buf
->ReadByte();
4108 for (int j
= 0; j
!= n
; j
++) {
4109 RailTypeLabel label
= buf
->ReadDWord();
4110 RailType rt
= GetRailTypeByLabel(BSWAP32(label
), false);
4111 if (rt
!= INVALID_RAILTYPE
) {
4113 case 0x0F: SetBit(rti
->powered_railtypes
, rt
); // Powered implies compatible.
4114 case 0x0E: SetBit(rti
->compatible_railtypes
, rt
); break;
4115 case 0x18: SetBit(rti
->introduction_required_railtypes
, rt
); break;
4116 case 0x19: SetBit(rti
->introduces_railtypes
, rt
); break;
4123 case 0x10: // Rail Type flags
4124 rti
->flags
= (RailTypeFlags
)buf
->ReadByte();
4127 case 0x11: // Curve speed advantage
4128 rti
->curve_speed
= buf
->ReadByte();
4131 case 0x12: // Station graphic
4132 rti
->fallback_railtype
= Clamp(buf
->ReadByte(), 0, 2);
4135 case 0x13: // Construction cost factor
4136 rti
->cost_multiplier
= buf
->ReadWord();
4139 case 0x14: // Speed limit
4140 rti
->max_speed
= buf
->ReadWord();
4143 case 0x15: // Acceleration model
4144 rti
->acceleration_type
= Clamp(buf
->ReadByte(), 0, 2);
4147 case 0x16: // Map colour
4148 rti
->map_colour
= buf
->ReadByte();
4151 case 0x17: // Introduction date
4152 rti
->introduction_date
= buf
->ReadDWord();
4155 case 0x1A: // Sort order
4156 rti
->sorting_order
= buf
->ReadByte();
4159 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4160 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.name
);
4163 case 0x1C: // Maintenance cost factor
4164 rti
->maintenance_multiplier
= buf
->ReadWord();
4167 case 0x1D: // Alternate rail type label list
4168 /* Skipped here as this is loaded during reservation stage. */
4169 for (int j
= buf
->ReadByte(); j
!= 0; j
--) buf
->ReadDWord();
4181 static ChangeInfoResult
RailTypeReserveInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4183 ChangeInfoResult ret
= CIR_SUCCESS
;
4185 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
4187 if (id
+ numinfo
> RAILTYPE_END
) {
4188 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id
+ numinfo
, RAILTYPE_END
);
4189 return CIR_INVALID_ID
;
4192 for (int i
= 0; i
< numinfo
; i
++) {
4194 case 0x08: // Label of rail type
4196 RailTypeLabel rtl
= buf
->ReadDWord();
4199 RailType rt
= GetRailTypeByLabel(rtl
, false);
4200 if (rt
== INVALID_RAILTYPE
) {
4201 /* Set up new rail type */
4202 rt
= AllocateRailType(rtl
);
4205 _cur
.grffile
->railtype_map
[id
+ i
] = rt
;
4209 case 0x09: // Toolbar caption of railtype
4210 case 0x0A: // Menu text
4211 case 0x0B: // Build window caption
4212 case 0x0C: // Autoreplace text
4213 case 0x0D: // New loco
4214 case 0x13: // Construction cost
4215 case 0x14: // Speed limit
4216 case 0x1B: // Name of railtype
4217 case 0x1C: // Maintenance cost factor
4221 case 0x1D: // Alternate rail type label list
4222 if (_cur
.grffile
->railtype_map
[id
+ i
] != INVALID_RAILTYPE
) {
4223 int n
= buf
->ReadByte();
4224 for (int j
= 0; j
!= n
; j
++) {
4225 *_railtypes
[_cur
.grffile
->railtype_map
[id
+ i
]].alternate_labels
.Append() = BSWAP32(buf
->ReadDWord());
4229 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id
+ i
);
4232 case 0x0E: // Compatible railtype list
4233 case 0x0F: // Powered railtype list
4234 case 0x18: // Railtype list required for date introduction
4235 case 0x19: // Introduced railtype list
4236 for (int j
= buf
->ReadByte(); j
!= 0; j
--) buf
->ReadDWord();
4239 case 0x10: // Rail Type flags
4240 case 0x11: // Curve speed advantage
4241 case 0x12: // Station graphic
4242 case 0x15: // Acceleration model
4243 case 0x16: // Map colour
4244 case 0x1A: // Sort order
4248 case 0x17: // Introduction date
4261 static ChangeInfoResult
AirportTilesChangeInfo(uint airtid
, int numinfo
, int prop
, ByteReader
*buf
)
4263 ChangeInfoResult ret
= CIR_SUCCESS
;
4265 if (airtid
+ numinfo
> NUM_AIRPORTTILES_PER_GRF
) {
4266 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid
+ numinfo
, NUM_AIRPORTTILES_PER_GRF
);
4267 return CIR_INVALID_ID
;
4270 /* Allocate airport tile specs if they haven't been allocated already. */
4271 if (_cur
.grffile
->airtspec
== NULL
) {
4272 _cur
.grffile
->airtspec
= xcalloct
<AirportTileSpec
*>(NUM_AIRPORTTILES_PER_GRF
);
4275 for (int i
= 0; i
< numinfo
; i
++) {
4276 AirportTileSpec
*tsp
= _cur
.grffile
->airtspec
[airtid
+ i
];
4278 if (prop
!= 0x08 && tsp
== NULL
) {
4279 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid
+ i
);
4280 return CIR_INVALID_ID
;
4284 case 0x08: { // Substitute airport tile type
4285 byte subs_id
= buf
->ReadByte();
4287 if (subs_id
>= NEW_AIRPORTTILE_OFFSET
) {
4288 /* The substitute id must be one of the original airport tiles. */
4289 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id
, airtid
+ i
);
4293 /* Allocate space for this airport tile. */
4295 tsp
= xmemdupt (AirportTileSpec::Get(subs_id
));
4296 _cur
.grffile
->airtspec
[airtid
+ i
] = tsp
;
4298 tsp
->enabled
= true;
4300 tsp
->animation
.status
= ANIM_STATUS_NO_ANIMATION
;
4302 tsp
->grf_prop
.local_id
= airtid
+ i
;
4303 tsp
->grf_prop
.subst_id
= subs_id
;
4304 tsp
->grf_prop
.grffile
= _cur
.grffile
;
4305 _airporttile_mngr
.AddEntityID(airtid
+ i
, _cur
.grffile
->grfid
, subs_id
); // pre-reserve the tile slot
4310 case 0x09: { // Airport tile override
4311 byte override
= buf
->ReadByte();
4313 /* The airport tile being overridden must be an original airport tile. */
4314 if (override
>= NEW_AIRPORTTILE_OFFSET
) {
4315 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override
, airtid
+ i
);
4319 _airporttile_mngr
.Add(airtid
+ i
, _cur
.grffile
->grfid
, override
);
4323 case 0x0E: // Callback mask
4324 tsp
->callback_mask
= buf
->ReadByte();
4327 case 0x0F: // Animation information
4328 tsp
->animation
.frames
= buf
->ReadByte();
4329 tsp
->animation
.status
= buf
->ReadByte();
4332 case 0x10: // Animation speed
4333 tsp
->animation
.speed
= buf
->ReadByte();
4336 case 0x11: // Animation triggers
4337 tsp
->animation
.triggers
= buf
->ReadByte();
4349 static bool HandleChangeInfoResult(const char *caller
, ChangeInfoResult cir
, uint8 feature
, uint8 property
)
4352 default: NOT_REACHED();
4355 /* Error has already been printed; just stop parsing */
4362 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller
, property
, feature
);
4366 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller
, property
, feature
);
4369 case CIR_INVALID_ID
: {
4370 /* No debug message for an invalid ID, as it has already been output */
4371 GRFError
*error
= DisableCur (cir
== CIR_INVALID_ID
? STR_NEWGRF_ERROR_INVALID_ID
: STR_NEWGRF_ERROR_UNKNOWN_PROPERTY
);
4372 if (cir
!= CIR_INVALID_ID
) error
->param_value
[1] = property
;
4379 static int FeatureChangeInfo (ByteReader
*buf
)
4381 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4384 * B num-props how many properties to change per vehicle/station
4385 * B num-info how many vehicles/stations to change
4386 * E id ID of first vehicle/station to change, if num-info is
4387 * greater than one, this one and the following
4388 * vehicles/stations will be changed
4389 * B property what property to change, depends on the feature
4390 * V new-info new bytes of info (variable size; depends on properties) */
4392 static const VCI_Handler handler
[] = {
4393 /* GSF_TRAINS */ RailVehicleChangeInfo
,
4394 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo
,
4395 /* GSF_SHIPS */ ShipVehicleChangeInfo
,
4396 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo
,
4397 /* GSF_STATIONS */ StationChangeInfo
,
4398 /* GSF_CANALS */ CanalChangeInfo
,
4399 /* GSF_BRIDGES */ BridgeChangeInfo
,
4400 /* GSF_HOUSES */ TownHouseChangeInfo
,
4401 /* GSF_GLOBALVAR */ GlobalVarChangeInfo
,
4402 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo
,
4403 /* GSF_INDUSTRIES */ IndustriesChangeInfo
,
4404 /* GSF_CARGOES */ NULL
, // Cargo is handled during reservation
4405 /* GSF_SOUNDFX */ SoundEffectChangeInfo
,
4406 /* GSF_AIRPORTS */ AirportChangeInfo
,
4407 /* GSF_SIGNALS */ NULL
,
4408 /* GSF_OBJECTS */ ObjectChangeInfo
,
4409 /* GSF_RAILTYPES */ RailTypeChangeInfo
,
4410 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo
,
4413 uint8 feature
= buf
->ReadByte();
4414 uint8 numprops
= buf
->ReadByte();
4415 uint numinfo
= buf
->ReadByte();
4416 uint engine
= buf
->ReadExtendedByte();
4418 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4419 feature
, numprops
, engine
, numinfo
);
4421 if (feature
>= lengthof(handler
) || handler
[feature
] == NULL
) {
4422 if (feature
!= GSF_CARGOES
) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature
);
4426 /* Mark the feature as used by the grf */
4427 SetBit(_cur
.grffile
->grf_features
, feature
);
4429 while (numprops
-- && buf
->HasData()) {
4430 uint8 prop
= buf
->ReadByte();
4432 ChangeInfoResult cir
= handler
[feature
](engine
, numinfo
, prop
, buf
);
4433 if (HandleChangeInfoResult ("FeatureChangeInfo", cir
, feature
, prop
)) {
4441 /* Action 0x00 (GLS_SAFETYSCAN) */
4442 static int SafeChangeInfo (ByteReader
*buf
)
4444 uint8 feature
= buf
->ReadByte();
4445 uint8 numprops
= buf
->ReadByte();
4446 uint numinfo
= buf
->ReadByte();
4447 buf
->ReadExtendedByte(); // id
4449 if (feature
== GSF_BRIDGES
&& numprops
== 1) {
4450 uint8 prop
= buf
->ReadByte();
4451 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4452 * is considered safe. */
4453 if (prop
== 0x0D) return 0;
4454 } else if (feature
== GSF_GLOBALVAR
&& numprops
== 1) {
4455 uint8 prop
= buf
->ReadByte();
4456 /* Engine ID Mappings are safe, if the source is static */
4458 bool is_safe
= true;
4459 for (uint i
= 0; i
< numinfo
; i
++) {
4460 uint32 s
= buf
->ReadDWord();
4461 buf
->ReadDWord(); // dest
4462 const GRFConfig
*grfconfig
= GetGRFConfig(s
);
4463 if (grfconfig
!= NULL
&& !HasBit(grfconfig
->flags
, GCF_STATIC
)) {
4468 if (is_safe
) return 0;
4472 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
4474 /* Skip remainder of GRF */
4478 /* Action 0x00 (GLS_RESERVE) */
4479 static int ReserveChangeInfo (ByteReader
*buf
)
4481 uint8 feature
= buf
->ReadByte();
4483 if (feature
!= GSF_CARGOES
&& feature
!= GSF_GLOBALVAR
&& feature
!= GSF_RAILTYPES
) return 0;
4485 uint8 numprops
= buf
->ReadByte();
4486 uint8 numinfo
= buf
->ReadByte();
4487 uint8 index
= buf
->ReadExtendedByte();
4489 while (numprops
-- && buf
->HasData()) {
4490 uint8 prop
= buf
->ReadByte();
4491 ChangeInfoResult cir
= CIR_SUCCESS
;
4494 default: NOT_REACHED();
4496 cir
= CargoChangeInfo(index
, numinfo
, prop
, buf
);
4500 cir
= GlobalVarReserveInfo(index
, numinfo
, prop
, buf
);
4504 cir
= RailTypeReserveInfo(index
, numinfo
, prop
, buf
);
4508 if (HandleChangeInfoResult ("ReserveChangeInfo", cir
, feature
, prop
)) {
4517 static int NewSpriteSet (ByteReader
*buf
)
4519 /* Basic format: <01> <feature> <num-sets> <num-ent>
4520 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4522 * B feature feature to define sprites for
4523 * 0, 1, 2, 3: veh-type, 4: train stations
4524 * E first-set first sprite set to define
4525 * B num-sets number of sprite sets (extended byte in extended format)
4526 * E num-ent how many entries per sprite set
4527 * For vehicles, this is the number of different
4528 * vehicle directions in each sprite set
4529 * Set num-dirs=8, unless your sprites are symmetric.
4530 * In that case, use num-dirs=4.
4533 uint8 feature
= buf
->ReadByte();
4534 uint16 num_sets
= buf
->ReadByte();
4535 uint16 first_set
= 0;
4537 if (num_sets
== 0 && buf
->HasData(3)) {
4538 /* Extended Action1 format.
4539 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4540 first_set
= buf
->ReadExtendedByte();
4541 num_sets
= buf
->ReadExtendedByte();
4543 uint16 num_ents
= buf
->ReadExtendedByte();
4545 _cur
.AddSpriteSets(feature
, _cur
.spriteid
, first_set
, num_sets
, num_ents
);
4547 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4548 _cur
.spriteid
, feature
, num_sets
, num_ents
, num_sets
* num_ents
4551 for (int i
= 0; i
< num_sets
* num_ents
; i
++) {
4553 LoadNextSprite(_cur
.spriteid
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
4559 /* Action 0x01 (SKIP) */
4560 static int SkipAct1 (ByteReader
*buf
)
4563 uint16 num_sets
= buf
->ReadByte();
4565 if (num_sets
== 0 && buf
->HasData(3)) {
4566 /* Extended Action1 format.
4567 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4568 buf
->ReadExtendedByte(); // first_set
4569 num_sets
= buf
->ReadExtendedByte();
4571 uint16 num_ents
= buf
->ReadExtendedByte();
4573 int skip
= num_sets
* num_ents
;
4574 grfmsg (3, "SkipAct1: Skipping %d sprites", skip
);
4578 /* Helper function to either create a callback or link to a previously
4579 * defined spritegroup. */
4580 static const SpriteGroup
*GetGroupFromGroupID(byte setid
, byte type
, uint16 groupid
)
4582 if (HasBit(groupid
, 15)) {
4583 assert(CallbackResultSpriteGroup::CanAllocateItem());
4584 return new CallbackResultSpriteGroup(groupid
, _cur
.grffile
->grf_version
>= 8);
4587 if (groupid
> MAX_SPRITEGROUP
|| _cur
.spritegroups
[groupid
] == NULL
) {
4588 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid
, type
, groupid
);
4592 return _cur
.spritegroups
[groupid
];
4596 * Helper function to either create a callback or a result sprite group.
4597 * @param feature GrfSpecFeature to define spritegroup for.
4598 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4599 * @param type Type of the currently being parsed Action2. (only for debug output)
4600 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4601 * @return Created spritegroup.
4603 static const SpriteGroup
*CreateGroupFromGroupID(byte feature
, byte setid
, byte type
, uint16 spriteid
)
4605 if (HasBit(spriteid
, 15)) {
4606 assert(CallbackResultSpriteGroup::CanAllocateItem());
4607 return new CallbackResultSpriteGroup(spriteid
, _cur
.grffile
->grf_version
>= 8);
4610 if (!_cur
.IsValidSpriteSet(feature
, spriteid
)) {
4611 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid
, type
, spriteid
);
4615 SpriteID spriteset_start
= _cur
.GetSprite(feature
, spriteid
);
4616 uint num_sprites
= _cur
.GetNumEnts(feature
, spriteid
);
4618 /* Ensure that the sprites are loeded */
4619 assert(spriteset_start
+ num_sprites
<= _cur
.spriteid
);
4621 assert(ResultSpriteGroup::CanAllocateItem());
4622 return new ResultSpriteGroup(spriteset_start
, num_sprites
);
4626 static int NewSpriteGroup (ByteReader
*buf
)
4628 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4630 * B feature see action 1
4631 * B set-id ID of this particular definition
4632 * B type/num-entries
4633 * if 80 or greater, this is a randomized or variational
4634 * list definition, see below
4635 * otherwise it specifies a number of entries, the exact
4636 * meaning depends on the feature
4637 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4638 SpriteGroup
*act_group
= NULL
;
4640 uint8 feature
= buf
->ReadByte();
4641 uint8 setid
= buf
->ReadByte();
4642 uint8 type
= buf
->ReadByte();
4644 /* Sprite Groups are created here but they are allocated from a pool, so
4645 * we do not need to delete anything if there is an exception from the
4649 /* Deterministic Sprite Group */
4650 case 0x81: // Self scope, byte
4651 case 0x82: // Parent scope, byte
4652 case 0x85: // Self scope, word
4653 case 0x86: // Parent scope, word
4654 case 0x89: // Self scope, dword
4655 case 0x8A: // Parent scope, dword
4660 assert(DeterministicSpriteGroup::CanAllocateItem());
4661 DeterministicSpriteGroup
*group
= new DeterministicSpriteGroup();
4663 group
->var_scope
= HasBit(type
, 1) ? VSG_SCOPE_PARENT
: VSG_SCOPE_SELF
;
4665 switch (GB(type
, 2, 2)) {
4666 default: NOT_REACHED();
4667 case 0: group
->size
= DSG_SIZE_BYTE
; varsize
= 1; break;
4668 case 1: group
->size
= DSG_SIZE_WORD
; varsize
= 2; break;
4669 case 2: group
->size
= DSG_SIZE_DWORD
; varsize
= 4; break;
4672 static SmallVector
<DeterministicSpriteGroupAdjust
, 16> adjusts
;
4675 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4676 * from the outset, so we shall have to keep reallocing. */
4678 DeterministicSpriteGroupAdjust
*adjust
= adjusts
.Append();
4680 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4681 adjust
->operation
= adjusts
.Length() == 1 ? DSGA_OP_ADD
: (DeterministicSpriteGroupAdjustOperation
)buf
->ReadByte();
4682 adjust
->variable
= buf
->ReadByte();
4683 if (adjust
->variable
== 0x7E) {
4684 /* Link subroutine group */
4685 adjust
->subroutine
= GetGroupFromGroupID(setid
, type
, buf
->ReadByte());
4687 adjust
->parameter
= IsInsideMM(adjust
->variable
, 0x60, 0x80) ? buf
->ReadByte() : 0;
4690 varadjust
= buf
->ReadByte();
4691 adjust
->shift_num
= GB(varadjust
, 0, 5);
4692 adjust
->type
= (DeterministicSpriteGroupAdjustType
)GB(varadjust
, 6, 2);
4693 adjust
->and_mask
= buf
->ReadVarSize(varsize
);
4695 if (adjust
->type
!= DSGA_TYPE_NONE
) {
4696 adjust
->add_val
= buf
->ReadVarSize(varsize
);
4697 adjust
->divmod_val
= buf
->ReadVarSize(varsize
);
4699 adjust
->add_val
= 0;
4700 adjust
->divmod_val
= 0;
4703 /* Continue reading var adjusts while bit 5 is set. */
4704 } while (HasBit(varadjust
, 5));
4706 group
->num_adjusts
= adjusts
.Length();
4707 group
->adjusts
= xmemdupt (adjusts
.Begin(), group
->num_adjusts
);
4709 group
->num_ranges
= buf
->ReadByte();
4710 if (group
->num_ranges
> 0) group
->ranges
= xcalloct
<DeterministicSpriteGroupRange
>(group
->num_ranges
);
4712 for (uint i
= 0; i
< group
->num_ranges
; i
++) {
4713 group
->ranges
[i
].group
= GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4714 group
->ranges
[i
].low
= buf
->ReadVarSize(varsize
);
4715 group
->ranges
[i
].high
= buf
->ReadVarSize(varsize
);
4718 group
->default_group
= GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4722 /* Randomized Sprite Group */
4723 case 0x80: // Self scope
4724 case 0x83: // Parent scope
4725 case 0x84: // Relative scope
4727 assert(RandomizedSpriteGroup::CanAllocateItem());
4728 RandomizedSpriteGroup
*group
= new RandomizedSpriteGroup();
4730 group
->var_scope
= HasBit(type
, 1) ? VSG_SCOPE_PARENT
: VSG_SCOPE_SELF
;
4732 if (HasBit(type
, 2)) {
4733 if (feature
<= GSF_AIRCRAFT
) group
->var_scope
= VSG_SCOPE_RELATIVE
;
4734 group
->count
= buf
->ReadByte();
4737 uint8 triggers
= buf
->ReadByte();
4738 group
->triggers
= GB(triggers
, 0, 7);
4739 group
->cmp_mode
= HasBit(triggers
, 7) ? RSG_CMP_ALL
: RSG_CMP_ANY
;
4740 group
->lowest_randbit
= buf
->ReadByte();
4741 group
->num_groups
= buf
->ReadByte();
4742 group
->groups
= xcalloct
<const SpriteGroup
*>(group
->num_groups
);
4744 for (uint i
= 0; i
< group
->num_groups
; i
++) {
4745 group
->groups
[i
] = GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4751 /* Neither a variable or randomized sprite group... must be a real group */
4756 case GSF_ROADVEHICLES
:
4765 byte num_loaded
= type
;
4766 byte num_loading
= buf
->ReadByte();
4768 if (!_cur
.HasValidSpriteSets(feature
)) {
4769 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4773 assert(RealSpriteGroup::CanAllocateItem());
4774 RealSpriteGroup
*group
= new RealSpriteGroup();
4777 group
->num_loaded
= num_loaded
;
4778 group
->num_loading
= num_loading
;
4779 if (num_loaded
> 0) group
->loaded
= xcalloct
<const SpriteGroup
*>(num_loaded
);
4780 if (num_loading
> 0) group
->loading
= xcalloct
<const SpriteGroup
*>(num_loading
);
4782 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4783 setid
, num_loaded
, num_loading
);
4785 for (uint i
= 0; i
< num_loaded
; i
++) {
4786 uint16 spriteid
= buf
->ReadWord();
4787 group
->loaded
[i
] = CreateGroupFromGroupID(feature
, setid
, type
, spriteid
);
4788 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i
, spriteid
);
4791 for (uint i
= 0; i
< num_loading
; i
++) {
4792 uint16 spriteid
= buf
->ReadWord();
4793 group
->loading
[i
] = CreateGroupFromGroupID(feature
, setid
, type
, spriteid
);
4794 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i
, spriteid
);
4801 case GSF_AIRPORTTILES
:
4803 case GSF_INDUSTRYTILES
: {
4804 byte num_building_sprites
= max((uint8
)1, type
);
4806 assert(TileLayoutSpriteGroup::CanAllocateItem());
4807 TileLayoutSpriteGroup
*group
= new TileLayoutSpriteGroup();
4810 /* On error, bail out immediately. Temporary GRF data was already freed */
4811 if (ReadSpriteLayout(buf
, num_building_sprites
, true, feature
, false, type
== 0, &group
->dts
)) {
4817 case GSF_INDUSTRIES
: {
4819 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type
);
4823 assert(IndustryProductionSpriteGroup::CanAllocateItem());
4824 IndustryProductionSpriteGroup
*group
= new IndustryProductionSpriteGroup();
4826 group
->version
= type
;
4828 for (uint i
= 0; i
< 3; i
++) {
4829 group
->subtract_input
[i
] = (int16
)buf
->ReadWord(); // signed
4831 for (uint i
= 0; i
< 2; i
++) {
4832 group
->add_output
[i
] = buf
->ReadWord(); // unsigned
4834 group
->again
= buf
->ReadByte();
4836 for (uint i
= 0; i
< 3; i
++) {
4837 group
->subtract_input
[i
] = buf
->ReadByte();
4839 for (uint i
= 0; i
< 2; i
++) {
4840 group
->add_output
[i
] = buf
->ReadByte();
4842 group
->again
= buf
->ReadByte();
4847 /* Loading of Tile Layout and Production Callback groups would happen here */
4848 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature
);
4853 _cur
.spritegroups
[setid
] = act_group
;
4858 static CargoID
TranslateCargo (uint8 ctype
)
4860 /* Special cargo type for purchase list */
4861 if (ctype
== 0xFF) return CT_PURCHASE
;
4863 if (_cur
.grffile
->cargo_list
.Length() == 0) {
4864 /* No cargo table, so use bitnum values */
4866 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype
);
4870 const CargoSpec
*cs
;
4871 FOR_ALL_CARGOSPECS(cs
) {
4872 if (cs
->bitnum
== ctype
) {
4873 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype
, cs
->Index());
4878 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype
);
4882 /* Check if the cargo type is out of bounds of the cargo translation table */
4883 if (ctype
>= _cur
.grffile
->cargo_list
.Length()) {
4884 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype
, _cur
.grffile
->cargo_list
.Length() - 1);
4888 /* Look up the cargo label from the translation table */
4889 CargoLabel cl
= _cur
.grffile
->cargo_list
[ctype
];
4891 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype
);
4895 ctype
= GetCargoIDByLabel(cl
);
4896 if (ctype
== CT_INVALID
) {
4897 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));
4901 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
);
4906 static bool IsValidGroupID(uint16 groupid
, const char *function
)
4908 if (groupid
> MAX_SPRITEGROUP
|| _cur
.spritegroups
[groupid
] == NULL
) {
4909 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function
, groupid
);
4916 static bool VehicleMapSpriteGroup (ByteReader
*buf
, byte feature
, uint8 idcount
)
4918 static EngineID
*last_engines
;
4919 static uint last_engines_count
;
4920 bool wagover
= false;
4922 /* Test for 'wagon override' flag */
4923 if (HasBit(idcount
, 7)) {
4925 /* Strip off the flag */
4926 idcount
= GB(idcount
, 0, 7);
4928 if (last_engines_count
== 0) {
4929 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4933 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4934 last_engines_count
, idcount
);
4936 if (last_engines_count
!= idcount
) {
4937 last_engines
= xrealloct (last_engines
, idcount
);
4938 last_engines_count
= idcount
;
4942 EngineID
*engines
= AllocaM(EngineID
, idcount
);
4943 for (uint i
= 0; i
< idcount
; i
++) {
4944 Engine
*e
= GetNewEngine(_cur
.grffile
, (VehicleType
)feature
, buf
->ReadExtendedByte());
4946 /* No engine could be allocated?!? Deal with it. Okay,
4947 * this might look bad. Also make sure this NewGRF
4948 * gets disabled, as a half loaded one is bad. */
4949 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID
, 0, 0);
4953 engines
[i
] = e
->index
;
4954 if (!wagover
) last_engines
[i
] = engines
[i
];
4957 uint8 cidcount
= buf
->ReadByte();
4958 for (uint c
= 0; c
< cidcount
; c
++) {
4959 uint8 ctype
= buf
->ReadByte();
4960 uint16 groupid
= buf
->ReadWord();
4961 if (!IsValidGroupID(groupid
, "VehicleMapSpriteGroup")) continue;
4963 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c
, ctype
, groupid
);
4965 ctype
= TranslateCargo (ctype
);
4966 if (ctype
== CT_INVALID
) continue;
4968 for (uint i
= 0; i
< idcount
; i
++) {
4969 EngineID engine
= engines
[i
];
4971 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i
, engine
);
4974 SetWagonOverrideSprites(engine
, ctype
, _cur
.spritegroups
[groupid
], last_engines
, last_engines_count
);
4976 SetCustomEngineSprites(engine
, ctype
, _cur
.spritegroups
[groupid
]);
4981 uint16 groupid
= buf
->ReadWord();
4982 if (!IsValidGroupID(groupid
, "VehicleMapSpriteGroup")) return true;
4984 grfmsg(8, "-- Default group id 0x%04X", groupid
);
4986 for (uint i
= 0; i
< idcount
; i
++) {
4987 EngineID engine
= engines
[i
];
4990 SetWagonOverrideSprites(engine
, CT_DEFAULT
, _cur
.spritegroups
[groupid
], last_engines
, last_engines_count
);
4992 SetCustomEngineSprites(engine
, CT_DEFAULT
, _cur
.spritegroups
[groupid
]);
4993 SetEngineGRF(engine
, _cur
.grffile
);
5001 static void CanalMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5003 CanalFeature
*cfs
= AllocaM(CanalFeature
, idcount
);
5004 for (uint i
= 0; i
< idcount
; i
++) {
5005 cfs
[i
] = (CanalFeature
)buf
->ReadByte();
5008 uint8 cidcount
= buf
->ReadByte();
5009 buf
->Skip(cidcount
* 3);
5011 uint16 groupid
= buf
->ReadWord();
5012 if (!IsValidGroupID(groupid
, "CanalMapSpriteGroup")) return;
5014 for (uint i
= 0; i
< idcount
; i
++) {
5015 CanalFeature cf
= cfs
[i
];
5018 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf
);
5022 _water_feature
[cf
].grffile
= _cur
.grffile
;
5023 _water_feature
[cf
].group
= _cur
.spritegroups
[groupid
];
5028 static void StationMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5030 uint8
*stations
= AllocaM(uint8
, idcount
);
5031 for (uint i
= 0; i
< idcount
; i
++) {
5032 stations
[i
] = buf
->ReadByte();
5035 uint8 cidcount
= buf
->ReadByte();
5036 for (uint c
= 0; c
< cidcount
; c
++) {
5037 uint8 ctype
= buf
->ReadByte();
5038 uint16 groupid
= buf
->ReadWord();
5039 if (!IsValidGroupID(groupid
, "StationMapSpriteGroup")) continue;
5041 if (ctype
== 0xFE) {
5042 ctype
= CT_DEFAULT_NA
;
5044 ctype
= TranslateCargo (ctype
);
5045 if (ctype
== CT_INVALID
) continue;
5048 for (uint i
= 0; i
< idcount
; i
++) {
5049 StationSpec
*statspec
= _cur
.grffile
->stations
== NULL
? NULL
: _cur
.grffile
->stations
[stations
[i
]];
5051 if (statspec
== NULL
) {
5052 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations
[i
]);
5056 statspec
->grf_prop
.spritegroup
[ctype
] = _cur
.spritegroups
[groupid
];
5060 uint16 groupid
= buf
->ReadWord();
5061 if (!IsValidGroupID(groupid
, "StationMapSpriteGroup")) return;
5063 for (uint i
= 0; i
< idcount
; i
++) {
5064 StationSpec
*statspec
= _cur
.grffile
->stations
== NULL
? NULL
: _cur
.grffile
->stations
[stations
[i
]];
5066 if (statspec
== NULL
) {
5067 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations
[i
]);
5071 if (statspec
->grf_prop
.grffile
!= NULL
) {
5072 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations
[i
]);
5076 statspec
->grf_prop
.spritegroup
[CT_DEFAULT
] = _cur
.spritegroups
[groupid
];
5077 statspec
->grf_prop
.grffile
= _cur
.grffile
;
5078 statspec
->grf_prop
.local_id
= stations
[i
];
5079 StationClass::Assign(statspec
);
5084 static void TownHouseMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5086 uint8
*houses
= AllocaM(uint8
, idcount
);
5087 for (uint i
= 0; i
< idcount
; i
++) {
5088 houses
[i
] = buf
->ReadByte();
5091 /* Skip the cargo type section, we only care about the default group */
5092 uint8 cidcount
= buf
->ReadByte();
5093 buf
->Skip(cidcount
* 3);
5095 uint16 groupid
= buf
->ReadWord();
5096 if (!IsValidGroupID(groupid
, "TownHouseMapSpriteGroup")) return;
5098 if (_cur
.grffile
->housespec
== NULL
) {
5099 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5103 for (uint i
= 0; i
< idcount
; i
++) {
5104 HouseSpec
*hs
= _cur
.grffile
->housespec
[houses
[i
]];
5107 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses
[i
]);
5111 hs
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5115 static void IndustryMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5117 uint8
*industries
= AllocaM(uint8
, idcount
);
5118 for (uint i
= 0; i
< idcount
; i
++) {
5119 industries
[i
] = buf
->ReadByte();
5122 /* Skip the cargo type section, we only care about the default group */
5123 uint8 cidcount
= buf
->ReadByte();
5124 buf
->Skip(cidcount
* 3);
5126 uint16 groupid
= buf
->ReadWord();
5127 if (!IsValidGroupID(groupid
, "IndustryMapSpriteGroup")) return;
5129 if (_cur
.grffile
->industryspec
== NULL
) {
5130 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5134 for (uint i
= 0; i
< idcount
; i
++) {
5135 IndustrySpec
*indsp
= _cur
.grffile
->industryspec
[industries
[i
]];
5137 if (indsp
== NULL
) {
5138 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries
[i
]);
5142 indsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5146 static void IndustrytileMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5148 uint8
*indtiles
= AllocaM(uint8
, idcount
);
5149 for (uint i
= 0; i
< idcount
; i
++) {
5150 indtiles
[i
] = buf
->ReadByte();
5153 /* Skip the cargo type section, we only care about the default group */
5154 uint8 cidcount
= buf
->ReadByte();
5155 buf
->Skip(cidcount
* 3);
5157 uint16 groupid
= buf
->ReadWord();
5158 if (!IsValidGroupID(groupid
, "IndustrytileMapSpriteGroup")) return;
5160 if (_cur
.grffile
->indtspec
== NULL
) {
5161 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5165 for (uint i
= 0; i
< idcount
; i
++) {
5166 IndustryTileSpec
*indtsp
= _cur
.grffile
->indtspec
[indtiles
[i
]];
5168 if (indtsp
== NULL
) {
5169 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles
[i
]);
5173 indtsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5177 static void CargoMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5179 CargoID
*cargoes
= AllocaM(CargoID
, idcount
);
5180 for (uint i
= 0; i
< idcount
; i
++) {
5181 cargoes
[i
] = buf
->ReadByte();
5184 /* Skip the cargo type section, we only care about the default group */
5185 uint8 cidcount
= buf
->ReadByte();
5186 buf
->Skip(cidcount
* 3);
5188 uint16 groupid
= buf
->ReadWord();
5189 if (!IsValidGroupID(groupid
, "CargoMapSpriteGroup")) return;
5191 for (uint i
= 0; i
< idcount
; i
++) {
5192 CargoID cid
= cargoes
[i
];
5194 if (cid
>= NUM_CARGO
) {
5195 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid
);
5199 CargoSpec
*cs
= CargoSpec::Get(cid
);
5200 cs
->grffile
= _cur
.grffile
;
5201 cs
->group
= _cur
.spritegroups
[groupid
];
5205 static void ObjectMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5207 if (_cur
.grffile
->objectspec
== NULL
) {
5208 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5212 uint8
*objects
= AllocaM(uint8
, idcount
);
5213 for (uint i
= 0; i
< idcount
; i
++) {
5214 objects
[i
] = buf
->ReadByte();
5217 uint8 cidcount
= buf
->ReadByte();
5218 for (uint c
= 0; c
< cidcount
; c
++) {
5219 uint8 ctype
= buf
->ReadByte();
5220 uint16 groupid
= buf
->ReadWord();
5221 if (!IsValidGroupID(groupid
, "ObjectMapSpriteGroup")) continue;
5225 case 0xFF: ctype
= CT_PURCHASE_OBJECT
; break;
5227 grfmsg(1, "ObjectMapSpriteGroup: Invalid cargo bitnum %d for objects, skipping.", ctype
);
5231 for (uint i
= 0; i
< idcount
; i
++) {
5232 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[objects
[i
]];
5235 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects
[i
]);
5239 spec
->grf_prop
.spritegroup
[ctype
] = _cur
.spritegroups
[groupid
];
5243 uint16 groupid
= buf
->ReadWord();
5244 if (!IsValidGroupID(groupid
, "ObjectMapSpriteGroup")) return;
5246 for (uint i
= 0; i
< idcount
; i
++) {
5247 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[objects
[i
]];
5250 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects
[i
]);
5254 if (spec
->grf_prop
.grffile
!= NULL
) {
5255 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects
[i
]);
5259 spec
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5260 spec
->grf_prop
.grffile
= _cur
.grffile
;
5261 spec
->grf_prop
.local_id
= objects
[i
];
5265 static void RailTypeMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5267 uint8
*railtypes
= AllocaM(uint8
, idcount
);
5268 for (uint i
= 0; i
< idcount
; i
++) {
5269 railtypes
[i
] = _cur
.grffile
->railtype_map
[buf
->ReadByte()];
5272 uint8 cidcount
= buf
->ReadByte();
5273 for (uint c
= 0; c
< cidcount
; c
++) {
5274 uint8 ctype
= buf
->ReadByte();
5275 uint16 groupid
= buf
->ReadWord();
5276 if (!IsValidGroupID(groupid
, "RailTypeMapSpriteGroup")) continue;
5278 if (ctype
>= RTSG_END
) continue;
5280 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
5281 for (uint i
= 0; i
< idcount
; i
++) {
5282 if (railtypes
[i
] != INVALID_RAILTYPE
) {
5283 RailtypeInfo
*rti
= &_railtypes
[railtypes
[i
]];
5285 rti
->grffile
[ctype
] = _cur
.grffile
;
5286 rti
->group
[ctype
] = _cur
.spritegroups
[groupid
];
5291 /* Railtypes do not use the default group. */
5295 static void AirportMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5297 uint8
*airports
= AllocaM(uint8
, idcount
);
5298 for (uint i
= 0; i
< idcount
; i
++) {
5299 airports
[i
] = buf
->ReadByte();
5302 /* Skip the cargo type section, we only care about the default group */
5303 uint8 cidcount
= buf
->ReadByte();
5304 buf
->Skip(cidcount
* 3);
5306 uint16 groupid
= buf
->ReadWord();
5307 if (!IsValidGroupID(groupid
, "AirportMapSpriteGroup")) return;
5309 if (_cur
.grffile
->airportspec
== NULL
) {
5310 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5314 for (uint i
= 0; i
< idcount
; i
++) {
5315 AirportSpec
*as
= _cur
.grffile
->airportspec
[airports
[i
]];
5318 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports
[i
]);
5322 as
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5326 static void AirportTileMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5328 uint8
*airptiles
= AllocaM(uint8
, idcount
);
5329 for (uint i
= 0; i
< idcount
; i
++) {
5330 airptiles
[i
] = buf
->ReadByte();
5333 /* Skip the cargo type section, we only care about the default group */
5334 uint8 cidcount
= buf
->ReadByte();
5335 buf
->Skip(cidcount
* 3);
5337 uint16 groupid
= buf
->ReadWord();
5338 if (!IsValidGroupID(groupid
, "AirportTileMapSpriteGroup")) return;
5340 if (_cur
.grffile
->airtspec
== NULL
) {
5341 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5345 for (uint i
= 0; i
< idcount
; i
++) {
5346 AirportTileSpec
*airtsp
= _cur
.grffile
->airtspec
[airptiles
[i
]];
5348 if (airtsp
== NULL
) {
5349 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles
[i
]);
5353 airtsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5359 static int FeatureMapSpriteGroup (ByteReader
*buf
)
5361 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5362 * id-list := [<id>] [id-list]
5363 * cargo-list := <cargo-type> <cid> [cargo-list]
5365 * B feature see action 0
5366 * B n-id bits 0-6: how many IDs this definition applies to
5367 * bit 7: if set, this is a wagon override definition (see below)
5368 * B ids the IDs for which this definition applies
5369 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5370 * can be zero, in that case the def-cid is used always
5371 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5372 * W cid cargo ID (sprite group ID) for this type of cargo
5373 * W def-cid default cargo ID (sprite group ID) */
5375 uint8 feature
= buf
->ReadByte();
5376 uint8 idcount
= buf
->ReadByte();
5378 /* If idcount is zero, this is a feature callback */
5380 /* Skip number of cargo ids? */
5382 uint16 groupid
= buf
->ReadWord();
5383 if (!IsValidGroupID(groupid
, "FeatureMapSpriteGroup")) return 0;
5385 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature
);
5387 AddGenericCallback(feature
, _cur
.grffile
, _cur
.spritegroups
[groupid
]);
5391 /* Mark the feature as used by the grf (generic callbacks do not count) */
5392 SetBit(_cur
.grffile
->grf_features
, feature
);
5394 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature
, idcount
);
5398 case GSF_ROADVEHICLES
:
5401 return VehicleMapSpriteGroup (buf
, feature
, idcount
) ? 0 : -1;
5404 CanalMapSpriteGroup(buf
, idcount
);
5408 StationMapSpriteGroup(buf
, idcount
);
5412 TownHouseMapSpriteGroup(buf
, idcount
);
5415 case GSF_INDUSTRIES
:
5416 IndustryMapSpriteGroup(buf
, idcount
);
5419 case GSF_INDUSTRYTILES
:
5420 IndustrytileMapSpriteGroup(buf
, idcount
);
5424 CargoMapSpriteGroup(buf
, idcount
);
5428 AirportMapSpriteGroup(buf
, idcount
);
5432 ObjectMapSpriteGroup(buf
, idcount
);
5436 RailTypeMapSpriteGroup(buf
, idcount
);
5439 case GSF_AIRPORTTILES
:
5440 AirportTileMapSpriteGroup(buf
, idcount
);
5444 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature
);
5450 static int FeatureNewName (ByteReader
*buf
)
5452 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5454 * B veh-type see action 0 (as 00..07, + 0A
5455 * But IF veh-type = 48, then generic text
5456 * B language-id If bit 6 is set, This is the extended language scheme,
5457 * with up to 64 language.
5458 * Otherwise, it is a mapping where set bits have meaning
5459 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5460 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5461 * B num-veh number of vehicles which are getting a new name
5462 * B/W offset number of the first vehicle that gets a new name
5463 * Byte : ID of vehicle to change
5464 * Word : ID of string to change/add
5465 * S data new texts, each of them zero-terminated, after
5466 * which the next name begins. */
5468 bool new_scheme
= _cur
.grffile
->grf_version
>= 7;
5470 uint8 feature
= buf
->ReadByte();
5471 uint8 lang
= buf
->ReadByte();
5472 uint8 num
= buf
->ReadByte();
5473 bool generic
= HasBit(lang
, 7);
5476 id
= buf
->ReadWord();
5477 } else if (feature
<= GSF_AIRCRAFT
) {
5478 id
= buf
->ReadExtendedByte();
5480 id
= buf
->ReadByte();
5485 uint16 endid
= id
+ num
;
5487 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5488 id
, endid
, feature
, lang
);
5490 for (; id
< endid
&& buf
->HasData(); id
++) {
5491 const char *name
= buf
->ReadString();
5492 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id
, name
);
5496 case GSF_ROADVEHICLES
:
5500 Engine
*e
= GetNewEngine(_cur
.grffile
, (VehicleType
)feature
, id
, HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
));
5501 if (e
== NULL
) break;
5502 StringID string
= AddGRFString(_cur
.grffile
->grfid
, e
->index
, lang
, new_scheme
, false, name
, e
->info
.string_id
);
5503 e
->info
.string_id
= string
;
5505 AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, true, name
, STR_UNDEFINED
);
5509 case GSF_INDUSTRIES
: {
5510 AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, true, name
, STR_UNDEFINED
);
5516 switch (GB(id
, 8, 8)) {
5517 case 0xC4: // Station class name
5518 if (_cur
.grffile
->stations
== NULL
|| _cur
.grffile
->stations
[GB(id
, 0, 8)] == NULL
) {
5519 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id
, 0, 8));
5521 StationClassID cls_id
= _cur
.grffile
->stations
[GB(id
, 0, 8)]->cls_id
;
5522 StationClass::Get(cls_id
)->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5526 case 0xC5: // Station name
5527 if (_cur
.grffile
->stations
== NULL
|| _cur
.grffile
->stations
[GB(id
, 0, 8)] == NULL
) {
5528 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id
, 0, 8));
5530 _cur
.grffile
->stations
[GB(id
, 0, 8)]->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5534 case 0xC7: // Airporttile name
5535 if (_cur
.grffile
->airtspec
== NULL
|| _cur
.grffile
->airtspec
[GB(id
, 0, 8)] == NULL
) {
5536 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id
, 0, 8));
5538 _cur
.grffile
->airtspec
[GB(id
, 0, 8)]->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5542 case 0xC9: // House name
5543 if (_cur
.grffile
->housespec
== NULL
|| _cur
.grffile
->housespec
[GB(id
, 0, 8)] == NULL
) {
5544 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id
, 0, 8));
5546 _cur
.grffile
->housespec
[GB(id
, 0, 8)]->building_name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5555 AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, true, name
, STR_UNDEFINED
);
5559 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id
);
5574 /* Shore sprite replacements for single-corner and inclined slopes. */
5575 static const SpritePair shore_sprites_1
[] = {
5576 { SPR_ORIGINALSHORE_START
+ 1, SPR_SHORE_BASE
+ 1 }, // SLOPE_W
5577 { SPR_ORIGINALSHORE_START
+ 2, SPR_SHORE_BASE
+ 2 }, // SLOPE_S
5578 { SPR_ORIGINALSHORE_START
+ 6, SPR_SHORE_BASE
+ 3 }, // SLOPE_SW
5579 { SPR_ORIGINALSHORE_START
+ 0, SPR_SHORE_BASE
+ 4 }, // SLOPE_E
5580 { SPR_ORIGINALSHORE_START
+ 4, SPR_SHORE_BASE
+ 6 }, // SLOPE_SE
5581 { SPR_ORIGINALSHORE_START
+ 3, SPR_SHORE_BASE
+ 8 }, // SLOPE_N
5582 { SPR_ORIGINALSHORE_START
+ 7, SPR_SHORE_BASE
+ 9 }, // SLOPE_NW
5583 { SPR_ORIGINALSHORE_START
+ 5, SPR_SHORE_BASE
+ 12 }, // SLOPE_NE
5586 /* Shore sprite replacements for three-corner and steep slopes. */
5587 static const SpritePair shore_sprites_2
[] = {
5588 { SPR_FLAT_GRASS_TILE
+ 16, SPR_SHORE_BASE
+ 0 }, // SLOPE_STEEP_S
5589 { SPR_FLAT_GRASS_TILE
+ 17, SPR_SHORE_BASE
+ 5 }, // SLOPE_STEEP_W
5590 { SPR_FLAT_GRASS_TILE
+ 7, SPR_SHORE_BASE
+ 7 }, // SLOPE_WSE
5591 { SPR_FLAT_GRASS_TILE
+ 15, SPR_SHORE_BASE
+ 10 }, // SLOPE_STEEP_N
5592 { SPR_FLAT_GRASS_TILE
+ 11, SPR_SHORE_BASE
+ 11 }, // SLOPE_NWS
5593 { SPR_FLAT_GRASS_TILE
+ 13, SPR_SHORE_BASE
+ 13 }, // SLOPE_ENW
5594 { SPR_FLAT_GRASS_TILE
+ 14, SPR_SHORE_BASE
+ 14 }, // SLOPE_SEN
5595 { SPR_FLAT_GRASS_TILE
+ 18, SPR_SHORE_BASE
+ 15 }, // SLOPE_STEEP_E
5596 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
5597 * If they would be used somewhen, then these grass tiles will most like not look as needed */
5598 { SPR_FLAT_GRASS_TILE
+ 5, SPR_SHORE_BASE
+ 16 }, // SLOPE_EW
5599 { SPR_FLAT_GRASS_TILE
+ 10, SPR_SHORE_BASE
+ 17 }, // SLOPE_NS
5603 /** The type of action 5 type. */
5604 enum Action5BlockType
{
5605 A5BLOCK_FIXED
, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5606 A5BLOCK_ALLOW_OFFSET
, ///< Allow replacing any subset by specifiing an offset.
5607 A5BLOCK_INVALID
, ///< unknown/not-implemented type
5609 /** Information about a single action 5 type. */
5610 struct Action5Type
{
5611 Action5BlockType block_type
; ///< How is this Action5 type processed?
5612 SpriteID sprite_base
; ///< Load the sprites starting from this sprite.
5613 uint16 min_sprites
; ///< If the Action5 contains less sprites, the whole block will be ignored.
5614 uint16 max_sprites
; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5615 const char *name
; ///< Name for error messages.
5618 /** The information about action 5 types. */
5619 static const Action5Type _action5_types
[] = {
5620 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5621 /* 0x00 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x00" },
5622 /* 0x01 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x01" },
5623 /* 0x02 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x02" },
5624 /* 0x03 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x03" },
5625 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET
, SPR_SIGNALS_BASE
, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT
, "Signal graphics" },
5626 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ELRAIL_BASE
, 1, ELRAIL_SPRITE_COUNT
, "Rail catenary graphics" },
5627 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET
, SPR_SLOPES_BASE
, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT
, "Foundation graphics" },
5628 /* 0x07 */ { A5BLOCK_INVALID
, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5629 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET
, SPR_CANALS_BASE
, 1, CANALS_SPRITE_COUNT
, "Canal graphics" },
5630 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ONEWAY_BASE
, 1, ONEWAY_SPRITE_COUNT
, "One way road graphics" },
5631 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET
, SPR_2CCMAP_BASE
, 1, TWOCCMAP_SPRITE_COUNT
, "2CC colour maps" },
5632 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET
, SPR_TRAMWAY_BASE
, 1, TRAMWAY_SPRITE_COUNT
, "Tramway graphics" },
5633 /* 0x0C */ { A5BLOCK_INVALID
, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5634 /* 0x0D */ { A5BLOCK_FIXED
, SPR_SHORE_BASE
, 16, SPR_SHORE_SPRITE_COUNT
, "Shore graphics" },
5635 /* 0x0E */ { A5BLOCK_INVALID
, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5636 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET
, SPR_TRACKS_FOR_SLOPES_BASE
, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT
, "Sloped rail track" },
5637 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AIRPORTX_BASE
, 1, AIRPORTX_SPRITE_COUNT
, "Airport graphics" },
5638 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ROADSTOP_BASE
, 1, ROADSTOP_SPRITE_COUNT
, "Road stop graphics" },
5639 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AQUEDUCT_BASE
, 1, AQUEDUCT_SPRITE_COUNT
, "Aqueduct graphics" },
5640 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AUTORAIL_BASE
, 1, AUTORAIL_SPRITE_COUNT
, "Autorail graphics" },
5641 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET
, SPR_FLAGS_BASE
, 1, FLAGS_SPRITE_COUNT
, "Flag graphics" },
5642 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET
, SPR_OPENTTD_BASE
, 1, OPENTTD_SPRITE_COUNT
, "OpenTTD GUI graphics" },
5643 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AIRPORT_PREVIEW_BASE
, 1, SPR_AIRPORT_PREVIEW_COUNT
, "Airport preview graphics" },
5644 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET
, SPR_RAILTYPE_TUNNEL_BASE
, 1, RAILTYPE_TUNNEL_BASE_COUNT
, "Railtype tunnel base" },
5645 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET
, SPR_PALETTE_BASE
, 1, PALETTE_SPRITE_COUNT
, "Palette" },
5649 static int GraphicsNew (ByteReader
*buf
)
5651 /* <05> <graphics-type> <num-sprites> <other data...>
5653 * B graphics-type What set of graphics the sprites define.
5654 * E num-sprites How many sprites are in this set?
5655 * V other data Graphics type specific data. Currently unused. */
5658 uint8 type
= buf
->ReadByte();
5659 uint16 num
= buf
->ReadExtendedByte();
5660 uint16 offset
= HasBit(type
, 7) ? buf
->ReadExtendedByte() : 0;
5661 ClrBit(type
, 7); // Clear the high bit as that only indicates whether there is an offset.
5663 if ((type
== 0x0D) && (num
== 10) && HasBit(_cur
.grfconfig
->flags
, GCF_SYSTEM
)) {
5664 /* Special not-TTDP-compatible case used in openttd.grf
5665 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5666 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5667 for (uint i
= 0; i
< lengthof(shore_sprites_2
); i
++) {
5668 LoadNextSprite (shore_sprites_2
[i
].spr
, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
);
5670 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_NONE
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ONLY_NEW
;
5674 /* Supported type? */
5675 if ((type
>= lengthof(_action5_types
)) || (_action5_types
[type
].block_type
== A5BLOCK_INVALID
)) {
5676 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type
, num
);
5680 const Action5Type
*action5_type
= &_action5_types
[type
];
5682 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5683 * except for the long version of the shore type:
5684 * Ignore offset if not allowed */
5685 if ((action5_type
->block_type
!= A5BLOCK_ALLOW_OFFSET
) && (offset
!= 0)) {
5686 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type
->name
, type
);
5690 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5691 * This does not make sense, if <offset> is allowed */
5692 if ((action5_type
->block_type
== A5BLOCK_FIXED
) && (num
< action5_type
->min_sprites
)) {
5693 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
);
5697 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5699 if (offset
>= action5_type
->max_sprites
) {
5700 grfmsg (1, "GraphicsNew: %s sprite offset must be less than %i, skipping", action5_type
->name
, action5_type
->max_sprites
);
5703 } else if (offset
+ num
> action5_type
->max_sprites
) {
5704 grfmsg (4, "GraphicsNew: %s sprite overflow, truncating...", action5_type
->name
);
5705 uint rem
= action5_type
->max_sprites
- offset
;
5706 skip_num
= num
- rem
;
5711 SpriteID replace
= action5_type
->sprite_base
+ offset
;
5713 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5714 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
);
5716 for (; num
> 0; num
--) {
5718 LoadNextSprite(replace
== 0 ? _cur
.spriteid
++ : replace
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
5721 if (type
== 0x0D) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_5
;
5726 /* Action 0x05 (SKIP) */
5727 static int SkipAct5 (ByteReader
*buf
)
5729 /* Ignore type byte */
5732 /* Skip the sprites of this action */
5733 int skip
= buf
->ReadExtendedByte();
5734 grfmsg (3, "SkipAct5: Skipping %d sprites", skip
);
5739 * Check whether we are (obviously) missing some of the extra
5740 * (Action 0x05) sprites that we like to use.
5741 * When missing sprites are found a warning will be shown.
5743 void CheckForMissingSprites()
5745 /* Don't break out quickly, but allow to check the other
5746 * sprites as well, so we can give the best information. */
5747 bool missing
= false;
5748 for (uint8 i
= 0; i
< lengthof(_action5_types
); i
++) {
5749 const Action5Type
*type
= &_action5_types
[i
];
5750 if (type
->block_type
== A5BLOCK_INVALID
) continue;
5752 for (uint j
= 0; j
< type
->max_sprites
; j
++) {
5753 if (!SpriteExists(type
->sprite_base
+ j
)) {
5754 DEBUG(grf
, 0, "%s sprites are missing", type
->name
);
5756 /* No need to log more of the same. */
5763 ShowErrorMessage(IsReleasedVersion() ? STR_NEWGRF_ERROR_MISSING_SPRITES
: STR_NEWGRF_ERROR_MISSING_SPRITES_UNSTABLE
, INVALID_STRING_ID
, WL_CRITICAL
);
5768 * Reads a variable common to VarAction2 and Action7/9/D.
5770 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5771 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5773 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5774 * @param value returns the value of the variable.
5775 * @param grffile NewGRF querying the variable
5776 * @return true iff the variable is known and the value is returned in 'value'.
5778 bool GetGlobalVariable(byte param
, uint32
*value
, const GRFFile
*grffile
)
5781 case 0x00: // current date
5782 *value
= max(_date
- DAYS_TILL_ORIGINAL_BASE_YEAR
, 0);
5785 case 0x01: // current year
5786 *value
= Clamp(_cur_year
, ORIGINAL_BASE_YEAR
, ORIGINAL_MAX_YEAR
) - ORIGINAL_BASE_YEAR
;
5789 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)
5791 ConvertDateToYMD(_date
, &ymd
);
5792 Date start_of_year
= ConvertYMDToDate(ymd
.year
, 0, 1);
5793 *value
= ymd
.month
| (ymd
.day
- 1) << 8 | (IsLeapYear(ymd
.year
) ? 1 << 15 : 0) | (_date
- start_of_year
) << 16;
5797 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5798 *value
= _settings_game
.game_creation
.landscape
;
5801 case 0x06: // road traffic side, bit 4 clear=left, set=right
5802 *value
= _settings_game
.vehicle
.road_side
<< 4;
5805 case 0x09: // date fraction
5806 *value
= _date_fract
* 885;
5809 case 0x0A: // animation counter
5810 *value
= _tick_counter
;
5813 case 0x0B: { // TTDPatch version
5816 uint revision
= 1; // special case: 2.0.1 is 2.0.10
5818 *value
= (major
<< 24) | (minor
<< 20) | (revision
<< 16) | build
;
5822 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5823 *value
= _cur
.grfconfig
->palette
& GRFP_USE_MASK
;
5826 case 0x0E: // Y-offset for train sprites
5827 *value
= _cur
.grffile
->traininfo_vehicle_pitch
;
5830 case 0x0F: // Rail track type cost factors
5832 SB(*value
, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL
)->cost_multiplier
); // normal rail
5833 if (_settings_game
.vehicle
.disable_elrails
) {
5834 /* skip elrail multiplier - disabled */
5835 SB(*value
, 8, 8, GetRailTypeInfo(RAILTYPE_MONO
)->cost_multiplier
); // monorail
5837 SB(*value
, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC
)->cost_multiplier
); // electified railway
5838 /* Skip monorail multiplier - no space in result */
5840 SB(*value
, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV
)->cost_multiplier
); // maglev
5843 case 0x11: // current rail tool type
5844 *value
= 0; // constant fake value to avoid desync
5847 case 0x12: // Game mode
5848 *value
= _game_mode
;
5851 /* case 0x13: // Tile refresh offset to left not implemented */
5852 /* case 0x14: // Tile refresh offset to right not implemented */
5853 /* case 0x15: // Tile refresh offset upwards not implemented */
5854 /* case 0x16: // Tile refresh offset downwards not implemented */
5855 /* case 0x17: // temperate snow line not implemented */
5857 case 0x1A: // Always -1
5861 case 0x1B: // Display options
5862 *value
= 0x3F; // constant fake value to avoid desync
5865 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5869 case 0x1E: // Miscellaneous GRF features
5870 *value
= _misc_grf_features
;
5872 /* Add the local flags */
5873 assert(!HasBit(*value
, GMB_TRAIN_WIDTH_32_PIXELS
));
5874 if (_cur
.grffile
->traininfo_vehicle_width
== VEHICLEINFO_FULL_VEHICLE_WIDTH
) SetBit(*value
, GMB_TRAIN_WIDTH_32_PIXELS
);
5877 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5879 case 0x20: { // snow line height
5880 byte snowline
= GetSnowLine();
5881 if (_settings_game
.game_creation
.landscape
== LT_ARCTIC
&& snowline
<= _settings_game
.construction
.max_heightlevel
) {
5882 *value
= Clamp(snowline
* (grffile
->grf_version
>= 8 ? 1 : TILE_HEIGHT
), 0, 0xFE);
5890 case 0x21: // OpenTTD version
5891 *value
= _openttd_newgrf_version
;
5894 case 0x22: // difficulty level
5898 case 0x23: // long format date
5902 case 0x24: // long format year
5906 default: return false;
5910 static uint32
GetParamVal(byte param
, uint32
*cond_val
)
5912 /* First handle variable common with VarAction2 */
5914 if (GetGlobalVariable(param
- 0x80, &value
, _cur
.grffile
)) return value
;
5916 /* Non-common variable */
5918 case 0x84: { // GRF loading stage
5921 if (_cur
.stage
> GLS_INIT
) SetBit(res
, 0);
5922 if (_cur
.stage
== GLS_RESERVE
) SetBit(res
, 8);
5923 if (_cur
.stage
== GLS_ACTIVATION
) SetBit(res
, 9);
5927 case 0x85: // TTDPatch flags, only for bit tests
5928 if (cond_val
== NULL
) {
5929 /* Supported in Action 0x07 and 0x09, not 0x0D */
5932 uint32 param_val
= _ttdpatch_flags
[*cond_val
/ 0x20];
5937 case 0x88: // GRF ID check
5940 /* case 0x99: Global ID offset not implemented */
5944 if (param
< 0x80) return _cur
.grffile
->GetParam(param
);
5946 /* In-game variable. */
5947 grfmsg(1, "Unsupported in-game variable 0x%02X", param
);
5953 static int CfgApply (ByteReader
*buf
)
5955 /* <06> <param-num> <param-size> <offset> ... <FF>
5957 * B param-num Number of parameter to substitute (First = "zero")
5958 * Ignored if that parameter was not specified in newgrf.cfg
5959 * B param-size How many bytes to replace. If larger than 4, the
5960 * bytes of the following parameter are used. In that
5961 * case, nothing is applied unless *all* parameters
5963 * B offset Offset into data from beginning of next sprite
5964 * to place where parameter is to be stored. */
5966 /* Preload the next sprite */
5967 size_t pos
= FioGetPos();
5968 uint32 num
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
5969 uint8 type
= FioReadByte();
5971 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5973 /* Reset the file position to the start of the next sprite */
5974 FioSeekTo(pos
, SEEK_SET
);
5976 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5980 GRFLocation
location(_cur
.grfconfig
->ident
.grfid
, _cur
.nfo_line
+ 1);
5981 std::pair
<GRFLineToSpriteOverride::iterator
, bool> ins
=
5982 _grf_line_to_action6_sprite_override
.insert (std::make_pair (location
, ttd_unique_free_ptr
<byte
>()));
5984 byte
*preload_sprite
;
5986 preload_sprite
= xmalloct
<byte
> (num
);
5987 ins
.first
->second
.reset (preload_sprite
);
5988 FioReadBlock (preload_sprite
, num
);
5990 preload_sprite
= ins
.first
->second
.get();
5993 /* Reset the file position to the start of the next sprite */
5994 FioSeekTo (pos
, SEEK_SET
);
5996 /* Now perform the Action 0x06 on our data. */
6005 /* Read the parameter to apply. 0xFF indicates no more data to change. */
6006 param_num
= buf
->ReadByte();
6007 if (param_num
== 0xFF) break;
6009 /* Get the size of the parameter to use. If the size covers multiple
6010 * double words, sequential parameter values are used. */
6011 param_size
= buf
->ReadByte();
6013 /* Bit 7 of param_size indicates we should add to the original value
6014 * instead of replacing it. */
6015 add_value
= HasBit(param_size
, 7);
6016 param_size
= GB(param_size
, 0, 7);
6018 /* Where to apply the data to within the pseudo sprite data. */
6019 offset
= buf
->ReadExtendedByte();
6021 /* If the parameter is a GRF parameter (not an internal variable) check
6022 * if it (and all further sequential parameters) has been defined. */
6023 if (param_num
< 0x80 && (param_num
+ (param_size
- 1) / 4) >= _cur
.grffile
->param_end
) {
6024 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num
+ (param_size
- 1) / 4));
6028 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size
, param_num
, offset
);
6031 for (i
= 0; i
< param_size
&& offset
+ i
< num
; i
++) {
6032 uint32 value
= GetParamVal(param_num
+ i
/ 4, NULL
);
6033 /* Reset carry flag for each iteration of the variable (only really
6034 * matters if param_size is greater than 4) */
6035 if (i
% 4 == 0) carry
= false;
6038 uint new_value
= preload_sprite
[offset
+ i
] + GB(value
, (i
% 4) * 8, 8) + (carry
? 1 : 0);
6039 preload_sprite
[offset
+ i
] = GB(new_value
, 0, 8);
6040 /* Check if the addition overflowed */
6041 carry
= new_value
>= 256;
6043 preload_sprite
[offset
+ i
] = GB(value
, (i
% 4) * 8, 8);
6052 * Disable a static NewGRF when it is influencing another (non-static)
6053 * NewGRF as this could cause desyncs.
6055 * We could just tell the NewGRF querying that the file doesn't exist,
6056 * but that might give unwanted results. Disabling the NewGRF gives the
6057 * best result as no NewGRF author can complain about that.
6058 * @param c The NewGRF to disable.
6060 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig
*c
)
6062 DisableGrf (STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC
, c
);
6067 static int SkipIf (ByteReader
*buf
)
6069 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6076 /* TODO: More params. More condition types. */
6077 uint32 cond_val
= 0;
6081 uint8 param
= buf
->ReadByte();
6082 uint8 paramsize
= buf
->ReadByte();
6083 uint8 condtype
= buf
->ReadByte();
6086 /* Always 1 for bit tests, the given value should be ignored. */
6090 switch (paramsize
) {
6091 case 8: cond_val
= buf
->ReadDWord(); mask
= buf
->ReadDWord(); break;
6092 case 4: cond_val
= buf
->ReadDWord(); mask
= 0xFFFFFFFF; break;
6093 case 2: cond_val
= buf
->ReadWord(); mask
= 0x0000FFFF; break;
6094 case 1: cond_val
= buf
->ReadByte(); mask
= 0x000000FF; break;
6098 if (param
< 0x80 && _cur
.grffile
->param_end
<= param
) {
6099 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param
);
6103 uint32 param_val
= GetParamVal(param
, &cond_val
);
6105 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype
, param_val
, cond_val
);
6108 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6109 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6110 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6111 * So, when the condition type is one of those, the specific variable
6112 * 0x88 code is skipped, so the "general" code for the cargo
6113 * availability conditions kicks in.
6115 if (param
== 0x88 && (condtype
< 0x0B || condtype
> 0x0E)) {
6118 GRFConfig
*c
= GetGRFConfig(cond_val
, mask
);
6120 if (c
!= NULL
&& HasBit(c
->flags
, GCF_STATIC
) && !HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
) && _networking
) {
6121 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c
);
6125 if (condtype
!= 10 && c
== NULL
) {
6126 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val
));
6131 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6132 case 0x06: // Is GRFID active?
6133 result
= c
->status
== GCS_ACTIVATED
;
6136 case 0x07: // Is GRFID non-active?
6137 result
= c
->status
!= GCS_ACTIVATED
;
6140 case 0x08: // GRFID is not but will be active?
6141 result
= c
->status
== GCS_INITIALISED
;
6144 case 0x09: // GRFID is or will be active?
6145 result
= c
->status
== GCS_ACTIVATED
|| c
->status
== GCS_INITIALISED
;
6148 case 0x0A: // GRFID is not nor will be active
6149 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6150 result
= c
== NULL
|| c
->status
== GCS_DISABLED
|| c
->status
== GCS_NOT_FOUND
;
6153 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype
); return 0;
6156 /* Parameter or variable tests */
6158 case 0x00: result
= !!(param_val
& (1 << cond_val
));
6160 case 0x01: result
= !(param_val
& (1 << cond_val
));
6162 case 0x02: result
= (param_val
& mask
) == cond_val
;
6164 case 0x03: result
= (param_val
& mask
) != cond_val
;
6166 case 0x04: result
= (param_val
& mask
) < cond_val
;
6168 case 0x05: result
= (param_val
& mask
) > cond_val
;
6170 case 0x0B: result
= GetCargoIDByLabel(BSWAP32(cond_val
)) == CT_INVALID
;
6172 case 0x0C: result
= GetCargoIDByLabel(BSWAP32(cond_val
)) != CT_INVALID
;
6174 case 0x0D: result
= GetRailTypeByLabel(BSWAP32(cond_val
)) == INVALID_RAILTYPE
;
6176 case 0x0E: result
= GetRailTypeByLabel(BSWAP32(cond_val
)) != INVALID_RAILTYPE
;
6179 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype
); return 0;
6184 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6188 uint8 numsprites
= buf
->ReadByte();
6190 /* numsprites can be a GOTO label if it has been defined in the GRF
6191 * file. The jump will always be the first matching label that follows
6192 * the current nfo_line. If no matching label is found, the first matching
6193 * label in the file is used. */
6194 GRFLabel
*choice
= NULL
;
6195 for (GRFLabel
*label
= _cur
.grffile
->label
; label
!= NULL
; label
= label
->next
) {
6196 if (label
->label
!= numsprites
) continue;
6198 /* Remember a goto before the current line */
6199 if (choice
== NULL
) choice
= label
;
6200 /* If we find a label here, this is definitely good */
6201 if (label
->nfo_line
> _cur
.nfo_line
) {
6207 if (choice
!= NULL
) {
6208 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice
->label
, choice
->nfo_line
);
6209 FioSeekTo(choice
->pos
, SEEK_SET
);
6210 _cur
.nfo_line
= choice
->nfo_line
;
6214 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites
);
6216 if (numsprites
!= 0) return numsprites
;
6218 /* If an action 8 hasn't been encountered yet, disable the grf. */
6219 if (_cur
.grfconfig
->status
!= (_cur
.stage
< GLS_RESERVE
? GCS_INITIALISED
: GCS_ACTIVATED
)) {
6223 /* Zero means there are no sprites to skip, so we use -1 to indicate
6224 * that all further sprites should be skipped. */
6229 /* Action 0x08 (GLS_FILESCAN) */
6230 static int ScanInfo (ByteReader
*buf
)
6232 uint8 grf_version
= buf
->ReadByte();
6233 uint32 grfid
= buf
->ReadDWord();
6234 const char *name
= buf
->ReadString();
6236 _cur
.grfconfig
->ident
.grfid
= grfid
;
6238 if (grf_version
< 2 || grf_version
> 8) {
6239 SetBit(_cur
.grfconfig
->flags
, GCF_INVALID
);
6240 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
);
6243 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6244 if (GB(grfid
, 0, 8) == 0xFF) SetBit(_cur
.grfconfig
->flags
, GCF_SYSTEM
);
6246 _cur
.grfconfig
->name
->add (0x7F, grfid
, false, name
);
6248 if (buf
->HasData()) {
6249 const char *info
= buf
->ReadString();
6250 _cur
.grfconfig
->info
->add (0x7F, grfid
, true, info
);
6253 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6258 static int GRFInfo (ByteReader
*buf
)
6260 /* <08> <version> <grf-id> <name> <info>
6262 * B version newgrf version, currently 06
6263 * 4*B grf-id globally unique ID of this .grf file
6264 * S name name of this .grf set
6265 * S info string describing the set, and e.g. author and copyright */
6267 uint8 version
= buf
->ReadByte();
6268 uint32 grfid
= buf
->ReadDWord();
6269 const char *name
= buf
->ReadString();
6271 if (_cur
.stage
< GLS_RESERVE
&& _cur
.grfconfig
->status
!= GCS_UNKNOWN
) {
6272 DisableCur (STR_NEWGRF_ERROR_MULTIPLE_ACTION_8
);
6276 if (_cur
.grffile
->grfid
!= grfid
) {
6277 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
));
6278 _cur
.grffile
->grfid
= grfid
;
6281 _cur
.grffile
->grf_version
= version
;
6282 _cur
.grfconfig
->status
= _cur
.stage
< GLS_RESERVE
? GCS_INITIALISED
: GCS_ACTIVATED
;
6284 /* Do swap the GRFID for displaying purposes since people expect that */
6285 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
);
6291 static int SpriteReplace (ByteReader
*buf
)
6293 /* <0A> <num-sets> <set1> [<set2> ...]
6294 * <set>: <num-sprites> <first-sprite>
6296 * B num-sets How many sets of sprites to replace.
6298 * B num-sprites How many sprites are in this set
6299 * W first-sprite First sprite number to replace */
6301 uint8 num_sets
= buf
->ReadByte();
6303 for (uint i
= 0; i
< num_sets
; i
++) {
6304 uint8 num_sprites
= buf
->ReadByte();
6305 uint16 first_sprite
= buf
->ReadWord();
6307 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6308 i
, num_sprites
, first_sprite
6311 for (uint j
= 0; j
< num_sprites
; j
++) {
6312 int load_index
= first_sprite
+ j
;
6314 LoadNextSprite(load_index
, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
); // XXX
6316 /* Shore sprites now located at different addresses.
6317 * So detect when the old ones get replaced. */
6318 if (IsInsideMM(load_index
, SPR_ORIGINALSHORE_START
, SPR_ORIGINALSHORE_END
+ 1)) {
6319 if (_loaded_newgrf_features
.shore
!= SHORE_REPLACE_ACTION_5
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_A
;
6327 /* Action 0x0A (SKIP) */
6328 static int SkipActA (ByteReader
*buf
)
6330 uint8 num_sets
= buf
->ReadByte();
6333 for (uint i
= 0; i
< num_sets
; i
++) {
6334 /* Skip the sprites this replaces */
6335 skip
+= buf
->ReadByte();
6336 /* But ignore where they go */
6340 grfmsg (3, "SkipActA: Skipping %d sprites", skip
);
6346 static int GRFLoadError (ByteReader
*buf
)
6348 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6350 * B severity 00: notice, contine loading grf file
6351 * 01: warning, continue loading grf file
6352 * 02: error, but continue loading grf file, and attempt
6353 * loading grf again when loading or starting next game
6354 * 03: error, abort loading and prevent loading again in
6355 * the future (only when restarting the patch)
6356 * B language-id see action 4, use 1F for built-in error messages
6357 * B message-id message to show, see below
6358 * S message for custom messages (message-id FF), text of the message
6359 * not present for built-in messages.
6360 * V data additional data for built-in (or custom) messages
6361 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6363 static const StringID msgstr
[] = {
6364 STR_NEWGRF_ERROR_VERSION_NUMBER
,
6365 STR_NEWGRF_ERROR_DOS_OR_WINDOWS
,
6366 STR_NEWGRF_ERROR_UNSET_SWITCH
,
6367 STR_NEWGRF_ERROR_INVALID_PARAMETER
,
6368 STR_NEWGRF_ERROR_LOAD_BEFORE
,
6369 STR_NEWGRF_ERROR_LOAD_AFTER
,
6370 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER
,
6373 static const StringID sevstr
[] = {
6374 STR_NEWGRF_ERROR_MSG_INFO
,
6375 STR_NEWGRF_ERROR_MSG_WARNING
,
6376 STR_NEWGRF_ERROR_MSG_ERROR
,
6377 STR_NEWGRF_ERROR_MSG_FATAL
6380 byte severity
= buf
->ReadByte();
6381 byte lang
= buf
->ReadByte();
6382 byte message_id
= buf
->ReadByte();
6384 /* Skip the error if it isn't valid for the current language. */
6385 if (!CheckGrfLangID(lang
, _cur
.grffile
->grf_version
)) return 0;
6387 /* Skip the error until the activation stage unless bit 7 of the severity
6389 if (!HasBit(severity
, 7) && _cur
.stage
== GLS_INIT
) {
6390 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur
.stage
);
6393 ClrBit(severity
, 7);
6395 if (severity
>= lengthof(sevstr
)) {
6396 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity
);
6398 } else if (severity
== 3) {
6399 /* This is a fatal error, so make sure the GRF is deactivated and no
6400 * more of it gets loaded. */
6403 /* Make sure we show fatal errors, instead of silly infos from before */
6404 delete _cur
.grfconfig
->error
;
6405 _cur
.grfconfig
->error
= NULL
;
6408 if (message_id
>= lengthof(msgstr
) && message_id
!= 0xFF) {
6409 grfmsg(7, "GRFLoadError: Invalid message id.");
6411 } else if (!buf
->HasData (2)) {
6412 grfmsg(7, "GRFLoadError: No message data supplied.");
6414 } else if (_cur
.grfconfig
->error
== NULL
) {
6415 /* For now we can only show one message per newgrf file. */
6416 GRFError
*error
= new GRFError (sevstr
[severity
]);
6418 if (message_id
!= 0xFF) {
6419 error
->message
= msgstr
[message_id
];
6420 } else if (buf
->HasData()) {
6421 /* This is a custom error message. */
6422 const char *message
= buf
->ReadString();
6423 error
->custom_message
= TranslateTTDPatchCodes(_cur
.grffile
->grfid
, lang
, true, message
, NULL
, SCC_RAW_STRING_POINTER
);
6425 grfmsg(7, "GRFLoadError: No custom message supplied.");
6426 error
->custom_message
= xstrdup("");
6429 if (buf
->HasData()) {
6430 const char *data
= buf
->ReadString();
6431 error
->data
= TranslateTTDPatchCodes(_cur
.grffile
->grfid
, lang
, true, data
);
6433 grfmsg(7, "GRFLoadError: No message data supplied.");
6434 error
->data
= xstrdup("");
6437 /* Only two parameter numbers can be used in the string. */
6438 for (uint i
= 0; i
< lengthof(error
->param_value
) && buf
->HasData(); i
++) {
6439 uint param_number
= buf
->ReadByte();
6440 error
->param_value
[i
] = _cur
.grffile
->GetParam(param_number
);
6443 _cur
.grfconfig
->error
= error
;
6446 return (severity
== 3) ? -1 : 0;
6450 static int GRFComment (ByteReader
*buf
)
6452 /* <0C> [<ignored...>]
6454 * V ignored Anything following the 0C is ignored */
6456 if (buf
->HasData()) grfmsg (2, "GRFComment: %s", buf
->ReadString());
6461 /* Action 0x0D (GLS_SAFETYSCAN) */
6462 static int SafeParamSet (ByteReader
*buf
)
6464 uint8 target
= buf
->ReadByte();
6466 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6467 if (target
< 0x80 || target
== 0x9E) return 0;
6469 /* GRM could be unsafe, but as here it can only happen after other GRFs
6470 * are loaded, it should be okay. If the GRF tried to use the slots it
6471 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6472 * sprites is considered safe. */
6474 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
6476 /* Skip remainder of GRF */
6481 static uint32
GetPatchVariable(uint8 param
)
6484 /* start year - 1920 */
6485 case 0x0B: return max(_settings_game
.game_creation
.starting_year
, ORIGINAL_BASE_YEAR
) - ORIGINAL_BASE_YEAR
;
6487 /* freight trains weight factor */
6488 case 0x0E: return _settings_game
.vehicle
.freight_trains
;
6490 /* empty wagon speed increase */
6491 case 0x0F: return 0;
6493 /* plane speed factor; our patch option is reversed from TTDPatch's,
6494 * the following is good for 1x, 2x and 4x (most common?) and...
6495 * well not really for 3x. */
6497 switch (_settings_game
.vehicle
.plane_speed
) {
6506 /* 2CC colourmap base sprite */
6507 case 0x11: return SPR_2CCMAP_BASE
;
6509 /* map size: format = -MABXYSS
6510 * M : the type of map
6511 * bit 0 : set : squared map. Bit 1 is now not relevant
6512 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6513 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6514 * clear : X is the bigger edge.
6515 * A : minimum edge(log2) of the map
6516 * B : maximum edge(log2) of the map
6517 * XY : edges(log2) of each side of the map.
6518 * SS : combination of both X and Y, thus giving the size(log2) of the map
6522 byte log_X
= MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6523 byte log_Y
= MapLogY() - 6;
6524 byte max_edge
= max(log_X
, log_Y
);
6526 if (log_X
== log_Y
) { // we have a squared map, since both edges are identical
6527 SetBit(map_bits
, 0);
6529 if (max_edge
== log_Y
) SetBit(map_bits
, 1); // edge Y been the biggest, mark it
6532 return (map_bits
<< 24) | (min(log_X
, log_Y
) << 20) | (max_edge
<< 16) |
6533 (log_X
<< 12) | (log_Y
<< 8) | (log_X
+ log_Y
);
6536 /* The maximum height of the map. */
6538 return _settings_game
.construction
.max_heightlevel
;
6540 /* Extra foundations base sprite */
6542 return SPR_SLOPES_BASE
;
6544 /* Shore base sprite */
6546 return SPR_SHORE_BASE
;
6549 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param
);
6555 static bool PerformGRM (uint32
*grm
, uint16 num_ids
, uint16 count
,
6556 uint8 op
, uint8 target
, uint32
*res
, const char *type
)
6562 /* Return GRFID of set that reserved ID */
6563 *res
= grm
[_cur
.grffile
->GetParam(target
)];
6567 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6568 if (op
== 2 || op
== 3) start
= _cur
.grffile
->GetParam(target
);
6570 for (uint i
= start
; i
< num_ids
; i
++) {
6574 if (op
== 2 || op
== 3) break;
6579 if (size
== count
) break;
6582 if (size
== count
) {
6583 /* Got the slot... */
6584 if (op
== 0 || op
== 3) {
6585 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count
, type
, start
);
6586 for (uint i
= 0; i
< count
; i
++) grm
[start
+ i
] = _cur
.grffile
->grfid
;
6592 /* Unable to allocate */
6593 if (op
!= 4 && op
!= 5) {
6594 /* Deactivate GRF */
6595 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count
, type
);
6596 DisableCur (STR_NEWGRF_ERROR_GRM_FAILED
);
6600 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count
, type
);
6606 /** Action 0x0D: Set parameter */
6607 static int ParamSet (ByteReader
*buf
)
6609 /* <0D> <target> <operation> <source1> <source2> [<data>]
6611 * B target parameter number where result is stored
6612 * B operation operation to perform, see below
6613 * B source1 first source operand
6614 * B source2 second source operand
6615 * D data data to use in the calculation, not necessary
6616 * if both source1 and source2 refer to actual parameters
6619 * 00 Set parameter equal to source1
6620 * 01 Addition, source1 + source2
6621 * 02 Subtraction, source1 - source2
6622 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6623 * 04 Signed multiplication, source1 * source2 (both signed)
6624 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6625 * signed quantity; left shift if positive and right shift if
6626 * negative, source1 is unsigned)
6627 * 06 Signed bit shift, source1 by source2
6628 * (source2 like in 05, and source1 as well)
6631 uint8 target
= buf
->ReadByte();
6632 uint8 oper
= buf
->ReadByte();
6633 uint32 src1
= buf
->ReadByte();
6634 uint32 src2
= buf
->ReadByte();
6637 if (buf
->HasData (4)) data
= buf
->ReadDWord();
6639 /* You can add 80 to the operation to make it apply only if the target
6640 * is not defined yet. In this respect, a parameter is taken to be
6641 * defined if any of the following applies:
6642 * - it has been set to any value in the newgrf(w).cfg parameter list
6643 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6644 * an earlier action D */
6645 if (HasBit(oper
, 7)) {
6646 if (target
< 0x80 && target
< _cur
.grffile
->param_end
) {
6647 grfmsg(7, "ParamSet: Param %u already defined, skipping", target
);
6651 oper
= GB(oper
, 0, 7);
6655 /* The source1 and source2 operands refer to the grf parameter number
6656 * like in action 6 and 7. In addition, they can refer to the special
6657 * variables available in action 7, or they can be FF to use the value
6658 * of <data>. If referring to parameters that are undefined, a value
6659 * of 0 is used instead. */
6660 src1
= (src1
== 0xFF) ? data
: GetParamVal(src1
, NULL
);
6661 src2
= (src2
== 0xFF) ? data
: GetParamVal(src2
, NULL
);
6662 } else if (GB(data
, 0, 8) != 0xFF) {
6663 /* Read another GRF File's parameter */
6664 const GRFFile
*file
= GetFileByGRFID(data
);
6665 GRFConfig
*c
= GetGRFConfig(data
);
6666 if (c
!= NULL
&& HasBit(c
->flags
, GCF_STATIC
) && !HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
) && _networking
) {
6667 /* Disable the read GRF if it is a static NewGRF. */
6668 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c
);
6670 } else if (file
== NULL
|| c
== NULL
|| c
->status
== GCS_DISABLED
) {
6672 } else if (src1
== 0xFE) {
6675 src1
= file
->GetParam(src1
);
6677 } else if (data
== 0x0000FFFF) {
6678 /* Patch variables */
6679 src1
= GetPatchVariable(src1
);
6681 /* GRF Resource Management */
6683 uint8 feature
= GB(data
, 8, 8);
6684 uint16 count
= GB(data
, 16, 16);
6686 if (_cur
.stage
== GLS_RESERVE
) {
6687 if (feature
== 0x08) {
6688 /* General sprites */
6690 /* Check if the allocated sprites will fit below the original sprite limit */
6691 if (_cur
.spriteid
+ count
>= 16384) {
6692 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count
);
6693 DisableCur (STR_NEWGRF_ERROR_GRM_FAILED
);
6697 /* Reserve space at the current sprite ID */
6698 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count
, _cur
.spriteid
);
6699 _grm_sprites
[GRFLocation(_cur
.grffile
->grfid
, _cur
.nfo_line
)] = _cur
.spriteid
;
6700 _cur
.spriteid
+= count
;
6703 /* Ignore GRM result during reservation */
6705 } else if (_cur
.stage
== GLS_ACTIVATION
) {
6707 case 0x00: // Trains
6708 case 0x01: // Road Vehicles
6710 case 0x03: // Aircraft
6711 if (!_settings_game
.vehicle
.dynamic_engines
) {
6712 if (!PerformGRM (&_grm_engines
[_engine_offsets
[feature
]], _engine_counts
[feature
], count
, op
, target
, &src1
, "vehicles")) {
6716 /* GRM does not apply for dynamic engine allocation. */
6720 src1
= _cur
.grffile
->GetParam(target
);
6730 case 0x08: // General sprites
6733 /* Return space reserved during reservation stage */
6734 src1
= _grm_sprites
[GRFLocation(_cur
.grffile
->grfid
, _cur
.nfo_line
)];
6735 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1
);
6739 src1
= _cur
.spriteid
;
6743 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op
);
6749 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6750 if (!PerformGRM (_grm_cargoes
, NUM_CARGO
* 2, count
, op
, target
, &src1
, "cargoes")) {
6755 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature
); return 0;
6758 /* Ignore GRM during initialization */
6763 /* TODO: You can access the parameters of another GRF file by using
6764 * source2=FE, source1=the other GRF's parameter number and data=GRF
6765 * ID. This is only valid with operation 00 (set). If the GRF ID
6766 * cannot be found, a value of 0 is used for the parameter value
6788 res
= (int32
)src1
* (int32
)src2
;
6792 if ((int32
)src2
< 0) {
6793 res
= src1
>> -(int32
)src2
;
6795 res
= src1
<< (src2
& 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6800 if ((int32
)src2
< 0) {
6801 res
= (int32
)src1
>> -(int32
)src2
;
6803 res
= (int32
)src1
<< (src2
& 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6807 case 0x07: // Bitwise AND
6811 case 0x08: // Bitwise OR
6815 case 0x09: // Unsigned division
6823 case 0x0A: // Signed divison
6827 res
= (int32
)src1
/ (int32
)src2
;
6831 case 0x0B: // Unsigned modulo
6839 case 0x0C: // Signed modulo
6843 res
= (int32
)src1
% (int32
)src2
;
6847 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper
); return 0;
6851 case 0x8E: // Y-Offset for train sprites
6852 _cur
.grffile
->traininfo_vehicle_pitch
= res
;
6855 case 0x8F: { // Rail track type cost factors
6856 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
6857 _railtypes
[RAILTYPE_RAIL
].cost_multiplier
= GB(res
, 0, 8);
6858 if (_settings_game
.vehicle
.disable_elrails
) {
6859 _railtypes
[RAILTYPE_ELECTRIC
].cost_multiplier
= GB(res
, 0, 8);
6860 _railtypes
[RAILTYPE_MONO
].cost_multiplier
= GB(res
, 8, 8);
6862 _railtypes
[RAILTYPE_ELECTRIC
].cost_multiplier
= GB(res
, 8, 8);
6863 _railtypes
[RAILTYPE_MONO
].cost_multiplier
= GB(res
, 16, 8);
6865 _railtypes
[RAILTYPE_MAGLEV
].cost_multiplier
= GB(res
, 16, 8);
6869 /* @todo implement */
6870 case 0x93: // Tile refresh offset to left
6871 case 0x94: // Tile refresh offset to right
6872 case 0x95: // Tile refresh offset upwards
6873 case 0x96: // Tile refresh offset downwards
6874 case 0x97: // Snow line height
6875 case 0x99: // Global ID offset
6876 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target
);
6879 case 0x9E: // Miscellaneous GRF features
6880 /* Set train list engine width */
6881 _cur
.grffile
->traininfo_vehicle_width
= HasBit(res
, GMB_TRAIN_WIDTH_32_PIXELS
) ? VEHICLEINFO_FULL_VEHICLE_WIDTH
: TRAININFO_DEFAULT_VEHICLE_WIDTH
;
6882 /* Remove the local flags from the global flags */
6883 ClrBit(res
, GMB_TRAIN_WIDTH_32_PIXELS
);
6885 /* Only copy safe bits for static grfs */
6886 if (HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
)) {
6887 uint32 safe_bits
= 0;
6888 SetBit(safe_bits
, GMB_SECOND_ROCKY_TILE_SET
);
6890 _misc_grf_features
= (_misc_grf_features
& ~safe_bits
) | (res
& safe_bits
);
6892 _misc_grf_features
= res
;
6896 case 0x9F: // locale-dependent settings
6897 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target
);
6901 if (target
< 0x80) {
6902 _cur
.grffile
->param
[target
] = res
;
6903 /* param is zeroed by default */
6904 if (target
+ 1U > _cur
.grffile
->param_end
) _cur
.grffile
->param_end
= target
+ 1;
6906 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target
);
6914 /* Action 0x0E (GLS_SAFETYSCAN) */
6915 static int SafeGRFInhibit (ByteReader
*buf
)
6917 /* <0E> <num> <grfids...>
6919 * B num Number of GRFIDs that follow
6920 * D grfids GRFIDs of the files to deactivate */
6922 uint8 num
= buf
->ReadByte();
6924 for (uint i
= 0; i
< num
; i
++) {
6925 uint32 grfid
= buf
->ReadDWord();
6927 /* GRF is unsafe it if tries to deactivate other GRFs */
6928 if (grfid
!= _cur
.grfconfig
->ident
.grfid
) {
6929 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
6931 /* Skip remainder of GRF */
6940 static int GRFInhibit (ByteReader
*buf
)
6942 /* <0E> <num> <grfids...>
6944 * B num Number of GRFIDs that follow
6945 * D grfids GRFIDs of the files to deactivate */
6947 uint8 num
= buf
->ReadByte();
6949 for (uint i
= 0; i
< num
; i
++) {
6950 uint32 grfid
= buf
->ReadDWord();
6951 GRFConfig
*file
= GetGRFConfig(grfid
);
6953 /* Unset activation flag */
6954 if (file
!= NULL
&& file
!= _cur
.grfconfig
) {
6955 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file
->filename
);
6956 DisableGrf (STR_NEWGRF_ERROR_FORCEFULLY_DISABLED
, file
);
6963 /** Action 0x0F - Define Town names */
6964 static int FeatureTownName (ByteReader
*buf
)
6966 /* <0F> <id> <style-name> <num-parts> <parts>
6968 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6969 * V style-name Name of the style (only for final definition)
6970 * B num-parts Number of parts in this definition
6971 * V parts The parts */
6973 uint32 grfid
= _cur
.grffile
->grfid
;
6975 GRFTownName
*townname
= AddGRFTownName(grfid
);
6977 byte id
= buf
->ReadByte();
6978 grfmsg(6, "FeatureTownName: definition 0x%02X", id
& 0x7F);
6980 if (HasBit(id
, 7)) {
6981 /* Final definition */
6983 bool new_scheme
= _cur
.grffile
->grf_version
>= 7;
6985 byte lang
= buf
->ReadByte();
6987 byte nb_gen
= townname
->nb_gen
;
6991 const char *name
= buf
->ReadString();
6993 char *lang_name
= TranslateTTDPatchCodes(grfid
, lang
, false, name
);
6994 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang
, lang_name
);
6997 townname
->name
[nb_gen
] = AddGRFString(grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
6999 lang
= buf
->ReadByte();
7000 } while (lang
!= 0);
7001 townname
->id
[nb_gen
] = id
;
7005 byte nb
= buf
->ReadByte();
7006 grfmsg(6, "FeatureTownName: %u parts", nb
);
7008 townname
->nbparts
[id
] = nb
;
7009 townname
->partlist
[id
] = xcalloct
<NamePartList
>(nb
);
7011 for (int i
= 0; i
< nb
; i
++) {
7012 byte nbtext
= buf
->ReadByte();
7013 townname
->partlist
[id
][i
].bitstart
= buf
->ReadByte();
7014 townname
->partlist
[id
][i
].bitcount
= buf
->ReadByte();
7015 townname
->partlist
[id
][i
].maxprob
= 0;
7016 townname
->partlist
[id
][i
].partcount
= nbtext
;
7017 townname
->partlist
[id
][i
].parts
= xcalloct
<NamePart
>(nbtext
);
7018 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
);
7020 for (int j
= 0; j
< nbtext
; j
++) {
7021 byte prob
= buf
->ReadByte();
7023 if (HasBit(prob
, 7)) {
7024 byte ref_id
= buf
->ReadByte();
7026 if (townname
->nbparts
[ref_id
] == 0) {
7027 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id
);
7028 DelGRFTownName(grfid
);
7029 DisableCur (STR_NEWGRF_ERROR_INVALID_ID
);
7033 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i
, j
, ref_id
, prob
& 0x7F);
7034 townname
->partlist
[id
][i
].parts
[j
].data
.id
= ref_id
;
7036 const char *text
= buf
->ReadString();
7037 townname
->partlist
[id
][i
].parts
[j
].data
.text
= TranslateTTDPatchCodes(grfid
, 0, false, text
);
7038 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i
, j
, townname
->partlist
[id
][i
].parts
[j
].data
.text
, prob
);
7040 townname
->partlist
[id
][i
].parts
[j
].prob
= prob
;
7041 townname
->partlist
[id
][i
].maxprob
+= GB(prob
, 0, 7);
7043 grfmsg(6, "FeatureTownName: part %d, total probability %d", i
, townname
->partlist
[id
][i
].maxprob
);
7049 /** Action 0x10 - Define goto label */
7050 static int DefineGotoLabel (ByteReader
*buf
)
7052 /* <10> <label> [<comment>]
7054 * B label The label to define
7055 * V comment Optional comment - ignored */
7057 byte nfo_label
= buf
->ReadByte();
7059 GRFLabel
*label
= xmalloct
<GRFLabel
>();
7060 label
->label
= nfo_label
;
7061 label
->nfo_line
= _cur
.nfo_line
;
7062 label
->pos
= FioGetPos();
7065 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7066 if (_cur
.grffile
->label
== NULL
) {
7067 _cur
.grffile
->label
= label
;
7069 /* Attach the label to the end of the list */
7071 for (l
= _cur
.grffile
->label
; l
->next
!= NULL
; l
= l
->next
) {}
7075 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label
->label
);
7081 * Process a sound import from another GRF file.
7082 * @param sound Destination for sound.
7084 static void ImportGRFSound(SoundEntry
*sound
)
7086 const GRFFile
*file
;
7087 uint32 grfid
= FioReadDword();
7088 SoundID sound_id
= FioReadWord();
7090 file
= GetFileByGRFID(grfid
);
7091 if (file
== NULL
|| file
->sound_offset
== 0) {
7092 grfmsg(1, "ImportGRFSound: Source file not available");
7096 if (sound_id
>= file
->num_sounds
) {
7097 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id
);
7101 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id
, file
->sound_offset
+ sound_id
, grfid
);
7103 *sound
= *GetSound(file
->sound_offset
+ sound_id
);
7105 /* Reset volume and priority, which TTDPatch doesn't copy */
7106 sound
->volume
= 128;
7107 sound
->priority
= 0;
7111 * Load a sound from a file.
7112 * @param offs File offset to read sound from.
7113 * @param sound Destination for sound.
7115 static void LoadGRFSound(size_t offs
, SoundEntry
*sound
)
7117 /* Set default volume and priority */
7118 sound
->volume
= 0x80;
7119 sound
->priority
= 0;
7121 if (offs
!= SIZE_MAX
) {
7122 /* Sound is present in the NewGRF. */
7123 sound
->file_slot
= _cur
.file_index
;
7124 sound
->file_offset
= offs
;
7125 sound
->grf_container_ver
= _cur
.grf_container_ver
;
7130 static int GRFSound (ByteReader
*buf
)
7134 * W num Number of sound files that follow */
7136 uint16 num
= buf
->ReadWord();
7137 if (num
== 0) return 0;
7140 if (_cur
.grffile
->sound_offset
== 0) {
7141 _cur
.grffile
->sound_offset
= GetNumSounds();
7142 _cur
.grffile
->num_sounds
= num
;
7143 sound
= AllocateSound(num
);
7145 sound
= GetSound(_cur
.grffile
->sound_offset
);
7148 for (int i
= 0; i
< num
; i
++) {
7151 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7152 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7153 bool invalid
= i
>= _cur
.grffile
->num_sounds
;
7155 size_t offs
= FioGetPos();
7157 uint32 len
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
7158 byte type
= FioReadByte();
7160 if (_cur
.grf_container_ver
>= 2 && type
== 0xFD) {
7161 /* Reference to sprite section. */
7163 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7165 } else if (len
!= 4) {
7166 grfmsg(1, "GRFSound: Invalid sprite section import");
7169 uint32 id
= FioReadDword();
7170 if (_cur
.stage
== GLS_INIT
) LoadGRFSound(GetGRFSpriteOffset(id
), sound
+ i
);
7176 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7178 SkipSpriteData(type
, len
- 8);
7183 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7187 byte action
= FioReadByte();
7190 /* Allocate sound only in init stage. */
7191 if (_cur
.stage
== GLS_INIT
) {
7192 if (_cur
.grf_container_ver
>= 2) {
7193 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7195 LoadGRFSound(offs
, sound
+ i
);
7198 FioSkipBytes(len
- 1); // already read <action>
7202 if (_cur
.stage
== GLS_ACTIVATION
) {
7203 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7204 * importing sounds, so this is probably all wrong... */
7205 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7206 ImportGRFSound(sound
+ i
);
7208 FioSkipBytes(len
- 1); // already read <action>
7213 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action
);
7214 FioSkipBytes(len
- 1); // already read <action>
7222 /* Action 0x11 (SKIP) */
7223 static int SkipAct11 (ByteReader
*buf
)
7227 * W num Number of sound files that follow */
7229 int skip
= buf
->ReadWord();
7230 grfmsg (3, "SkipAct11: Skipping %d sprites", skip
);
7235 static int LoadFontGlyph (ByteReader
*buf
)
7237 /* <12> <num_def> <font_size> <num_char> <base_char>
7239 * B num_def Number of definitions
7240 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7241 * B num_char Number of consecutive glyphs
7242 * W base_char First character index */
7244 uint8 num_def
= buf
->ReadByte();
7246 for (uint i
= 0; i
< num_def
; i
++) {
7247 FontSize size
= (FontSize
)buf
->ReadByte();
7248 uint8 num_char
= buf
->ReadByte();
7249 uint16 base_char
= buf
->ReadWord();
7252 if (size
>= FS_END
) {
7253 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size
);
7256 fc
= FontCache::Get (size
);
7259 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char
, base_char
, size
);
7261 for (uint c
= 0; c
< num_char
; c
++) {
7262 if (fc
!= NULL
) fc
->SetUnicodeGlyph (base_char
+ c
, _cur
.spriteid
);
7264 LoadNextSprite(_cur
.spriteid
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
7271 /** Action 0x12 (SKIP) */
7272 static int SkipAct12 (ByteReader
*buf
)
7274 /* <12> <num_def> <font_size> <num_char> <base_char>
7276 * B num_def Number of definitions
7277 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7278 * B num_char Number of consecutive glyphs
7279 * W base_char First character index */
7281 uint8 num_def
= buf
->ReadByte();
7284 for (uint i
= 0; i
< num_def
; i
++) {
7285 /* Ignore 'size' byte */
7288 /* Sum up number of characters */
7289 skip
+= buf
->ReadByte();
7291 /* Ignore 'base_char' word */
7295 grfmsg (3, "SkipAct12: Skipping %d sprites", skip
);
7301 static int TranslateGRFStrings (ByteReader
*buf
)
7303 /* <13> <grfid> <num-ent> <offset> <text...>
7305 * 4*B grfid The GRFID of the file whose texts are to be translated
7306 * B num-ent Number of strings
7307 * W offset First text ID
7308 * S text... Zero-terminated strings */
7310 uint32 grfid
= buf
->ReadDWord();
7311 const GRFConfig
*c
= GetGRFConfig(grfid
);
7312 if (c
== NULL
|| (c
->status
!= GCS_INITIALISED
&& c
->status
!= GCS_ACTIVATED
)) {
7313 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid
));
7317 if (c
->status
== GCS_INITIALISED
) {
7318 /* If the file is not active but will be activated later, give an error
7319 * and disable this file. */
7320 GRFError
*error
= DisableCur (STR_NEWGRF_ERROR_LOAD_AFTER
);
7323 GetString (tmp
, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE
);
7324 error
->data
= xstrdup(tmp
);
7329 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7330 * to be added as a generic string, thus the language id of 0x7F. For this to work
7331 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7332 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7333 * not change anything if a string has been provided specifically for this language. */
7334 byte language
= _cur
.grffile
->grf_version
>= 8 ? buf
->ReadByte() : 0x7F;
7335 byte num_strings
= buf
->ReadByte();
7336 uint16 first_id
= buf
->ReadWord();
7338 if (!((first_id
>= 0xD000 && first_id
+ num_strings
<= 0xD3FF) || (first_id
>= 0xDC00 && first_id
+ num_strings
<= 0xDCFF))) {
7339 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id
, num_strings
);
7343 for (uint i
= 0; i
< num_strings
&& buf
->HasData(); i
++) {
7344 const char *string
= buf
->ReadString();
7346 if (StrEmpty(string
)) {
7347 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7351 AddGRFString(grfid
, first_id
+ i
, language
, true, true, string
, STR_UNDEFINED
);
7357 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7358 static bool ChangeGRFName(byte langid
, const char *str
)
7360 _cur
.grfconfig
->name
->add (langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7364 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7365 static bool ChangeGRFDescription(byte langid
, const char *str
)
7367 _cur
.grfconfig
->info
->add (langid
, _cur
.grfconfig
->ident
.grfid
, true, str
);
7371 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7372 static bool ChangeGRFURL(byte langid
, const char *str
)
7374 _cur
.grfconfig
->url
->add (langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7378 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7379 static bool ChangeGRFNumUsedParams(size_t len
, ByteReader
*buf
)
7382 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len
);
7385 _cur
.grfconfig
->num_valid_params
= min(buf
->ReadByte(), lengthof(_cur
.grfconfig
->param
));
7390 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7391 static bool ChangeGRFPalette(size_t len
, ByteReader
*buf
)
7394 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len
);
7397 char data
= buf
->ReadByte();
7398 GRFPalette pal
= GRFP_GRF_UNSET
;
7401 case 'A': pal
= GRFP_GRF_ANY
; break;
7402 case 'W': pal
= GRFP_GRF_WINDOWS
; break;
7403 case 'D': pal
= GRFP_GRF_DOS
; break;
7405 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data
);
7408 if (pal
!= GRFP_GRF_UNSET
) {
7409 _cur
.grfconfig
->palette
&= ~GRFP_GRF_MASK
;
7410 _cur
.grfconfig
->palette
|= pal
;
7416 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7417 static bool ChangeGRFBlitter(size_t len
, ByteReader
*buf
)
7420 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len
);
7423 char data
= buf
->ReadByte();
7424 GRFPalette pal
= GRFP_BLT_UNSET
;
7426 case '8': pal
= GRFP_BLT_UNSET
; break;
7427 case '3': pal
= GRFP_BLT_32BPP
; break;
7429 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data
);
7432 _cur
.grfconfig
->palette
&= ~GRFP_BLT_MASK
;
7433 _cur
.grfconfig
->palette
|= pal
;
7438 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7439 static bool ChangeGRFVersion(size_t len
, ByteReader
*buf
)
7442 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len
);
7445 /* Set min_loadable_version as well (default to minimal compatibility) */
7446 _cur
.grfconfig
->version
= _cur
.grfconfig
->min_loadable_version
= buf
->ReadDWord();
7451 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7452 static bool ChangeGRFMinVersion(size_t len
, ByteReader
*buf
)
7455 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len
);
7458 _cur
.grfconfig
->min_loadable_version
= buf
->ReadDWord();
7459 if (_cur
.grfconfig
->version
== 0) {
7460 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7461 _cur
.grfconfig
->min_loadable_version
= 0;
7463 if (_cur
.grfconfig
->version
< _cur
.grfconfig
->min_loadable_version
) {
7464 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur
.grfconfig
->min_loadable_version
);
7465 _cur
.grfconfig
->min_loadable_version
= _cur
.grfconfig
->version
;
7471 static GRFParameterInfo
*_cur_parameter
; ///< The parameter which info is currently changed by the newgrf.
7473 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7474 static bool ChangeGRFParamName(byte langid
, const char *str
)
7476 _cur_parameter
->name
.add (langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7480 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7481 static bool ChangeGRFParamDescription(byte langid
, const char *str
)
7483 _cur_parameter
->desc
.add (langid
, _cur
.grfconfig
->ident
.grfid
, true, str
);
7487 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7488 static bool ChangeGRFParamType(size_t len
, ByteReader
*buf
)
7491 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len
);
7494 GRFParameterType type
= (GRFParameterType
)buf
->ReadByte();
7495 if (type
< PTYPE_END
) {
7496 _cur_parameter
->type
= type
;
7498 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type
);
7504 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7505 static bool ChangeGRFParamLimits(size_t len
, ByteReader
*buf
)
7507 if (_cur_parameter
->type
!= PTYPE_UINT_ENUM
) {
7508 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7510 } else if (len
!= 8) {
7511 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len
);
7514 _cur_parameter
->min_value
= buf
->ReadDWord();
7515 _cur_parameter
->max_value
= buf
->ReadDWord();
7520 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7521 static bool ChangeGRFParamMask(size_t len
, ByteReader
*buf
)
7523 if (len
< 1 || len
> 3) {
7524 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len
);
7527 byte param_nr
= buf
->ReadByte();
7528 if (param_nr
>= lengthof(_cur
.grfconfig
->param
)) {
7529 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr
);
7532 _cur_parameter
->param_nr
= param_nr
;
7533 if (len
>= 2) _cur_parameter
->first_bit
= min(buf
->ReadByte(), 31);
7534 if (len
>= 3) _cur_parameter
->num_bit
= min(buf
->ReadByte(), 32 - _cur_parameter
->first_bit
);
7541 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7542 static bool ChangeGRFParamDefault(size_t len
, ByteReader
*buf
)
7545 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len
);
7548 _cur_parameter
->def_value
= buf
->ReadDWord();
7550 _cur
.grfconfig
->has_param_defaults
= true;
7555 * Data structure to store the allowed id/type combinations for action 14. The
7556 * data can be represented as a tree with 3 types of nodes:
7557 * 1. Branch nodes (identified by 'C' for choice).
7558 * 2. Binary leaf nodes (identified by 'B').
7559 * 3. Text leaf nodes (identified by 'T').
7561 struct AllowedSubtags
{
7562 typedef bool (*DataHandler
) (size_t, ByteReader
*); ///< Type of callback function for binary nodes
7563 typedef bool (*TextHandler
) (byte
, const char *str
); ///< Type of callback function for text nodes
7564 typedef bool (*BranchHandler
) (ByteReader
*); ///< Type of callback function for branch nodes
7566 uint32 id
; ///< The identifier for this node
7567 byte type
; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7568 byte nsub
; ///< The number of subtags, or 0 if not applicable
7570 DataHandler data
; ///< Callback function for a binary node, only valid if type == 'B'.
7571 TextHandler text
; ///< Callback function for a text node, only valid if type == 'T'.
7572 BranchHandler branch
; ///< Callback function for a branch node, only valid if type == 'C' && nsub == 0.
7573 const AllowedSubtags
*subtags
; ///< Pointer to a list of subtags, only valid if type == 'C' && nsub != 0.
7576 /** Create empty subtags object used to identify the end of a list. */
7577 CONSTEXPR
AllowedSubtags() :
7578 id(0), type(0), nsub(0), subtags(NULL
)
7582 * Create a binary leaf node.
7583 * @param id The id for this node.
7584 * @param handler The callback function to call.
7586 CONSTEXPR
AllowedSubtags (uint32 id
, DataHandler handler
) :
7587 id(id
), type('B'), nsub(0), data(handler
)
7592 * Create a text leaf node.
7593 * @param id The id for this node.
7594 * @param handler The callback function to call.
7596 CONSTEXPR
AllowedSubtags (uint32 id
, TextHandler handler
) :
7597 id(id
), type('T'), nsub(0), text(handler
)
7602 * Create a branch node with a callback handler
7603 * @param id The id for this node.
7604 * @param handler The callback function to call.
7606 CONSTEXPR
AllowedSubtags (uint32 id
, BranchHandler handler
) :
7607 id(id
), type('C'), nsub(0), branch(handler
)
7612 * Create a branch node with a list of sub-nodes.
7613 * @param id The id for this node.
7614 * @param subtags Array with all valid subtags.
7617 CONSTEXPR
AllowedSubtags (uint32 id
, const AllowedSubtags (&subtags
) [N
]) :
7618 id(id
), type('C'), nsub(N
), subtags(subtags
)
7620 assert_tcompile (N
> 0);
7621 assert_tcompile (N
<= UINT8_MAX
);
7625 static bool SkipUnknownInfo(ByteReader
*buf
, byte type
);
7626 static bool HandleNodes(ByteReader
*buf
, const AllowedSubtags
*tags
);
7629 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7630 * of some parameter values (type uint/enum) or the names of some bits
7631 * (type bitmask). In both cases the format is the same:
7632 * Each subnode should be a text node with the value/bit number as id.
7634 static bool ChangeGRFParamValueNames(ByteReader
*buf
)
7637 byte type
= buf
->ReadByte();
7638 if (type
== 0) break;
7640 uint32 id
= buf
->ReadDWord();
7641 if (type
!= 'T' || id
> _cur_parameter
->max_value
) {
7642 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7643 if (!SkipUnknownInfo(buf
, type
)) return false;
7647 byte langid
= buf
->ReadByte();
7648 const char *name_string
= buf
->ReadString();
7650 _cur_parameter
->value_names
[id
].add (langid
,
7651 _cur
.grfconfig
->ident
.grfid
, false, name_string
);
7656 /** Action14 parameter tags */
7657 static const AllowedSubtags _tags_parameters
[] = {
7658 AllowedSubtags('NAME', ChangeGRFParamName
),
7659 AllowedSubtags('DESC', ChangeGRFParamDescription
),
7660 AllowedSubtags('TYPE', ChangeGRFParamType
),
7661 AllowedSubtags('LIMI', ChangeGRFParamLimits
),
7662 AllowedSubtags('MASK', ChangeGRFParamMask
),
7663 AllowedSubtags('VALU', ChangeGRFParamValueNames
),
7664 AllowedSubtags('DFLT', ChangeGRFParamDefault
),
7669 * Callback function for 'INFO'->'PARA' to set extra information about the
7670 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7671 * the parameter number as id. The first parameter has id 0. The maximum
7672 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7674 static bool HandleParameterInfo(ByteReader
*buf
)
7677 byte type
= buf
->ReadByte();
7678 if (type
== 0) break;
7680 uint32 id
= buf
->ReadDWord();
7681 if (type
!= 'C' || id
>= _cur
.grfconfig
->num_valid_params
) {
7682 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7683 if (!SkipUnknownInfo(buf
, type
)) return false;
7687 if (id
>= _cur
.grfconfig
->param_info
.Length()) {
7688 uint num_to_add
= id
- _cur
.grfconfig
->param_info
.Length() + 1;
7689 GRFParameterInfo
**newdata
= _cur
.grfconfig
->param_info
.Append(num_to_add
);
7690 MemSetT
<GRFParameterInfo
*>(newdata
, 0, num_to_add
);
7692 if (_cur
.grfconfig
->param_info
[id
] == NULL
) {
7693 _cur
.grfconfig
->param_info
[id
] = new GRFParameterInfo(id
);
7695 _cur_parameter
= _cur
.grfconfig
->param_info
[id
];
7696 /* Read all parameter-data and process each node. */
7697 if (!HandleNodes(buf
, _tags_parameters
)) return false;
7702 /** Action14 tags for the INFO node */
7703 static const AllowedSubtags _tags_info
[] = {
7704 AllowedSubtags('NAME', ChangeGRFName
),
7705 AllowedSubtags('DESC', ChangeGRFDescription
),
7706 AllowedSubtags('URL_', ChangeGRFURL
),
7707 AllowedSubtags('NPAR', ChangeGRFNumUsedParams
),
7708 AllowedSubtags('PALS', ChangeGRFPalette
),
7709 AllowedSubtags('BLTR', ChangeGRFBlitter
),
7710 AllowedSubtags('VRSN', ChangeGRFVersion
),
7711 AllowedSubtags('MINV', ChangeGRFMinVersion
),
7712 AllowedSubtags('PARA', HandleParameterInfo
),
7716 /** Action14 root tags */
7717 static const AllowedSubtags _tags_root
[] = {
7718 AllowedSubtags('INFO', _tags_info
),
7724 * Try to skip the current node and all subnodes (if it's a branch node).
7725 * @param buf Buffer.
7726 * @param type The node type to skip.
7727 * @return True if we could skip the node, false if an error occurred.
7729 static bool SkipUnknownInfo(ByteReader
*buf
, byte type
)
7731 /* type and id are already read */
7735 byte new_type
= buf
->ReadByte();
7736 if (new_type
== 0) break;
7737 buf
->ReadDWord(); // skip the id
7738 if (!SkipUnknownInfo(buf
, new_type
)) return false;
7743 buf
->ReadByte(); // lang
7744 buf
->ReadString(); // actual text
7748 uint16 size
= buf
->ReadWord();
7761 * Handle the nodes of an Action14
7762 * @param type Type of node.
7764 * @param buf Buffer.
7765 * @param subtags Allowed subtags.
7766 * @return Whether all tags could be handled.
7768 static bool HandleNode (byte type
, uint32 id
, ByteReader
*buf
, const AllowedSubtags
*subtags
)
7770 for (const AllowedSubtags
*tag
= subtags
; tag
->type
!= 0; tag
++) {
7771 if (tag
->id
!= BSWAP32(id
) || tag
->type
!= type
) continue;
7773 default: NOT_REACHED();
7776 byte langid
= buf
->ReadByte();
7777 return tag
->text (langid
, buf
->ReadString());
7781 size_t len
= buf
->ReadWord();
7782 if (!buf
->HasData (len
)) return false;
7783 return tag
->data (len
, buf
);
7787 if (tag
->nsub
== 0) {
7788 return tag
->branch (buf
);
7790 return HandleNodes (buf
, tag
->subtags
);
7794 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type
, id
);
7795 return SkipUnknownInfo(buf
, type
);
7799 * Handle the contents of a 'C' choice of an Action14
7800 * @param buf Buffer.
7801 * @param subtags List of subtags.
7802 * @return Whether the nodes could all be handled.
7804 static bool HandleNodes (ByteReader
*buf
, const AllowedSubtags
*subtags
)
7807 byte type
= buf
->ReadByte();
7808 if (type
== 0) break;
7809 uint32 id
= buf
->ReadDWord();
7810 if (!HandleNode(type
, id
, buf
, subtags
)) return false;
7816 * Handle Action 0x14
7817 * @param buf Buffer.
7819 static int StaticGRFInfo (ByteReader
*buf
)
7821 /* <14> <type> <id> <text/data...> */
7822 HandleNodes(buf
, _tags_root
);
7827 * Set the current NewGRF as unsafe for static use
7828 * @param buf Unused.
7829 * @note Used during safety scan on unsafe actions.
7831 static int GRFUnsafe (ByteReader
*buf
)
7833 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
7835 /* Skip remainder of GRF */
7840 /** Initialize the TTDPatch flags */
7841 static void InitializeGRFSpecial()
7843 _ttdpatch_flags
[0] = ((_settings_game
.station
.never_expire_airports
? 1 : 0) << 0x0C) // keepsmallairport
7844 | (1 << 0x0D) // newairports
7845 | (1 << 0x0E) // largestations
7846 | ((_settings_game
.construction
.max_bridge_length
> 16 ? 1 : 0) << 0x0F) // longbridges
7847 | (0 << 0x10) // loadtime
7848 | (1 << 0x12) // presignals
7849 | (1 << 0x13) // extpresignals
7850 | ((_settings_game
.vehicle
.never_expire_vehicles
? 1 : 0) << 0x16) // enginespersist
7851 | (1 << 0x1B) // multihead
7852 | (1 << 0x1D) // lowmemory
7853 | (1 << 0x1E); // generalfixes
7855 _ttdpatch_flags
[1] = ((_settings_game
.economy
.station_noise_level
? 1 : 0) << 0x07) // moreairports - based on units of noise
7856 | (1 << 0x08) // mammothtrains
7857 | (1 << 0x09) // trainrefit
7858 | (0 << 0x0B) // subsidiaries
7859 | ((_settings_game
.order
.gradual_loading
? 1 : 0) << 0x0C) // gradualloading
7860 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7861 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7862 | (1 << 0x14) // bridgespeedlimits
7863 | (1 << 0x16) // eternalgame
7864 | (1 << 0x17) // newtrains
7865 | (1 << 0x18) // newrvs
7866 | (1 << 0x19) // newships
7867 | (1 << 0x1A) // newplanes
7868 | ((_settings_game
.construction
.train_signal_side
== 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7869 | ((_settings_game
.vehicle
.disable_elrails
? 0 : 1) << 0x1C); // electrifiedrailway
7871 _ttdpatch_flags
[2] = (1 << 0x01) // loadallgraphics - obsolote
7872 | (1 << 0x03) // semaphores
7873 | (1 << 0x0A) // newobjects
7874 | (0 << 0x0B) // enhancedgui
7875 | (0 << 0x0C) // newagerating
7876 | ((_settings_game
.construction
.build_on_slopes
? 1 : 0) << 0x0D) // buildonslopes
7877 | (1 << 0x0E) // fullloadany
7878 | (1 << 0x0F) // planespeed
7879 | (0 << 0x10) // moreindustriesperclimate - obsolete
7880 | (0 << 0x11) // moretoylandfeatures
7881 | (1 << 0x12) // newstations
7882 | (1 << 0x13) // tracktypecostdiff
7883 | (1 << 0x14) // manualconvert
7884 | ((_settings_game
.construction
.build_on_slopes
? 1 : 0) << 0x15) // buildoncoasts
7885 | (1 << 0x16) // canals
7886 | (1 << 0x17) // newstartyear
7887 | ((_settings_game
.vehicle
.freight_trains
> 1 ? 1 : 0) << 0x18) // freighttrains
7888 | (1 << 0x19) // newhouses
7889 | (1 << 0x1A) // newbridges
7890 | (1 << 0x1B) // newtownnames
7891 | (1 << 0x1C) // moreanimation
7892 | ((_settings_game
.vehicle
.wagon_speed_limits
? 1 : 0) << 0x1D) // wagonspeedlimits
7893 | (1 << 0x1E) // newshistory
7894 | (0 << 0x1F); // custombridgeheads
7896 _ttdpatch_flags
[3] = (0 << 0x00) // newcargodistribution
7897 | (1 << 0x01) // windowsnap
7898 | ((_settings_game
.economy
.allow_town_roads
|| _generating_world
? 0 : 1) << 0x02) // townbuildnoroad
7899 | (1 << 0x03) // pathbasedsignalling
7900 | (0 << 0x04) // aichoosechance
7901 | (1 << 0x05) // resolutionwidth
7902 | (1 << 0x06) // resolutionheight
7903 | (1 << 0x07) // newindustries
7904 | ((_settings_game
.order
.improved_load
? 1 : 0) << 0x08) // fifoloading
7905 | (0 << 0x09) // townroadbranchprob
7906 | (0 << 0x0A) // tempsnowline
7907 | (1 << 0x0B) // newcargo
7908 | (1 << 0x0C) // enhancemultiplayer
7909 | (1 << 0x0D) // onewayroads
7910 | (1 << 0x0E) // irregularstations
7911 | (1 << 0x0F) // statistics
7912 | (1 << 0x10) // newsounds
7913 | (1 << 0x11) // autoreplace
7914 | (1 << 0x12) // autoslope
7915 | (0 << 0x13) // followvehicle
7916 | (1 << 0x14) // trams
7917 | (0 << 0x15) // enhancetunnels
7918 | (1 << 0x16) // shortrvs
7919 | (1 << 0x17) // articulatedrvs
7920 | ((_settings_game
.vehicle
.dynamic_engines
? 1 : 0) << 0x18) // dynamic engines
7921 | (1 << 0x1E) // variablerunningcosts
7922 | (1 << 0x1F); // any switch is on
7925 /** Reset and clear all NewGRF stations */
7926 static void ResetCustomStations()
7928 const GRFFile
* const *end
= _grf_files
.End();
7929 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7930 StationSpec
**&stations
= (*file
)->stations
;
7931 if (stations
== NULL
) continue;
7932 for (uint i
= 0; i
< NUM_STATIONS_PER_GRF
; i
++) {
7933 if (stations
[i
] == NULL
) continue;
7934 StationSpec
*statspec
= stations
[i
];
7936 delete[] statspec
->renderdata
;
7938 /* Release platforms and layouts */
7939 if (!statspec
->copied_layouts
) {
7940 for (uint l
= 0; l
< statspec
->lengths
; l
++) {
7941 for (uint p
= 0; p
< statspec
->platforms
[l
]; p
++) {
7942 free(statspec
->layouts
[l
][p
]);
7944 free(statspec
->layouts
[l
]);
7946 free(statspec
->layouts
);
7947 free(statspec
->platforms
);
7950 /* Release this station */
7954 /* Free and reset the station data */
7960 /** Reset and clear all NewGRF houses */
7961 static void ResetCustomHouses()
7963 const GRFFile
* const *end
= _grf_files
.End();
7964 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7965 HouseSpec
**&housespec
= (*file
)->housespec
;
7966 if (housespec
== NULL
) continue;
7967 for (uint i
= 0; i
< NUM_HOUSES_PER_GRF
; i
++) {
7976 /** Reset and clear all NewGRF airports */
7977 static void ResetCustomAirports()
7979 const GRFFile
* const *end
= _grf_files
.End();
7980 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7981 AirportSpec
**aslist
= (*file
)->airportspec
;
7982 if (aslist
!= NULL
) {
7983 for (uint i
= 0; i
< NUM_AIRPORTS_PER_GRF
; i
++) {
7984 AirportSpec
*as
= aslist
[i
];
7987 /* We need to remove the tiles layouts */
7988 for (int j
= 0; j
< as
->num_table
; j
++) {
7989 /* remove the individual layouts */
7993 free(as
->depot_table
);
7999 (*file
)->airportspec
= NULL
;
8002 AirportTileSpec
**&airporttilespec
= (*file
)->airtspec
;
8003 if (airporttilespec
!= NULL
) {
8004 for (uint i
= 0; i
< NUM_AIRPORTTILES_PER_GRF
; i
++) {
8005 free(airporttilespec
[i
]);
8007 free(airporttilespec
);
8008 airporttilespec
= NULL
;
8013 /** Reset and clear all NewGRF industries */
8014 static void ResetCustomIndustries()
8016 const GRFFile
* const *end
= _grf_files
.End();
8017 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8018 IndustrySpec
**&industryspec
= (*file
)->industryspec
;
8019 IndustryTileSpec
**&indtspec
= (*file
)->indtspec
;
8021 /* We are verifiying both tiles and industries specs loaded from the grf file
8022 * First, let's deal with industryspec */
8023 if (industryspec
!= NULL
) {
8024 for (uint i
= 0; i
< NUM_INDUSTRYTYPES_PER_GRF
; i
++) {
8025 IndustrySpec
*ind
= industryspec
[i
];
8026 if (ind
== NULL
) continue;
8028 /* We need to remove the sounds array */
8029 if (HasBit(ind
->cleanup_flag
, CLEAN_RANDOMSOUNDS
)) {
8030 free(ind
->random_sounds
);
8033 /* We need to remove the tiles layouts */
8034 CleanIndustryTileTable(ind
);
8040 industryspec
= NULL
;
8043 if (indtspec
== NULL
) continue;
8044 for (uint i
= 0; i
< NUM_INDUSTRYTILES_PER_GRF
; i
++) {
8053 /** Reset and clear all NewObjects */
8054 static void ResetCustomObjects()
8056 const GRFFile
* const *end
= _grf_files
.End();
8057 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8058 ObjectSpec
**&objectspec
= (*file
)->objectspec
;
8059 if (objectspec
== NULL
) continue;
8060 for (uint i
= 0; i
< NUM_OBJECTS_PER_GRF
; i
++) {
8061 free(objectspec
[i
]);
8069 /** Reset and clear all NewGRFs */
8070 static void ResetNewGRF()
8072 const GRFFile
* const *end
= _grf_files
.End();
8073 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8078 _cur
.grffile
= NULL
;
8081 /** Clear all NewGRF errors */
8082 static void ResetNewGRFErrors()
8084 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
8085 if (!HasBit(c
->flags
, GCF_COPY
) && c
->error
!= NULL
) {
8093 * Reset all NewGRF loaded data
8096 void ResetNewGRFData()
8099 CleanUpGRFTownNames();
8101 /* Copy/reset original engine info data */
8104 /* Copy/reset original bridge info data */
8107 /* Reset rail type information */
8110 /* Allocate temporary refit/cargo class data */
8111 _gted
= xcalloct
<GRFTempEngineData
>(Engine::GetPoolSize());
8113 /* Fill rail type label temporary data for default trains */
8115 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_TRAIN
) {
8116 _gted
[e
->index
].railtypelabel
= GetRailTypeInfo(e
->u
.rail
.railtype
)->label
;
8119 /* Reset GRM reservations */
8120 memset(&_grm_engines
, 0, sizeof(_grm_engines
));
8121 memset(&_grm_cargoes
, 0, sizeof(_grm_cargoes
));
8123 /* Reset generic feature callback lists */
8124 ResetGenericCallbacks();
8126 /* Reset price base data */
8127 ResetPriceBaseMultipliers();
8129 /* Reset the curencies array */
8132 /* Reset the house array */
8133 ResetCustomHouses();
8136 /* Reset the industries structures*/
8137 ResetCustomIndustries();
8140 /* Reset the objects. */
8141 ObjectClass::Reset();
8142 ResetCustomObjects();
8145 /* Reset station classes */
8146 StationClass::Reset();
8147 ResetCustomStations();
8149 /* Reset airport-related structures */
8150 AirportClass::Reset();
8151 ResetCustomAirports();
8152 AirportSpec::ResetAirports();
8153 AirportTileSpec::ResetAirportTiles();
8155 /* Reset canal sprite groups and flags */
8156 memset(_water_feature
, 0, sizeof(_water_feature
));
8158 /* Reset the snowline table. */
8161 /* Reset NewGRF files */
8164 /* Reset NewGRF errors. */
8165 ResetNewGRFErrors();
8167 /* Set up the default cargo types */
8168 SetupCargoForClimate(_settings_game
.game_creation
.landscape
);
8170 /* Reset misc GRF features and train list display variables */
8171 _misc_grf_features
= 0;
8173 _loaded_newgrf_features
.has_2CC
= false;
8174 _loaded_newgrf_features
.used_liveries
= 1 << LS_DEFAULT
;
8175 _loaded_newgrf_features
.has_newhouses
= false;
8176 _loaded_newgrf_features
.has_newindustries
= false;
8177 _loaded_newgrf_features
.shore
= SHORE_REPLACE_NONE
;
8179 /* Clear all GRF overrides */
8180 _grf_id_overrides
.clear();
8182 InitializeSoundPool();
8183 SpriteGroup::pool
.CleanPool();
8187 * Reset NewGRF data which is stored persistently in savegames.
8189 void ResetPersistentNewGRFData()
8191 /* Reset override managers */
8192 _engine_mngr
.ResetToDefaultMapping();
8193 _house_mngr
.ResetMapping();
8194 _industry_mngr
.ResetMapping();
8195 _industile_mngr
.ResetMapping();
8196 _airport_mngr
.ResetMapping();
8197 _airporttile_mngr
.ResetMapping();
8201 * Construct the Cargo Mapping
8202 * @note This is the reverse of a cargo translation table
8204 static void BuildCargoTranslationMap()
8206 memset(_cur
.grffile
->cargo_map
, 0xFF, sizeof(_cur
.grffile
->cargo_map
));
8208 for (CargoID c
= 0; c
< NUM_CARGO
; c
++) {
8209 const CargoSpec
*cs
= CargoSpec::Get(c
);
8210 if (!cs
->IsValid()) continue;
8212 if (_cur
.grffile
->cargo_list
.Length() == 0) {
8213 /* Default translation table, so just a straight mapping to bitnum */
8214 _cur
.grffile
->cargo_map
[c
] = cs
->bitnum
;
8216 /* Check the translation table for this cargo's label */
8217 int index
= _cur
.grffile
->cargo_list
.FindIndex(cs
->label
);
8218 if (index
>= 0) _cur
.grffile
->cargo_map
[c
] = index
;
8224 * Constructor for GRFFile
8225 * @param config GRFConfig to copy name, grfid and parameters from.
8227 GRFFile::GRFFile(const GRFConfig
*config
)
8229 this->filename
= xstrdup(config
->filename
);
8230 this->grfid
= config
->ident
.grfid
;
8232 /* Initialise local settings to defaults */
8233 this->traininfo_vehicle_pitch
= 0;
8234 this->traininfo_vehicle_width
= TRAININFO_DEFAULT_VEHICLE_WIDTH
;
8236 /* Mark price_base_multipliers as 'not set' */
8237 for (Price i
= PR_BEGIN
; i
< PR_END
; i
++) {
8238 this->price_base_multipliers
[i
] = INVALID_PRICE_MODIFIER
;
8241 /* Initialise rail type map with default rail types */
8242 memset(this->railtype_map
, INVALID_RAILTYPE
, sizeof(this->railtype_map
));
8243 this->railtype_map
[0] = RAILTYPE_RAIL
;
8244 this->railtype_map
[1] = RAILTYPE_ELECTRIC
;
8245 this->railtype_map
[2] = RAILTYPE_MONO
;
8246 this->railtype_map
[3] = RAILTYPE_MAGLEV
;
8248 /* Copy the initial parameter list
8249 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8250 assert_compile(lengthof(this->param
) == lengthof(config
->param
) && lengthof(this->param
) == 0x80);
8252 assert(config
->num_params
<= lengthof(config
->param
));
8253 this->param_end
= config
->num_params
;
8254 if (this->param_end
> 0) {
8255 MemCpyT(this->param
, config
->param
, this->param_end
);
8261 free(this->filename
);
8262 delete[] this->language_map
;
8267 * List of what cargo labels are refittable for the given the vehicle-type.
8268 * Only currently active labels are applied.
8270 static const CargoLabel _default_refitmasks_rail
[] = {
8271 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8272 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8273 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8277 static const CargoLabel _default_refitmasks_road
[] = {
8280 static const CargoLabel _default_refitmasks_ships
[] = {
8281 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8282 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8283 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8287 static const CargoLabel _default_refitmasks_aircraft
[] = {
8288 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8289 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8292 static const CargoLabel
* const _default_refitmasks
[] = {
8293 _default_refitmasks_rail
,
8294 _default_refitmasks_road
,
8295 _default_refitmasks_ships
,
8296 _default_refitmasks_aircraft
,
8301 * Precalculate refit masks from cargo classes for all vehicles.
8303 static void CalculateRefitMasks()
8307 FOR_ALL_ENGINES(e
) {
8308 EngineID engine
= e
->index
;
8309 EngineInfo
*ei
= &e
->info
;
8310 bool only_defaultcargo
; ///< Set if the vehicle shall carry only the default cargo
8312 /* Did the newgrf specify any refitting? If not, use defaults. */
8313 if (_gted
[engine
].refittability
!= GRFTempEngineData::UNSET
) {
8315 uint32 not_mask
= 0;
8316 uint32 xor_mask
= ei
->refit_mask
;
8318 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8319 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8320 only_defaultcargo
= _gted
[engine
].refittability
== GRFTempEngineData::EMPTY
;
8322 if (_gted
[engine
].cargo_allowed
!= 0) {
8323 /* Build up the list of cargo types from the set cargo classes. */
8324 const CargoSpec
*cs
;
8325 FOR_ALL_CARGOSPECS(cs
) {
8326 if (_gted
[engine
].cargo_allowed
& cs
->classes
) SetBit(mask
, cs
->Index());
8327 if (_gted
[engine
].cargo_disallowed
& cs
->classes
) SetBit(not_mask
, cs
->Index());
8331 ei
->refit_mask
= ((mask
& ~not_mask
) ^ xor_mask
) & _cargo_mask
;
8333 /* Apply explicit refit includes/excludes. */
8334 ei
->refit_mask
|= _gted
[engine
].ctt_include_mask
;
8335 ei
->refit_mask
&= ~_gted
[engine
].ctt_exclude_mask
;
8337 uint32 xor_mask
= 0;
8339 /* Don't apply default refit mask to wagons nor engines with no capacity */
8340 if (e
->type
!= VEH_TRAIN
|| (e
->u
.rail
.capacity
!= 0 && e
->u
.rail
.railveh_type
!= RAILVEH_WAGON
)) {
8341 const CargoLabel
*cl
= _default_refitmasks
[e
->type
];
8342 for (uint i
= 0;; i
++) {
8343 if (cl
[i
] == 0) break;
8345 CargoID cargo
= GetCargoIDByLabel(cl
[i
]);
8346 if (cargo
== CT_INVALID
) continue;
8348 SetBit(xor_mask
, cargo
);
8352 ei
->refit_mask
= xor_mask
& _cargo_mask
;
8354 /* If the mask is zero, the vehicle shall only carry the default cargo */
8355 only_defaultcargo
= (ei
->refit_mask
== 0);
8358 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8359 if (!HasBit(_cargo_mask
, ei
->cargo_type
)) ei
->cargo_type
= CT_INVALID
;
8361 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8362 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8363 if (!only_defaultcargo
&& (e
->type
!= VEH_SHIP
|| e
->u
.ship
.old_refittable
) && ei
->cargo_type
!= CT_INVALID
&& !HasBit(ei
->refit_mask
, ei
->cargo_type
)) {
8364 ei
->cargo_type
= CT_INVALID
;
8367 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8368 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8369 if (ei
->cargo_type
== CT_INVALID
&& ei
->refit_mask
!= 0) {
8370 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8371 const uint8
*cargo_map_for_first_refittable
= NULL
;
8373 const GRFFile
*file
= _gted
[engine
].defaultcargo_grf
;
8374 if (file
== NULL
) file
= e
->GetGRF();
8375 if (file
!= NULL
&& file
->grf_version
>= 8 && file
->cargo_list
.Length() != 0) {
8376 cargo_map_for_first_refittable
= file
->cargo_map
;
8380 if (cargo_map_for_first_refittable
!= NULL
) {
8381 /* Use first refittable cargo from cargo translation table */
8382 byte best_local_slot
= 0xFF;
8384 FOR_EACH_SET_CARGO_ID(cargo_type
, ei
->refit_mask
) {
8385 byte local_slot
= cargo_map_for_first_refittable
[cargo_type
];
8386 if (local_slot
< best_local_slot
) {
8387 best_local_slot
= local_slot
;
8388 ei
->cargo_type
= cargo_type
;
8393 if (ei
->cargo_type
== CT_INVALID
) {
8394 /* Use first refittable cargo slot */
8395 ei
->cargo_type
= (CargoID
)FindFirstBit(ei
->refit_mask
);
8398 if (ei
->cargo_type
== CT_INVALID
) ei
->climates
= 0;
8400 /* Clear refit_mask for not refittable ships */
8401 if (e
->type
== VEH_SHIP
&& !e
->u
.ship
.old_refittable
) {
8407 /** Set to use the correct action0 properties for each canal feature */
8408 static void FinaliseCanals()
8410 for (uint i
= 0; i
< CF_END
; i
++) {
8411 if (_water_feature
[i
].grffile
!= NULL
) {
8412 _water_feature
[i
].callback_mask
= _water_feature
[i
].grffile
->canal_local_properties
[i
].callback_mask
;
8413 _water_feature
[i
].flags
= _water_feature
[i
].grffile
->canal_local_properties
[i
].flags
;
8418 /** Check for invalid engines */
8419 static void FinaliseEngineArray()
8423 FOR_ALL_ENGINES(e
) {
8424 if (e
->GetGRF() == NULL
) {
8425 const EngineIDMapping
&eid
= _engine_mngr
[e
->index
];
8426 if (eid
.grfid
!= INVALID_GRFID
|| eid
.internal_id
!= eid
.substitute_id
) {
8427 e
->info
.string_id
= STR_NEWGRF_INVALID_ENGINE
;
8431 /* When the train does not set property 27 (misc flags), but it
8432 * is overridden by a NewGRF graphically we want to disable the
8433 * flipping possibility. */
8434 if (e
->type
== VEH_TRAIN
&& !_gted
[e
->index
].prop27_set
&& e
->GetGRF() != NULL
&& is_custom_sprite(e
->u
.rail
.image_index
)) {
8435 ClrBit(e
->info
.misc_flags
, EF_RAIL_FLIPS
);
8438 /* Skip wagons, there livery is defined via the engine */
8439 if (e
->type
!= VEH_TRAIN
|| e
->u
.rail
.railveh_type
!= RAILVEH_WAGON
) {
8440 LiveryScheme ls
= GetEngineLiveryScheme(e
->index
, INVALID_ENGINE
, NULL
);
8441 SetBit(_loaded_newgrf_features
.used_liveries
, ls
);
8442 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8444 if (e
->type
== VEH_TRAIN
) {
8445 SetBit(_loaded_newgrf_features
.used_liveries
, LS_FREIGHT_WAGON
);
8452 SetBit(_loaded_newgrf_features
.used_liveries
, LS_PASSENGER_WAGON_STEAM
+ ls
- LS_STEAM
);
8457 SetBit(_loaded_newgrf_features
.used_liveries
, LS_PASSENGER_WAGON_DIESEL
+ ls
- LS_DMU
);
8460 default: NOT_REACHED();
8467 /** Check for invalid cargoes */
8468 static void FinaliseCargoArray()
8470 for (CargoID c
= 0; c
< NUM_CARGO
; c
++) {
8471 CargoSpec
*cs
= CargoSpec::Get(c
);
8472 if (!cs
->IsValid()) {
8473 cs
->name
= cs
->name_single
= cs
->units_volume
= STR_NEWGRF_INVALID_CARGO
;
8474 cs
->quantifier
= STR_NEWGRF_INVALID_CARGO_QUANTITY
;
8475 cs
->abbrev
= STR_NEWGRF_INVALID_CARGO_ABBREV
;
8481 * Check if a given housespec is valid and disable it if it's not.
8482 * The housespecs that follow it are used to check the validity of
8484 * @param hs The housespec to check.
8485 * @param next1 The housespec that follows \c hs.
8486 * @param next2 The housespec that follows \c next1.
8487 * @param next3 The housespec that follows \c next2.
8488 * @param filename The filename of the newgrf this house was defined in.
8489 * @return Whether the given housespec is valid.
8491 static bool IsHouseSpecValid(HouseSpec
*hs
, const HouseSpec
*next1
, const HouseSpec
*next2
, const HouseSpec
*next3
, const char *filename
)
8493 if (((hs
->building_flags
& BUILDING_HAS_2_TILES
) != 0 &&
8494 (next1
== NULL
|| !next1
->enabled
|| (next1
->building_flags
& BUILDING_HAS_1_TILE
) != 0)) ||
8495 ((hs
->building_flags
& BUILDING_HAS_4_TILES
) != 0 &&
8496 (next2
== NULL
|| !next2
->enabled
|| (next2
->building_flags
& BUILDING_HAS_1_TILE
) != 0 ||
8497 next3
== NULL
|| !next3
->enabled
|| (next3
->building_flags
& BUILDING_HAS_1_TILE
) != 0))) {
8498 hs
->enabled
= false;
8499 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
);
8503 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8504 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8505 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8506 if (((hs
->building_flags
& BUILDING_HAS_2_TILES
) != 0 && next1
->population
!= 0) ||
8507 ((hs
->building_flags
& BUILDING_HAS_4_TILES
) != 0 && (next2
->population
!= 0 || next3
->population
!= 0))) {
8508 hs
->enabled
= false;
8509 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
);
8513 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8514 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8515 if (filename
!= NULL
&& (hs
->building_flags
& BUILDING_HAS_1_TILE
) != (HouseSpec::Get(hs
->grf_prop
.subst_id
)->building_flags
& BUILDING_HAS_1_TILE
)) {
8516 hs
->enabled
= false;
8517 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
);
8521 /* Make sure that additional parts of multitile houses are not available. */
8522 if ((hs
->building_flags
& BUILDING_HAS_1_TILE
) == 0 && (hs
->building_availability
& HZ_ZONALL
) != 0 && (hs
->building_availability
& HZ_CLIMALL
) != 0) {
8523 hs
->enabled
= false;
8524 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
);
8532 * Make sure there is at least one house available in the year 0 for the given
8534 * @param bitmask The climate to check for. Exactly one climate bit should be
8537 static void EnsureEarlyHouses (HouseZones climate_mask
)
8539 for (uint z
= 0; z
< HZB_END
; z
++) {
8540 HouseZones bitmask
= (HouseZones
)(1U << z
) | climate_mask
;
8541 Year min_year
= MAX_YEAR
;
8543 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8544 const HouseSpec
*hs
= HouseSpec::Get(i
);
8545 if (hs
== NULL
|| !hs
->enabled
) continue;
8546 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
8547 if (hs
->min_year
< min_year
) min_year
= hs
->min_year
;
8550 if (min_year
== 0) continue;
8552 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8553 HouseSpec
*hs
= HouseSpec::Get(i
);
8554 if (hs
== NULL
|| !hs
->enabled
) continue;
8555 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
8556 if (hs
->min_year
== min_year
) hs
->min_year
= 0;
8562 * Add all new houses to the house array. House properties can be set at any
8563 * time in the GRF file, so we can only add a house spec to the house array
8564 * after the file has finished loading. We also need to check the dates, due to
8565 * the TTDPatch behaviour described below that we need to emulate.
8567 static void FinaliseHouseArray()
8569 /* If there are no houses with start dates before 1930, then all houses
8570 * with start dates of 1930 have them reset to 0. This is in order to be
8571 * compatible with TTDPatch, where if no houses have start dates before
8572 * 1930 and the date is before 1930, the game pretends that this is 1930.
8573 * If there have been any houses defined with start dates before 1930 then
8574 * the dates are left alone.
8575 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8576 * minimum introduction date to 0.
8578 const GRFFile
* const *end
= _grf_files
.End();
8579 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8580 HouseSpec
**&housespec
= (*file
)->housespec
;
8581 if (housespec
== NULL
) continue;
8583 for (int i
= 0; i
< NUM_HOUSES_PER_GRF
; i
++) {
8584 HouseSpec
*hs
= housespec
[i
];
8586 if (hs
== NULL
) continue;
8588 const HouseSpec
*next1
= (i
+ 1 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 1] : NULL
);
8589 const HouseSpec
*next2
= (i
+ 2 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 2] : NULL
);
8590 const HouseSpec
*next3
= (i
+ 3 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 3] : NULL
);
8592 if (!IsHouseSpecValid(hs
, next1
, next2
, next3
, (*file
)->filename
)) continue;
8594 _house_mngr
.SetEntitySpec(hs
);
8598 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8599 HouseSpec
*hs
= HouseSpec::Get(i
);
8600 const HouseSpec
*next1
= (i
+ 1 < NUM_HOUSES
? HouseSpec::Get(i
+ 1) : NULL
);
8601 const HouseSpec
*next2
= (i
+ 2 < NUM_HOUSES
? HouseSpec::Get(i
+ 2) : NULL
);
8602 const HouseSpec
*next3
= (i
+ 3 < NUM_HOUSES
? HouseSpec::Get(i
+ 3) : NULL
);
8604 /* We need to check all houses again to we are sure that multitile houses
8605 * did get consecutive IDs and none of the parts are missing. */
8606 if (!IsHouseSpecValid(hs
, next1
, next2
, next3
, NULL
)) {
8607 /* GetHouseNorthPart checks 3 houses that are directly before
8608 * it in the house pool. If any of those houses have multi-tile
8609 * flags set it assumes it's part of a multitile house. Since
8610 * we can have invalid houses in the pool marked as disabled, we
8611 * don't want to have them influencing valid tiles. As such set
8612 * building_flags to zero here to make sure any house following
8613 * this one in the pool is properly handled as 1x1 house. */
8614 hs
->building_flags
= TILE_NO_FLAG
;
8618 HouseZones climate_mask
= (HouseZones
)(1 << (_settings_game
.game_creation
.landscape
+ 12));
8619 EnsureEarlyHouses (climate_mask
);
8621 if (_settings_game
.game_creation
.landscape
== LT_ARCTIC
) {
8622 EnsureEarlyHouses (HZ_SUBARTC_ABOVE
);
8627 * Add all new industries to the industry array. Industry properties can be set at any
8628 * time in the GRF file, so we can only add a industry spec to the industry array
8629 * after the file has finished loading.
8631 static void FinaliseIndustriesArray()
8633 const GRFFile
* const *end
= _grf_files
.End();
8634 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8635 IndustrySpec
**&industryspec
= (*file
)->industryspec
;
8636 IndustryTileSpec
**&indtspec
= (*file
)->indtspec
;
8637 if (industryspec
!= NULL
) {
8638 for (int i
= 0; i
< NUM_INDUSTRYTYPES_PER_GRF
; i
++) {
8639 IndustrySpec
*indsp
= industryspec
[i
];
8641 if (indsp
!= NULL
&& indsp
->enabled
) {
8643 /* process the conversion of text at the end, so to be sure everything will be fine
8644 * and available. Check if it does not return undefind marker, which is a very good sign of a
8645 * substitute industry who has not changed the string been examined, thus using it as such */
8646 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->name
);
8647 if (strid
!= STR_UNDEFINED
) indsp
->name
= strid
;
8649 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->closure_text
);
8650 if (strid
!= STR_UNDEFINED
) indsp
->closure_text
= strid
;
8652 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->production_up_text
);
8653 if (strid
!= STR_UNDEFINED
) indsp
->production_up_text
= strid
;
8655 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->production_down_text
);
8656 if (strid
!= STR_UNDEFINED
) indsp
->production_down_text
= strid
;
8658 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->new_industry_text
);
8659 if (strid
!= STR_UNDEFINED
) indsp
->new_industry_text
= strid
;
8661 if (indsp
->station_name
!= STR_NULL
) {
8662 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8663 * station's name. Don't want to lose the value, therefore, do not process. */
8664 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->station_name
);
8665 if (strid
!= STR_UNDEFINED
) indsp
->station_name
= strid
;
8668 _industry_mngr
.SetEntitySpec(indsp
);
8669 _loaded_newgrf_features
.has_newindustries
= true;
8674 if (indtspec
!= NULL
) {
8675 for (int i
= 0; i
< NUM_INDUSTRYTILES_PER_GRF
; i
++) {
8676 IndustryTileSpec
*indtsp
= indtspec
[i
];
8677 if (indtsp
!= NULL
) {
8678 _industile_mngr
.SetEntitySpec(indtsp
);
8684 for (uint j
= 0; j
< NUM_INDUSTRYTYPES
; j
++) {
8685 IndustrySpec
*indsp
= &_industry_specs
[j
];
8686 if (indsp
->enabled
&& indsp
->grf_prop
.grffile
!= NULL
) {
8687 for (uint i
= 0; i
< 3; i
++) {
8688 indsp
->conflicting
[i
] = MapNewGRFIndustryType(indsp
->conflicting
[i
], indsp
->grf_prop
.grffile
->grfid
);
8691 if (!indsp
->enabled
) {
8692 indsp
->name
= STR_NEWGRF_INVALID_INDUSTRYTYPE
;
8698 * Add all new objects to the object array. Object properties can be set at any
8699 * time in the GRF file, so we can only add an object spec to the object array
8700 * after the file has finished loading.
8702 static void FinaliseObjectsArray()
8704 const GRFFile
* const *end
= _grf_files
.End();
8705 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8706 ObjectSpec
**&objectspec
= (*file
)->objectspec
;
8707 if (objectspec
!= NULL
) {
8708 for (int i
= 0; i
< NUM_OBJECTS_PER_GRF
; i
++) {
8709 if (objectspec
[i
] != NULL
&& objectspec
[i
]->grf_prop
.grffile
!= NULL
&& objectspec
[i
]->enabled
) {
8710 _object_mngr
.SetEntitySpec(objectspec
[i
]);
8718 * Add all new airports to the airport array. Airport properties can be set at any
8719 * time in the GRF file, so we can only add a airport spec to the airport array
8720 * after the file has finished loading.
8722 static void FinaliseAirportsArray()
8724 const GRFFile
* const *end
= _grf_files
.End();
8725 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8726 AirportSpec
**&airportspec
= (*file
)->airportspec
;
8727 if (airportspec
!= NULL
) {
8728 for (int i
= 0; i
< NUM_AIRPORTS_PER_GRF
; i
++) {
8729 if (airportspec
[i
] != NULL
&& airportspec
[i
]->enabled
) {
8730 _airport_mngr
.SetEntitySpec(airportspec
[i
]);
8735 AirportTileSpec
**&airporttilespec
= (*file
)->airtspec
;
8736 if (airporttilespec
!= NULL
) {
8737 for (uint i
= 0; i
< NUM_AIRPORTTILES_PER_GRF
; i
++) {
8738 if (airporttilespec
[i
] != NULL
&& airporttilespec
[i
]->enabled
) {
8739 _airporttile_mngr
.SetEntitySpec(airporttilespec
[i
]);
8746 /* Here we perform initial decoding of some special sprites (as are they
8747 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8748 * partial implementation yet).
8749 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8750 * a crafted invalid GRF file. We should tell that to the user somehow, or
8751 * better make this more robust in the future. */
8752 static int DecodeSpecialSprite (byte
*buf
, uint num
, GrfLoadingStage stage
)
8754 /* XXX: There is a difference between staged loading in TTDPatch and
8755 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8756 * during stage 1, whilst action 3 is carried out during stage 2 (to
8757 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8758 * IDs are valid only within a given set (action 1) block, and may be
8759 * overwritten after action 3 associates them. But overwriting happens
8760 * in an earlier stage than associating, so... We just process actions
8761 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8763 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8764 * is not in memory and scanning the file every time would be too expensive.
8765 * In other stages we skip action 0x10 since it's already dealt with. */
8766 static const SpecialSpriteHandler handlers
[][GLS_END
] = {
8767 /* 0x00 */ { NULL
, SafeChangeInfo
, NULL
, NULL
, ReserveChangeInfo
, FeatureChangeInfo
, },
8768 /* 0x01 */ { SkipAct1
, SkipAct1
, SkipAct1
, SkipAct1
, SkipAct1
, NewSpriteSet
, },
8769 /* 0x02 */ { NULL
, NULL
, NULL
, NULL
, NULL
, NewSpriteGroup
, },
8770 /* 0x03 */ { NULL
, GRFUnsafe
, NULL
, NULL
, NULL
, FeatureMapSpriteGroup
, },
8771 /* 0x04 */ { NULL
, NULL
, NULL
, NULL
, NULL
, FeatureNewName
, },
8772 /* 0x05 */ { SkipAct5
, SkipAct5
, SkipAct5
, SkipAct5
, SkipAct5
, GraphicsNew
, },
8773 /* 0x06 */ { NULL
, NULL
, NULL
, CfgApply
, CfgApply
, CfgApply
, },
8774 /* 0x07 */ { NULL
, NULL
, NULL
, NULL
, SkipIf
, SkipIf
, },
8775 /* 0x08 */ { ScanInfo
, NULL
, NULL
, GRFInfo
, GRFInfo
, GRFInfo
, },
8776 /* 0x09 */ { NULL
, NULL
, NULL
, SkipIf
, SkipIf
, SkipIf
, },
8777 /* 0x0A */ { SkipActA
, SkipActA
, SkipActA
, SkipActA
, SkipActA
, SpriteReplace
, },
8778 /* 0x0B */ { NULL
, NULL
, NULL
, GRFLoadError
, GRFLoadError
, GRFLoadError
, },
8779 /* 0x0C */ { NULL
, NULL
, NULL
, GRFComment
, NULL
, GRFComment
, },
8780 /* 0x0D */ { NULL
, SafeParamSet
, NULL
, ParamSet
, ParamSet
, ParamSet
, },
8781 /* 0x0E */ { NULL
, SafeGRFInhibit
, NULL
, GRFInhibit
, GRFInhibit
, GRFInhibit
, },
8782 /* 0x0F */ { NULL
, GRFUnsafe
, NULL
, FeatureTownName
, NULL
, NULL
, },
8783 /* 0x10 */ { NULL
, NULL
, DefineGotoLabel
, NULL
, NULL
, NULL
, },
8784 /* 0x11 */ { SkipAct11
,GRFUnsafe
, SkipAct11
, GRFSound
, SkipAct11
, GRFSound
, },
8785 /* 0x12 */ { SkipAct12
, SkipAct12
, SkipAct12
, SkipAct12
, SkipAct12
, LoadFontGlyph
, },
8786 /* 0x13 */ { NULL
, NULL
, NULL
, NULL
, NULL
, TranslateGRFStrings
, },
8787 /* 0x14 */ { StaticGRFInfo
, NULL
, NULL
, NULL
, NULL
, NULL
, },
8790 GRFLocation
location(_cur
.grfconfig
->ident
.grfid
, _cur
.nfo_line
);
8792 GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.find(location
);
8793 if (it
== _grf_line_to_action6_sprite_override
.end()) {
8794 /* No preloaded sprite to work with; read the
8795 * pseudo sprite content. */
8796 FioReadBlock(buf
, num
);
8798 /* Use the preloaded sprite data. */
8799 buf
= it
->second
.get();
8800 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8802 /* Skip the real (original) content of this action. */
8803 FioSeekTo(num
, SEEK_CUR
);
8806 ByteReader
br(buf
, buf
+ num
);
8807 ByteReader
*bufp
= &br
;
8810 byte action
= bufp
->ReadByte();
8812 if (action
== 0xFF) {
8813 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8814 } else if (action
== 0xFE) {
8815 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8816 } else if (action
>= lengthof(handlers
)) {
8817 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action
);
8818 } else if (handlers
[action
][stage
] == NULL
) {
8819 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action
, stage
);
8821 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action
, stage
);
8822 return handlers
[action
][stage
](bufp
);
8825 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8826 DisableCur (STR_NEWGRF_ERROR_READ_BOUNDS
);
8834 /** Signature of a container version 2 GRF. */
8835 extern const byte _grf_cont_v2_sig
[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8838 * Get the container version of the currently opened GRF file.
8839 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
8841 byte
GetGRFContainerVersion()
8843 size_t pos
= FioGetPos();
8845 if (FioReadWord() == 0) {
8846 /* Check for GRF container version 2, which is identified by the bytes
8847 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8848 for (uint i
= 0; i
< lengthof(_grf_cont_v2_sig
); i
++) {
8849 if (FioReadByte() != _grf_cont_v2_sig
[i
]) return 0; // Invalid format
8855 /* Container version 1 has no header, rewind to start. */
8856 FioSeekTo(pos
, SEEK_SET
);
8861 * Load a particular NewGRF.
8862 * @param config The configuration of the to be loaded NewGRF.
8863 * @param file_index The Fio index of the first NewGRF to load.
8864 * @param stage The loading stage of the NewGRF.
8865 * @param subdir The sub directory to find the NewGRF in.
8867 void LoadNewGRFFile(GRFConfig
*config
, uint file_index
, GrfLoadingStage stage
, Subdirectory subdir
)
8869 const char *filename
= config
->filename
;
8871 if (file_index
> LAST_GRF_SLOT
) {
8872 DEBUG(grf
, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename
);
8873 config
->status
= GCS_DISABLED
;
8874 config
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED
);
8878 FioOpenFile(file_index
, filename
, subdir
);
8879 _cur
.file_index
= file_index
; // XXX
8880 _palette_remap_grf
[_cur
.file_index
] = (config
->palette
& GRFP_USE_MASK
);
8882 _cur
.grfconfig
= config
;
8884 DEBUG(grf
, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename
);
8886 _cur
.grf_container_ver
= GetGRFContainerVersion();
8887 if (_cur
.grf_container_ver
== 0) {
8888 DEBUG(grf
, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8892 if (stage
== GLS_INIT
|| stage
== GLS_ACTIVATION
) {
8893 /* We need the sprite offsets in the init stage for NewGRF sounds
8894 * and in the activation stage for real sprites. */
8895 ReadGRFSpriteOffsets(_cur
.grf_container_ver
);
8897 /* Skip sprite section offset if present. */
8898 if (_cur
.grf_container_ver
>= 2) FioReadDword();
8901 if (_cur
.grf_container_ver
>= 2) {
8902 /* Read compression value. */
8903 byte compression
= FioReadByte();
8904 if (compression
!= 0) {
8905 DEBUG(grf
, 7, "LoadNewGRFFile: Unsupported compression format");
8910 /* Skip the first sprite; we don't care about how many sprites this
8911 * does contain; newest TTDPatches and George's longvehicles don't
8912 * neither, apparently. */
8913 uint32 num
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
8914 if (num
== 4 && FioReadByte() == 0xFF) {
8917 DEBUG(grf
, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8921 _cur
.ClearDataForNextFile();
8923 ReusableBuffer
<byte
> buf
;
8924 int skip_sprites
= 0;
8926 while ((num
= (_cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord())) != 0) {
8927 byte type
= FioReadByte();
8931 if (skip_sprites
== 0) {
8932 skip_sprites
= DecodeSpecialSprite (buf
.Allocate(num
), num
, stage
);
8934 /* Stop all processing if we are to skip the remaining sprites */
8935 if (skip_sprites
== -1) break;
8942 if (skip_sprites
== 0) {
8943 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8944 DisableCur (STR_NEWGRF_ERROR_UNEXPECTED_SPRITE
);
8948 if (_cur
.grf_container_ver
>= 2 && type
== 0xFD) {
8949 /* Reference to data section. Container version >= 2 only. */
8953 SkipSpriteData(type
, num
- 8);
8957 if (skip_sprites
> 0) skip_sprites
--;
8962 * Relocates the old shore sprites at new positions.
8964 * 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)
8965 * 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)
8966 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
8968 static void ActivateOldShore()
8970 /* Use default graphics, if no shore sprites were loaded.
8971 * Should not happen, as the base set's extra grf should include some. */
8972 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_NONE
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_A
;
8974 if (_loaded_newgrf_features
.shore
!= SHORE_REPLACE_ACTION_5
) {
8975 for (uint i
= 0; i
< lengthof(shore_sprites_1
); i
++) {
8976 DupSprite (shore_sprites_1
[i
].old
, shore_sprites_1
[i
].spr
);
8980 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_ACTION_A
) {
8981 for (uint i
= 0; i
< lengthof(shore_sprites_2
); i
++) {
8982 DupSprite (shore_sprites_2
[i
].old
, shore_sprites_2
[i
].spr
);
8988 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
8990 static void FinalisePriceBaseMultipliers()
8992 extern const PriceBaseSpec _price_base_specs
[];
8993 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
8994 static const uint32 override_features
= (1 << GSF_TRAINS
) | (1 << GSF_ROADVEHICLES
) | (1 << GSF_SHIPS
) | (1 << GSF_AIRCRAFT
);
8996 /* Evaluate grf overrides */
8997 int num_grfs
= _grf_files
.Length();
8998 int *grf_overrides
= AllocaM(int, num_grfs
);
8999 for (int i
= 0; i
< num_grfs
; i
++) {
9000 grf_overrides
[i
] = -1;
9002 GRFFile
*source
= _grf_files
[i
];
9003 uint32 override
= _grf_id_overrides
[source
->grfid
];
9004 if (override
== 0) continue;
9006 GRFFile
*dest
= GetFileByGRFID(override
);
9007 if (dest
== NULL
) continue;
9009 grf_overrides
[i
] = _grf_files
.FindIndex(dest
);
9010 assert(grf_overrides
[i
] >= 0);
9013 /* Override features and price base multipliers of earlier loaded grfs */
9014 for (int i
= 0; i
< num_grfs
; i
++) {
9015 if (grf_overrides
[i
] < 0 || grf_overrides
[i
] >= i
) continue;
9016 GRFFile
*source
= _grf_files
[i
];
9017 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9019 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9020 source
->grf_features
|= features
;
9021 dest
->grf_features
|= features
;
9023 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9024 /* No price defined -> nothing to do */
9025 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
) || source
->price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) continue;
9026 DEBUG(grf
, 3, "'%s' overrides price base multiplier %d of '%s'", source
->filename
, p
, dest
->filename
);
9027 dest
->price_base_multipliers
[p
] = source
->price_base_multipliers
[p
];
9031 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9032 for (int i
= num_grfs
- 1; i
>= 0; i
--) {
9033 if (grf_overrides
[i
] < 0 || grf_overrides
[i
] <= i
) continue;
9034 GRFFile
*source
= _grf_files
[i
];
9035 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9037 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9038 source
->grf_features
|= features
;
9039 dest
->grf_features
|= features
;
9041 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9042 /* Already a price defined -> nothing to do */
9043 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
) || dest
->price_base_multipliers
[p
] != INVALID_PRICE_MODIFIER
) continue;
9044 DEBUG(grf
, 3, "Price base multiplier %d from '%s' propagated to '%s'", p
, source
->filename
, dest
->filename
);
9045 dest
->price_base_multipliers
[p
] = source
->price_base_multipliers
[p
];
9049 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9050 for (int i
= 0; i
< num_grfs
; i
++) {
9051 if (grf_overrides
[i
] < 0) continue;
9052 GRFFile
*source
= _grf_files
[i
];
9053 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9055 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9056 source
->grf_features
|= features
;
9057 dest
->grf_features
|= features
;
9059 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9060 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
)) continue;
9061 if (source
->price_base_multipliers
[p
] != dest
->price_base_multipliers
[p
]) {
9062 DEBUG(grf
, 3, "Price base multiplier %d from '%s' propagated to '%s'", p
, dest
->filename
, source
->filename
);
9064 source
->price_base_multipliers
[p
] = dest
->price_base_multipliers
[p
];
9068 /* Apply fallback prices for grf version < 8 */
9069 const GRFFile
* const *end
= _grf_files
.End();
9070 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
9071 if ((*file
)->grf_version
>= 8) continue;
9072 PriceMultipliers
&price_base_multipliers
= (*file
)->price_base_multipliers
;
9073 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9074 Price fallback_price
= _price_base_specs
[p
].fallback_price
;
9075 if (fallback_price
!= INVALID_PRICE
&& price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) {
9076 /* No price multiplier has been set.
9077 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9078 price_base_multipliers
[p
] = price_base_multipliers
[fallback_price
];
9083 /* Decide local/global scope of price base multipliers */
9084 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
9085 PriceMultipliers
&price_base_multipliers
= (*file
)->price_base_multipliers
;
9086 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9087 if (price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) {
9088 /* No multiplier was set; set it to a neutral value */
9089 price_base_multipliers
[p
] = 0;
9091 if (!HasBit((*file
)->grf_features
, _price_base_specs
[p
].grf_feature
)) {
9092 /* The grf does not define any objects of the feature,
9093 * so it must be a difficulty setting. Apply it globally */
9094 DEBUG(grf
, 3, "'%s' sets global price base multiplier %d", (*file
)->filename
, p
);
9095 SetPriceBaseMultiplier(p
, price_base_multipliers
[p
]);
9096 price_base_multipliers
[p
] = 0;
9098 DEBUG(grf
, 3, "'%s' sets local price base multiplier %d", (*file
)->filename
, p
);
9105 extern void InitGRFTownGeneratorNames();
9107 /** Finish loading NewGRFs and execute needed post-processing */
9108 static void AfterLoadGRFs()
9110 for (StringIDMapping
*it
= _string_to_grf_mapping
.Begin(); it
!= _string_to_grf_mapping
.End(); it
++) {
9111 *it
->target
= MapGRFStringID(it
->grfid
, it
->source
);
9113 _string_to_grf_mapping
.Clear();
9115 /* Free the action 6 override sprites. */
9116 _grf_line_to_action6_sprite_override
.clear();
9118 /* Polish cargoes */
9119 FinaliseCargoArray();
9121 /* Pre-calculate all refit masks after loading GRF files. */
9122 CalculateRefitMasks();
9124 /* Polish engines */
9125 FinaliseEngineArray();
9127 /* Set the actually used Canal properties */
9130 /* Add all new houses to the house array. */
9131 FinaliseHouseArray();
9133 /* Add all new industries to the industry array. */
9134 FinaliseIndustriesArray();
9136 /* Add all new objects to the object array. */
9137 FinaliseObjectsArray();
9139 InitializeSortedCargoSpecs();
9141 /* Sort the list of industry types. */
9142 SortIndustryTypes();
9144 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9145 BuildIndustriesLegend();
9147 /* Build the routemap legend, based on the available cargos */
9148 BuildLinkStatsLegend();
9150 /* Add all new airports to the airports array. */
9151 FinaliseAirportsArray();
9154 /* Update the townname generators list */
9155 InitGRFTownGeneratorNames();
9157 /* Run all queued vehicle list order changes */
9158 CommitVehicleListOrderChanges();
9160 /* Load old shore sprites in new position, if they were replaced by ActionA */
9163 /* Set up custom rail types */
9167 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_ROAD
) {
9168 if (_gted
[e
->index
].rv_max_speed
!= 0) {
9169 /* Set RV maximum speed from the mph/0.8 unit value */
9170 e
->u
.road
.max_speed
= _gted
[e
->index
].rv_max_speed
* 4;
9174 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_TRAIN
) {
9175 RailType railtype
= GetRailTypeByLabel(_gted
[e
->index
].railtypelabel
);
9176 if (railtype
== INVALID_RAILTYPE
) {
9177 /* Rail type is not available, so disable this engine */
9178 e
->info
.climates
= 0;
9180 e
->u
.rail
.railtype
= railtype
;
9184 SetYearEngineAgingStops();
9186 FinalisePriceBaseMultipliers();
9188 /* Deallocate temporary loading data */
9190 _grm_sprites
.clear();
9194 * Load all the NewGRFs.
9195 * @param load_index The offset for the first sprite to add.
9196 * @param file_index The Fio index of the first NewGRF to load.
9198 void LoadNewGRF(uint load_index
, uint file_index
)
9200 /* In case of networking we need to "sync" the start values
9201 * so all NewGRFs are loaded equally. For this we use the
9202 * start date of the game and we set the counters, etc. to
9203 * 0 so they're the same too. */
9205 Year year
= _cur_year
;
9206 DateFract date_fract
= _date_fract
;
9207 uint16 tick_counter
= _tick_counter
;
9208 byte display_opt
= _display_opt
;
9211 _cur_year
= _settings_game
.game_creation
.starting_year
;
9212 _date
= ConvertYMDToDate(_cur_year
, 0, 1);
9218 InitializeGRFSpecial();
9223 * Reset the status of all files, so we can 'retry' to load them.
9224 * This is needed when one for example rearranges the NewGRFs in-game
9225 * and a previously disabled NewGRF becomes useable. If it would not
9226 * be reset, the NewGRF would remain disabled even though it should
9227 * have been enabled.
9229 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9230 if (c
->status
!= GCS_NOT_FOUND
) c
->status
= GCS_UNKNOWN
;
9233 _cur
.spriteid
= load_index
;
9235 /* Load newgrf sprites
9236 * in each loading stage, (try to) open each file specified in the config
9237 * and load information from it. */
9238 for (GrfLoadingStage stage
= GLS_LABELSCAN
; stage
<= GLS_ACTIVATION
; stage
++) {
9239 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9240 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9241 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9242 if (c
->status
== GCS_ACTIVATED
) c
->status
= GCS_INITIALISED
;
9245 if (stage
== GLS_RESERVE
) {
9246 static const uint32 overrides
[][2] = {
9247 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9248 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9249 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9251 for (size_t i
= 0; i
< lengthof(overrides
); i
++) {
9252 SetNewGRFOverride(BSWAP32(overrides
[i
][0]), BSWAP32(overrides
[i
][1]));
9256 uint slot
= file_index
;
9259 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9260 if (c
->status
== GCS_DISABLED
|| c
->status
== GCS_NOT_FOUND
) continue;
9261 if (stage
> GLS_INIT
&& HasBit(c
->flags
, GCF_INIT_ONLY
)) continue;
9263 Subdirectory subdir
= slot
== file_index
? BASESET_DIR
: NEWGRF_DIR
;
9264 if (!FioCheckFileExists(c
->filename
, subdir
)) {
9265 DEBUG(grf
, 0, "NewGRF file is missing '%s'; disabling", c
->filename
);
9266 c
->status
= GCS_NOT_FOUND
;
9270 /* A .grf file is activated only if it was active
9271 * when the game was started. If a game is loaded,
9272 * only its active .grfs will be reactivated, unless
9273 * "loadallgraphics on" is used. A .grf file is
9274 * considered active if its action 8 has been
9275 * processed, i.e. its action 8 hasn't been skipped
9276 * using an action 7.
9278 * During activation, only actions 0, 1, 2, 3, 4, 5,
9279 * 7, 8, 9, 0A and 0B are carried out. All others
9280 * are ignored, because they only need to be
9281 * processed once at initialization. */
9283 if (stage
== GLS_LABELSCAN
) {
9284 GRFFile
*newfile
= GetFileByFilename (c
->filename
);
9285 if (newfile
== NULL
) {
9286 newfile
= new GRFFile (c
);
9287 *_grf_files
.Append() = newfile
;
9289 _cur
.grffile
= newfile
;
9292 if (stage
!= GLS_LABELSCAN
) {
9293 _cur
.grffile
= GetFileByFilename (c
->filename
);
9294 if (_cur
.grffile
== NULL
) usererror ("File '%s' lost in cache.\n", c
->filename
);
9295 if (stage
== GLS_RESERVE
&& c
->status
!= GCS_INITIALISED
) return;
9296 if (stage
== GLS_ACTIVATION
&& !HasBit(c
->flags
, GCF_RESERVED
)) return;
9299 LoadNewGRFFile(c
, slot
++, stage
, subdir
);
9300 if (stage
== GLS_RESERVE
) {
9301 SetBit(c
->flags
, GCF_RESERVED
);
9302 } else if (stage
== GLS_ACTIVATION
) {
9303 ClrBit(c
->flags
, GCF_RESERVED
);
9304 assert(GetFileByGRFID(c
->ident
.grfid
) == _cur
.grffile
);
9305 ClearTemporaryNewGRFData(_cur
.grffile
);
9306 BuildCargoTranslationMap();
9307 DEBUG(sprite
, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur
.spriteid
);
9308 } else if (stage
== GLS_INIT
&& HasBit(c
->flags
, GCF_INIT_ONLY
)) {
9309 /* We're not going to activate this, so free whatever data we allocated */
9310 ClearTemporaryNewGRFData(_cur
.grffile
);
9315 /* Pseudo sprite processing is finished; free temporary stuff */
9316 _cur
.ClearDataForNextFile();
9318 /* Call any functions that should be run after GRFs have been loaded. */
9321 /* Now revert back to the original situation */
9324 _date_fract
= date_fract
;
9325 _tick_counter
= tick_counter
;
9326 _display_opt
= display_opt
;