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
);
203 static inline uint16
ReadWord (const byte
*p
)
205 return p
[0] | (p
[1] << 8);
208 static inline uint32
ReadDWord (const byte
*p
)
210 return p
[0] | (p
[1] << 8) | (p
[2] << 16) | (p
[3] << 24);
213 static uint32
ReadVarSize (const byte
*p
, byte size
)
217 case 2: return ReadWord (p
);
218 case 4: return ReadDWord (p
);
225 /** Class to read from a NewGRF file */
232 ByteReader(byte
*data
, byte
*end
) : data(data
), end(end
) { }
234 class out_of_data
{ };
236 inline byte
ReadByte()
238 if (data
< end
) return *(data
)++;
244 uint16 val
= ReadByte();
245 return val
| (ReadByte() << 8);
248 uint16
ReadExtendedByte()
250 uint16 val
= ReadByte();
251 return val
== 0xFF ? ReadWord() : val
;
256 uint32 val
= ReadWord();
257 return val
| (ReadWord() << 16);
260 uint32
ReadLabel (void)
262 return BSWAP32(this->ReadDWord());
265 const char *ReadString (void);
267 inline size_t Remaining() const
272 inline bool HasData(size_t count
= 1) const
274 return Remaining() >= count
;
277 const byte
*GetData (size_t n
)
279 if (!HasData (n
)) throw out_of_data();
280 const byte
*p
= data
;
285 const byte
*GetData (void)
290 inline void Skip(size_t len
)
293 /* It is valid to move the buffer to exactly the end of the data,
294 * as there may not be any more data read. */
295 if (data
> end
) throw out_of_data();
298 byte
*Dup (size_t len
)
300 if (!HasData (len
)) throw out_of_data();
302 byte
*p
= xmemdupt (data
, len
);
308 const char *ByteReader::ReadString (void)
310 const char *string
= reinterpret_cast<char *>(data
);
312 size_t remaining
= Remaining();
313 size_t string_length
= ttd_strnlen (string
, remaining
);
315 if (string_length
== remaining
) {
316 /* String was not NUL terminated, so make sure it is now. */
317 grfmsg(7, "String was not terminated with a zero byte.");
321 /* Increase the string length to include the NUL byte. */
323 data
+= string_length
;
329 typedef int (*SpecialSpriteHandler
) (ByteReader
*buf
);
331 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.
333 /** Temporary engine data used when loading only */
334 struct GRFTempEngineData
{
335 /** Summary state of refittability properties */
337 UNSET
= 0, ///< No properties assigned. Default refit masks shall be activated.
338 EMPTY
, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
339 NONEMPTY
, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
342 uint16 cargo_allowed
;
343 uint16 cargo_disallowed
;
344 RailTypeLabel railtypelabel
;
345 const GRFFile
*defaultcargo_grf
; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
346 Refittability refittability
; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
347 bool prop27_set
; ///< Did the NewGRF set property 27 (misc flags)?
348 uint8 rv_max_speed
; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
349 uint32 ctt_include_mask
; ///< Cargo types always included in the refit mask.
350 uint32 ctt_exclude_mask
; ///< Cargo types always excluded from the refit mask.
353 * Update the summary refittability on setting a refittability property.
354 * @param non_empty true if the GRF sets the vehicle to be refittable.
356 void UpdateRefittability(bool non_empty
)
359 this->refittability
= NONEMPTY
;
360 } else if (this->refittability
== UNSET
) {
361 this->refittability
= EMPTY
;
366 static GRFTempEngineData
*_gted
; ///< Temporary engine data used during NewGRF loading
369 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
370 * GRM for vehicles is only used if dynamic engine allocation is disabled,
371 * so 256 is the number of original engines. */
372 static uint32 _grm_engines
[256];
374 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
375 static uint32 _grm_cargoes
[NUM_CARGO
* 2];
381 GRFLocation(uint32 grfid
, uint32 nfoline
) : grfid(grfid
), nfoline(nfoline
) { }
383 bool operator<(const GRFLocation
&other
) const
385 return this->grfid
< other
.grfid
|| (this->grfid
== other
.grfid
&& this->nfoline
< other
.nfoline
);
388 bool operator == (const GRFLocation
&other
) const
390 return this->grfid
== other
.grfid
&& this->nfoline
== other
.nfoline
;
394 static std::map
<GRFLocation
, SpriteID
> _grm_sprites
;
395 typedef std::map
<GRFLocation
, ttd_unique_free_ptr
<byte
> > GRFLineToSpriteOverride
;
396 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override
;
399 * DEBUG() function dedicated to newGRF debugging messages
400 * Function is essentially the same as DEBUG(grf, severity, ...) with the
401 * addition of file:line information when parsing grf files.
402 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
403 * loading/parsing grf files, not for runtime debug messages as there
404 * is no file information available during that time.
405 * @param severity debugging severity level, see debug.h
406 * @param str message in printf() format
408 void CDECL
grfmsg(int severity
, const char *str
, ...)
414 bstrvfmt (buf
, str
, va
);
417 DEBUG(grf
, severity
, "[%s:%d] %s", _cur
.grfconfig
->filename
, _cur
.nfo_line
, buf
);
421 * Obtain a NewGRF file by its grfID
422 * @param grfid The grfID to obtain the file for
425 static GRFFile
*GetFileByGRFID(uint32 grfid
)
427 const GRFFile
* const *end
= _grf_files
.End();
428 for (GRFFile
* const *file
= _grf_files
.Begin(); file
!= end
; file
++) {
429 if ((*file
)->grfid
== grfid
) return *file
;
435 * Obtain a NewGRF file by its filename
436 * @param filename The filename to obtain the file for.
439 static GRFFile
*GetFileByFilename(const char *filename
)
441 const GRFFile
* const *end
= _grf_files
.End();
442 for (GRFFile
* const *file
= _grf_files
.Begin(); file
!= end
; file
++) {
443 if (strcmp((*file
)->filename
, filename
) == 0) return *file
;
448 /** Reset all NewGRFData that was used only while processing data */
449 static void ClearTemporaryNewGRFData(GRFFile
*gf
)
451 /* Clear the GOTO labels used for GRF processing */
452 for (GRFLabel
*l
= gf
->label
; l
!= NULL
;) {
453 GRFLabel
*l2
= l
->next
;
461 * Disable the GRF being loaded
462 * @param message Error message or STR_NULL.
463 * @return Error message of the GRF for further customisation.
465 static GRFError
*DisableCur (StringID message
= STR_NULL
)
467 GRFConfig
*config
= _cur
.grfconfig
;
469 config
->status
= GCS_DISABLED
;
470 if (_cur
.grffile
!= NULL
) ClearTemporaryNewGRFData (_cur
.grffile
);
472 if (message
!= STR_NULL
) {
473 delete config
->error
;
474 config
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, message
);
475 if (config
== _cur
.grfconfig
) config
->error
->param_value
[0] = _cur
.nfo_line
;
478 return config
->error
;
483 * @param message Error message.
484 * @param config GRFConfig to disable.
486 static void DisableGrf (StringID message
, GRFConfig
*config
)
488 assert (config
!= NULL
);
489 assert (config
!= _cur
.grfconfig
);
491 config
->status
= GCS_DISABLED
;
493 GRFFile
*file
= GetFileByGRFID (config
->ident
.grfid
);
494 if (file
!= NULL
) ClearTemporaryNewGRFData(file
);
496 delete config
->error
;
497 config
->error
= new GRFError (STR_NEWGRF_ERROR_MSG_FATAL
, message
);
498 config
->error
->data
= xstrdup (_cur
.grfconfig
->GetName());
502 * Information for mapping static StringIDs.
504 struct StringIDMapping
{
505 uint32 grfid
; ///< Source NewGRF.
506 StringID source
; ///< Source StringID (GRF local).
507 StringID
*target
; ///< Destination for mapping result.
509 typedef SmallVector
<StringIDMapping
, 16> StringIDMappingVector
;
510 static StringIDMappingVector _string_to_grf_mapping
;
513 * Record a static StringID for getting translated later.
514 * @param source Source StringID (GRF local).
515 * @param target Destination for the mapping result.
517 static void AddStringForMapping(StringID source
, StringID
*target
)
519 *target
= STR_UNDEFINED
;
520 StringIDMapping
*item
= _string_to_grf_mapping
.Append();
521 item
->grfid
= _cur
.grffile
->grfid
;
522 item
->source
= source
;
523 item
->target
= target
;
527 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
528 * string IDs, but only for the ones we are aware off; the rest
529 * like likely unused and will show a warning.
530 * @param str the string ID to convert
531 * @return the converted string ID
533 static StringID
TTDPStringIDToOTTDStringIDMapping(StringID str
)
535 /* StringID table for TextIDs 0x4E->0x6D */
536 static const StringID units_volume
[] = {
537 STR_ITEMS
, STR_PASSENGERS
, STR_TONS
, STR_BAGS
,
538 STR_LITERS
, STR_ITEMS
, STR_CRATES
, STR_TONS
,
539 STR_TONS
, STR_TONS
, STR_TONS
, STR_BAGS
,
540 STR_TONS
, STR_TONS
, STR_TONS
, STR_BAGS
,
541 STR_TONS
, STR_TONS
, STR_BAGS
, STR_LITERS
,
542 STR_TONS
, STR_LITERS
, STR_TONS
, STR_ITEMS
,
543 STR_BAGS
, STR_LITERS
, STR_TONS
, STR_ITEMS
,
544 STR_TONS
, STR_ITEMS
, STR_LITERS
, STR_ITEMS
547 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
548 assert(!IsInsideMM(str
, 0xD000, 0xD7FF));
550 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
551 assert_compile(stringend - stringid == end - begin); \
552 if (str >= begin && str <= end) return str + (stringid - begin)
554 /* We have some changes in our cargo strings, resulting in some missing. */
555 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING
, STR_CARGO_PLURAL_FIZZY_DRINKS
);
556 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING
, STR_CARGO_SINGULAR_FIZZY_DRINK
);
557 if (str
>= 0x004E && str
<= 0x006D) return units_volume
[str
- 0x004E];
558 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING
, STR_QUANTITY_FIZZY_DRINKS
);
559 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING
, STR_ABBREV_FIZZY_DRINKS
);
560 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE
, STR_COLOUR_WHITE
);
562 /* Map building names according to our lang file changes. There are several
563 * ranges of house ids, all of which need to be remapped to allow newgrfs
564 * to use original house names. */
565 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1
, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1
);
566 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1
, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1
);
567 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1
, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1
);
569 /* Same thing for industries */
570 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE
, STR_INDUSTRY_NAME_SUGAR_MINE
);
571 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION
, STR_NEWS_INDUSTRY_PLANTED
);
572 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL
, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES
);
573 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL
, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM
);
574 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL
, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM
);
577 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY
;
578 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED
;
579 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED
;
581 #undef TEXTID_TO_STRINGID
583 if (str
== STR_NULL
) return STR_EMPTY
;
585 DEBUG(grf
, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str
);
591 * Used when setting an object's property to map to the GRF's strings
592 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
593 * @param grfid Id of the grf file.
594 * @param str StringID that we want to have the equivalent in OoenTTD.
595 * @return The properly adjusted StringID.
597 StringID
MapGRFStringID(uint32 grfid
, StringID str
)
599 if (IsInsideMM(str
, 0xD800, 0xE000)) {
600 /* General text provided by NewGRF.
601 * In the specs this is called the 0xDCxx range (misc presistent texts),
602 * but we meanwhile extended the range to 0xD800-0xDFFF.
603 * Note: We are not involved in the "persistent" business, since we do not store
604 * any NewGRF strings in savegames. */
605 return GetGRFStringID(grfid
, str
);
606 } else if (IsInsideMM(str
, 0xD000, 0xD800)) {
607 /* Callback text provided by NewGRF.
608 * In the specs this is called the 0xD0xx range (misc graphics texts).
609 * These texts can be returned by various callbacks.
611 * Due to how TTDP implements the GRF-local- to global-textid translation
612 * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
613 * We do not care about that difference and just mask out the 0x400 bit.
616 return GetGRFStringID(grfid
, str
);
618 /* The NewGRF wants to include/reference an original TTD string.
619 * Try our best to find an equivalent one. */
620 return TTDPStringIDToOTTDStringIDMapping(str
);
624 static std::map
<uint32
, uint32
> _grf_id_overrides
;
627 * Set the override for a NewGRF
628 * @param source_grfid The grfID which wants to override another NewGRF.
629 * @param target_grfid The grfID which is being overridden.
631 static void SetNewGRFOverride(uint32 source_grfid
, uint32 target_grfid
)
633 _grf_id_overrides
[source_grfid
] = target_grfid
;
634 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid
), BSWAP32(target_grfid
));
638 * Returns the engine associated to a certain internal_id, resp. allocates it.
639 * @param file NewGRF that wants to change the engine.
640 * @param type Vehicle type.
641 * @param internal_id Engine ID inside the NewGRF.
642 * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04).
643 * @return The requested engine.
645 static Engine
*GetNewEngine(const GRFFile
*file
, VehicleType type
, uint16 internal_id
, bool static_access
= false)
647 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
648 * them use the same engine slots. */
649 uint32 scope_grfid
= INVALID_GRFID
; // If not using dynamic_engines, all newgrfs share their ID range
650 if (_settings_game
.vehicle
.dynamic_engines
) {
651 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
652 scope_grfid
= file
->grfid
;
653 uint32 override
= _grf_id_overrides
[file
->grfid
];
655 scope_grfid
= override
;
656 const GRFFile
*grf_match
= GetFileByGRFID(override
);
657 if (grf_match
== NULL
) {
658 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file
->grfid
), BSWAP32(override
));
660 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file
->grfid
), BSWAP32(override
));
664 /* Check if the engine is registered in the override manager */
665 EngineID engine
= _engine_mngr
.GetID(type
, internal_id
, scope_grfid
);
666 if (engine
!= INVALID_ENGINE
) {
667 Engine
*e
= Engine::Get(engine
);
668 if (e
->grf_prop
.grffile
== NULL
) e
->grf_prop
.grffile
= file
;
673 /* Check if there is an unreserved slot */
674 EngineID engine
= _engine_mngr
.GetID(type
, internal_id
, INVALID_GRFID
);
675 if (engine
!= INVALID_ENGINE
) {
676 Engine
*e
= Engine::Get(engine
);
678 if (e
->grf_prop
.grffile
== NULL
) {
679 e
->grf_prop
.grffile
= file
;
680 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e
->index
, BSWAP32(file
->grfid
), type
, internal_id
);
683 /* Reserve the engine slot */
684 if (!static_access
) {
685 EngineIDMapping
*eid
= _engine_mngr
.Get(engine
);
686 eid
->grfid
= scope_grfid
; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
692 if (static_access
) return NULL
;
694 if (!Engine::CanAllocateItem()) {
695 grfmsg(0, "Can't allocate any more engines");
699 size_t engine_pool_size
= Engine::GetPoolSize();
701 /* ... it's not, so create a new one based off an existing engine */
702 Engine
*e
= new Engine(type
, internal_id
);
703 e
->grf_prop
.grffile
= file
;
705 /* Reserve the engine slot */
706 assert(_engine_mngr
.Length() == e
->index
);
707 EngineIDMapping
*eid
= _engine_mngr
.Append();
709 eid
->grfid
= scope_grfid
; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
710 eid
->internal_id
= internal_id
;
711 eid
->substitute_id
= min(internal_id
, _engine_counts
[type
]); // substitute_id == _engine_counts[subtype] means "no substitute"
713 if (engine_pool_size
!= Engine::GetPoolSize()) {
714 /* Resize temporary engine data ... */
715 _gted
= xrealloct (_gted
, Engine::GetPoolSize());
717 /* and blank the new block. */
718 size_t len
= (Engine::GetPoolSize() - engine_pool_size
) * sizeof(*_gted
);
719 memset(_gted
+ engine_pool_size
, 0, len
);
721 if (type
== VEH_TRAIN
) {
722 _gted
[e
->index
].railtypelabel
= GetRailTypeInfo(e
->u
.rail
.railtype
)->label
;
725 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e
->index
, BSWAP32(file
->grfid
), type
, internal_id
);
731 * Return the ID of a new engine
732 * @param file The NewGRF file providing the engine.
733 * @param type The Vehicle type.
734 * @param internal_id NewGRF-internal ID of the engine.
735 * @return The new EngineID.
736 * @note depending on the dynamic_engine setting and a possible override
737 * property the grfID may be unique or overwriting or partially re-defining
738 * properties of an existing engine.
740 EngineID
GetNewEngineID(const GRFFile
*file
, VehicleType type
, uint16 internal_id
)
742 uint32 scope_grfid
= INVALID_GRFID
; // If not using dynamic_engines, all newgrfs share their ID range
743 if (_settings_game
.vehicle
.dynamic_engines
) {
744 scope_grfid
= file
->grfid
;
745 uint32 override
= _grf_id_overrides
[file
->grfid
];
746 if (override
!= 0) scope_grfid
= override
;
749 return _engine_mngr
.GetID(type
, internal_id
, scope_grfid
);
753 * Read a sprite and paletteD from the GRF and map the colour modifiers
754 * of TTDPatch to those that Open is using.
755 * @param buf Input stream.
756 * @param grf_sprite Pointer to the structure to read.
758 static void ReadPalSprite (const byte
*buf
, PalSpriteID
*grf_sprite
)
760 SpriteID sprite
= ReadWord (buf
);
761 PaletteID pal
= ReadWord (buf
+ 2);
763 if (HasBit(pal
, 14)) {
765 SetBit(sprite
, SPRITE_MODIFIER_OPAQUE
);
768 if (HasBit(sprite
, 14)) {
770 SetBit(sprite
, PALETTE_MODIFIER_TRANSPARENT
);
773 if (HasBit(sprite
, 15)) {
775 SetBit(sprite
, PALETTE_MODIFIER_COLOUR
);
778 grf_sprite
->sprite
= sprite
;
779 grf_sprite
->pal
= pal
;
783 * Read a sprite and paletteD from the GRF and map the colour modifiers
784 * of TTDPatch to those that Open is using.
785 * @param buf Input stream.
786 * @param grf_sprite Pointer to the structure to read.
788 static void ReadPalSprite (ByteReader
*buf
, PalSpriteID
*grf_sprite
)
790 ReadPalSprite (buf
->GetData(4), grf_sprite
);
794 * Adjust a sprite and a palette read from the GRF.
795 * @param grf_sprite Sprite and palette to adjust.
796 * @param feature GrfSpecFeature to use spritesets from.
797 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
798 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
799 * @param flags Tile layout flags.
800 * @param [out] max_offset Optionally returns the number of sprites in the spriteset of the sprite and palette (0 if no spritset).
801 * @return Whether reading succeeded.
803 static bool AdjustSpriteLayoutSprite (PalSpriteID
*grf_sprite
, int feature
,
804 bool invert_action1_flag
, bool use_cur_spritesets
= false,
805 TileLayoutFlags flags
= TLF_NOTHING
, uint16
*max_offset
= NULL
)
807 bool custom_sprite
= HasBit(grf_sprite
->pal
, 15) != invert_action1_flag
;
808 ClrBit(grf_sprite
->pal
, 15);
810 /* Use sprite from Action 1 */
811 uint index
= GB(grf_sprite
->sprite
, 0, 14);
812 if (use_cur_spritesets
&& (!_cur
.IsValidSpriteSet(feature
, index
) || _cur
.GetNumEnts(feature
, index
) == 0)) {
813 grfmsg(1, "sprite layout uses undefined custom spriteset %d", index
);
814 grf_sprite
->sprite
= SPR_IMG_QUERY
;
815 grf_sprite
->pal
= PAL_NONE
;
817 SpriteID sprite
= use_cur_spritesets
? _cur
.GetSprite(feature
, index
) : index
;
818 if (max_offset
!= NULL
) max_offset
[0] = use_cur_spritesets
? _cur
.GetNumEnts (feature
, index
) : UINT16_MAX
;
819 SB(grf_sprite
->sprite
, 0, SPRITE_WIDTH
, sprite
);
820 SetBit(grf_sprite
->sprite
, SPRITE_MODIFIER_CUSTOM_SPRITE
);
822 } else if ((flags
& TLF_SPRITE_VAR10
) && !(flags
& TLF_SPRITE_REG_FLAGS
)) {
823 grfmsg(1, "sprite layout specifies var10 value for non-action-1 sprite");
824 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
828 if (flags
& TLF_CUSTOM_PALETTE
) {
829 /* Use palette from Action 1 */
830 uint index
= GB(grf_sprite
->pal
, 0, 14);
831 if (use_cur_spritesets
&& (!_cur
.IsValidSpriteSet(feature
, index
) || _cur
.GetNumEnts(feature
, index
) == 0)) {
832 grfmsg(1, "sprite layout uses undefined custom spriteset %d for palette", index
);
833 grf_sprite
->pal
= PAL_NONE
;
835 SpriteID sprite
= use_cur_spritesets
? _cur
.GetSprite(feature
, index
) : index
;
836 if (max_offset
!= NULL
) max_offset
[1] = use_cur_spritesets
? _cur
.GetNumEnts (feature
, index
) : UINT16_MAX
;
837 SB(grf_sprite
->pal
, 0, SPRITE_WIDTH
, sprite
);
838 SetBit(grf_sprite
->pal
, SPRITE_MODIFIER_CUSTOM_SPRITE
);
840 } else if ((flags
& TLF_PALETTE_VAR10
) && !(flags
& TLF_PALETTE_REG_FLAGS
)) {
841 grfmsg(1, "sprite layout specifies var10 value for non-action-1 palette");
842 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
850 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
851 * @param buf Input stream.
852 * @param flags TileLayoutFlags to process.
853 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
854 * @param r Where to store the registers.
855 * @return Whether reading succeeded.
857 static bool ReadSpriteLayoutRegisters (ByteReader
*buf
, TileLayoutFlags flags
,
858 bool is_parent
, TileLayoutRegisters
*r
)
860 TileLayoutRegisters
®s
= *r
;
863 if (flags
== TLF_NOTHING
) return true; // nothing to read
865 if (flags
& TLF_DODRAW
) regs
.dodraw
= buf
->ReadByte();
866 if (flags
& TLF_SPRITE
) regs
.sprite
= buf
->ReadByte();
867 if (flags
& TLF_PALETTE
) regs
.palette
= buf
->ReadByte();
870 if (flags
& TLF_BB_XY_OFFSET
) {
871 regs
.delta
.parent
[0] = buf
->ReadByte();
872 regs
.delta
.parent
[1] = buf
->ReadByte();
874 if (flags
& TLF_BB_Z_OFFSET
) regs
.delta
.parent
[2] = buf
->ReadByte();
876 if (flags
& TLF_CHILD_X_OFFSET
) regs
.delta
.child
[0] = buf
->ReadByte();
877 if (flags
& TLF_CHILD_Y_OFFSET
) regs
.delta
.child
[1] = buf
->ReadByte();
880 if (flags
& TLF_SPRITE_VAR10
) {
881 regs
.sprite_var10
= buf
->ReadByte();
882 if (regs
.sprite_var10
> TLR_MAX_VAR10
) {
883 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs
.sprite_var10
, TLR_MAX_VAR10
);
884 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
889 if (flags
& TLF_PALETTE_VAR10
) {
890 regs
.palette_var10
= buf
->ReadByte();
891 if (regs
.palette_var10
> TLR_MAX_VAR10
) {
892 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs
.palette_var10
, TLR_MAX_VAR10
);
893 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
901 struct SpriteLayoutReader
{
902 static const uint MAX_BUILDING_SPRITES
= 255;
904 PalSpriteID ground
; ///< Ground sprite and palette.
905 DrawTileSeqStruct seq
[MAX_BUILDING_SPRITES
]; ///< Building sprites.
906 TileLayoutRegisters regs
[MAX_BUILDING_SPRITES
+ 1]; ///< Registers.
907 uint num_building_sprites
; ///< Amount of building sprites.
908 uint consistent_max_offset
; ///< Maximum offset for sprites.
909 bool has_registers
; ///< Any register is actually used.
913 * Read a spritelayout from the GRF.
914 * @param reader Where to read the sprite into.
916 * @param num_building_sprites Number of building sprites to read
917 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
918 * @param feature GrfSpecFeature to use spritesets from.
919 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
920 * @param no_z_position Whether bounding boxes have no Z offset
921 * @return True on error (GRF was disabled).
923 static bool ReadSpriteLayout (SpriteLayoutReader
*reader
, ByteReader
*buf
,
924 uint num_building_sprites
, bool use_cur_spritesets
, byte feature
,
925 bool allow_var10
, bool no_z_position
)
927 assert (num_building_sprites
<= lengthof(reader
->seq
));
928 assert (num_building_sprites
< lengthof(reader
->regs
));
930 uint16 max_offset
[2 * (SpriteLayoutReader::MAX_BUILDING_SPRITES
+ 1)]; // (sprite, palette) pairs
931 assert (2 * num_building_sprites
< lengthof(max_offset
));
932 memset (max_offset
, 0, sizeof(max_offset
));
934 bool has_flags
= HasBit(num_building_sprites
, 6);
935 ClrBit(num_building_sprites
, 6);
936 reader
->num_building_sprites
= num_building_sprites
;
937 TileLayoutFlags valid_flags
= TLF_KNOWN_FLAGS
;
938 if (!allow_var10
) valid_flags
&= ~TLF_VAR10_FLAGS
;
941 ReadPalSprite (buf
, &reader
->ground
);
942 TileLayoutFlags flags
= has_flags
? (TileLayoutFlags
)buf
->ReadWord() : TLF_NOTHING
;
943 if (!AdjustSpriteLayoutSprite (&reader
->ground
, feature
, false,
944 use_cur_spritesets
, flags
, max_offset
)) {
948 if (flags
& ~(valid_flags
& ~TLF_NON_GROUND_FLAGS
)) {
949 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags
& ~(valid_flags
& ~TLF_NON_GROUND_FLAGS
));
950 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
954 flags
&= TLF_DRAWING_FLAGS
;
955 bool has_registers
= (flags
!= TLF_NOTHING
);
956 if (!ReadSpriteLayoutRegisters (buf
, flags
, false, &reader
->regs
[0])) {
960 for (uint i
= 0; i
< num_building_sprites
; i
++) {
961 DrawTileSeqStruct
*seq
= &reader
->seq
[i
];
963 ReadPalSprite (buf
, &seq
->image
);
964 flags
= has_flags
? (TileLayoutFlags
)buf
->ReadWord() : TLF_NOTHING
;
965 if (!AdjustSpriteLayoutSprite (&seq
->image
, feature
, false,
966 use_cur_spritesets
, flags
,
967 max_offset
+ 2 * (i
+ 1))) {
971 if (flags
& ~valid_flags
) {
972 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags
& ~valid_flags
);
973 DisableCur (STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
977 seq
->delta_x
= buf
->ReadByte();
978 seq
->delta_y
= buf
->ReadByte();
979 seq
->delta_z
= no_z_position
? 0 : buf
->ReadByte();
981 if (seq
->IsParentSprite()) {
982 seq
->size_x
= buf
->ReadByte();
983 seq
->size_y
= buf
->ReadByte();
984 seq
->size_z
= buf
->ReadByte();
987 flags
&= TLF_DRAWING_FLAGS
;
988 has_registers
|= (flags
!= TLF_NOTHING
);
990 if (!ReadSpriteLayoutRegisters (buf
, flags
, seq
->IsParentSprite(), &reader
->regs
[i
+ 1])) {
995 /* Check if the number of sprites per spriteset is consistent */
996 uint consistent_max_offset
= 0;
997 for (uint i
= 0; i
< 2 * (num_building_sprites
+ 1); i
++) {
998 if (max_offset
[i
] > 0) {
999 if (consistent_max_offset
== 0) {
1000 consistent_max_offset
= max_offset
[i
];
1001 } else if (consistent_max_offset
!= max_offset
[i
]) {
1002 assert (use_cur_spritesets
);
1003 /* Not consistent, so use registers. */
1004 has_registers
= true;
1010 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
1011 assert (use_cur_spritesets
|| (consistent_max_offset
== 0 || consistent_max_offset
== UINT16_MAX
));
1013 if (has_registers
) {
1014 for (uint i
= 0; i
< num_building_sprites
+ 1; i
++) {
1015 TileLayoutRegisters
®s
= reader
->regs
[i
];
1016 regs
.max_sprite_offset
= max_offset
[2 * i
];
1017 regs
.max_palette_offset
= max_offset
[2 * i
+ 1];
1020 consistent_max_offset
= 0;
1023 reader
->consistent_max_offset
= consistent_max_offset
;
1024 reader
->has_registers
= has_registers
;
1030 * Translate the refit mask.
1032 static uint32
TranslateRefitMask(uint32 refit_mask
)
1036 FOR_EACH_SET_BIT(bit
, refit_mask
) {
1037 CargoID cargo
= GetCargoTranslation(bit
, _cur
.grffile
, true);
1038 if (cargo
!= CT_INVALID
) SetBit(result
, cargo
);
1044 * Converts TTD(P) Base Price pointers into the enum used by OTTD
1045 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
1046 * @param base_pointer TTD(P) Base Price Pointer
1047 * @param error_location Function name for grf error messages
1048 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
1050 static void ConvertTTDBasePrice(uint32 base_pointer
, const char *error_location
, Price
*index
)
1052 /* Special value for 'none' */
1053 if (base_pointer
== 0) {
1054 *index
= INVALID_PRICE
;
1058 static const uint32 start
= 0x4B34; ///< Position of first base price
1059 static const uint32 size
= 6; ///< Size of each base price record
1061 if (base_pointer
< start
|| (base_pointer
- start
) % size
!= 0 || (base_pointer
- start
) / size
>= PR_END
) {
1062 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location
, base_pointer
);
1066 *index
= (Price
)((base_pointer
- start
) / size
);
1069 /** Possible return values for the FeatureChangeInfo functions */
1070 enum ChangeInfoResult
{
1071 CIR_SUCCESS
, ///< Variable was parsed and read
1072 CIR_DISABLED
, ///< GRF was disabled due to error
1073 CIR_UNHANDLED
, ///< Variable was parsed but unread
1074 CIR_UNKNOWN
, ///< Variable is unknown
1075 CIR_INVALID_ID
, ///< Attempt to modify an invalid ID
1078 typedef ChangeInfoResult (*VCI_Handler
)(uint engine
, int numinfo
, int prop
, ByteReader
*buf
);
1081 * Define properties common to all vehicles
1082 * @param ei Engine info.
1083 * @param prop The property to change.
1084 * @param buf The property value.
1085 * @return ChangeInfoResult.
1087 static ChangeInfoResult
CommonVehicleChangeInfo(EngineInfo
*ei
, int prop
, ByteReader
*buf
)
1090 case 0x00: // Introduction date
1091 ei
->base_intro
= buf
->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR
;
1094 case 0x02: // Decay speed
1095 ei
->decay_speed
= buf
->ReadByte();
1098 case 0x03: // Vehicle life
1099 ei
->lifelength
= buf
->ReadByte();
1102 case 0x04: // Model life
1103 ei
->base_life
= buf
->ReadByte();
1106 case 0x06: // Climates available
1107 ei
->climates
= buf
->ReadByte();
1110 case PROP_VEHICLE_LOAD_AMOUNT
: // 0x07 Loading speed
1111 /* Amount of cargo loaded during a vehicle's "loading tick" */
1112 ei
->load_amount
= buf
->ReadByte();
1123 * Define properties for rail vehicles
1124 * @param engine :ocal ID of the first vehicle.
1125 * @param numinfo Number of subsequent IDs to change the property for.
1126 * @param prop The property to change.
1127 * @param buf The property value.
1128 * @return ChangeInfoResult.
1130 static ChangeInfoResult
RailVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1132 ChangeInfoResult ret
= CIR_SUCCESS
;
1134 for (int i
= 0; i
< numinfo
; i
++) {
1135 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_TRAIN
, engine
+ i
);
1136 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1138 EngineInfo
*ei
= &e
->info
;
1139 RailVehicleInfo
*rvi
= &e
->u
.rail
;
1142 case 0x05: { // Track type
1143 uint8 tracktype
= buf
->ReadByte();
1145 if (tracktype
< _cur
.grffile
->railtype_list
.Length()) {
1146 _gted
[e
->index
].railtypelabel
= _cur
.grffile
->railtype_list
[tracktype
];
1150 switch (tracktype
) {
1151 case 0: _gted
[e
->index
].railtypelabel
= rvi
->engclass
>= 2 ? RAILTYPE_ELECTRIC_LABEL
: RAILTYPE_RAIL_LABEL
; break;
1152 case 1: _gted
[e
->index
].railtypelabel
= RAILTYPE_MONO_LABEL
; break;
1153 case 2: _gted
[e
->index
].railtypelabel
= RAILTYPE_MAGLEV_LABEL
; break;
1155 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype
);
1161 case 0x08: // AI passenger service
1162 /* Tells the AI that this engine is designed for
1163 * passenger services and shouldn't be used for freight. */
1164 rvi
->ai_passenger_only
= buf
->ReadByte();
1167 case PROP_TRAIN_SPEED
: { // 0x09 Speed (1 unit is 1 km-ish/h)
1168 uint16 speed
= buf
->ReadWord();
1169 if (speed
== 0xFFFF) speed
= 0;
1171 rvi
->max_speed
= speed
;
1175 case PROP_TRAIN_POWER
: // 0x0B Power
1176 rvi
->power
= buf
->ReadWord();
1178 /* Set engine / wagon state based on power */
1179 if (rvi
->power
!= 0) {
1180 if (rvi
->railveh_type
== RAILVEH_WAGON
) {
1181 rvi
->railveh_type
= RAILVEH_SINGLEHEAD
;
1184 rvi
->railveh_type
= RAILVEH_WAGON
;
1188 case PROP_TRAIN_RUNNING_COST_FACTOR
: // 0x0D Running cost factor
1189 rvi
->running_cost
= buf
->ReadByte();
1192 case 0x0E: // Running cost base
1193 ConvertTTDBasePrice(buf
->ReadDWord(), "RailVehicleChangeInfo", &rvi
->running_cost_class
);
1196 case 0x12: { // Sprite ID
1197 uint8 spriteid
= buf
->ReadByte();
1198 uint8 orig_spriteid
= spriteid
;
1200 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1201 * as an array index, so we need it to be half the original value. */
1202 if (spriteid
< 0xFD) spriteid
>>= 1;
1204 if (IsValidNewGRFImageIndex
<VEH_TRAIN
>(spriteid
)) {
1205 rvi
->image_index
= spriteid
;
1207 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1208 rvi
->image_index
= 0;
1213 case 0x13: { // Dual-headed
1214 uint8 dual
= buf
->ReadByte();
1217 rvi
->railveh_type
= RAILVEH_MULTIHEAD
;
1219 rvi
->railveh_type
= rvi
->power
== 0 ?
1220 RAILVEH_WAGON
: RAILVEH_SINGLEHEAD
;
1225 case PROP_TRAIN_CARGO_CAPACITY
: // 0x14 Cargo capacity
1226 rvi
->capacity
= buf
->ReadByte();
1229 case 0x15: { // Cargo type
1230 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1231 uint8 ctype
= buf
->ReadByte();
1233 if (ctype
== 0xFF) {
1234 /* 0xFF is specified as 'use first refittable' */
1235 ei
->cargo_type
= CT_INVALID
;
1236 } else if (_cur
.grffile
->grf_version
>= 8) {
1237 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1238 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1239 } else if (ctype
< NUM_CARGO
) {
1240 /* Use untranslated cargo. */
1241 ei
->cargo_type
= ctype
;
1243 ei
->cargo_type
= CT_INVALID
;
1244 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1249 case PROP_TRAIN_WEIGHT
: // 0x16 Weight
1250 SB(rvi
->weight
, 0, 8, buf
->ReadByte());
1253 case PROP_TRAIN_COST_FACTOR
: // 0x17 Cost factor
1254 rvi
->cost_factor
= buf
->ReadByte();
1257 case 0x18: // AI rank
1258 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1262 case 0x19: { // Engine traction type
1263 /* What do the individual numbers mean?
1264 * 0x00 .. 0x07: Steam
1265 * 0x08 .. 0x27: Diesel
1266 * 0x28 .. 0x31: Electric
1267 * 0x32 .. 0x37: Monorail
1268 * 0x38 .. 0x41: Maglev
1270 uint8 traction
= buf
->ReadByte();
1271 EngineClass engclass
;
1273 if (traction
<= 0x07) {
1274 engclass
= EC_STEAM
;
1275 } else if (traction
<= 0x27) {
1276 engclass
= EC_DIESEL
;
1277 } else if (traction
<= 0x31) {
1278 engclass
= EC_ELECTRIC
;
1279 } else if (traction
<= 0x37) {
1280 engclass
= EC_MONORAIL
;
1281 } else if (traction
<= 0x41) {
1282 engclass
= EC_MAGLEV
;
1287 if (_cur
.grffile
->railtype_list
.Length() == 0) {
1288 /* Use traction type to select between normal and electrified
1289 * rail only when no translation list is in place. */
1290 if (_gted
[e
->index
].railtypelabel
== RAILTYPE_RAIL_LABEL
&& engclass
>= EC_ELECTRIC
) _gted
[e
->index
].railtypelabel
= RAILTYPE_ELECTRIC_LABEL
;
1291 if (_gted
[e
->index
].railtypelabel
== RAILTYPE_ELECTRIC_LABEL
&& engclass
< EC_ELECTRIC
) _gted
[e
->index
].railtypelabel
= RAILTYPE_RAIL_LABEL
;
1294 rvi
->engclass
= engclass
;
1298 case 0x1A: // Alter purchase list sort order
1299 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1302 case 0x1B: // Powered wagons power bonus
1303 rvi
->pow_wag_power
= buf
->ReadWord();
1306 case 0x1C: // Refit cost
1307 ei
->refit_cost
= buf
->ReadByte();
1310 case 0x1D: { // Refit cargo
1311 uint32 mask
= buf
->ReadDWord();
1312 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1313 ei
->refit_mask
= TranslateRefitMask(mask
);
1314 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1318 case 0x1E: // Callback
1319 ei
->callback_mask
= buf
->ReadByte();
1322 case PROP_TRAIN_TRACTIVE_EFFORT
: // 0x1F Tractive effort coefficient
1323 rvi
->tractive_effort
= buf
->ReadByte();
1326 case 0x20: // Air drag
1327 rvi
->air_drag
= buf
->ReadByte();
1330 case PROP_TRAIN_SHORTEN_FACTOR
: // 0x21 Shorter vehicle
1331 rvi
->shorten_factor
= buf
->ReadByte();
1334 case 0x22: // Visual effect
1335 rvi
->visual_effect
= buf
->ReadByte();
1336 /* Avoid accidentally setting visual_effect to the default value
1337 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1338 if (rvi
->visual_effect
== VE_DEFAULT
) {
1339 assert(HasBit(rvi
->visual_effect
, VE_DISABLE_EFFECT
));
1340 SB(rvi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1344 case 0x23: // Powered wagons weight bonus
1345 rvi
->pow_wag_weight
= buf
->ReadByte();
1348 case 0x24: { // High byte of vehicle weight
1349 byte weight
= buf
->ReadByte();
1352 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight
<< 8);
1354 SB(rvi
->weight
, 8, 8, weight
);
1359 case PROP_TRAIN_USER_DATA
: // 0x25 User-defined bit mask to set when checking veh. var. 42
1360 rvi
->user_def_data
= buf
->ReadByte();
1363 case 0x26: // Retire vehicle early
1364 ei
->retire_early
= buf
->ReadByte();
1367 case 0x27: // Miscellaneous flags
1368 ei
->misc_flags
= buf
->ReadByte();
1369 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1370 _gted
[e
->index
].prop27_set
= true;
1373 case 0x28: // Cargo classes allowed
1374 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1375 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1376 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1379 case 0x29: // Cargo classes disallowed
1380 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1381 _gted
[e
->index
].UpdateRefittability(false);
1384 case 0x2A: // Long format introduction date (days since year 0)
1385 ei
->base_intro
= buf
->ReadDWord();
1388 case PROP_TRAIN_CARGO_AGE_PERIOD
: // 0x2B Cargo aging period
1389 ei
->cargo_age_period
= buf
->ReadWord();
1392 case 0x2C: // CTT refit include list
1393 case 0x2D: { // CTT refit exclude list
1394 uint8 count
= buf
->ReadByte();
1395 _gted
[e
->index
].UpdateRefittability(prop
== 0x2C && count
!= 0);
1396 if (prop
== 0x2C) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1397 uint32
&ctt
= prop
== 0x2C ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1400 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1401 if (ctype
== CT_INVALID
) continue;
1408 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1417 * Define properties for road vehicles
1418 * @param engine Local ID of the first vehicle.
1419 * @param numinfo Number of subsequent IDs to change the property for.
1420 * @param prop The property to change.
1421 * @param buf The property value.
1422 * @return ChangeInfoResult.
1424 static ChangeInfoResult
RoadVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1426 ChangeInfoResult ret
= CIR_SUCCESS
;
1428 for (int i
= 0; i
< numinfo
; i
++) {
1429 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_ROAD
, engine
+ i
);
1430 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1432 EngineInfo
*ei
= &e
->info
;
1433 RoadVehicleInfo
*rvi
= &e
->u
.road
;
1436 case 0x08: // Speed (1 unit is 0.5 kmh)
1437 rvi
->max_speed
= buf
->ReadByte();
1440 case PROP_ROADVEH_RUNNING_COST_FACTOR
: // 0x09 Running cost factor
1441 rvi
->running_cost
= buf
->ReadByte();
1444 case 0x0A: // Running cost base
1445 ConvertTTDBasePrice(buf
->ReadDWord(), "RoadVehicleChangeInfo", &rvi
->running_cost_class
);
1448 case 0x0E: { // Sprite ID
1449 uint8 spriteid
= buf
->ReadByte();
1450 uint8 orig_spriteid
= spriteid
;
1452 /* cars have different custom id in the GRF file */
1453 if (spriteid
== 0xFF) spriteid
= 0xFD;
1455 if (spriteid
< 0xFD) spriteid
>>= 1;
1457 if (IsValidNewGRFImageIndex
<VEH_ROAD
>(spriteid
)) {
1458 rvi
->image_index
= spriteid
;
1460 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1461 rvi
->image_index
= 0;
1466 case PROP_ROADVEH_CARGO_CAPACITY
: // 0x0F Cargo capacity
1467 rvi
->capacity
= buf
->ReadByte();
1470 case 0x10: { // Cargo type
1471 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1472 uint8 ctype
= buf
->ReadByte();
1474 if (ctype
== 0xFF) {
1475 /* 0xFF is specified as 'use first refittable' */
1476 ei
->cargo_type
= CT_INVALID
;
1477 } else if (_cur
.grffile
->grf_version
>= 8) {
1478 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1479 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1480 } else if (ctype
< NUM_CARGO
) {
1481 /* Use untranslated cargo. */
1482 ei
->cargo_type
= ctype
;
1484 ei
->cargo_type
= CT_INVALID
;
1485 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1490 case PROP_ROADVEH_COST_FACTOR
: // 0x11 Cost factor
1491 rvi
->cost_factor
= buf
->ReadByte();
1495 rvi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1498 case PROP_ROADVEH_POWER
: // Power in units of 10 HP.
1499 rvi
->power
= buf
->ReadByte();
1502 case PROP_ROADVEH_WEIGHT
: // Weight in units of 1/4 tons.
1503 rvi
->weight
= buf
->ReadByte();
1506 case PROP_ROADVEH_SPEED
: // Speed in mph/0.8
1507 _gted
[e
->index
].rv_max_speed
= buf
->ReadByte();
1510 case 0x16: { // Cargoes available for refitting
1511 uint32 mask
= buf
->ReadDWord();
1512 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1513 ei
->refit_mask
= TranslateRefitMask(mask
);
1514 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1518 case 0x17: // Callback mask
1519 ei
->callback_mask
= buf
->ReadByte();
1522 case PROP_ROADVEH_TRACTIVE_EFFORT
: // Tractive effort coefficient in 1/256.
1523 rvi
->tractive_effort
= buf
->ReadByte();
1526 case 0x19: // Air drag
1527 rvi
->air_drag
= buf
->ReadByte();
1530 case 0x1A: // Refit cost
1531 ei
->refit_cost
= buf
->ReadByte();
1534 case 0x1B: // Retire vehicle early
1535 ei
->retire_early
= buf
->ReadByte();
1538 case 0x1C: // Miscellaneous flags
1539 ei
->misc_flags
= buf
->ReadByte();
1540 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1543 case 0x1D: // Cargo classes allowed
1544 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1545 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1546 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1549 case 0x1E: // Cargo classes disallowed
1550 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1551 _gted
[e
->index
].UpdateRefittability(false);
1554 case 0x1F: // Long format introduction date (days since year 0)
1555 ei
->base_intro
= buf
->ReadDWord();
1558 case 0x20: // Alter purchase list sort order
1559 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1562 case 0x21: // Visual effect
1563 rvi
->visual_effect
= buf
->ReadByte();
1564 /* Avoid accidentally setting visual_effect to the default value
1565 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1566 if (rvi
->visual_effect
== VE_DEFAULT
) {
1567 assert(HasBit(rvi
->visual_effect
, VE_DISABLE_EFFECT
));
1568 SB(rvi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1572 case PROP_ROADVEH_CARGO_AGE_PERIOD
: // 0x22 Cargo aging period
1573 ei
->cargo_age_period
= buf
->ReadWord();
1576 case PROP_ROADVEH_SHORTEN_FACTOR
: // 0x23 Shorter vehicle
1577 rvi
->shorten_factor
= buf
->ReadByte();
1580 case 0x24: // CTT refit include list
1581 case 0x25: { // CTT refit exclude list
1582 uint8 count
= buf
->ReadByte();
1583 _gted
[e
->index
].UpdateRefittability(prop
== 0x24 && count
!= 0);
1584 if (prop
== 0x24) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1585 uint32
&ctt
= prop
== 0x24 ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1588 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1589 if (ctype
== CT_INVALID
) continue;
1596 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1605 * Define properties for ships
1606 * @param engine Local ID of the first vehicle.
1607 * @param numinfo Number of subsequent IDs to change the property for.
1608 * @param prop The property to change.
1609 * @param buf The property value.
1610 * @return ChangeInfoResult.
1612 static ChangeInfoResult
ShipVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1614 ChangeInfoResult ret
= CIR_SUCCESS
;
1616 for (int i
= 0; i
< numinfo
; i
++) {
1617 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_SHIP
, engine
+ i
);
1618 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1620 EngineInfo
*ei
= &e
->info
;
1621 ShipVehicleInfo
*svi
= &e
->u
.ship
;
1624 case 0x08: { // Sprite ID
1625 uint8 spriteid
= buf
->ReadByte();
1626 uint8 orig_spriteid
= spriteid
;
1628 /* ships have different custom id in the GRF file */
1629 if (spriteid
== 0xFF) spriteid
= 0xFD;
1631 if (spriteid
< 0xFD) spriteid
>>= 1;
1633 if (IsValidNewGRFImageIndex
<VEH_SHIP
>(spriteid
)) {
1634 svi
->image_index
= spriteid
;
1636 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1637 svi
->image_index
= 0;
1642 case 0x09: // Refittable
1643 svi
->old_refittable
= (buf
->ReadByte() != 0);
1646 case PROP_SHIP_COST_FACTOR
: // 0x0A Cost factor
1647 svi
->cost_factor
= buf
->ReadByte();
1650 case PROP_SHIP_SPEED
: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1651 svi
->max_speed
= buf
->ReadByte();
1654 case 0x0C: { // Cargo type
1655 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1656 uint8 ctype
= buf
->ReadByte();
1658 if (ctype
== 0xFF) {
1659 /* 0xFF is specified as 'use first refittable' */
1660 ei
->cargo_type
= CT_INVALID
;
1661 } else if (_cur
.grffile
->grf_version
>= 8) {
1662 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1663 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1664 } else if (ctype
< NUM_CARGO
) {
1665 /* Use untranslated cargo. */
1666 ei
->cargo_type
= ctype
;
1668 ei
->cargo_type
= CT_INVALID
;
1669 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1674 case PROP_SHIP_CARGO_CAPACITY
: // 0x0D Cargo capacity
1675 svi
->capacity
= buf
->ReadWord();
1678 case PROP_SHIP_RUNNING_COST_FACTOR
: // 0x0F Running cost factor
1679 svi
->running_cost
= buf
->ReadByte();
1683 svi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1686 case 0x11: { // Cargoes available for refitting
1687 uint32 mask
= buf
->ReadDWord();
1688 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1689 ei
->refit_mask
= TranslateRefitMask(mask
);
1690 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1694 case 0x12: // Callback mask
1695 ei
->callback_mask
= buf
->ReadByte();
1698 case 0x13: // Refit cost
1699 ei
->refit_cost
= buf
->ReadByte();
1702 case 0x14: // Ocean speed fraction
1703 svi
->ocean_speed_frac
= buf
->ReadByte();
1706 case 0x15: // Canal speed fraction
1707 svi
->canal_speed_frac
= buf
->ReadByte();
1710 case 0x16: // Retire vehicle early
1711 ei
->retire_early
= buf
->ReadByte();
1714 case 0x17: // Miscellaneous flags
1715 ei
->misc_flags
= buf
->ReadByte();
1716 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1719 case 0x18: // Cargo classes allowed
1720 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1721 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1722 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1725 case 0x19: // Cargo classes disallowed
1726 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1727 _gted
[e
->index
].UpdateRefittability(false);
1730 case 0x1A: // Long format introduction date (days since year 0)
1731 ei
->base_intro
= buf
->ReadDWord();
1734 case 0x1B: // Alter purchase list sort order
1735 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1738 case 0x1C: // Visual effect
1739 svi
->visual_effect
= buf
->ReadByte();
1740 /* Avoid accidentally setting visual_effect to the default value
1741 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1742 if (svi
->visual_effect
== VE_DEFAULT
) {
1743 assert(HasBit(svi
->visual_effect
, VE_DISABLE_EFFECT
));
1744 SB(svi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1748 case PROP_SHIP_CARGO_AGE_PERIOD
: // 0x1D Cargo aging period
1749 ei
->cargo_age_period
= buf
->ReadWord();
1752 case 0x1E: // CTT refit include list
1753 case 0x1F: { // CTT refit exclude list
1754 uint8 count
= buf
->ReadByte();
1755 _gted
[e
->index
].UpdateRefittability(prop
== 0x1E && count
!= 0);
1756 if (prop
== 0x1E) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1757 uint32
&ctt
= prop
== 0x1E ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1760 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1761 if (ctype
== CT_INVALID
) continue;
1768 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1777 * Define properties for aircraft
1778 * @param engine Local ID of the aircraft.
1779 * @param numinfo Number of subsequent IDs to change the property for.
1780 * @param prop The property to change.
1781 * @param buf The property value.
1782 * @return ChangeInfoResult.
1784 static ChangeInfoResult
AircraftVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1786 ChangeInfoResult ret
= CIR_SUCCESS
;
1788 for (int i
= 0; i
< numinfo
; i
++) {
1789 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_AIRCRAFT
, engine
+ i
);
1790 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1792 EngineInfo
*ei
= &e
->info
;
1793 AircraftVehicleInfo
*avi
= &e
->u
.air
;
1796 case 0x08: { // Sprite ID
1797 uint8 spriteid
= buf
->ReadByte();
1798 uint8 orig_spriteid
= spriteid
;
1800 /* aircraft have different custom id in the GRF file */
1801 if (spriteid
== 0xFF) spriteid
= 0xFD;
1803 if (spriteid
< 0xFD) spriteid
>>= 1;
1805 if (IsValidNewGRFImageIndex
<VEH_AIRCRAFT
>(spriteid
)) {
1806 avi
->image_index
= spriteid
;
1808 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1809 avi
->image_index
= 0;
1814 case 0x09: // Helicopter
1815 if (buf
->ReadByte() == 0) {
1816 avi
->subtype
= AIR_HELI
;
1818 SB(avi
->subtype
, 0, 1, 1); // AIR_CTOL
1823 SB(avi
->subtype
, 1, 1, (buf
->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1826 case PROP_AIRCRAFT_COST_FACTOR
: // 0x0B Cost factor
1827 avi
->cost_factor
= buf
->ReadByte();
1830 case PROP_AIRCRAFT_SPEED
: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1831 avi
->max_speed
= (buf
->ReadByte() * 128) / 10;
1834 case 0x0D: // Acceleration
1835 avi
->acceleration
= buf
->ReadByte();
1838 case PROP_AIRCRAFT_RUNNING_COST_FACTOR
: // 0x0E Running cost factor
1839 avi
->running_cost
= buf
->ReadByte();
1842 case PROP_AIRCRAFT_PASSENGER_CAPACITY
: // 0x0F Passenger capacity
1843 avi
->passenger_capacity
= buf
->ReadWord();
1846 case PROP_AIRCRAFT_MAIL_CAPACITY
: // 0x11 Mail capacity
1847 avi
->mail_capacity
= buf
->ReadByte();
1851 avi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1854 case 0x13: { // Cargoes available for refitting
1855 uint32 mask
= buf
->ReadDWord();
1856 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1857 ei
->refit_mask
= TranslateRefitMask(mask
);
1858 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1862 case 0x14: // Callback mask
1863 ei
->callback_mask
= buf
->ReadByte();
1866 case 0x15: // Refit cost
1867 ei
->refit_cost
= buf
->ReadByte();
1870 case 0x16: // Retire vehicle early
1871 ei
->retire_early
= buf
->ReadByte();
1874 case 0x17: // Miscellaneous flags
1875 ei
->misc_flags
= buf
->ReadByte();
1876 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1879 case 0x18: // Cargo classes allowed
1880 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1881 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1882 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1885 case 0x19: // Cargo classes disallowed
1886 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1887 _gted
[e
->index
].UpdateRefittability(false);
1890 case 0x1A: // Long format introduction date (days since year 0)
1891 ei
->base_intro
= buf
->ReadDWord();
1894 case 0x1B: // Alter purchase list sort order
1895 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1898 case PROP_AIRCRAFT_CARGO_AGE_PERIOD
: // 0x1C Cargo aging period
1899 ei
->cargo_age_period
= buf
->ReadWord();
1902 case 0x1D: // CTT refit include list
1903 case 0x1E: { // CTT refit exclude list
1904 uint8 count
= buf
->ReadByte();
1905 _gted
[e
->index
].UpdateRefittability(prop
== 0x1D && count
!= 0);
1906 if (prop
== 0x1D) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1907 uint32
&ctt
= prop
== 0x1D ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1910 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1911 if (ctype
== CT_INVALID
) continue;
1917 case PROP_AIRCRAFT_RANGE
: // 0x1F Max aircraft range
1918 avi
->max_range
= buf
->ReadWord();
1922 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1930 /** Sprite layout for a station tile. */
1931 struct StationTileSpriteLayout
: NewGRFSpriteLayout
, FlexArrayBase
{
1933 template <typename T
>
1934 static CONSTEXPR T
*offset_pointer (void *ptr
, size_t offset
)
1936 return (T
*) (((char*)ptr
) + offset
);
1939 static CONSTEXPR
size_t seq_offset (void)
1941 return ttd_align_up
<DrawTileSeqStruct
> (sizeof(StationTileSpriteLayout
));
1944 StationTileSpriteLayout (const PalSpriteID
&ground
, uint n
,
1945 DrawTileSeqStruct
**pseq
)
1947 this->ground
= ground
;
1949 DrawTileSeqStruct
*q
= offset_pointer
<DrawTileSeqStruct
> (this, seq_offset());
1950 q
[n
].MakeTerminator();
1953 this->registers
= NULL
;
1955 this->consistent_max_offset
= UINT16_MAX
;
1960 StationTileSpriteLayout (const PalSpriteID
&ground
, uint n
,
1961 const DrawTileSeqStruct
*seq
, size_t regs_offset
,
1962 const TileLayoutRegisters
*regs
,
1963 uint consistent_max_offset
)
1965 this->ground
= ground
;
1967 DrawTileSeqStruct
*q
= offset_pointer
<DrawTileSeqStruct
> (this, seq_offset());
1968 memcpy (q
, seq
, n
* sizeof(DrawTileSeqStruct
));
1969 q
[n
].MakeTerminator();
1973 TileLayoutRegisters
*r
= offset_pointer
<TileLayoutRegisters
> (this, regs_offset
);
1974 memcpy (r
, regs
, (n
+ 1) * sizeof(TileLayoutRegisters
));
1975 this->registers
= r
;
1977 this->registers
= NULL
;
1980 this->consistent_max_offset
= consistent_max_offset
;
1983 /** Custom operator new to account for the extra storage. */
1984 void *operator new (size_t size
, size_t total
, size_t = 1)
1986 assert (total
>= size
);
1987 return ::operator new (total
);
1991 static StationTileSpriteLayout
*create (const PalSpriteID
&ground
,
1992 uint n
, const DrawTileSeqStruct
*seq
,
1993 const TileLayoutRegisters
*regs
, uint consistent_max_offset
);
1995 static StationTileSpriteLayout
*clone (const PalSpriteID
&ground
,
1996 const DrawTileSeqStruct
*seq
)
1998 size_t n
= 1; // 1 for the terminator
1999 const DrawTileSeqStruct
*dtss
;
2000 foreach_draw_tile_seq(dtss
, seq
) n
++;
2002 return create (ground
, n
, seq
, NULL
, UINT16_MAX
);
2005 static StationTileSpriteLayout
*clone (const NewGRFSpriteLayout
*src
)
2007 size_t n
= 1; // 1 for the terminator
2008 const DrawTileSeqStruct
*dtss
;
2009 foreach_draw_tile_seq(dtss
, src
->seq
) n
++;
2011 return create (src
->ground
, n
, src
->seq
, src
->registers
,
2012 src
->consistent_max_offset
);
2015 static StationTileSpriteLayout
*init (const PalSpriteID
&ground
,
2016 uint n
, DrawTileSeqStruct
**p
)
2018 /* Make room for terminator. */
2019 size_t seq_end
= seq_offset() + (n
+ 1) * sizeof(DrawTileSeqStruct
);
2020 size_t total_size
= ttd_align_up
<TileLayoutSpriteGroup
> (seq_end
);
2021 return new (total_size
) StationTileSpriteLayout (ground
, n
, p
);
2025 StationTileSpriteLayout
*StationTileSpriteLayout::create (const PalSpriteID
&ground
,
2026 uint n
, const DrawTileSeqStruct
*seq
, const TileLayoutRegisters
*regs
,
2027 uint consistent_max_offset
)
2029 /* Make room for terminator. */
2030 size_t seq_end
= seq_offset() + (n
+ 1) * sizeof(DrawTileSeqStruct
);
2032 size_t regs_offset
, regs_end
;
2034 regs_offset
= ttd_align_up
<TileLayoutRegisters
> (seq_end
);
2035 regs_end
= regs_offset
+ (n
+ 1) * sizeof(TileLayoutRegisters
);
2041 size_t total_size
= ttd_align_up
<TileLayoutSpriteGroup
> (regs_end
);
2042 return new (total_size
) StationTileSpriteLayout (ground
, n
, seq
,
2043 regs_offset
, regs
, consistent_max_offset
);
2047 * Define properties for stations
2048 * @param stdid StationID of the first station tile.
2049 * @param numinfo Number of subsequent station tiles to change the property for.
2050 * @param prop The property to change.
2051 * @param buf The property value.
2052 * @return ChangeInfoResult.
2054 static ChangeInfoResult
StationChangeInfo(uint stid
, int numinfo
, int prop
, ByteReader
*buf
)
2056 ChangeInfoResult ret
= CIR_SUCCESS
;
2058 if (stid
+ numinfo
> NUM_STATIONS_PER_GRF
) {
2059 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid
+ numinfo
, NUM_STATIONS_PER_GRF
);
2060 return CIR_INVALID_ID
;
2063 /* Allocate station specs if necessary */
2064 if (_cur
.grffile
->stations
== NULL
) _cur
.grffile
->stations
= xcalloct
<StationSpec
*>(NUM_STATIONS_PER_GRF
);
2066 for (int i
= 0; i
< numinfo
; i
++) {
2067 StationSpec
*statspec
= _cur
.grffile
->stations
[stid
+ i
];
2069 /* Check that the station we are modifying is defined. */
2070 if (statspec
== NULL
&& prop
!= 0x08) {
2071 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid
+ i
);
2072 return CIR_INVALID_ID
;
2076 case 0x08: { // Class ID
2077 StationSpec
**spec
= &_cur
.grffile
->stations
[stid
+ i
];
2079 /* Property 0x08 is special; it is where the station is allocated */
2080 if (*spec
== NULL
) *spec
= new StationSpec
;
2082 /* Swap classid because we read it in BE meaning WAYP or DFLT */
2083 uint32 classid
= buf
->ReadLabel();
2084 (*spec
)->cls_id
= StationClass::Allocate (classid
);
2088 case 0x09: { // Define sprite layout
2089 statspec
->renderdata
.clear(); // delete earlier loaded stuff
2090 uint n
= buf
->ReadExtendedByte();
2091 statspec
->renderdata
.reserve (n
);
2093 for (uint t
= 0; t
< n
; t
++) {
2094 assert (statspec
->renderdata
.size() == t
);
2096 const byte
*gp
= buf
->GetData (4);
2098 if (ReadDWord (gp
) == 0) {
2099 extern const DrawTileSprites _station_display_datas_rail
[8];
2100 const DrawTileSprites
*src
= &_station_display_datas_rail
[t
% 8];
2101 NewGRFSpriteLayout
*dts
= StationTileSpriteLayout::clone (src
->ground
, src
->seq
);
2102 statspec
->renderdata
.push_back (ttd_unique_ptr
<NewGRFSpriteLayout
> (dts
));
2106 /* On error, bail out immediately. Temporary GRF data was already freed */
2108 ReadPalSprite (gp
, &ground
);
2109 if (!AdjustSpriteLayoutSprite (&ground
, GSF_STATIONS
, false)) {
2110 return CIR_DISABLED
;
2113 const byte
*p
= buf
->GetData();
2114 uint num_building_sprites
= 0;
2115 while (buf
->ReadByte() != 0x80) {
2117 num_building_sprites
++;
2120 DrawTileSeqStruct
*seq
;
2121 NewGRFSpriteLayout
*dts
= StationTileSpriteLayout::init (ground
, num_building_sprites
, &seq
);
2122 statspec
->renderdata
.push_back (ttd_unique_ptr
<NewGRFSpriteLayout
> (dts
));
2123 for (uint i
= 0; i
< num_building_sprites
; i
++) {
2124 /* no relative bounding box support */
2125 DrawTileSeqStruct
*dtss
= &seq
[i
];
2128 dtss
->delta_x
= *p
++;
2129 dtss
->delta_y
= *p
++;
2130 dtss
->delta_z
= *p
++;
2131 dtss
->size_x
= *p
++;
2132 dtss
->size_y
= *p
++;
2133 dtss
->size_z
= *p
++;
2135 /* On error, bail out immediately. Temporary GRF data was already freed */
2136 ReadPalSprite (p
, &dtss
->image
);
2137 if (!AdjustSpriteLayoutSprite (&dtss
->image
, GSF_STATIONS
, true)) {
2138 return CIR_DISABLED
;
2146 case 0x0A: { // Copy sprite layout
2147 byte srcid
= buf
->ReadByte();
2148 const StationSpec
*srcstatspec
= _cur
.grffile
->stations
[srcid
];
2150 if (srcstatspec
== NULL
) {
2151 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid
, stid
+ i
);
2155 statspec
->renderdata
.clear(); // delete earlier loaded stuff
2156 uint n
= srcstatspec
->renderdata
.size();
2157 statspec
->renderdata
.reserve (n
);
2159 for (uint t
= 0; t
< n
; t
++) {
2160 assert (statspec
->renderdata
.size() == t
);
2161 const NewGRFSpriteLayout
*src
= srcstatspec
->renderdata
[t
].get();
2162 NewGRFSpriteLayout
*dts
= StationTileSpriteLayout::clone (src
);
2163 statspec
->renderdata
.push_back (ttd_unique_ptr
<NewGRFSpriteLayout
> (dts
));
2168 case 0x0B: // Callback mask
2169 statspec
->callback_mask
= buf
->ReadByte();
2172 case 0x0C: // Disallowed number of platforms
2173 statspec
->disallowed_platforms
= buf
->ReadByte();
2176 case 0x0D: // Disallowed platform lengths
2177 statspec
->disallowed_lengths
= buf
->ReadByte();
2180 case 0x0E: { // Define custom layout
2181 byte max_length
[256]; // 0 is max width
2182 memset (max_length
, 0, sizeof(max_length
));
2183 byte
&max_width
= max_length
[0];
2185 const byte
*p
= buf
->GetData();
2187 /* Total layout size. */
2190 while (buf
->HasData()) {
2191 byte length
= buf
->ReadByte();
2192 byte number
= buf
->ReadByte();
2194 if (length
== 0 || number
== 0) break;
2196 max_width
= max (max_width
, number
);
2197 max_length
[number
] = max (max_length
[number
], length
);
2199 uint n
= length
* number
;
2204 /* Compute how many pointers we need. */
2205 uint nptr
= max_width
;
2206 for (uint i
= 1; i
<= max_width
; i
++) {
2207 nptr
+= max_length
[i
];
2210 assert_compile (sizeof(void*) == sizeof(byte
*));
2211 assert_compile (sizeof(void*) == sizeof(byte
**));
2213 void **alloc
= (void**) xmalloc (nptr
* sizeof(void*) + max_width
+ size
);
2214 memset (alloc
, 0, nptr
* sizeof(void*));
2216 byte
***layouts
= (byte
***) alloc
;
2217 byte
**q
= (byte
**) (alloc
+ max_width
);
2218 for (uint i
= 1; i
<= max_width
; i
++) {
2219 if (max_length
[i
] != 0) {
2224 assert ((void*)(alloc
+ nptr
) == (void*)q
);
2226 struct delete_free
{
2227 void operator() (void *p
) { free(p
); }
2230 byte
*buffer
= (byte
*) q
;
2231 statspec
->layouts
.reset (layouts
, delete_free());
2232 statspec
->max_layout_length
= buffer
- 1;
2233 statspec
->max_layout_width
= max_width
;
2235 memcpy (buffer
, &max_length
[1], max_width
);
2236 buffer
+= max_width
;
2242 if (length
== 0 || number
== 0) break;
2244 layouts
[number
- 1][length
- 1] = buffer
;
2246 uint n
= length
* number
;
2247 memcpy (buffer
, p
, n
);
2252 assert (p
== buf
->GetData());
2257 case 0x0F: { // Copy custom layout
2258 byte srcid
= buf
->ReadByte();
2259 const StationSpec
*srcstatspec
= _cur
.grffile
->stations
[srcid
];
2261 if (srcstatspec
== NULL
) {
2262 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid
, stid
+ i
);
2266 statspec
->layouts
= srcstatspec
->layouts
;
2267 statspec
->max_layout_length
= srcstatspec
->max_layout_length
;
2268 statspec
->max_layout_width
= srcstatspec
->max_layout_width
;
2272 case 0x10: // Little/lots cargo threshold
2273 statspec
->cargo_threshold
= buf
->ReadWord();
2276 case 0x11: // Pylon placement
2277 statspec
->pylons
= buf
->ReadByte();
2280 case 0x12: // Cargo types for random triggers
2281 statspec
->cargo_triggers
= buf
->ReadDWord();
2282 if (_cur
.grffile
->grf_version
>= 7) {
2283 statspec
->cargo_triggers
= TranslateRefitMask(statspec
->cargo_triggers
);
2287 case 0x13: // General flags
2288 statspec
->flags
= buf
->ReadByte();
2291 case 0x14: // Overhead wire placement
2292 statspec
->wires
= buf
->ReadByte();
2295 case 0x15: // Blocked tiles
2296 statspec
->blocked
= buf
->ReadByte();
2299 case 0x16: // Animation info
2300 statspec
->animation
.frames
= buf
->ReadByte();
2301 statspec
->animation
.status
= buf
->ReadByte();
2304 case 0x17: // Animation speed
2305 statspec
->animation
.speed
= buf
->ReadByte();
2308 case 0x18: // Animation triggers
2309 statspec
->animation
.triggers
= buf
->ReadWord();
2312 case 0x1A: { // Advanced sprite layout
2313 statspec
->renderdata
.clear(); // delete earlier loaded stuff
2314 uint n
= buf
->ReadExtendedByte();
2315 statspec
->renderdata
.reserve (n
);
2317 for (uint t
= 0; t
< n
; t
++) {
2318 assert (statspec
->renderdata
.size() == t
);
2319 uint num_building_sprites
= buf
->ReadByte();
2320 /* On error, bail out immediately. Temporary GRF data was already freed */
2321 SpriteLayoutReader reader
;
2322 if (ReadSpriteLayout (&reader
, buf
, num_building_sprites
, false, GSF_STATIONS
, true, false)) {
2323 return CIR_DISABLED
;
2326 NewGRFSpriteLayout
*dts
= StationTileSpriteLayout::create (reader
.ground
,
2327 reader
.num_building_sprites
, reader
.seq
,
2328 reader
.has_registers
? reader
.regs
: NULL
,
2329 reader
.consistent_max_offset
);
2330 statspec
->renderdata
.push_back (ttd_unique_ptr
<NewGRFSpriteLayout
> (dts
));
2345 * Define properties for water features
2346 * @param id Type of the first water feature.
2347 * @param numinfo Number of subsequent water feature ids to change the property for.
2348 * @param prop The property to change.
2349 * @param buf The property value.
2350 * @return ChangeInfoResult.
2352 static ChangeInfoResult
CanalChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
2354 ChangeInfoResult ret
= CIR_SUCCESS
;
2356 if (id
+ numinfo
> CF_END
) {
2357 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id
+ numinfo
, CF_END
);
2358 return CIR_INVALID_ID
;
2361 for (int i
= 0; i
< numinfo
; i
++) {
2362 CanalProperties
*cp
= &_cur
.grffile
->canal_local_properties
[id
+ i
];
2366 cp
->callback_mask
= buf
->ReadByte();
2370 cp
->flags
= buf
->ReadByte();
2383 * Define properties for bridges
2384 * @param brid BridgeID of the bridge.
2385 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2386 * @param prop The property to change.
2387 * @param buf The property value.
2388 * @return ChangeInfoResult.
2390 static ChangeInfoResult
BridgeChangeInfo(uint brid
, int numinfo
, int prop
, ByteReader
*buf
)
2392 ChangeInfoResult ret
= CIR_SUCCESS
;
2394 if (brid
+ numinfo
> MAX_BRIDGES
) {
2395 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid
+ numinfo
, MAX_BRIDGES
);
2396 return CIR_INVALID_ID
;
2399 for (int i
= 0; i
< numinfo
; i
++) {
2400 BridgeSpec
*bridge
= &_bridge
[brid
+ i
];
2403 case 0x08: { // Year of availability
2404 /* We treat '0' as always available */
2405 byte year
= buf
->ReadByte();
2406 bridge
->avail_year
= (year
> 0 ? ORIGINAL_BASE_YEAR
+ year
: 0);
2410 case 0x09: // Minimum length
2411 bridge
->min_length
= buf
->ReadByte();
2414 case 0x0A: // Maximum length
2415 bridge
->max_length
= buf
->ReadByte();
2416 if (bridge
->max_length
> 16) bridge
->max_length
= 0xFFFF;
2419 case 0x0B: // Cost factor
2420 bridge
->price
= buf
->ReadByte();
2423 case 0x0C: // Maximum speed
2424 bridge
->speed
= buf
->ReadWord();
2427 case 0x0D: { // Bridge sprite tables
2428 byte tableid
= buf
->ReadByte();
2429 byte numtables
= buf
->ReadByte();
2431 if (bridge
->sprite_table
== NULL
) {
2432 /* Allocate memory for sprite table pointers and zero out */
2433 bridge
->sprite_table
= xcalloct
<PalSpriteID
*>(7);
2436 for (; numtables
-- != 0; tableid
++) {
2437 if (tableid
>= 7) { // skip invalid data
2438 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid
);
2443 if (bridge
->sprite_table
[tableid
] == NULL
) {
2444 bridge
->sprite_table
[tableid
] = xmalloct
<PalSpriteID
>(32);
2447 for (byte sprite
= 0; sprite
< 32; sprite
++) {
2448 ReadPalSprite (buf
, &bridge
->sprite_table
[tableid
][sprite
]);
2454 case 0x0E: // Flags; bit 0 - disable far pillars
2455 bridge
->flags
= buf
->ReadByte();
2458 case 0x0F: // Long format year of availability (year since year 0)
2459 bridge
->avail_year
= Clamp(buf
->ReadDWord(), MIN_YEAR
, MAX_YEAR
);
2462 case 0x10: { // purchase string
2463 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2464 if (newone
!= STR_UNDEFINED
) bridge
->material
= newone
;
2468 case 0x11: // description of bridge with rails or roads
2470 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2471 if (newone
!= STR_UNDEFINED
) bridge
->transport_name
[prop
- 0x11] = newone
;
2475 case 0x13: // 16 bits cost multiplier
2476 bridge
->price
= buf
->ReadWord();
2479 case 0x14: // purchase sprite
2480 bridge
->sprite
= buf
->ReadWord();
2481 bridge
->pal
= buf
->ReadWord();
2494 * Ignore a house property
2495 * @param prop Property to read.
2496 * @param buf Property value.
2497 * @return ChangeInfoResult.
2499 static ChangeInfoResult
IgnoreTownHouseProperty(int prop
, ByteReader
*buf
)
2501 static const byte skip
[] = {
2502 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
2503 /* 00 */ 1, 2, 1, 1, 1, 1, 1,
2504 /* 10 */ 2, 1, 2, 2, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 4, 1,
2508 uint k
= prop
- 0x09;
2509 if (k
>= lengthof(skip
)) return CIR_UNKNOWN
;
2512 buf
->Skip (s
!= 0 ? s
: buf
->ReadByte());
2517 * Define properties for houses
2518 * @param hid HouseID of the house.
2519 * @param numinfo Number of subsequent houseIDs to change the property for.
2520 * @param prop The property to change.
2521 * @param buf The property value.
2522 * @return ChangeInfoResult.
2524 static ChangeInfoResult
TownHouseChangeInfo(uint hid
, int numinfo
, int prop
, ByteReader
*buf
)
2526 ChangeInfoResult ret
= CIR_SUCCESS
;
2528 if (hid
+ numinfo
> NUM_HOUSES_PER_GRF
) {
2529 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid
+ numinfo
, NUM_HOUSES_PER_GRF
);
2530 return CIR_INVALID_ID
;
2533 /* Allocate house specs if they haven't been allocated already. */
2534 if (_cur
.grffile
->housespec
== NULL
) {
2535 _cur
.grffile
->housespec
= xcalloct
<HouseSpec
*>(NUM_HOUSES_PER_GRF
);
2538 for (int i
= 0; i
< numinfo
; i
++) {
2539 HouseSpec
*housespec
= _cur
.grffile
->housespec
[hid
+ i
];
2541 if (prop
!= 0x08 && housespec
== NULL
) {
2542 /* If the house property 08 is not yet set, ignore this property */
2543 ChangeInfoResult cir
= IgnoreTownHouseProperty(prop
, buf
);
2544 if (cir
> ret
) ret
= cir
;
2549 case 0x08: { // Substitute building type, and definition of a new house
2550 HouseSpec
**house
= &_cur
.grffile
->housespec
[hid
+ i
];
2551 byte subs_id
= buf
->ReadByte();
2553 if (subs_id
== 0xFF) {
2554 /* Instead of defining a new house, a substitute house id
2555 * of 0xFF disables the old house with the current id. */
2556 HouseSpec::Get(hid
+ i
)->enabled
= false;
2558 } else if (subs_id
>= NEW_HOUSE_OFFSET
) {
2559 /* The substitute id must be one of the original houses. */
2560 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id
, hid
+ i
);
2564 /* Allocate space for this house. */
2565 if (*house
== NULL
) *house
= xcalloct
<HouseSpec
>();
2569 MemCpyT(housespec
, HouseSpec::Get(subs_id
));
2571 housespec
->enabled
= true;
2572 housespec
->grf_prop
.local_id
= hid
+ i
;
2573 housespec
->grf_prop
.subst_id
= subs_id
;
2574 housespec
->grf_prop
.grffile
= _cur
.grffile
;
2575 housespec
->random_colour
[0] = 0x04; // those 4 random colours are the base colour
2576 housespec
->random_colour
[1] = 0x08; // for all new houses
2577 housespec
->random_colour
[2] = 0x0C; // they stand for red, blue, orange and green
2578 housespec
->random_colour
[3] = 0x06;
2580 /* Make sure that the third cargo type is valid in this
2581 * climate. This can cause problems when copying the properties
2582 * of a house that accepts food, where the new house is valid
2583 * in the temperate climate. */
2584 if (!CargoSpec::Get(housespec
->accepts_cargo
[2])->IsValid()) {
2585 housespec
->cargo_acceptance
[2] = 0;
2588 _loaded_newgrf_features
.has_newhouses
= true;
2592 case 0x09: // Building flags
2593 housespec
->building_flags
= (BuildingFlags
)buf
->ReadByte();
2596 case 0x0A: { // Availability years
2597 uint16 years
= buf
->ReadWord();
2598 housespec
->min_year
= GB(years
, 0, 8) > 150 ? MAX_YEAR
: ORIGINAL_BASE_YEAR
+ GB(years
, 0, 8);
2599 housespec
->max_year
= GB(years
, 8, 8) > 150 ? MAX_YEAR
: ORIGINAL_BASE_YEAR
+ GB(years
, 8, 8);
2603 case 0x0B: // Population
2604 housespec
->population
= buf
->ReadByte();
2607 case 0x0C: // Mail generation multiplier
2608 housespec
->mail_generation
= buf
->ReadByte();
2611 case 0x0D: // Passenger acceptance
2612 case 0x0E: // Mail acceptance
2613 housespec
->cargo_acceptance
[prop
- 0x0D] = buf
->ReadByte();
2616 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2617 int8 goods
= buf
->ReadByte();
2619 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2620 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2621 CargoID cid
= (goods
>= 0) ? ((_settings_game
.game_creation
.landscape
== LT_TOYLAND
) ? CT_CANDY
: CT_GOODS
) :
2622 ((_settings_game
.game_creation
.landscape
== LT_TOYLAND
) ? CT_FIZZY_DRINKS
: CT_FOOD
);
2624 /* Make sure the cargo type is valid in this climate. */
2625 if (!CargoSpec::Get(cid
)->IsValid()) goods
= 0;
2627 housespec
->accepts_cargo
[2] = cid
;
2628 housespec
->cargo_acceptance
[2] = abs(goods
); // but we do need positive value here
2632 case 0x10: // Local authority rating decrease on removal
2633 housespec
->remove_rating_decrease
= buf
->ReadWord();
2636 case 0x11: // Removal cost multiplier
2637 housespec
->removal_cost
= buf
->ReadByte();
2640 case 0x12: // Building name ID
2641 AddStringForMapping(buf
->ReadWord(), &housespec
->building_name
);
2644 case 0x13: // Building availability mask
2645 housespec
->building_availability
= (HouseZones
)buf
->ReadWord();
2648 case 0x14: // House callback mask
2649 housespec
->callback_mask
|= buf
->ReadByte();
2652 case 0x15: { // House override byte
2653 byte override
= buf
->ReadByte();
2655 /* The house being overridden must be an original house. */
2656 if (override
>= NEW_HOUSE_OFFSET
) {
2657 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override
, hid
+ i
);
2661 _house_mngr
.Add(hid
+ i
, _cur
.grffile
->grfid
, override
);
2665 case 0x16: // Periodic refresh multiplier
2666 housespec
->processing_time
= min(buf
->ReadByte(), 63);
2669 case 0x17: // Four random colours to use
2670 for (uint j
= 0; j
< 4; j
++) housespec
->random_colour
[j
] = buf
->ReadByte();
2673 case 0x18: // Relative probability of appearing
2674 housespec
->probability
= buf
->ReadByte();
2677 case 0x19: // Extra flags
2678 housespec
->extra_flags
= (HouseExtraFlags
)buf
->ReadByte();
2681 case 0x1A: // Animation frames
2682 housespec
->animation
.frames
= buf
->ReadByte();
2683 housespec
->animation
.status
= GB(housespec
->animation
.frames
, 7, 1);
2684 SB(housespec
->animation
.frames
, 7, 1, 0);
2687 case 0x1B: // Animation speed
2688 housespec
->animation
.speed
= Clamp(buf
->ReadByte(), 2, 16);
2691 case 0x1C: // Class of the building type
2692 housespec
->class_id
= AllocateHouseClassID(buf
->ReadByte(), _cur
.grffile
->grfid
);
2695 case 0x1D: // Callback mask part 2
2696 housespec
->callback_mask
|= (buf
->ReadByte() << 8);
2699 case 0x1E: { // Accepted cargo types
2700 uint32 cargotypes
= buf
->ReadDWord();
2702 /* Check if the cargo types should not be changed */
2703 if (cargotypes
== 0xFFFFFFFF) break;
2705 for (uint j
= 0; j
< 3; j
++) {
2706 /* Get the cargo number from the 'list' */
2707 uint8 cargo_part
= GB(cargotypes
, 8 * j
, 8);
2708 CargoID cargo
= GetCargoTranslation(cargo_part
, _cur
.grffile
);
2710 if (cargo
== CT_INVALID
) {
2711 /* Disable acceptance of invalid cargo type */
2712 housespec
->cargo_acceptance
[j
] = 0;
2714 housespec
->accepts_cargo
[j
] = cargo
;
2720 case 0x1F: // Minimum life span
2721 housespec
->minimum_life
= buf
->ReadByte();
2724 case 0x20: { // Cargo acceptance watch list
2725 byte count
= buf
->ReadByte();
2726 for (byte j
= 0; j
< count
; j
++) {
2727 CargoID cargo
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
2728 if (cargo
!= CT_INVALID
) SetBit(housespec
->watched_cargoes
, cargo
);
2733 case 0x21: // long introduction year
2734 housespec
->min_year
= buf
->ReadWord();
2737 case 0x22: // long maximum year
2738 housespec
->max_year
= buf
->ReadWord();
2751 * Get the language map associated with a given NewGRF and language.
2752 * @param grfid The NewGRF to get the map for.
2753 * @param language_id The (NewGRF) language ID to get the map for.
2754 * @return The LanguageMap, or NULL if it couldn't be found.
2756 /* static */ const LanguageMap
*LanguageMap::GetLanguageMap(uint32 grfid
, uint8 language_id
)
2758 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2759 const GRFFile
*grffile
= GetFileByGRFID(grfid
);
2760 return (grffile
!= NULL
&& grffile
->language_map
!= NULL
&& language_id
< MAX_LANG
) ? &grffile
->language_map
[language_id
] : NULL
;
2764 * Load a cargo- or railtype-translation table.
2765 * @param gvid ID of the global variable. This is basically only checked for zerones.
2766 * @param numinfo Number of subsequent IDs to change the property for.
2767 * @param buf The property value.
2768 * @param [in,out] translation_table Storage location for the translation table.
2769 * @param name Name of the table for debug output.
2770 * @return ChangeInfoResult.
2772 template <typename T
>
2773 static ChangeInfoResult
LoadTranslationTable(uint gvid
, int numinfo
, ByteReader
*buf
, T
&translation_table
, const char *name
)
2776 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name
);
2777 return CIR_INVALID_ID
;
2780 translation_table
.Clear();
2781 for (int i
= 0; i
< numinfo
; i
++) {
2782 *translation_table
.Append() = buf
->ReadLabel();
2788 /** Get the currency spec for a given NewGRF currency index. */
2789 static CurrencySpec
*GetNewgrfCurrencySpec (uint id
)
2791 /* Mapping of NewGRF (TTDPatch) currency indices to ours. */
2792 static const byte ttdp_map
[] = {
2793 CURRENCY_GBP
, CURRENCY_USD
, CURRENCY_FRF
, CURRENCY_DEM
,
2794 CURRENCY_JPY
, CURRENCY_ESP
, CURRENCY_HUF
, CURRENCY_PLN
,
2795 CURRENCY_ATS
, CURRENCY_BEF
, CURRENCY_DKK
, CURRENCY_FIM
,
2796 CURRENCY_GRD
, CURRENCY_CHF
, CURRENCY_NLG
, CURRENCY_ITL
,
2797 CURRENCY_SEK
, CURRENCY_RUR
, CURRENCY_EUR
,
2800 assert_compile (lengthof(ttdp_map
) < CURRENCY_END
);
2802 if (id
< lengthof(ttdp_map
)) {
2804 } else if (id
>= CURRENCY_END
) {
2805 grfmsg (1, "GlobalVarChangeInfo: Currency id %u out of range, ignoring", id
);
2809 return &_currency_specs
[id
];
2813 * Define properties for global variables
2814 * @param gvid ID of the global variable.
2815 * @param numinfo Number of subsequent IDs to change the property for.
2816 * @param prop The property to change.
2817 * @param buf The property value.
2818 * @return ChangeInfoResult.
2820 static ChangeInfoResult
GlobalVarChangeInfo(uint gvid
, int numinfo
, int prop
, ByteReader
*buf
)
2822 /* Properties which are handled as a whole */
2824 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2825 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->cargo_list
, "Cargo");
2827 case 0x10: // Snow line height table
2828 if (numinfo
!= 1 || IsSnowLineSet()) {
2829 grfmsg (1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo
);
2830 } else if (!buf
->HasData (SNOW_LINE_MONTHS
* SNOW_LINE_DAYS
)) {
2831 grfmsg (1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf
->Remaining());
2833 byte table
[SNOW_LINE_MONTHS
][SNOW_LINE_DAYS
];
2835 for (uint i
= 0; i
< SNOW_LINE_MONTHS
; i
++) {
2836 for (uint j
= 0; j
< SNOW_LINE_DAYS
; j
++) {
2837 table
[i
][j
] = buf
->ReadByte();
2838 if (_cur
.grffile
->grf_version
>= 8) {
2839 if (table
[i
][j
] != 0xFF) table
[i
][j
] = table
[i
][j
] * (1 + _settings_game
.construction
.max_heightlevel
) / 256;
2841 if (table
[i
][j
] >= 128) {
2845 table
[i
][j
] = table
[i
][j
] * (1 + _settings_game
.construction
.max_heightlevel
) / 128;
2850 SetSnowLine (table
);
2854 case 0x11: // GRF match for engine allocation
2855 /* This is loaded during the reservation stage,
2856 * so just skip it here. Each entry is 8 bytes. */
2857 buf
->Skip (8 * numinfo
);
2860 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2861 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->railtype_list
, "Rail type");
2867 /* Properties which are handled per item */
2868 ChangeInfoResult ret
= CIR_SUCCESS
;
2869 for (; numinfo
-- > 0; gvid
++) {
2871 case 0x08: { // Cost base factor
2872 int factor
= buf
->ReadByte();
2873 if (gvid
< PR_END
) {
2874 _cur
.grffile
->price_base_multipliers
[gvid
] = min
<int> (factor
- 8, MAX_PRICE_MODIFIER
);
2876 grfmsg (1, "GlobalVarChangeInfo: Price %d out of range, ignoring", gvid
);
2881 case 0x0A: { // Currency display names
2882 CurrencySpec
*cur
= GetNewgrfCurrencySpec (gvid
);
2883 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2885 if ((newone
!= STR_UNDEFINED
) && (cur
!= NULL
)) {
2891 case 0x0B: { // Currency multipliers
2892 CurrencySpec
*cur
= GetNewgrfCurrencySpec (gvid
);
2893 uint32 rate
= buf
->ReadDWord();
2896 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2897 * which OTTD does not. For this reason, divide grf value by 1000,
2898 * to be compatible */
2899 cur
->rate
= rate
/ 1000;
2904 case 0x0C: { // Currency options
2905 CurrencySpec
*cur
= GetNewgrfCurrencySpec (gvid
);
2906 uint16 options
= buf
->ReadWord();
2909 cur
->separator
[0] = GB(options
, 0, 8);
2910 cur
->separator
[1] = '\0';
2911 /* By specifying only one bit, we prevent errors,
2912 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2913 cur
->symbol_pos
= GB(options
, 8, 1);
2918 case 0x0D: // Currency prefix symbol
2919 case 0x0E: { // Currency suffix symbol
2920 CurrencySpec
*cur
= GetNewgrfCurrencySpec (gvid
);
2921 uint32 tempfix
= buf
->ReadDWord();
2924 assert_compile (lengthof(cur
->prefix
) > 4);
2925 assert_compile (lengthof(cur
->suffix
) > 4);
2926 char *s
= (prop
== 0x0E) ? cur
->suffix
: cur
->prefix
;
2927 memcpy (s
, &tempfix
, 4);
2933 case 0x0F: { // Euro introduction dates
2934 CurrencySpec
*cur
= GetNewgrfCurrencySpec (gvid
);
2935 Year year_euro
= buf
->ReadWord();
2938 cur
->to_euro
= year_euro
;
2943 case 0x13: // Gender translation table
2944 case 0x14: // Case translation table
2945 case 0x15: { // Plural form translation
2946 const LanguageMetadata
*lang
= gvid
< MAX_LANG
? GetLanguage(gvid
) : NULL
;
2948 grfmsg (1, "GlobalVarChangeInfo: Language %d is not known, ignoring", gvid
);
2949 /* Skip over the data. */
2953 while (buf
->ReadByte() != 0) {
2960 if (_cur
.grffile
->language_map
== NULL
) _cur
.grffile
->language_map
= new LanguageMap
[MAX_LANG
];
2963 uint plural_form
= buf
->ReadByte();
2964 if (plural_form
>= LANGUAGE_MAX_PLURAL
) {
2965 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form
);
2967 _cur
.grffile
->language_map
[gvid
].plural_form
= plural_form
;
2973 byte newgrf_id
= buf
->ReadByte(); // The NewGRF (custom) identifier.
2974 if (newgrf_id
== 0) break;
2976 const char *name
= buf
->ReadString(); // The name for the OpenTTD identifier.
2978 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2979 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2980 * is just a subset of UTF8, or they need the bigger UTF8 characters
2981 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2982 skip_nfo_utf8_identifier (&name
);
2984 LanguageMap::Mapping map
;
2985 map
.newgrf_id
= newgrf_id
;
2987 map
.openttd_id
= lang
->GetGenderIndex(name
);
2988 if (map
.openttd_id
>= MAX_NUM_GENDERS
) {
2989 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name
);
2991 *_cur
.grffile
->language_map
[gvid
].gender_map
.Append() = map
;
2994 map
.openttd_id
= lang
->GetCaseIndex(name
);
2995 if (map
.openttd_id
>= MAX_NUM_CASES
) {
2996 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name
);
2998 *_cur
.grffile
->language_map
[gvid
].case_map
.Append() = map
;
3014 static ChangeInfoResult
GlobalVarReserveInfo(uint gvid
, int numinfo
, int prop
, ByteReader
*buf
)
3016 /* Properties which are handled as a whole */
3018 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
3019 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->cargo_list
, "Cargo");
3021 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
3022 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->railtype_list
, "Rail type");
3028 /* Properties which are handled per item */
3029 ChangeInfoResult ret
= CIR_SUCCESS
;
3030 for (int i
= 0; i
< numinfo
; i
++) {
3032 case 0x08: // Cost base factor
3033 case 0x15: // Plural form translation
3037 case 0x0A: // Currency display names
3038 case 0x0C: // Currency options
3039 case 0x0F: // Euro introduction dates
3043 case 0x0B: // Currency multipliers
3044 case 0x0D: // Currency prefix symbol
3045 case 0x0E: // Currency suffix symbol
3049 case 0x10: // Snow line height table
3050 buf
->Skip(SNOW_LINE_MONTHS
* SNOW_LINE_DAYS
);
3053 case 0x11: { // GRF match for engine allocation
3054 uint32 s
= buf
->ReadDWord();
3055 uint32 t
= buf
->ReadDWord();
3056 SetNewGRFOverride(s
, t
);
3060 case 0x13: // Gender translation table
3061 case 0x14: // Case translation table
3062 while (buf
->ReadByte() != 0) {
3078 * Define properties for cargoes
3079 * @param cid Local ID of the cargo.
3080 * @param numinfo Number of subsequent IDs to change the property for.
3081 * @param prop The property to change.
3082 * @param buf The property value.
3083 * @return ChangeInfoResult.
3085 static ChangeInfoResult
CargoChangeInfo(uint cid
, int numinfo
, int prop
, ByteReader
*buf
)
3087 ChangeInfoResult ret
= CIR_SUCCESS
;
3089 if (cid
+ numinfo
> NUM_CARGO
) {
3090 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid
+ numinfo
, NUM_CARGO
- 1);
3091 return CIR_INVALID_ID
;
3094 for (int i
= 0; i
< numinfo
; i
++) {
3095 CargoSpec
*cs
= CargoSpec::Get(cid
+ i
);
3098 case 0x08: // Bit number of cargo
3099 cs
->bitnum
= buf
->ReadByte();
3100 if (cs
->IsValid()) {
3101 cs
->grffile
= _cur
.grffile
;
3102 SetBit(_cargo_mask
, cid
+ i
);
3104 ClrBit(_cargo_mask
, cid
+ i
);
3108 case 0x09: // String ID for cargo type name
3109 AddStringForMapping(buf
->ReadWord(), &cs
->name
);
3112 case 0x0A: // String for 1 unit of cargo
3113 AddStringForMapping(buf
->ReadWord(), &cs
->name_single
);
3116 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
3117 case 0x1B: // String for cargo units
3118 /* String for units of cargo. This is different in OpenTTD
3119 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
3120 * Property 1B is used to set OpenTTD's behaviour. */
3121 AddStringForMapping(buf
->ReadWord(), &cs
->units_volume
);
3124 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
3125 case 0x1C: // String for any amount of cargo
3126 /* Strings for an amount of cargo. This is different in OpenTTD
3127 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
3128 * Property 1C is used to set OpenTTD's behaviour. */
3129 AddStringForMapping(buf
->ReadWord(), &cs
->quantifier
);
3132 case 0x0D: // String for two letter cargo abbreviation
3133 AddStringForMapping(buf
->ReadWord(), &cs
->abbrev
);
3136 case 0x0E: // Sprite ID for cargo icon
3137 cs
->sprite
= buf
->ReadWord();
3140 case 0x0F: // Weight of one unit of cargo
3141 cs
->weight
= buf
->ReadByte();
3144 case 0x10: // Used for payment calculation
3145 cs
->transit_days
[0] = buf
->ReadByte();
3148 case 0x11: // Used for payment calculation
3149 cs
->transit_days
[1] = buf
->ReadByte();
3152 case 0x12: // Base cargo price
3153 cs
->initial_payment
= buf
->ReadDWord();
3156 case 0x13: // Colour for station rating bars
3157 cs
->rating_colour
= buf
->ReadByte();
3160 case 0x14: // Colour for cargo graph
3161 cs
->legend_colour
= buf
->ReadByte();
3164 case 0x15: // Freight status
3165 cs
->is_freight
= (buf
->ReadByte() != 0);
3168 case 0x16: // Cargo classes
3169 cs
->classes
= buf
->ReadWord();
3172 case 0x17: // Cargo label
3173 cs
->label
= buf
->ReadLabel();
3176 case 0x18: { // Town growth substitute type
3177 uint8 substitute_type
= buf
->ReadByte();
3179 switch (substitute_type
) {
3180 case 0x00: cs
->town_effect
= TE_PASSENGERS
; break;
3181 case 0x02: cs
->town_effect
= TE_MAIL
; break;
3182 case 0x05: cs
->town_effect
= TE_GOODS
; break;
3183 case 0x09: cs
->town_effect
= TE_WATER
; break;
3184 case 0x0B: cs
->town_effect
= TE_FOOD
; break;
3186 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type
);
3188 case 0xFF: cs
->town_effect
= TE_NONE
; break;
3193 case 0x19: // Town growth coefficient
3194 cs
->multipliertowngrowth
= buf
->ReadWord();
3197 case 0x1A: // Bitmask of callbacks to use
3198 cs
->callback_mask
= buf
->ReadByte();
3201 case 0x1D: // Vehicle capacity muliplier
3202 cs
->multiplier
= max
<uint16
>(1u, buf
->ReadWord());
3216 * Define properties for sound effects
3217 * @param sid Local ID of the sound.
3218 * @param numinfo Number of subsequent IDs to change the property for.
3219 * @param prop The property to change.
3220 * @param buf The property value.
3221 * @return ChangeInfoResult.
3223 static ChangeInfoResult
SoundEffectChangeInfo(uint sid
, int numinfo
, int prop
, ByteReader
*buf
)
3225 ChangeInfoResult ret
= CIR_SUCCESS
;
3227 if (_cur
.grffile
->sound_offset
== 0) {
3228 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3229 return CIR_INVALID_ID
;
3232 if (sid
+ numinfo
- ORIGINAL_SAMPLE_COUNT
> _cur
.grffile
->num_sounds
) {
3233 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid
+ numinfo
, ORIGINAL_SAMPLE_COUNT
+ _cur
.grffile
->num_sounds
);
3234 return CIR_INVALID_ID
;
3237 for (int i
= 0; i
< numinfo
; i
++) {
3238 SoundEntry
*sound
= GetSound(sid
+ i
+ _cur
.grffile
->sound_offset
- ORIGINAL_SAMPLE_COUNT
);
3241 case 0x08: // Relative volume
3242 sound
->volume
= buf
->ReadByte();
3245 case 0x09: // Priority
3246 sound
->priority
= buf
->ReadByte();
3249 case 0x0A: { // Override old sound
3250 SoundID orig_sound
= buf
->ReadByte();
3252 if (orig_sound
>= ORIGINAL_SAMPLE_COUNT
) {
3253 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound
, ORIGINAL_SAMPLE_COUNT
);
3255 SoundEntry
*old_sound
= GetSound(orig_sound
);
3257 /* Literally copy the data of the new sound over the original */
3258 *old_sound
= *sound
;
3273 * Ignore an industry tile property
3274 * @param prop The property to ignore.
3275 * @param buf The property value.
3276 * @return ChangeInfoResult.
3278 static ChangeInfoResult
IgnoreIndustryTileProperty(int prop
, ByteReader
*buf
)
3280 static const byte skip
[] = {
3281 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
3282 /* 00 */ 1, 2, 2, 2, 1, 1, 2,
3286 uint k
= prop
- 0x09;
3287 if (k
>= lengthof(skip
)) return CIR_UNKNOWN
;
3295 * Define properties for industry tiles
3296 * @param indtid Local ID of the industry tile.
3297 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3298 * @param prop The property to change.
3299 * @param buf The property value.
3300 * @return ChangeInfoResult.
3302 static ChangeInfoResult
IndustrytilesChangeInfo(uint indtid
, int numinfo
, int prop
, ByteReader
*buf
)
3304 ChangeInfoResult ret
= CIR_SUCCESS
;
3306 if (indtid
+ numinfo
> NUM_INDUSTRYTILES_PER_GRF
) {
3307 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid
+ numinfo
, NUM_INDUSTRYTILES_PER_GRF
);
3308 return CIR_INVALID_ID
;
3311 /* Allocate industry tile specs if they haven't been allocated already. */
3312 if (_cur
.grffile
->indtspec
== NULL
) {
3313 _cur
.grffile
->indtspec
= xcalloct
<IndustryTileSpec
*>(NUM_INDUSTRYTILES_PER_GRF
);
3316 for (int i
= 0; i
< numinfo
; i
++) {
3317 IndustryTileSpec
*tsp
= _cur
.grffile
->indtspec
[indtid
+ i
];
3319 if (prop
!= 0x08 && tsp
== NULL
) {
3320 ChangeInfoResult cir
= IgnoreIndustryTileProperty(prop
, buf
);
3321 if (cir
> ret
) ret
= cir
;
3326 case 0x08: { // Substitute industry tile type
3327 byte subs_id
= buf
->ReadByte();
3329 if (subs_id
>= NEW_INDUSTRYTILEOFFSET
) {
3330 /* The substitute id must be one of the original industry tile. */
3331 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id
, indtid
+ i
);
3335 /* Allocate space for this industry. */
3337 tsp
= xmemdupt (&_industry_tile_specs
[subs_id
]);
3338 _cur
.grffile
->indtspec
[indtid
+ i
] = tsp
;
3340 tsp
->enabled
= true;
3342 /* A copied tile should not have the animation infos copied too.
3343 * The anim_state should be left untouched, though
3344 * It is up to the author to animate them himself */
3345 tsp
->anim_production
= INDUSTRYTILE_NOANIM
;
3346 tsp
->anim_next
= INDUSTRYTILE_NOANIM
;
3348 tsp
->grf_prop
.local_id
= indtid
+ i
;
3349 tsp
->grf_prop
.subst_id
= subs_id
;
3350 tsp
->grf_prop
.grffile
= _cur
.grffile
;
3351 _industile_mngr
.AddEntityID(indtid
+ i
, _cur
.grffile
->grfid
, subs_id
); // pre-reserve the tile slot
3356 case 0x09: { // Industry tile override
3357 byte ovrid
= buf
->ReadByte();
3359 /* The industry being overridden must be an original industry. */
3360 if (ovrid
>= NEW_INDUSTRYTILEOFFSET
) {
3361 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid
, indtid
+ i
);
3365 _industile_mngr
.Add(indtid
+ i
, _cur
.grffile
->grfid
, ovrid
);
3369 case 0x0A: // Tile acceptance
3372 uint16 acctp
= buf
->ReadWord();
3373 tsp
->accepts_cargo
[prop
- 0x0A] = GetCargoTranslation(GB(acctp
, 0, 8), _cur
.grffile
);
3374 tsp
->acceptance
[prop
- 0x0A] = GB(acctp
, 8, 8);
3378 case 0x0D: // Land shape flags
3379 tsp
->slopes_refused
= (Slope
)buf
->ReadByte();
3382 case 0x0E: // Callback mask
3383 tsp
->callback_mask
= buf
->ReadByte();
3386 case 0x0F: // Animation information
3387 tsp
->animation
.frames
= buf
->ReadByte();
3388 tsp
->animation
.status
= buf
->ReadByte();
3391 case 0x10: // Animation speed
3392 tsp
->animation
.speed
= buf
->ReadByte();
3395 case 0x11: // Triggers for callback 25
3396 tsp
->animation
.triggers
= buf
->ReadByte();
3399 case 0x12: // Special flags
3400 tsp
->special_flags
= (IndustryTileSpecialFlags
)buf
->ReadByte();
3413 * Ignore an industry property
3414 * @param prop The property to ignore.
3415 * @param buf The property value.
3416 * @return ChangeInfoResult.
3418 static ChangeInfoResult
IgnoreIndustryProperty(int prop
, ByteReader
*buf
)
3421 for (byte j
= buf
->ReadByte(); j
> 0; j
--) {
3422 for (uint k
= 0;; k
++) {
3423 byte x
= buf
->ReadByte();
3424 if (x
== 0xFE && k
== 0) {
3430 byte y
= buf
->ReadByte();
3431 if (x
== 0 && y
== 0x80) break;
3433 byte gfx
= buf
->ReadByte();
3434 if (gfx
== 0xFE) buf
->ReadWord();
3440 static const byte skip
[] = {
3441 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
3442 /* 00 */ 1, 0, 1, 2, 2, 2, 1,
3443 /* 10 */ 2, 4, 1, 1, 1, 0, 3, 1, 1, 1, 4, 2, 4, 4, 4, 2,
3444 /* 20 */ 4, 1, 1, 4, 2,
3447 uint k
= prop
- 0x09;
3448 if (k
>= lengthof(skip
)) return CIR_UNKNOWN
;
3451 buf
->Skip (s
!= 0 ? s
: buf
->ReadByte());
3456 * Validate the industry layout; e.g. to prevent duplicate tiles.
3457 * @param layout The layout to check.
3458 * @param size The size of the layout.
3459 * @return True if the layout is deemed valid.
3461 static bool ValidateIndustryLayout(const IndustryTileTable
*layout
, int size
)
3463 for (int i
= 0; i
< size
- 1; i
++) {
3464 for (int j
= i
+ 1; j
< size
; j
++) {
3465 if (layout
[i
].ti
.x
== layout
[j
].ti
.x
&&
3466 layout
[i
].ti
.y
== layout
[j
].ti
.y
) {
3474 /** Clean the tile table of the IndustrySpec if it's needed. */
3475 static void CleanIndustryTileTable(IndustrySpec
*ind
)
3477 if (HasBit(ind
->cleanup_flag
, CLEAN_TILELAYOUT
) && ind
->table
!= NULL
) {
3484 * Define properties for industries
3485 * @param indid Local ID of the industry.
3486 * @param numinfo Number of subsequent industry IDs to change the property for.
3487 * @param prop The property to change.
3488 * @param buf The property value.
3489 * @return ChangeInfoResult.
3491 static ChangeInfoResult
IndustriesChangeInfo(uint indid
, int numinfo
, int prop
, ByteReader
*buf
)
3493 ChangeInfoResult ret
= CIR_SUCCESS
;
3495 if (indid
+ numinfo
> NUM_INDUSTRYTYPES_PER_GRF
) {
3496 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid
+ numinfo
, NUM_INDUSTRYTYPES_PER_GRF
);
3497 return CIR_INVALID_ID
;
3500 /* Allocate industry specs if they haven't been allocated already. */
3501 if (_cur
.grffile
->industryspec
== NULL
) {
3502 _cur
.grffile
->industryspec
= xcalloct
<IndustrySpec
*>(NUM_INDUSTRYTYPES_PER_GRF
);
3505 for (int i
= 0; i
< numinfo
; i
++) {
3506 IndustrySpec
*indsp
= _cur
.grffile
->industryspec
[indid
+ i
];
3508 if (prop
!= 0x08 && indsp
== NULL
) {
3509 ChangeInfoResult cir
= IgnoreIndustryProperty(prop
, buf
);
3510 if (cir
> ret
) ret
= cir
;
3515 case 0x08: { // Substitute industry type
3516 byte subs_id
= buf
->ReadByte();
3518 if (subs_id
== 0xFF) {
3519 /* Instead of defining a new industry, a substitute industry id
3520 * of 0xFF disables the old industry with the current id. */
3521 _industry_specs
[indid
+ i
].enabled
= false;
3523 } else if (subs_id
>= NEW_INDUSTRYOFFSET
) {
3524 /* The substitute id must be one of the original industry. */
3525 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id
, indid
+ i
);
3529 /* Allocate space for this industry.
3530 * Only need to do it once. If ever it is called again, it should not
3532 if (indsp
== NULL
) {
3533 indsp
= xmemdupt (&_origin_industry_specs
[subs_id
]);
3534 _cur
.grffile
->industryspec
[indid
+ i
] = indsp
;
3536 indsp
->enabled
= true;
3537 indsp
->grf_prop
.local_id
= indid
+ i
;
3538 indsp
->grf_prop
.subst_id
= subs_id
;
3539 indsp
->grf_prop
.grffile
= _cur
.grffile
;
3540 /* If the grf industry needs to check its surounding upon creation, it should
3541 * rely on callbacks, not on the original placement functions */
3542 indsp
->check_proc
= CHECK_NOTHING
;
3547 case 0x09: { // Industry type override
3548 byte ovrid
= buf
->ReadByte();
3550 /* The industry being overridden must be an original industry. */
3551 if (ovrid
>= NEW_INDUSTRYOFFSET
) {
3552 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid
, indid
+ i
);
3555 indsp
->grf_prop
.override
= ovrid
;
3556 _industry_mngr
.Add(indid
+ i
, _cur
.grffile
->grfid
, ovrid
);
3560 case 0x0A: { // Set industry layout(s)
3565 size_t total_tiles
= 0;
3567 byte new_num_layouts
= buf
->ReadByte(); // Number of layaouts
3568 /* Discard total size in bytes. */
3571 for (byte j
= 0; j
< new_num_layouts
; j
++) {
3572 const byte
*p
= buf
->GetData (2);
3576 /* This means we have to borrow the layout from an old industry */
3579 /* Count the number of tiles. */
3581 for (; (p
[0] != 0) || (p
[1] != 0x80); size
++) {
3582 byte gfx
= buf
->ReadByte();
3586 p
= buf
->GetData (2);
3588 layouts
[j
].size
= size
;
3589 total_tiles
+= size
+ 1;
3593 size_t table_offset
= ttd_align_up
<IndustryTileTable
> (new_num_layouts
* sizeof(IndustryTileTable
*));
3594 void *alloc
= malloc (table_offset
+ (total_tiles
* sizeof(IndustryTileTable
)));
3595 memset (alloc
, 0, new_num_layouts
* sizeof(IndustryTileTable
*));
3596 const IndustryTileTable
**tile_table
= (const IndustryTileTable
**) alloc
;
3597 IndustryTileTable
*itt
= (IndustryTileTable
*) (((char*)alloc
) + table_offset
);
3598 assert ((void*)itt
>= (void*)(tile_table
+ new_num_layouts
));
3600 uint n
= 0; // Count number of valid layouts
3601 for (byte j
= 0; j
< new_num_layouts
; j
++) {
3602 const byte
*p
= layouts
[j
].p
;
3605 /* This means we have to borrow the layout from an old industry */
3606 IndustryType type
= p
[1]; // industry holding required layout
3607 byte laynbr
= p
[2]; // layout number to borrow
3608 tile_table
[n
++] = _origin_industry_specs
[type
].table
[laynbr
];
3610 tile_table
[n
] = itt
;
3611 for (size_t k
= layouts
[j
].size
; k
-- > 0; itt
++) {
3612 assert (p
[0] != 0 || p
[1] != 0x80);
3613 itt
->ti
.x
= *p
++; // Offsets from northermost tile
3617 if (itt
->gfx
== 0xFE) {
3618 /* Use a new tile from this GRF */
3619 int local_tile_id
= ReadWord (p
);
3622 /* Read the ID from the _industile_mngr. */
3623 int tempid
= _industile_mngr
.GetID(local_tile_id
, _cur
.grffile
->grfid
);
3625 if (tempid
== INVALID_INDUSTRYTILE
) {
3626 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id
, indid
);
3628 /* Declared as been valid, can be used */
3631 } else if (itt
->gfx
== 0xFF) {
3632 itt
->ti
.x
= (int8
)GB(itt
->ti
.x
, 0, 8);
3633 itt
->ti
.y
= (int8
)GB(itt
->ti
.y
, 0, 8);
3635 /* When there were only 256x256 maps, TileIndex was a uint16 and
3636 * itt->ti was just a TileIndexDiff that was added to it.
3637 * As such negative "x" values were shifted into the "y" position.
3638 * x = -1, y = 1 -> x = 255, y = 0
3639 * Since GRF version 8 the position is interpreted as pair of independent int8.
3640 * For GRF version < 8 we need to emulate the old shifting behaviour.
3642 if (_cur
.grffile
->grf_version
< 8 && itt
->ti
.x
< 0) itt
->ti
.y
+= 1;
3646 /* Append terminator. */
3648 assert (p
[1] == 0x80);
3654 if (!ValidateIndustryLayout (tile_table
[n
], layouts
[j
].size
+ 1)) {
3655 /* The industry layout was not valid, so skip this one. */
3656 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid
);
3663 /* Clean the tile table if it was already set by a previous prop A. */
3664 CleanIndustryTileTable(indsp
);
3665 /* Install final layout construction in the industry spec */
3666 indsp
->num_table
= n
;
3667 indsp
->table
= tile_table
;
3668 SetBit(indsp
->cleanup_flag
, CLEAN_TILELAYOUT
);
3672 case 0x0B: // Industry production flags
3673 indsp
->life_type
= (IndustryLifeType
)buf
->ReadByte();
3676 case 0x0C: // Industry closure message
3677 AddStringForMapping(buf
->ReadWord(), &indsp
->closure_text
);
3680 case 0x0D: // Production increase message
3681 AddStringForMapping(buf
->ReadWord(), &indsp
->production_up_text
);
3684 case 0x0E: // Production decrease message
3685 AddStringForMapping(buf
->ReadWord(), &indsp
->production_down_text
);
3688 case 0x0F: // Fund cost multiplier
3689 indsp
->cost_multiplier
= buf
->ReadByte();
3692 case 0x10: // Production cargo types
3693 for (byte j
= 0; j
< 2; j
++) {
3694 indsp
->produced_cargo
[j
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3698 case 0x11: // Acceptance cargo types
3699 for (byte j
= 0; j
< 3; j
++) {
3700 indsp
->accepts_cargo
[j
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3702 buf
->ReadByte(); // Unnused, eat it up
3705 case 0x12: // Production multipliers
3707 indsp
->production_rate
[prop
- 0x12] = buf
->ReadByte();
3710 case 0x14: // Minimal amount of cargo distributed
3711 indsp
->minimal_cargo
= buf
->ReadByte();
3714 case 0x15: { // Random sound effects
3715 indsp
->number_of_sounds
= buf
->ReadByte();
3716 uint8
*sounds
= buf
->Dup (indsp
->number_of_sounds
);
3718 if (HasBit(indsp
->cleanup_flag
, CLEAN_RANDOMSOUNDS
)) {
3719 free(indsp
->random_sounds
);
3721 indsp
->random_sounds
= sounds
;
3722 SetBit(indsp
->cleanup_flag
, CLEAN_RANDOMSOUNDS
);
3726 case 0x16: // Conflicting industry types
3727 for (byte j
= 0; j
< 3; j
++) indsp
->conflicting
[j
] = buf
->ReadByte();
3730 case 0x17: // Probability in random game
3731 indsp
->appear_creation
[_settings_game
.game_creation
.landscape
] = buf
->ReadByte();
3734 case 0x18: // Probability during gameplay
3735 indsp
->appear_ingame
[_settings_game
.game_creation
.landscape
] = buf
->ReadByte();
3738 case 0x19: // Map colour
3739 indsp
->map_colour
= buf
->ReadByte();
3742 case 0x1A: // Special industry flags to define special behavior
3743 indsp
->behaviour
= (IndustryBehaviour
)buf
->ReadDWord();
3746 case 0x1B: // New industry text ID
3747 AddStringForMapping(buf
->ReadWord(), &indsp
->new_industry_text
);
3750 case 0x1C: // Input cargo multipliers for the three input cargo types
3753 uint32 multiples
= buf
->ReadDWord();
3754 indsp
->input_cargo_multiplier
[prop
- 0x1C][0] = GB(multiples
, 0, 16);
3755 indsp
->input_cargo_multiplier
[prop
- 0x1C][1] = GB(multiples
, 16, 16);
3759 case 0x1F: // Industry name
3760 AddStringForMapping(buf
->ReadWord(), &indsp
->name
);
3763 case 0x20: // Prospecting success chance
3764 indsp
->prospecting_chance
= buf
->ReadDWord();
3767 case 0x21: // Callback mask
3768 case 0x22: { // Callback additional mask
3769 byte aflag
= buf
->ReadByte();
3770 SB(indsp
->callback_mask
, (prop
- 0x21) * 8, 8, aflag
);
3774 case 0x23: // removal cost multiplier
3775 indsp
->removal_cost_multiplier
= buf
->ReadDWord();
3778 case 0x24: { // name for nearby station
3779 uint16 str
= buf
->ReadWord();
3781 indsp
->station_name
= STR_NULL
;
3783 AddStringForMapping(str
, &indsp
->station_name
);
3798 * Clone an AirportSpec.
3799 * @param src The AirportSpec to clone.
3800 * @return A fresh copy of the AirportSpec
3802 static AirportSpec
*CloneAirportSpec (const AirportSpec
*src
)
3804 AirportSpec
*as
= xmemdupt (src
);
3806 AirportTileTable
**table_list
= xmalloct
<AirportTileTable
*> (src
->num_table
);
3807 for (uint i
= 0; i
< src
->num_table
; i
++) {
3809 const AirportTileTable
*it
= src
->table
[i
];
3812 } while ((++it
)->ti
.x
!= -0x80);
3813 table_list
[i
] = xmemdupt (src
->table
[i
], num_tiles
);
3815 as
->table
= table_list
;
3821 * Define properties for airports
3822 * @param airport Local ID of the airport.
3823 * @param numinfo Number of subsequent airport IDs to change the property for.
3824 * @param prop The property to change.
3825 * @param buf The property value.
3826 * @return ChangeInfoResult.
3828 static ChangeInfoResult
AirportChangeInfo(uint airport
, int numinfo
, int prop
, ByteReader
*buf
)
3830 ChangeInfoResult ret
= CIR_SUCCESS
;
3832 if (airport
+ numinfo
> NUM_AIRPORTS_PER_GRF
) {
3833 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport
+ numinfo
, NUM_AIRPORTS_PER_GRF
);
3834 return CIR_INVALID_ID
;
3837 /* Allocate industry specs if they haven't been allocated already. */
3838 if (_cur
.grffile
->airportspec
== NULL
) {
3839 _cur
.grffile
->airportspec
= xcalloct
<AirportSpec
*>(NUM_AIRPORTS_PER_GRF
);
3842 for (int i
= 0; i
< numinfo
; i
++) {
3843 AirportSpec
*as
= _cur
.grffile
->airportspec
[airport
+ i
];
3845 if (as
== NULL
&& prop
!= 0x08 && prop
!= 0x09) {
3846 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport
+ i
);
3847 return CIR_INVALID_ID
;
3851 case 0x08: { // Modify original airport
3852 byte subs_id
= buf
->ReadByte();
3854 if (subs_id
== 0xFF) {
3855 /* Instead of defining a new airport, an airport id
3856 * of 0xFF disables the old airport with the current id. */
3857 AirportSpec::GetWithoutOverride(airport
+ i
)->enabled
= false;
3859 } else if (subs_id
>= NEW_AIRPORT_OFFSET
) {
3860 /* The substitute id must be one of the original airports. */
3861 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id
, airport
+ i
);
3865 /* Allocate space for this airport.
3866 * Only need to do it once. If ever it is called again, it should not
3869 as
= CloneAirportSpec (AirportSpec::GetWithoutOverride(subs_id
));
3870 _cur
.grffile
->airportspec
[airport
+ i
] = as
;
3873 as
->grf_prop
.local_id
= airport
+ i
;
3874 as
->grf_prop
.subst_id
= subs_id
;
3875 as
->grf_prop
.grffile
= _cur
.grffile
;
3876 /* override the default airport */
3877 _airport_mngr
.Add(airport
+ i
, _cur
.grffile
->grfid
, subs_id
);
3882 case 0x0A: { // Set airport layout
3888 uint new_num_layouts
= buf
->ReadByte(); // Number of layouts
3889 buf
->Skip (4); // Total size of the definition
3891 for (uint j
= 0; j
< new_num_layouts
; j
++) {
3892 /* First byte is rotation. */
3893 const byte
*p
= buf
->GetData (3);
3896 /* Count the number of tiles. */
3898 for (; (p
[0] != 0) || (p
[1] != 0x80); size
++) {
3899 byte gfx
= buf
->ReadByte();
3903 p
= buf
->GetData (2);
3905 layouts
[j
].size
= size
;
3908 as
->num_table
= new_num_layouts
; // Number of layouts
3909 AirportTileTable
**tile_table
= xcalloct
<AirportTileTable
*>(as
->num_table
); // Table with tiles to compose the airport
3911 for (uint j
= 0; j
< as
->num_table
; j
++) {
3912 const byte
*p
= layouts
[j
].p
;
3913 size_t size
= layouts
[j
].size
;
3914 AirportTileTable
*att
= xmalloct
<AirportTileTable
> (size
+ 1);
3915 att
->rotation
= *p
++;
3917 for (size_t k
= 0; k
< size
; k
++) {
3918 assert (p
[0] != 0 || p
[1] != 0x80);
3919 att
[k
].ti
.x
= *p
++; // Offsets from northermost tile
3923 if (att
[k
].gfx
== 0xFE) {
3924 /* Use a new tile from this GRF */
3925 int local_tile_id
= ReadWord (p
);
3928 /* Read the ID from the _airporttile_mngr. */
3929 uint16 tempid
= _airporttile_mngr
.GetID (local_tile_id
, _cur
.grffile
->grfid
);
3931 if (tempid
== INVALID_AIRPORTTILE
) {
3932 grfmsg (2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id
, airport
+ i
);
3934 /* Declared as been valid, can be used */
3935 att
[k
].gfx
= tempid
;
3937 } else if (att
[k
].gfx
== 0xFF) {
3938 att
[k
].ti
.x
= (int8
)GB(att
[k
].ti
.x
, 0, 8);
3939 att
[k
].ti
.y
= (int8
)GB(att
[k
].ti
.y
, 0, 8);
3942 if (att
->rotation
== DIR_E
|| att
->rotation
== DIR_W
) {
3943 as
->size_x
= max
<byte
> (as
->size_x
, att
[k
].ti
.y
+ 1);
3944 as
->size_y
= max
<byte
> (as
->size_y
, att
[k
].ti
.x
+ 1);
3946 as
->size_x
= max
<byte
> (as
->size_x
, att
[k
].ti
.x
+ 1);
3947 as
->size_y
= max
<byte
> (as
->size_y
, att
[k
].ti
.y
+ 1);
3951 /* Append terminator. */
3953 assert (p
[1] == 0x80);
3954 att
[size
].ti
.x
= -0x80;
3958 tile_table
[j
] = att
;
3961 /* Install final layout construction in the airport spec */
3962 as
->table
= tile_table
;
3967 as
->min_year
= buf
->ReadWord();
3968 as
->max_year
= buf
->ReadWord();
3969 if (as
->max_year
== 0xFFFF) as
->max_year
= MAX_YEAR
;
3973 as
->ttd_airport_type
= (TTDPAirportType
)buf
->ReadByte();
3977 as
->catchment
= Clamp(buf
->ReadByte(), 1, MAX_CATCHMENT
);
3981 as
->noise_level
= buf
->ReadByte();
3985 AddStringForMapping(buf
->ReadWord(), &as
->name
);
3988 case 0x11: // Maintenance cost factor
3989 as
->maintenance_cost
= buf
->ReadWord();
4002 * Ignore properties for objects
4003 * @param prop The property to ignore.
4004 * @param buf The property value.
4005 * @return ChangeInfoResult.
4007 static ChangeInfoResult
IgnoreObjectProperty(uint prop
, ByteReader
*buf
)
4009 static const byte skip
[] = {
4010 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
4011 /* 00 */ 4, 2, 2, 1, 1, 1, 4, 4,
4012 /* 10 */ 2, 2, 1, 2, 1, 2, 1, 1,
4015 uint k
= prop
- 0x08;
4016 if (k
>= lengthof(skip
)) return CIR_UNKNOWN
;
4024 * Define properties for objects
4025 * @param id Local ID of the object.
4026 * @param numinfo Number of subsequent objectIDs to change the property for.
4027 * @param prop The property to change.
4028 * @param buf The property value.
4029 * @return ChangeInfoResult.
4031 static ChangeInfoResult
ObjectChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4033 ChangeInfoResult ret
= CIR_SUCCESS
;
4035 if (id
+ numinfo
> NUM_OBJECTS_PER_GRF
) {
4036 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id
+ numinfo
, NUM_OBJECTS_PER_GRF
);
4037 return CIR_INVALID_ID
;
4040 /* Allocate object specs if they haven't been allocated already. */
4041 if (_cur
.grffile
->objectspec
== NULL
) {
4042 _cur
.grffile
->objectspec
= xcalloct
<ObjectSpec
*>(NUM_OBJECTS_PER_GRF
);
4045 for (int i
= 0; i
< numinfo
; i
++) {
4046 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[id
+ i
];
4048 if (prop
!= 0x08 && spec
== NULL
) {
4049 /* If the object property 08 is not yet set, ignore this property */
4050 ChangeInfoResult cir
= IgnoreObjectProperty(prop
, buf
);
4051 if (cir
> ret
) ret
= cir
;
4056 case 0x08: { // Class ID
4057 ObjectSpec
**ospec
= &_cur
.grffile
->objectspec
[id
+ i
];
4059 /* Allocate space for this object. */
4060 if (*ospec
== NULL
) {
4061 *ospec
= xcalloct
<ObjectSpec
>();
4062 (*ospec
)->views
= 1; // Default for NewGRFs that don't set it.
4065 /* Swap classid because we read it in BE. */
4066 uint32 classid
= buf
->ReadLabel();
4067 (*ospec
)->cls_id
= ObjectClass::Allocate (classid
);
4068 (*ospec
)->enabled
= true;
4072 case 0x09: { // Class name
4073 ObjectClass
*objclass
= ObjectClass::Get(spec
->cls_id
);
4074 AddStringForMapping(buf
->ReadWord(), &objclass
->name
);
4078 case 0x0A: // Object name
4079 AddStringForMapping(buf
->ReadWord(), &spec
->name
);
4082 case 0x0B: // Climate mask
4083 spec
->climate
= buf
->ReadByte();
4087 spec
->size
= buf
->ReadByte();
4090 case 0x0D: // Build cost multipler
4091 spec
->build_cost_multiplier
= buf
->ReadByte();
4092 spec
->clear_cost_multiplier
= spec
->build_cost_multiplier
;
4095 case 0x0E: // Introduction date
4096 spec
->introduction_date
= buf
->ReadDWord();
4099 case 0x0F: // End of life
4100 spec
->end_of_life_date
= buf
->ReadDWord();
4104 spec
->flags
= (ObjectFlags
)buf
->ReadWord();
4105 _loaded_newgrf_features
.has_2CC
|= (spec
->flags
& OBJECT_FLAG_2CC_COLOUR
) != 0;
4108 case 0x11: // Animation info
4109 spec
->animation
.frames
= buf
->ReadByte();
4110 spec
->animation
.status
= buf
->ReadByte();
4113 case 0x12: // Animation speed
4114 spec
->animation
.speed
= buf
->ReadByte();
4117 case 0x13: // Animation triggers
4118 spec
->animation
.triggers
= buf
->ReadWord();
4121 case 0x14: // Removal cost multiplier
4122 spec
->clear_cost_multiplier
= buf
->ReadByte();
4125 case 0x15: // Callback mask
4126 spec
->callback_mask
= buf
->ReadWord();
4129 case 0x16: // Building height
4130 spec
->height
= buf
->ReadByte();
4134 spec
->views
= buf
->ReadByte();
4135 if (spec
->views
!= 1 && spec
->views
!= 2 && spec
->views
!= 4) {
4136 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec
->views
, id
+ i
);
4141 case 0x18: // Amount placed on 256^2 map on map creation
4142 spec
->generate_amount
= buf
->ReadByte();
4155 * Define properties for railtypes
4156 * @param id ID of the railtype.
4157 * @param numinfo Number of subsequent IDs to change the property for.
4158 * @param prop The property to change.
4159 * @param buf The property value.
4160 * @return ChangeInfoResult.
4162 static ChangeInfoResult
RailTypeChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4164 ChangeInfoResult ret
= CIR_SUCCESS
;
4166 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
4168 if (id
+ numinfo
> RAILTYPE_END
) {
4169 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id
+ numinfo
, RAILTYPE_END
);
4170 return CIR_INVALID_ID
;
4173 for (int i
= 0; i
< numinfo
; i
++) {
4174 RailType rt
= _cur
.grffile
->railtype_map
[id
+ i
];
4175 if (rt
== INVALID_RAILTYPE
) return CIR_INVALID_ID
;
4177 RailtypeInfo
*rti
= &_railtypes
[rt
];
4180 case 0x08: // Label of rail type
4181 /* Skipped here as this is loaded during reservation stage. */
4185 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4186 uint16 str
= buf
->ReadWord();
4187 AddStringForMapping(str
, &rti
->strings
.toolbar_caption
);
4188 if (_cur
.grffile
->grf_version
< 8) {
4189 AddStringForMapping(str
, &rti
->strings
.name
);
4194 case 0x0A: // Menu text of railtype
4195 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.menu_text
);
4198 case 0x0B: // Build window caption
4199 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.build_caption
);
4202 case 0x0C: // Autoreplace text
4203 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.replace_text
);
4206 case 0x0D: // New locomotive text
4207 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.new_loco
);
4210 case 0x0E: // Compatible railtype list
4211 case 0x0F: // Powered railtype list
4212 case 0x18: // Railtype list required for date introduction
4213 case 0x19: // Introduced railtype list
4215 /* Rail type compatibility bits are added to the existing bits
4216 * to allow multiple GRFs to modify compatibility with the
4217 * default rail types. */
4218 int n
= buf
->ReadByte();
4219 for (int j
= 0; j
!= n
; j
++) {
4220 RailTypeLabel label
= buf
->ReadLabel();
4221 RailType rt
= GetRailTypeByLabel (label
, false);
4222 if (rt
!= INVALID_RAILTYPE
) {
4224 case 0x0F: SetBit(rti
->powered_railtypes
, rt
); FALLTHROUGH
; // Powered implies compatible.
4225 case 0x0E: SetBit(rti
->compatible_railtypes
, rt
); break;
4226 case 0x18: SetBit(rti
->introduction_required_railtypes
, rt
); break;
4227 case 0x19: SetBit(rti
->introduces_railtypes
, rt
); break;
4234 case 0x10: // Rail Type flags
4235 rti
->flags
= (RailTypeFlags
)buf
->ReadByte();
4238 case 0x11: // Curve speed advantage
4239 rti
->curve_speed
= buf
->ReadByte();
4242 case 0x12: // Station graphic
4243 rti
->fallback_railtype
= Clamp(buf
->ReadByte(), 0, 2);
4246 case 0x13: // Construction cost factor
4247 rti
->cost_multiplier
= buf
->ReadWord();
4250 case 0x14: // Speed limit
4251 rti
->max_speed
= buf
->ReadWord();
4254 case 0x15: // Acceleration model
4255 rti
->acceleration_type
= Clamp(buf
->ReadByte(), 0, 2);
4258 case 0x16: // Map colour
4259 rti
->map_colour
= buf
->ReadByte();
4262 case 0x17: // Introduction date
4263 rti
->introduction_date
= buf
->ReadDWord();
4266 case 0x1A: // Sort order
4267 rti
->sorting_order
= buf
->ReadByte();
4270 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4271 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.name
);
4274 case 0x1C: // Maintenance cost factor
4275 rti
->maintenance_multiplier
= buf
->ReadWord();
4278 case 0x1D: // Alternate rail type label list
4279 /* Skipped here as this is loaded during reservation stage. */
4280 buf
->Skip (4 * buf
->ReadByte());
4292 static ChangeInfoResult
RailTypeReserveInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4294 ChangeInfoResult ret
= CIR_SUCCESS
;
4296 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
4298 if (id
+ numinfo
> RAILTYPE_END
) {
4299 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id
+ numinfo
, RAILTYPE_END
);
4300 return CIR_INVALID_ID
;
4303 for (int i
= 0; i
< numinfo
; i
++) {
4305 case 0x08: // Label of rail type
4307 RailTypeLabel rtl
= buf
->ReadLabel();
4309 RailType rt
= GetRailTypeByLabel(rtl
, false);
4310 if (rt
== INVALID_RAILTYPE
) {
4311 /* Set up new rail type */
4312 rt
= AllocateRailType(rtl
);
4315 _cur
.grffile
->railtype_map
[id
+ i
] = rt
;
4319 case 0x09: // Toolbar caption of railtype
4320 case 0x0A: // Menu text
4321 case 0x0B: // Build window caption
4322 case 0x0C: // Autoreplace text
4323 case 0x0D: // New loco
4324 case 0x13: // Construction cost
4325 case 0x14: // Speed limit
4326 case 0x1B: // Name of railtype
4327 case 0x1C: // Maintenance cost factor
4331 case 0x1D: // Alternate rail type label list
4332 if (_cur
.grffile
->railtype_map
[id
+ i
] != INVALID_RAILTYPE
) {
4333 int n
= buf
->ReadByte();
4334 for (int j
= 0; j
!= n
; j
++) {
4335 *_railtypes
[_cur
.grffile
->railtype_map
[id
+ i
]].alternate_labels
.Append() = buf
->ReadLabel();
4339 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id
+ i
);
4342 case 0x0E: // Compatible railtype list
4343 case 0x0F: // Powered railtype list
4344 case 0x18: // Railtype list required for date introduction
4345 case 0x19: // Introduced railtype list
4346 buf
->Skip (4 * buf
->ReadByte());
4349 case 0x10: // Rail Type flags
4350 case 0x11: // Curve speed advantage
4351 case 0x12: // Station graphic
4352 case 0x15: // Acceleration model
4353 case 0x16: // Map colour
4354 case 0x1A: // Sort order
4358 case 0x17: // Introduction date
4371 static ChangeInfoResult
AirportTilesChangeInfo(uint airtid
, int numinfo
, int prop
, ByteReader
*buf
)
4373 ChangeInfoResult ret
= CIR_SUCCESS
;
4375 if (airtid
+ numinfo
> NUM_AIRPORTTILES_PER_GRF
) {
4376 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid
+ numinfo
, NUM_AIRPORTTILES_PER_GRF
);
4377 return CIR_INVALID_ID
;
4380 /* Allocate airport tile specs if they haven't been allocated already. */
4381 if (_cur
.grffile
->airtspec
== NULL
) {
4382 _cur
.grffile
->airtspec
= xcalloct
<AirportTileSpec
*>(NUM_AIRPORTTILES_PER_GRF
);
4385 for (int i
= 0; i
< numinfo
; i
++) {
4386 AirportTileSpec
*tsp
= _cur
.grffile
->airtspec
[airtid
+ i
];
4388 if (prop
!= 0x08 && tsp
== NULL
) {
4389 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid
+ i
);
4390 return CIR_INVALID_ID
;
4394 case 0x08: { // Substitute airport tile type
4395 byte subs_id
= buf
->ReadByte();
4397 if (subs_id
>= NEW_AIRPORTTILE_OFFSET
) {
4398 /* The substitute id must be one of the original airport tiles. */
4399 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id
, airtid
+ i
);
4403 /* Allocate space for this airport tile. */
4405 tsp
= xmemdupt (AirportTileSpec::Get(subs_id
));
4406 _cur
.grffile
->airtspec
[airtid
+ i
] = tsp
;
4408 tsp
->enabled
= true;
4410 tsp
->animation
.status
= ANIM_STATUS_NO_ANIMATION
;
4412 tsp
->grf_prop
.local_id
= airtid
+ i
;
4413 tsp
->grf_prop
.subst_id
= subs_id
;
4414 tsp
->grf_prop
.grffile
= _cur
.grffile
;
4415 _airporttile_mngr
.AddEntityID(airtid
+ i
, _cur
.grffile
->grfid
, subs_id
); // pre-reserve the tile slot
4420 case 0x09: { // Airport tile override
4421 byte override
= buf
->ReadByte();
4423 /* The airport tile being overridden must be an original airport tile. */
4424 if (override
>= NEW_AIRPORTTILE_OFFSET
) {
4425 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override
, airtid
+ i
);
4429 _airporttile_mngr
.Add(airtid
+ i
, _cur
.grffile
->grfid
, override
);
4433 case 0x0E: // Callback mask
4434 tsp
->callback_mask
= buf
->ReadByte();
4437 case 0x0F: // Animation information
4438 tsp
->animation
.frames
= buf
->ReadByte();
4439 tsp
->animation
.status
= buf
->ReadByte();
4442 case 0x10: // Animation speed
4443 tsp
->animation
.speed
= buf
->ReadByte();
4446 case 0x11: // Animation triggers
4447 tsp
->animation
.triggers
= buf
->ReadByte();
4459 static bool HandleChangeInfoResult(const char *caller
, ChangeInfoResult cir
, uint8 feature
, uint8 property
)
4462 default: NOT_REACHED();
4465 /* Error has already been printed; just stop parsing */
4472 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller
, property
, feature
);
4476 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller
, property
, feature
);
4479 case CIR_INVALID_ID
: {
4480 /* No debug message for an invalid ID, as it has already been output */
4481 GRFError
*error
= DisableCur (cir
== CIR_INVALID_ID
? STR_NEWGRF_ERROR_INVALID_ID
: STR_NEWGRF_ERROR_UNKNOWN_PROPERTY
);
4482 if (cir
!= CIR_INVALID_ID
) error
->param_value
[1] = property
;
4489 static int FeatureChangeInfo (ByteReader
*buf
)
4491 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4494 * B num-props how many properties to change per vehicle/station
4495 * B num-info how many vehicles/stations to change
4496 * E id ID of first vehicle/station to change, if num-info is
4497 * greater than one, this one and the following
4498 * vehicles/stations will be changed
4499 * B property what property to change, depends on the feature
4500 * V new-info new bytes of info (variable size; depends on properties) */
4502 static const VCI_Handler handler
[] = {
4503 /* GSF_TRAINS */ RailVehicleChangeInfo
,
4504 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo
,
4505 /* GSF_SHIPS */ ShipVehicleChangeInfo
,
4506 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo
,
4507 /* GSF_STATIONS */ StationChangeInfo
,
4508 /* GSF_CANALS */ CanalChangeInfo
,
4509 /* GSF_BRIDGES */ BridgeChangeInfo
,
4510 /* GSF_HOUSES */ TownHouseChangeInfo
,
4511 /* GSF_GLOBALVAR */ GlobalVarChangeInfo
,
4512 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo
,
4513 /* GSF_INDUSTRIES */ IndustriesChangeInfo
,
4514 /* GSF_CARGOES */ NULL
, // Cargo is handled during reservation
4515 /* GSF_SOUNDFX */ SoundEffectChangeInfo
,
4516 /* GSF_AIRPORTS */ AirportChangeInfo
,
4517 /* GSF_SIGNALS */ NULL
,
4518 /* GSF_OBJECTS */ ObjectChangeInfo
,
4519 /* GSF_RAILTYPES */ RailTypeChangeInfo
,
4520 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo
,
4523 uint8 feature
= buf
->ReadByte();
4524 uint8 numprops
= buf
->ReadByte();
4525 uint numinfo
= buf
->ReadByte();
4526 uint engine
= buf
->ReadExtendedByte();
4528 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4529 feature
, numprops
, engine
, numinfo
);
4531 if (feature
>= lengthof(handler
) || handler
[feature
] == NULL
) {
4532 if (feature
!= GSF_CARGOES
) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature
);
4536 /* Mark the feature as used by the grf */
4537 SetBit(_cur
.grffile
->grf_features
, feature
);
4539 while (numprops
-- && buf
->HasData()) {
4540 uint8 prop
= buf
->ReadByte();
4542 ChangeInfoResult cir
= handler
[feature
](engine
, numinfo
, prop
, buf
);
4543 if (HandleChangeInfoResult ("FeatureChangeInfo", cir
, feature
, prop
)) {
4551 /* Action 0x00 (GLS_SAFETYSCAN) */
4552 static int SafeChangeInfo (ByteReader
*buf
)
4554 uint8 feature
= buf
->ReadByte();
4555 uint8 numprops
= buf
->ReadByte();
4556 uint numinfo
= buf
->ReadByte();
4557 buf
->ReadExtendedByte(); // id
4559 if (feature
== GSF_BRIDGES
&& numprops
== 1) {
4560 uint8 prop
= buf
->ReadByte();
4561 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4562 * is considered safe. */
4563 if (prop
== 0x0D) return 0;
4564 } else if (feature
== GSF_GLOBALVAR
&& numprops
== 1) {
4565 uint8 prop
= buf
->ReadByte();
4566 /* Engine ID Mappings are safe, if the source is static */
4568 bool is_safe
= true;
4569 for (uint i
= 0; i
< numinfo
; i
++) {
4570 uint32 s
= buf
->ReadDWord();
4571 buf
->ReadDWord(); // dest
4572 const GRFConfig
*grfconfig
= GetGRFConfig(s
);
4573 if (grfconfig
!= NULL
&& !HasBit(grfconfig
->flags
, GCF_STATIC
)) {
4578 if (is_safe
) return 0;
4582 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
4584 /* Skip remainder of GRF */
4588 /* Action 0x00 (GLS_RESERVE) */
4589 static int ReserveChangeInfo (ByteReader
*buf
)
4591 uint8 feature
= buf
->ReadByte();
4593 if (feature
!= GSF_CARGOES
&& feature
!= GSF_GLOBALVAR
&& feature
!= GSF_RAILTYPES
) return 0;
4595 uint8 numprops
= buf
->ReadByte();
4596 uint8 numinfo
= buf
->ReadByte();
4597 uint8 index
= buf
->ReadExtendedByte();
4599 while (numprops
-- && buf
->HasData()) {
4600 uint8 prop
= buf
->ReadByte();
4601 ChangeInfoResult cir
= CIR_SUCCESS
;
4604 default: NOT_REACHED();
4606 cir
= CargoChangeInfo(index
, numinfo
, prop
, buf
);
4610 cir
= GlobalVarReserveInfo(index
, numinfo
, prop
, buf
);
4614 cir
= RailTypeReserveInfo(index
, numinfo
, prop
, buf
);
4618 if (HandleChangeInfoResult ("ReserveChangeInfo", cir
, feature
, prop
)) {
4627 static int NewSpriteSet (ByteReader
*buf
)
4629 /* Basic format: <01> <feature> <num-sets> <num-ent>
4630 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4632 * B feature feature to define sprites for
4633 * 0, 1, 2, 3: veh-type, 4: train stations
4634 * E first-set first sprite set to define
4635 * B num-sets number of sprite sets (extended byte in extended format)
4636 * E num-ent how many entries per sprite set
4637 * For vehicles, this is the number of different
4638 * vehicle directions in each sprite set
4639 * Set num-dirs=8, unless your sprites are symmetric.
4640 * In that case, use num-dirs=4.
4643 uint8 feature
= buf
->ReadByte();
4644 uint16 num_sets
= buf
->ReadByte();
4645 uint16 first_set
= 0;
4647 if (num_sets
== 0 && buf
->HasData(3)) {
4648 /* Extended Action1 format.
4649 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4650 first_set
= buf
->ReadExtendedByte();
4651 num_sets
= buf
->ReadExtendedByte();
4653 uint16 num_ents
= buf
->ReadExtendedByte();
4655 _cur
.AddSpriteSets(feature
, _cur
.spriteid
, first_set
, num_sets
, num_ents
);
4657 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4658 _cur
.spriteid
, feature
, num_sets
, num_ents
, num_sets
* num_ents
4661 for (int i
= 0; i
< num_sets
* num_ents
; i
++) {
4663 LoadNextSprite(_cur
.spriteid
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
4669 /* Action 0x01 (SKIP) */
4670 static int SkipAct1 (ByteReader
*buf
)
4673 uint16 num_sets
= buf
->ReadByte();
4675 if (num_sets
== 0 && buf
->HasData(3)) {
4676 /* Extended Action1 format.
4677 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4678 buf
->ReadExtendedByte(); // first_set
4679 num_sets
= buf
->ReadExtendedByte();
4681 uint16 num_ents
= buf
->ReadExtendedByte();
4683 int skip
= num_sets
* num_ents
;
4684 grfmsg (3, "SkipAct1: Skipping %d sprites", skip
);
4688 /* Helper function to either create a callback or link to a previously
4689 * defined spritegroup. */
4690 static const SpriteGroup
*GetGroupFromGroupID(byte setid
, byte type
, uint16 groupid
)
4692 if (HasBit(groupid
, 15)) {
4693 return CallbackResultSpriteGroup::create (groupid
, _cur
.grffile
->grf_version
>= 8);
4696 if (groupid
> MAX_SPRITEGROUP
|| _cur
.spritegroups
[groupid
] == NULL
) {
4697 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid
, type
, groupid
);
4701 return _cur
.spritegroups
[groupid
];
4705 * Helper function to either create a callback or a result sprite group.
4706 * @param feature GrfSpecFeature to define spritegroup for.
4707 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4708 * @param type Type of the currently being parsed Action2. (only for debug output)
4709 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4710 * @return Created spritegroup.
4712 static const SpriteGroup
*CreateGroupFromGroupID(byte feature
, byte setid
, byte type
, uint16 spriteid
)
4714 if (HasBit(spriteid
, 15)) {
4715 return CallbackResultSpriteGroup::create (spriteid
, _cur
.grffile
->grf_version
>= 8);
4718 if (!_cur
.IsValidSpriteSet(feature
, spriteid
)) {
4719 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid
, type
, spriteid
);
4723 SpriteID spriteset_start
= _cur
.GetSprite(feature
, spriteid
);
4724 uint num_sprites
= _cur
.GetNumEnts(feature
, spriteid
);
4726 /* Ensure that the sprites are loeded */
4727 assert(spriteset_start
+ num_sprites
<= _cur
.spriteid
);
4729 return ResultSpriteGroup::create (spriteset_start
, num_sprites
);
4733 static int NewSpriteGroup (ByteReader
*buf
)
4735 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4737 * B feature see action 1
4738 * B set-id ID of this particular definition
4739 * B type/num-entries
4740 * if 80 or greater, this is a randomized or variational
4741 * list definition, see below
4742 * otherwise it specifies a number of entries, the exact
4743 * meaning depends on the feature
4744 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4745 SpriteGroup
*act_group
= NULL
;
4747 uint8 feature
= buf
->ReadByte();
4748 uint8 setid
= buf
->ReadByte();
4749 uint8 type
= buf
->ReadByte();
4751 /* Sprite Groups are created here but they are allocated from a pool, so
4752 * we do not need to delete anything if there is an exception from the
4756 /* Deterministic Sprite Group */
4757 case 0x81: // Self scope, byte
4758 case 0x82: // Parent scope, byte
4759 case 0x85: // Self scope, word
4760 case 0x86: // Parent scope, word
4761 case 0x89: // Self scope, dword
4762 case 0x8A: // Parent scope, dword
4764 byte varsize
= (1 << GB(type
, 2, 2));
4766 /* Count the number of adjusts. */
4767 const byte
*data
= buf
->GetData();
4768 uint num_adjusts
= 1;
4770 byte variable
= buf
->ReadByte();
4771 if (IsInsideMM(variable
, 0x60, 0x80)) buf
->ReadByte();
4773 byte varadjust
= buf
->ReadByte();
4774 buf
->Skip (GB(varadjust
, 6, 2) != 0 ? 3 * varsize
: varsize
);
4776 /* Continue reading var adjusts while bit 5 is set. */
4777 if (!HasBit(varadjust
, 5)) break;
4782 byte num_ranges
= buf
->ReadByte();
4784 DeterministicSpriteGroup
*group
= DeterministicSpriteGroup::create (HasBit(type
, 1),
4785 GB(type
, 2, 2), num_adjusts
, num_ranges
);
4788 for (uint i
= 0; i
< num_adjusts
; i
++) {
4789 DeterministicSpriteGroup::Adjust
*adjust
= group
->get_adjust (i
);
4791 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4792 adjust
->operation
= (i
== 0) ? 0 : *data
++;
4793 adjust
->variable
= *data
++;
4794 if (adjust
->variable
== 0x7E) {
4795 /* Link subroutine group */
4796 adjust
->subroutine
= GetGroupFromGroupID (setid
, type
, *data
++);
4798 adjust
->parameter
= IsInsideMM (adjust
->variable
, 0x60, 0x80) ? *data
++ : 0;
4801 byte varadjust
= *data
++;
4802 adjust
->shift_num
= GB(varadjust
, 0, 5);
4803 adjust
->type
= GB(varadjust
, 6, 2);
4804 adjust
->and_mask
= ReadVarSize (data
, varsize
);
4807 if (adjust
->type
!= 0) {
4808 adjust
->add_val
= ReadVarSize (data
, varsize
);
4810 adjust
->divmod_val
= ReadVarSize (data
, varsize
);
4813 adjust
->add_val
= 0;
4814 adjust
->divmod_val
= 0;
4817 /* Continue reading var adjusts while bit 5 is set. */
4818 assert (HasBit(varadjust
, 5) == (i
+ 1 != num_adjusts
));
4821 data
= buf
->GetData (num_ranges
* (2 * varsize
+ 2) + 2);
4823 const SpriteGroup
*g
;
4824 for (uint i
= 0; ; i
++) {
4825 g
= GetGroupFromGroupID (setid
, type
, ReadWord (data
));
4826 if (i
== num_ranges
) break;
4828 uint32 low
= ReadVarSize (data
, varsize
);
4830 uint32 high
= ReadVarSize (data
, varsize
);
4832 group
->set_range (i
, g
, low
, high
);
4835 group
->set_default (g
);
4839 /* Randomized Sprite Group */
4840 case 0x80: // Self scope
4841 case 0x83: // Parent scope
4842 case 0x84: // Relative scope
4844 VarSpriteGroupScope scope
= HasBit(type
, 1) ? VSG_SCOPE_PARENT
: VSG_SCOPE_SELF
;
4846 if (HasBit(type
, 2)) {
4847 if (feature
<= GSF_AIRCRAFT
) scope
= VSG_SCOPE_RELATIVE
;
4848 count
= buf
->ReadByte();
4853 uint8 triggers
= buf
->ReadByte();
4854 uint8 bit
= buf
->ReadByte();
4855 uint8 num
= buf
->ReadByte();
4857 RandomizedSpriteGroup
*group
= RandomizedSpriteGroup::create (scope
,
4858 HasBit(triggers
, 7), GB(triggers
, 0, 7),
4862 for (uint i
= 0; i
< num
; i
++) {
4863 group
->set_group (i
, GetGroupFromGroupID (setid
, type
, buf
->ReadWord()));
4869 /* Neither a variable or randomized sprite group... must be a real group */
4874 case GSF_ROADVEHICLES
:
4883 byte num_loaded
= type
;
4884 byte num_loading
= buf
->ReadByte();
4886 if (!_cur
.HasValidSpriteSets(feature
)) {
4887 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4891 RealSpriteGroup
*group
= RealSpriteGroup::create (num_loaded
, num_loading
);
4894 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4895 setid
, num_loaded
, num_loading
);
4897 uint total
= (uint
)num_loaded
+ (uint
)num_loading
;
4898 for (uint i
= 0; i
< total
; i
++) {
4899 uint16 spriteid
= buf
->ReadWord();
4900 group
->set (i
, CreateGroupFromGroupID (feature
, setid
, type
, spriteid
));
4901 grfmsg(8, "NewSpriteGroup: + rg->groups[%i] = subset %u", i
, spriteid
);
4908 case GSF_AIRPORTTILES
:
4910 case GSF_INDUSTRYTILES
: {
4911 byte num_building_sprites
= max((uint8
)1, type
);
4913 /* On error, bail out immediately. Temporary GRF data was already freed */
4914 SpriteLayoutReader reader
;
4915 if (ReadSpriteLayout (&reader
, buf
, num_building_sprites
, true, feature
, false, type
== 0)) {
4919 act_group
= TileLayoutSpriteGroup::create (reader
.ground
,
4920 reader
.num_building_sprites
, reader
.seq
,
4921 reader
.has_registers
? reader
.regs
: NULL
,
4922 reader
.consistent_max_offset
);
4926 case GSF_INDUSTRIES
: {
4928 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type
);
4932 IndustryProductionSpriteGroup
*group
= IndustryProductionSpriteGroup::create (type
);
4935 for (uint i
= 0; i
< 3; i
++) {
4936 group
->subtract_input
[i
] = (int16
)buf
->ReadWord(); // signed
4938 for (uint i
= 0; i
< 2; i
++) {
4939 group
->add_output
[i
] = buf
->ReadWord(); // unsigned
4942 for (uint i
= 0; i
< 3; i
++) {
4943 group
->subtract_input
[i
] = buf
->ReadByte();
4945 for (uint i
= 0; i
< 2; i
++) {
4946 group
->add_output
[i
] = buf
->ReadByte();
4949 group
->again
= buf
->ReadByte();
4953 /* Loading of Tile Layout and Production Callback groups would happen here */
4954 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature
);
4959 _cur
.spritegroups
[setid
] = act_group
;
4964 static CargoID
TranslateCargo (uint8 ctype
)
4966 /* Special cargo type for purchase list */
4967 if (ctype
== 0xFF) return CT_PURCHASE
;
4969 if (_cur
.grffile
->cargo_list
.Length() == 0) {
4970 /* No cargo table, so use bitnum values */
4972 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype
);
4976 const CargoSpec
*cs
;
4977 FOR_ALL_CARGOSPECS(cs
) {
4978 if (cs
->bitnum
== ctype
) {
4979 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype
, cs
->Index());
4984 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype
);
4988 /* Check if the cargo type is out of bounds of the cargo translation table */
4989 if (ctype
>= _cur
.grffile
->cargo_list
.Length()) {
4990 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype
, _cur
.grffile
->cargo_list
.Length() - 1);
4994 /* Look up the cargo label from the translation table */
4995 CargoLabel cl
= _cur
.grffile
->cargo_list
[ctype
];
4997 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype
);
5001 ctype
= GetCargoIDByLabel(cl
);
5002 if (ctype
== CT_INVALID
) {
5003 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));
5007 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
);
5012 static bool IsValidGroupID(uint16 groupid
, const char *function
)
5014 if (groupid
> MAX_SPRITEGROUP
|| _cur
.spritegroups
[groupid
] == NULL
) {
5015 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function
, groupid
);
5022 static bool VehicleMapSpriteGroup (ByteReader
*buf
, byte feature
, uint8 idcount
)
5024 static EngineID
*last_engines
;
5025 static uint last_engines_count
;
5026 bool wagover
= false;
5028 /* Test for 'wagon override' flag */
5029 if (HasBit(idcount
, 7)) {
5031 /* Strip off the flag */
5032 idcount
= GB(idcount
, 0, 7);
5034 if (last_engines_count
== 0) {
5035 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
5039 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
5040 last_engines_count
, idcount
);
5042 if (last_engines_count
!= idcount
) {
5043 last_engines
= xrealloct (last_engines
, idcount
);
5044 last_engines_count
= idcount
;
5048 EngineID engines
[128];
5049 assert (idcount
< lengthof(engines
));
5051 for (uint i
= 0; i
< idcount
; i
++) {
5052 Engine
*e
= GetNewEngine(_cur
.grffile
, (VehicleType
)feature
, buf
->ReadExtendedByte());
5054 /* No engine could be allocated?!? Deal with it. Okay,
5055 * this might look bad. Also make sure this NewGRF
5056 * gets disabled, as a half loaded one is bad. */
5057 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID
, 0, 0);
5061 engines
[i
] = e
->index
;
5062 if (!wagover
) last_engines
[i
] = engines
[i
];
5065 uint8 cidcount
= buf
->ReadByte();
5066 for (uint c
= 0; c
< cidcount
; c
++) {
5067 uint8 ctype
= buf
->ReadByte();
5068 uint16 groupid
= buf
->ReadWord();
5069 if (!IsValidGroupID(groupid
, "VehicleMapSpriteGroup")) continue;
5071 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c
, ctype
, groupid
);
5073 ctype
= TranslateCargo (ctype
);
5074 if (ctype
== CT_INVALID
) continue;
5076 for (uint i
= 0; i
< idcount
; i
++) {
5077 EngineID engine
= engines
[i
];
5079 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i
, engine
);
5082 SetWagonOverrideSprites(engine
, ctype
, _cur
.spritegroups
[groupid
], last_engines
, last_engines_count
);
5084 SetCustomEngineSprites(engine
, ctype
, _cur
.spritegroups
[groupid
]);
5089 uint16 groupid
= buf
->ReadWord();
5090 if (!IsValidGroupID(groupid
, "VehicleMapSpriteGroup")) return true;
5092 grfmsg(8, "-- Default group id 0x%04X", groupid
);
5094 for (uint i
= 0; i
< idcount
; i
++) {
5095 EngineID engine
= engines
[i
];
5098 SetWagonOverrideSprites(engine
, CT_DEFAULT
, _cur
.spritegroups
[groupid
], last_engines
, last_engines_count
);
5100 SetCustomEngineSprites(engine
, CT_DEFAULT
, _cur
.spritegroups
[groupid
]);
5101 SetEngineGRF(engine
, _cur
.grffile
);
5109 static void CanalMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5111 const byte
*cfs
= buf
->GetData (idcount
);
5113 uint8 cidcount
= buf
->ReadByte();
5114 buf
->Skip(cidcount
* 3);
5116 uint16 groupid
= buf
->ReadWord();
5117 if (!IsValidGroupID(groupid
, "CanalMapSpriteGroup")) return;
5119 for (uint i
= 0; i
< idcount
; i
++) {
5120 CanalFeature cf
= (CanalFeature
)cfs
[i
];
5123 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf
);
5127 _water_feature
[cf
].grffile
= _cur
.grffile
;
5128 _water_feature
[cf
].group
= _cur
.spritegroups
[groupid
];
5133 static void StationMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5135 const byte
*stations
= buf
->GetData (idcount
);
5137 uint8 cidcount
= buf
->ReadByte();
5138 for (uint c
= 0; c
< cidcount
; c
++) {
5139 uint8 ctype
= buf
->ReadByte();
5140 uint16 groupid
= buf
->ReadWord();
5141 if (!IsValidGroupID(groupid
, "StationMapSpriteGroup")) continue;
5143 if (ctype
== 0xFE) {
5144 ctype
= CT_DEFAULT_NA
;
5146 ctype
= TranslateCargo (ctype
);
5147 if (ctype
== CT_INVALID
) continue;
5150 for (uint i
= 0; i
< idcount
; i
++) {
5151 StationSpec
*statspec
= _cur
.grffile
->stations
== NULL
? NULL
: _cur
.grffile
->stations
[stations
[i
]];
5153 if (statspec
== NULL
) {
5154 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations
[i
]);
5158 statspec
->spritegroup
[ctype
] = _cur
.spritegroups
[groupid
];
5162 uint16 groupid
= buf
->ReadWord();
5163 if (!IsValidGroupID(groupid
, "StationMapSpriteGroup")) return;
5165 for (uint i
= 0; i
< idcount
; i
++) {
5166 StationSpec
*statspec
= _cur
.grffile
->stations
== NULL
? NULL
: _cur
.grffile
->stations
[stations
[i
]];
5168 if (statspec
== NULL
) {
5169 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations
[i
]);
5173 if (statspec
->grf_prop
.grffile
!= NULL
) {
5174 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations
[i
]);
5178 statspec
->spritegroup
[CT_DEFAULT
] = _cur
.spritegroups
[groupid
];
5179 statspec
->grf_prop
.grffile
= _cur
.grffile
;
5180 statspec
->grf_prop
.local_id
= stations
[i
];
5181 StationClass::Assign(statspec
);
5186 static void TownHouseMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5188 const byte
*houses
= buf
->GetData (idcount
);
5190 /* Skip the cargo type section, we only care about the default group */
5191 uint8 cidcount
= buf
->ReadByte();
5192 buf
->Skip(cidcount
* 3);
5194 uint16 groupid
= buf
->ReadWord();
5195 if (!IsValidGroupID(groupid
, "TownHouseMapSpriteGroup")) return;
5197 if (_cur
.grffile
->housespec
== NULL
) {
5198 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5202 for (uint i
= 0; i
< idcount
; i
++) {
5203 HouseSpec
*hs
= _cur
.grffile
->housespec
[houses
[i
]];
5206 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses
[i
]);
5210 hs
->grf_prop
.spritegroup
= _cur
.spritegroups
[groupid
];
5214 static void IndustryMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5216 const byte
*industries
= buf
->GetData (idcount
);
5218 /* Skip the cargo type section, we only care about the default group */
5219 uint8 cidcount
= buf
->ReadByte();
5220 buf
->Skip(cidcount
* 3);
5222 uint16 groupid
= buf
->ReadWord();
5223 if (!IsValidGroupID(groupid
, "IndustryMapSpriteGroup")) return;
5225 if (_cur
.grffile
->industryspec
== NULL
) {
5226 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5230 for (uint i
= 0; i
< idcount
; i
++) {
5231 IndustrySpec
*indsp
= _cur
.grffile
->industryspec
[industries
[i
]];
5233 if (indsp
== NULL
) {
5234 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries
[i
]);
5238 indsp
->grf_prop
.spritegroup
= _cur
.spritegroups
[groupid
];
5242 static void IndustrytileMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5244 const byte
*indtiles
= buf
->GetData (idcount
);
5246 /* Skip the cargo type section, we only care about the default group */
5247 uint8 cidcount
= buf
->ReadByte();
5248 buf
->Skip(cidcount
* 3);
5250 uint16 groupid
= buf
->ReadWord();
5251 if (!IsValidGroupID(groupid
, "IndustrytileMapSpriteGroup")) return;
5253 if (_cur
.grffile
->indtspec
== NULL
) {
5254 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5258 for (uint i
= 0; i
< idcount
; i
++) {
5259 IndustryTileSpec
*indtsp
= _cur
.grffile
->indtspec
[indtiles
[i
]];
5261 if (indtsp
== NULL
) {
5262 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles
[i
]);
5266 indtsp
->grf_prop
.spritegroup
= _cur
.spritegroups
[groupid
];
5270 static void CargoMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5272 const byte
*cargoes
= buf
->GetData (idcount
);
5274 /* Skip the cargo type section, we only care about the default group */
5275 uint8 cidcount
= buf
->ReadByte();
5276 buf
->Skip(cidcount
* 3);
5278 uint16 groupid
= buf
->ReadWord();
5279 if (!IsValidGroupID(groupid
, "CargoMapSpriteGroup")) return;
5281 for (uint i
= 0; i
< idcount
; i
++) {
5282 CargoID cid
= (CargoID
)cargoes
[i
];
5284 if (cid
>= NUM_CARGO
) {
5285 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid
);
5289 CargoSpec
*cs
= CargoSpec::Get(cid
);
5290 cs
->grffile
= _cur
.grffile
;
5291 cs
->group
= _cur
.spritegroups
[groupid
];
5295 static void ObjectMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5297 if (_cur
.grffile
->objectspec
== NULL
) {
5298 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5302 const byte
*objects
= buf
->GetData (idcount
);
5304 uint8 cidcount
= buf
->ReadByte();
5305 for (uint c
= 0; c
< cidcount
; c
++) {
5306 uint8 ctype
= buf
->ReadByte();
5307 uint16 groupid
= buf
->ReadWord();
5308 if (!IsValidGroupID(groupid
, "ObjectMapSpriteGroup")) continue;
5312 case 0xFF: ctype
= CT_PURCHASE_OBJECT
; break;
5314 grfmsg(1, "ObjectMapSpriteGroup: Invalid cargo bitnum %d for objects, skipping.", ctype
);
5318 for (uint i
= 0; i
< idcount
; i
++) {
5319 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[objects
[i
]];
5322 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects
[i
]);
5326 spec
->spritegroup
[ctype
] = _cur
.spritegroups
[groupid
];
5330 uint16 groupid
= buf
->ReadWord();
5331 if (!IsValidGroupID(groupid
, "ObjectMapSpriteGroup")) return;
5333 for (uint i
= 0; i
< idcount
; i
++) {
5334 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[objects
[i
]];
5337 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects
[i
]);
5341 if (spec
->grf_prop
.grffile
!= NULL
) {
5342 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects
[i
]);
5346 spec
->spritegroup
[0] = _cur
.spritegroups
[groupid
];
5347 spec
->grf_prop
.grffile
= _cur
.grffile
;
5348 spec
->grf_prop
.local_id
= objects
[i
];
5352 static void RailTypeMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5354 const byte
*railtypes
= buf
->GetData (idcount
);
5356 uint8 cidcount
= buf
->ReadByte();
5357 for (uint c
= 0; c
< cidcount
; c
++) {
5358 uint8 ctype
= buf
->ReadByte();
5359 uint16 groupid
= buf
->ReadWord();
5360 if (!IsValidGroupID(groupid
, "RailTypeMapSpriteGroup")) continue;
5362 if (ctype
>= RTSG_END
) continue;
5364 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
5365 for (uint i
= 0; i
< idcount
; i
++) {
5366 RailType rt
= _cur
.grffile
->railtype_map
[railtypes
[i
]];
5367 if (rt
!= INVALID_RAILTYPE
) {
5368 RailtypeInfo
*rti
= &_railtypes
[rt
];
5370 rti
->grffile
[ctype
] = _cur
.grffile
;
5371 rti
->group
[ctype
] = _cur
.spritegroups
[groupid
];
5376 /* Railtypes do not use the default group. */
5380 static void AirportMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5382 const byte
*airports
= buf
->GetData (idcount
);
5384 /* Skip the cargo type section, we only care about the default group */
5385 uint8 cidcount
= buf
->ReadByte();
5386 buf
->Skip(cidcount
* 3);
5388 uint16 groupid
= buf
->ReadWord();
5389 if (!IsValidGroupID(groupid
, "AirportMapSpriteGroup")) return;
5391 if (_cur
.grffile
->airportspec
== NULL
) {
5392 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5396 for (uint i
= 0; i
< idcount
; i
++) {
5397 AirportSpec
*as
= _cur
.grffile
->airportspec
[airports
[i
]];
5400 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports
[i
]);
5404 as
->grf_prop
.spritegroup
= _cur
.spritegroups
[groupid
];
5408 static void AirportTileMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5410 const byte
*airptiles
= buf
->GetData (idcount
);
5412 /* Skip the cargo type section, we only care about the default group */
5413 uint8 cidcount
= buf
->ReadByte();
5414 buf
->Skip(cidcount
* 3);
5416 uint16 groupid
= buf
->ReadWord();
5417 if (!IsValidGroupID(groupid
, "AirportTileMapSpriteGroup")) return;
5419 if (_cur
.grffile
->airtspec
== NULL
) {
5420 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5424 for (uint i
= 0; i
< idcount
; i
++) {
5425 AirportTileSpec
*airtsp
= _cur
.grffile
->airtspec
[airptiles
[i
]];
5427 if (airtsp
== NULL
) {
5428 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles
[i
]);
5432 airtsp
->grf_prop
.spritegroup
= _cur
.spritegroups
[groupid
];
5438 static int FeatureMapSpriteGroup (ByteReader
*buf
)
5440 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5441 * id-list := [<id>] [id-list]
5442 * cargo-list := <cargo-type> <cid> [cargo-list]
5444 * B feature see action 0
5445 * B n-id bits 0-6: how many IDs this definition applies to
5446 * bit 7: if set, this is a wagon override definition (see below)
5447 * B ids the IDs for which this definition applies
5448 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5449 * can be zero, in that case the def-cid is used always
5450 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5451 * W cid cargo ID (sprite group ID) for this type of cargo
5452 * W def-cid default cargo ID (sprite group ID) */
5454 uint8 feature
= buf
->ReadByte();
5455 uint8 idcount
= buf
->ReadByte();
5457 /* If idcount is zero, this is a feature callback */
5459 /* Skip number of cargo ids? */
5461 uint16 groupid
= buf
->ReadWord();
5462 if (!IsValidGroupID(groupid
, "FeatureMapSpriteGroup")) return 0;
5464 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature
);
5466 AddGenericCallback(feature
, _cur
.grffile
, _cur
.spritegroups
[groupid
]);
5470 /* Mark the feature as used by the grf (generic callbacks do not count) */
5471 SetBit(_cur
.grffile
->grf_features
, feature
);
5473 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature
, idcount
);
5477 case GSF_ROADVEHICLES
:
5480 return VehicleMapSpriteGroup (buf
, feature
, idcount
) ? 0 : -1;
5483 CanalMapSpriteGroup(buf
, idcount
);
5487 StationMapSpriteGroup(buf
, idcount
);
5491 TownHouseMapSpriteGroup(buf
, idcount
);
5494 case GSF_INDUSTRIES
:
5495 IndustryMapSpriteGroup(buf
, idcount
);
5498 case GSF_INDUSTRYTILES
:
5499 IndustrytileMapSpriteGroup(buf
, idcount
);
5503 CargoMapSpriteGroup(buf
, idcount
);
5507 AirportMapSpriteGroup(buf
, idcount
);
5511 ObjectMapSpriteGroup(buf
, idcount
);
5515 RailTypeMapSpriteGroup(buf
, idcount
);
5518 case GSF_AIRPORTTILES
:
5519 AirportTileMapSpriteGroup(buf
, idcount
);
5523 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature
);
5529 static int FeatureNewName (ByteReader
*buf
)
5531 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5533 * B veh-type see action 0 (as 00..07, + 0A
5534 * But IF veh-type = 48, then generic text
5535 * B language-id If bit 6 is set, This is the extended language scheme,
5536 * with up to 64 language.
5537 * Otherwise, it is a mapping where set bits have meaning
5538 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5539 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5540 * B num-veh number of vehicles which are getting a new name
5541 * B/W offset number of the first vehicle that gets a new name
5542 * Byte : ID of vehicle to change
5543 * Word : ID of string to change/add
5544 * S data new texts, each of them zero-terminated, after
5545 * which the next name begins. */
5547 bool new_scheme
= _cur
.grffile
->grf_version
>= 7;
5549 uint8 feature
= buf
->ReadByte();
5550 uint8 lang
= buf
->ReadByte();
5551 uint8 num
= buf
->ReadByte();
5552 bool generic
= HasBit(lang
, 7);
5555 id
= buf
->ReadWord();
5556 } else if (feature
<= GSF_AIRCRAFT
) {
5557 id
= buf
->ReadExtendedByte();
5559 id
= buf
->ReadByte();
5564 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5565 id
, id
+ num
, feature
, lang
);
5567 for (; num
-- > 0 && buf
->HasData(); id
++) {
5568 const char *name
= buf
->ReadString();
5569 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id
, name
);
5571 bool add_generic
= false;
5572 bool add_name
= false;
5573 StringID stringid
= id
;
5574 StringID def
= STR_UNDEFINED
;
5577 if (feature
<= GSF_AIRCRAFT
) {
5581 Engine
*e
= GetNewEngine (_cur
.grffile
, (VehicleType
)feature
, id
, HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
));
5583 stringid
= e
->index
;
5584 def
= e
->info
.string_id
;
5585 p
= &e
->info
.string_id
;
5590 } else if (IsInsideMM (id
, 0xD000, 0xD400) || IsInsideMM (id
, 0xD800, 0xE000)) {
5594 switch (GB(id
, 8, 8)) {
5595 case 0xC4: // Station class name
5596 if (_cur
.grffile
->stations
== NULL
|| _cur
.grffile
->stations
[GB(id
, 0, 8)] == NULL
) {
5597 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id
, 0, 8));
5599 StationClassID cls_id
= _cur
.grffile
->stations
[GB(id
, 0, 8)]->cls_id
;
5600 p
= &StationClass::Get(cls_id
)->name
;
5605 case 0xC5: // Station name
5606 if (_cur
.grffile
->stations
== NULL
|| _cur
.grffile
->stations
[GB(id
, 0, 8)] == NULL
) {
5607 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id
, 0, 8));
5609 p
= &_cur
.grffile
->stations
[GB(id
, 0, 8)]->name
;
5614 case 0xC7: // Airporttile name
5615 if (_cur
.grffile
->airtspec
== NULL
|| _cur
.grffile
->airtspec
[GB(id
, 0, 8)] == NULL
) {
5616 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id
, 0, 8));
5618 p
= &_cur
.grffile
->airtspec
[GB(id
, 0, 8)]->name
;
5623 case 0xC9: // House name
5624 if (_cur
.grffile
->housespec
== NULL
|| _cur
.grffile
->housespec
[GB(id
, 0, 8)] == NULL
) {
5625 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id
, 0, 8));
5627 p
= &_cur
.grffile
->housespec
[GB(id
, 0, 8)]->building_name
;
5633 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id
);
5639 AddGRFString (_cur
.grffile
->grfid
, stringid
, lang
, new_scheme
, true, name
, def
);
5640 } else if (add_name
) {
5641 *p
= AddGRFString (_cur
.grffile
->grfid
, stringid
, lang
, new_scheme
, false, name
, def
);
5653 /* Shore sprite replacements for single-corner and inclined slopes. */
5654 static const SpritePair shore_sprites_1
[] = {
5655 { SPR_ORIGINALSHORE_START
+ 1, SPR_SHORE_BASE
+ 1 }, // SLOPE_W
5656 { SPR_ORIGINALSHORE_START
+ 2, SPR_SHORE_BASE
+ 2 }, // SLOPE_S
5657 { SPR_ORIGINALSHORE_START
+ 6, SPR_SHORE_BASE
+ 3 }, // SLOPE_SW
5658 { SPR_ORIGINALSHORE_START
+ 0, SPR_SHORE_BASE
+ 4 }, // SLOPE_E
5659 { SPR_ORIGINALSHORE_START
+ 4, SPR_SHORE_BASE
+ 6 }, // SLOPE_SE
5660 { SPR_ORIGINALSHORE_START
+ 3, SPR_SHORE_BASE
+ 8 }, // SLOPE_N
5661 { SPR_ORIGINALSHORE_START
+ 7, SPR_SHORE_BASE
+ 9 }, // SLOPE_NW
5662 { SPR_ORIGINALSHORE_START
+ 5, SPR_SHORE_BASE
+ 12 }, // SLOPE_NE
5665 /* Shore sprite replacements for three-corner and steep slopes. */
5666 static const SpritePair shore_sprites_2
[] = {
5667 { SPR_FLAT_GRASS_TILE
+ 16, SPR_SHORE_BASE
+ 0 }, // SLOPE_STEEP_S
5668 { SPR_FLAT_GRASS_TILE
+ 17, SPR_SHORE_BASE
+ 5 }, // SLOPE_STEEP_W
5669 { SPR_FLAT_GRASS_TILE
+ 7, SPR_SHORE_BASE
+ 7 }, // SLOPE_WSE
5670 { SPR_FLAT_GRASS_TILE
+ 15, SPR_SHORE_BASE
+ 10 }, // SLOPE_STEEP_N
5671 { SPR_FLAT_GRASS_TILE
+ 11, SPR_SHORE_BASE
+ 11 }, // SLOPE_NWS
5672 { SPR_FLAT_GRASS_TILE
+ 13, SPR_SHORE_BASE
+ 13 }, // SLOPE_ENW
5673 { SPR_FLAT_GRASS_TILE
+ 14, SPR_SHORE_BASE
+ 14 }, // SLOPE_SEN
5674 { SPR_FLAT_GRASS_TILE
+ 18, SPR_SHORE_BASE
+ 15 }, // SLOPE_STEEP_E
5675 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
5676 * If they would be used somewhen, then these grass tiles will most like not look as needed */
5677 { SPR_FLAT_GRASS_TILE
+ 5, SPR_SHORE_BASE
+ 16 }, // SLOPE_EW
5678 { SPR_FLAT_GRASS_TILE
+ 10, SPR_SHORE_BASE
+ 17 }, // SLOPE_NS
5682 /** The type of action 5 type. */
5683 enum Action5BlockType
{
5684 A5BLOCK_FIXED
, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5685 A5BLOCK_ALLOW_OFFSET
, ///< Allow replacing any subset by specifiing an offset.
5686 A5BLOCK_INVALID
, ///< unknown/not-implemented type
5688 /** Information about a single action 5 type. */
5689 struct Action5Type
{
5690 Action5BlockType block_type
; ///< How is this Action5 type processed?
5691 SpriteID sprite_base
; ///< Load the sprites starting from this sprite.
5692 uint16 min_sprites
; ///< If the Action5 contains less sprites, the whole block will be ignored.
5693 uint16 max_sprites
; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5694 const char *name
; ///< Name for error messages.
5697 /** The information about action 5 types. */
5698 static const Action5Type _action5_types
[] = {
5699 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5700 /* 0x00 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x00" },
5701 /* 0x01 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x01" },
5702 /* 0x02 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x02" },
5703 /* 0x03 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x03" },
5704 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET
, SPR_SIGNALS_BASE
, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT
, "Signal graphics" },
5705 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ELRAIL_BASE
, 1, ELRAIL_SPRITE_COUNT
, "Rail catenary graphics" },
5706 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET
, SPR_SLOPES_BASE
, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT
, "Foundation graphics" },
5707 /* 0x07 */ { A5BLOCK_INVALID
, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5708 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET
, SPR_CANALS_BASE
, 1, CANALS_SPRITE_COUNT
, "Canal graphics" },
5709 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ONEWAY_BASE
, 1, ONEWAY_SPRITE_COUNT
, "One way road graphics" },
5710 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET
, SPR_2CCMAP_BASE
, 1, TWOCCMAP_SPRITE_COUNT
, "2CC colour maps" },
5711 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET
, SPR_TRAMWAY_BASE
, 1, TRAMWAY_SPRITE_COUNT
, "Tramway graphics" },
5712 /* 0x0C */ { A5BLOCK_INVALID
, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5713 /* 0x0D */ { A5BLOCK_FIXED
, SPR_SHORE_BASE
, 16, SPR_SHORE_SPRITE_COUNT
, "Shore graphics" },
5714 /* 0x0E */ { A5BLOCK_INVALID
, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5715 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET
, SPR_TRACKS_FOR_SLOPES_BASE
, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT
, "Sloped rail track" },
5716 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AIRPORTX_BASE
, 1, AIRPORTX_SPRITE_COUNT
, "Airport graphics" },
5717 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ROADSTOP_BASE
, 1, ROADSTOP_SPRITE_COUNT
, "Road stop graphics" },
5718 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AQUEDUCT_BASE
, 1, AQUEDUCT_SPRITE_COUNT
, "Aqueduct graphics" },
5719 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AUTORAIL_BASE
, 1, AUTORAIL_SPRITE_COUNT
, "Autorail graphics" },
5720 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET
, SPR_FLAGS_BASE
, 1, FLAGS_SPRITE_COUNT
, "Flag graphics" },
5721 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET
, SPR_OPENTTD_BASE
, 1, OPENTTD_SPRITE_COUNT
, "OpenTTD GUI graphics" },
5722 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AIRPORT_PREVIEW_BASE
, 1, SPR_AIRPORT_PREVIEW_COUNT
, "Airport preview graphics" },
5723 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET
, SPR_RAILTYPE_TUNNEL_BASE
, 1, RAILTYPE_TUNNEL_BASE_COUNT
, "Railtype tunnel base" },
5724 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET
, SPR_PALETTE_BASE
, 1, PALETTE_SPRITE_COUNT
, "Palette" },
5728 static int GraphicsNew (ByteReader
*buf
)
5730 /* <05> <graphics-type> <num-sprites> <other data...>
5732 * B graphics-type What set of graphics the sprites define.
5733 * E num-sprites How many sprites are in this set?
5734 * V other data Graphics type specific data. Currently unused. */
5737 uint8 type
= buf
->ReadByte();
5738 uint16 num
= buf
->ReadExtendedByte();
5739 uint16 offset
= HasBit(type
, 7) ? buf
->ReadExtendedByte() : 0;
5740 ClrBit(type
, 7); // Clear the high bit as that only indicates whether there is an offset.
5742 if ((type
== 0x0D) && (num
== 10) && HasBit(_cur
.grfconfig
->flags
, GCF_SYSTEM
)) {
5743 /* Special not-TTDP-compatible case used in openttd.grf
5744 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5745 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5746 for (uint i
= 0; i
< lengthof(shore_sprites_2
); i
++) {
5747 LoadNextSprite (shore_sprites_2
[i
].spr
, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
);
5749 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_NONE
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ONLY_NEW
;
5753 /* Supported type? */
5754 if ((type
>= lengthof(_action5_types
)) || (_action5_types
[type
].block_type
== A5BLOCK_INVALID
)) {
5755 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type
, num
);
5759 const Action5Type
*action5_type
= &_action5_types
[type
];
5761 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5762 * except for the long version of the shore type:
5763 * Ignore offset if not allowed */
5764 if ((action5_type
->block_type
!= A5BLOCK_ALLOW_OFFSET
) && (offset
!= 0)) {
5765 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type
->name
, type
);
5769 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5770 * This does not make sense, if <offset> is allowed */
5771 if ((action5_type
->block_type
== A5BLOCK_FIXED
) && (num
< action5_type
->min_sprites
)) {
5772 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
);
5776 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5778 if (offset
>= action5_type
->max_sprites
) {
5779 grfmsg (1, "GraphicsNew: %s sprite offset must be less than %i, skipping", action5_type
->name
, action5_type
->max_sprites
);
5782 } else if (offset
+ num
> action5_type
->max_sprites
) {
5783 grfmsg (4, "GraphicsNew: %s sprite overflow, truncating...", action5_type
->name
);
5784 uint rem
= action5_type
->max_sprites
- offset
;
5785 skip_num
= num
- rem
;
5790 SpriteID replace
= action5_type
->sprite_base
+ offset
;
5792 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5793 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
);
5795 for (; num
> 0; num
--) {
5797 LoadNextSprite(replace
== 0 ? _cur
.spriteid
++ : replace
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
5800 if (type
== 0x0D) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_5
;
5805 /* Action 0x05 (SKIP) */
5806 static int SkipAct5 (ByteReader
*buf
)
5808 /* Ignore type byte */
5811 /* Skip the sprites of this action */
5812 int skip
= buf
->ReadExtendedByte();
5813 grfmsg (3, "SkipAct5: Skipping %d sprites", skip
);
5818 * Reads a variable common to VarAction2 and Action7/9/D.
5820 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5821 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5823 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5824 * @param value returns the value of the variable.
5825 * @param grffile NewGRF querying the variable
5826 * @return true iff the variable is known and the value is returned in 'value'.
5828 bool GetGlobalVariable(byte param
, uint32
*value
, const GRFFile
*grffile
)
5831 case 0x00: // current date
5832 *value
= max(_date
- DAYS_TILL_ORIGINAL_BASE_YEAR
, 0);
5835 case 0x01: // current year
5836 *value
= Clamp(_cur_year
, ORIGINAL_BASE_YEAR
, ORIGINAL_MAX_YEAR
) - ORIGINAL_BASE_YEAR
;
5839 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)
5841 ConvertDateToYMD(_date
, &ymd
);
5842 Date start_of_year
= ConvertYMDToDate(ymd
.year
, 0, 1);
5843 *value
= ymd
.month
| (ymd
.day
- 1) << 8 | (IsLeapYear(ymd
.year
) ? 1 << 15 : 0) | (_date
- start_of_year
) << 16;
5847 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5848 *value
= _settings_game
.game_creation
.landscape
;
5851 case 0x06: // road traffic side, bit 4 clear=left, set=right
5852 *value
= _settings_game
.vehicle
.road_side
<< 4;
5855 case 0x09: // date fraction
5856 *value
= _date_fract
* 885;
5859 case 0x0A: // animation counter
5860 *value
= _tick_counter
;
5863 case 0x0B: { // TTDPatch version
5866 uint revision
= 1; // special case: 2.0.1 is 2.0.10
5868 *value
= (major
<< 24) | (minor
<< 20) | (revision
<< 16) | build
;
5872 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5873 *value
= _cur
.grfconfig
->palette
& GRFP_USE_MASK
;
5876 case 0x0E: // Y-offset for train sprites
5877 *value
= _cur
.grffile
->traininfo_vehicle_pitch
;
5880 case 0x0F: // Rail track type cost factors
5882 SB(*value
, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL
)->cost_multiplier
); // normal rail
5883 if (_settings_game
.vehicle
.disable_elrails
) {
5884 /* skip elrail multiplier - disabled */
5885 SB(*value
, 8, 8, GetRailTypeInfo(RAILTYPE_MONO
)->cost_multiplier
); // monorail
5887 SB(*value
, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC
)->cost_multiplier
); // electified railway
5888 /* Skip monorail multiplier - no space in result */
5890 SB(*value
, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV
)->cost_multiplier
); // maglev
5893 case 0x11: // current rail tool type
5894 *value
= 0; // constant fake value to avoid desync
5897 case 0x12: // Game mode
5898 *value
= _game_mode
;
5901 /* case 0x13: // Tile refresh offset to left not implemented */
5902 /* case 0x14: // Tile refresh offset to right not implemented */
5903 /* case 0x15: // Tile refresh offset upwards not implemented */
5904 /* case 0x16: // Tile refresh offset downwards not implemented */
5905 /* case 0x17: // temperate snow line not implemented */
5907 case 0x1A: // Always -1
5911 case 0x1B: // Display options
5912 *value
= 0x3F; // constant fake value to avoid desync
5915 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5919 case 0x1E: // Miscellaneous GRF features
5920 *value
= _misc_grf_features
;
5922 /* Add the local flags */
5923 assert(!HasBit(*value
, GMB_TRAIN_WIDTH_32_PIXELS
));
5924 if (_cur
.grffile
->traininfo_vehicle_width
== VEHICLEINFO_FULL_VEHICLE_WIDTH
) SetBit(*value
, GMB_TRAIN_WIDTH_32_PIXELS
);
5927 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5929 case 0x20: { // snow line height
5930 byte snowline
= GetSnowLine();
5931 if (_settings_game
.game_creation
.landscape
== LT_ARCTIC
&& snowline
<= _settings_game
.construction
.max_heightlevel
) {
5932 *value
= Clamp(snowline
* (grffile
->grf_version
>= 8 ? 1 : TILE_HEIGHT
), 0, 0xFE);
5940 case 0x21: // OpenTTD version
5941 *value
= _openttd_newgrf_version
;
5944 case 0x22: // difficulty level
5948 case 0x23: // long format date
5952 case 0x24: // long format year
5956 default: return false;
5960 static uint32
GetParamVal(byte param
, uint32
*cond_val
)
5962 /* First handle variable common with VarAction2 */
5964 if (GetGlobalVariable(param
- 0x80, &value
, _cur
.grffile
)) return value
;
5966 /* Non-common variable */
5968 case 0x84: { // GRF loading stage
5971 if (_cur
.stage
> GLS_INIT
) SetBit(res
, 0);
5972 if (_cur
.stage
== GLS_RESERVE
) SetBit(res
, 8);
5973 if (_cur
.stage
== GLS_ACTIVATION
) SetBit(res
, 9);
5977 case 0x85: // TTDPatch flags, only for bit tests
5978 if (cond_val
== NULL
) {
5979 /* Supported in Action 0x07 and 0x09, not 0x0D */
5982 uint32 param_val
= _ttdpatch_flags
[*cond_val
/ 0x20];
5987 case 0x88: // GRF ID check
5990 /* case 0x99: Global ID offset not implemented */
5994 if (param
< 0x80) return _cur
.grffile
->GetParam(param
);
5996 /* In-game variable. */
5997 grfmsg(1, "Unsupported in-game variable 0x%02X", param
);
6003 static int CfgApply (ByteReader
*buf
)
6005 /* <06> <param-num> <param-size> <offset> ... <FF>
6007 * B param-num Number of parameter to substitute (First = "zero")
6008 * Ignored if that parameter was not specified in newgrf.cfg
6009 * B param-size How many bytes to replace. If larger than 4, the
6010 * bytes of the following parameter are used. In that
6011 * case, nothing is applied unless *all* parameters
6013 * B offset Offset into data from beginning of next sprite
6014 * to place where parameter is to be stored. */
6016 /* Preload the next sprite */
6017 size_t pos
= FioGetPos();
6018 uint32 num
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
6019 uint8 type
= FioReadByte();
6021 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
6023 /* Reset the file position to the start of the next sprite */
6024 FioSeekTo(pos
, SEEK_SET
);
6026 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
6030 GRFLocation
location(_cur
.grfconfig
->ident
.grfid
, _cur
.nfo_line
+ 1);
6031 std::pair
<GRFLineToSpriteOverride::iterator
, bool> ins
=
6032 _grf_line_to_action6_sprite_override
.insert (std::make_pair (location
, ttd_unique_free_ptr
<byte
>()));
6034 byte
*preload_sprite
;
6036 preload_sprite
= xmalloct
<byte
> (num
);
6037 ins
.first
->second
.reset (preload_sprite
);
6038 FioReadBlock (preload_sprite
, num
);
6040 preload_sprite
= ins
.first
->second
.get();
6043 /* Reset the file position to the start of the next sprite */
6044 FioSeekTo (pos
, SEEK_SET
);
6046 /* Now perform the Action 0x06 on our data. */
6055 /* Read the parameter to apply. 0xFF indicates no more data to change. */
6056 param_num
= buf
->ReadByte();
6057 if (param_num
== 0xFF) break;
6059 /* Get the size of the parameter to use. If the size covers multiple
6060 * double words, sequential parameter values are used. */
6061 param_size
= buf
->ReadByte();
6063 /* Bit 7 of param_size indicates we should add to the original value
6064 * instead of replacing it. */
6065 add_value
= HasBit(param_size
, 7);
6066 param_size
= GB(param_size
, 0, 7);
6068 /* Where to apply the data to within the pseudo sprite data. */
6069 offset
= buf
->ReadExtendedByte();
6071 /* If the parameter is a GRF parameter (not an internal variable) check
6072 * if it (and all further sequential parameters) has been defined. */
6073 if (param_num
< 0x80 && (param_num
+ (param_size
- 1) / 4) >= _cur
.grffile
->param_end
) {
6074 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num
+ (param_size
- 1) / 4));
6078 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size
, param_num
, offset
);
6081 for (i
= 0; i
< param_size
&& offset
+ i
< num
; i
++) {
6082 uint32 value
= GetParamVal(param_num
+ i
/ 4, NULL
);
6083 /* Reset carry flag for each iteration of the variable (only really
6084 * matters if param_size is greater than 4) */
6085 if (i
% 4 == 0) carry
= false;
6088 uint new_value
= preload_sprite
[offset
+ i
] + GB(value
, (i
% 4) * 8, 8) + (carry
? 1 : 0);
6089 preload_sprite
[offset
+ i
] = GB(new_value
, 0, 8);
6090 /* Check if the addition overflowed */
6091 carry
= new_value
>= 256;
6093 preload_sprite
[offset
+ i
] = GB(value
, (i
% 4) * 8, 8);
6102 * Disable a static NewGRF when it is influencing another (non-static)
6103 * NewGRF as this could cause desyncs.
6105 * We could just tell the NewGRF querying that the file doesn't exist,
6106 * but that might give unwanted results. Disabling the NewGRF gives the
6107 * best result as no NewGRF author can complain about that.
6108 * @param c The NewGRF to disable.
6110 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig
*c
)
6112 DisableGrf (STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC
, c
);
6117 static int SkipIf (ByteReader
*buf
)
6119 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6126 /* TODO: More params. More condition types. */
6127 uint32 cond_val
= 0;
6131 uint8 param
= buf
->ReadByte();
6132 uint8 paramsize
= buf
->ReadByte();
6133 uint8 condtype
= buf
->ReadByte();
6136 /* Always 1 for bit tests, the given value should be ignored. */
6140 switch (paramsize
) {
6141 case 8: cond_val
= buf
->ReadDWord(); mask
= buf
->ReadDWord(); break;
6142 case 4: cond_val
= buf
->ReadDWord(); mask
= 0xFFFFFFFF; break;
6143 case 2: cond_val
= buf
->ReadWord(); mask
= 0x0000FFFF; break;
6144 case 1: cond_val
= buf
->ReadByte(); mask
= 0x000000FF; break;
6148 if (param
< 0x80 && _cur
.grffile
->param_end
<= param
) {
6149 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param
);
6153 uint32 param_val
= GetParamVal(param
, &cond_val
);
6155 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype
, param_val
, cond_val
);
6158 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6159 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6160 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6161 * So, when the condition type is one of those, the specific variable
6162 * 0x88 code is skipped, so the "general" code for the cargo
6163 * availability conditions kicks in.
6165 if (param
== 0x88 && (condtype
< 0x0B || condtype
> 0x0E)) {
6168 GRFConfig
*c
= GetGRFConfig(cond_val
, mask
);
6170 if (c
!= NULL
&& HasBit(c
->flags
, GCF_STATIC
) && !HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
) && _networking
) {
6171 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c
);
6175 if (condtype
!= 10 && c
== NULL
) {
6176 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val
));
6181 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6182 case 0x06: // Is GRFID active?
6183 result
= c
->status
== GCS_ACTIVATED
;
6186 case 0x07: // Is GRFID non-active?
6187 result
= c
->status
!= GCS_ACTIVATED
;
6190 case 0x08: // GRFID is not but will be active?
6191 result
= c
->status
== GCS_INITIALISED
;
6194 case 0x09: // GRFID is or will be active?
6195 result
= c
->status
== GCS_ACTIVATED
|| c
->status
== GCS_INITIALISED
;
6198 case 0x0A: // GRFID is not nor will be active
6199 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6200 result
= c
== NULL
|| c
->status
== GCS_DISABLED
|| c
->status
== GCS_NOT_FOUND
;
6203 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype
); return 0;
6206 /* Parameter or variable tests */
6208 case 0x00: result
= !!(param_val
& (1 << cond_val
));
6210 case 0x01: result
= !(param_val
& (1 << cond_val
));
6212 case 0x02: result
= (param_val
& mask
) == cond_val
;
6214 case 0x03: result
= (param_val
& mask
) != cond_val
;
6216 case 0x04: result
= (param_val
& mask
) < cond_val
;
6218 case 0x05: result
= (param_val
& mask
) > cond_val
;
6220 case 0x0B: result
= GetCargoIDByLabel(BSWAP32(cond_val
)) == CT_INVALID
;
6222 case 0x0C: result
= GetCargoIDByLabel(BSWAP32(cond_val
)) != CT_INVALID
;
6224 case 0x0D: result
= GetRailTypeByLabel(BSWAP32(cond_val
)) == INVALID_RAILTYPE
;
6226 case 0x0E: result
= GetRailTypeByLabel(BSWAP32(cond_val
)) != INVALID_RAILTYPE
;
6229 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype
); return 0;
6234 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6238 uint8 numsprites
= buf
->ReadByte();
6240 /* numsprites can be a GOTO label if it has been defined in the GRF
6241 * file. The jump will always be the first matching label that follows
6242 * the current nfo_line. If no matching label is found, the first matching
6243 * label in the file is used. */
6244 GRFLabel
*choice
= NULL
;
6245 for (GRFLabel
*label
= _cur
.grffile
->label
; label
!= NULL
; label
= label
->next
) {
6246 if (label
->label
!= numsprites
) continue;
6248 /* Remember a goto before the current line */
6249 if (choice
== NULL
) choice
= label
;
6250 /* If we find a label here, this is definitely good */
6251 if (label
->nfo_line
> _cur
.nfo_line
) {
6257 if (choice
!= NULL
) {
6258 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice
->label
, choice
->nfo_line
);
6259 FioSeekTo(choice
->pos
, SEEK_SET
);
6260 _cur
.nfo_line
= choice
->nfo_line
;
6264 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites
);
6266 if (numsprites
!= 0) return numsprites
;
6268 /* If an action 8 hasn't been encountered yet, disable the grf. */
6269 if (_cur
.grfconfig
->status
!= (_cur
.stage
< GLS_RESERVE
? GCS_INITIALISED
: GCS_ACTIVATED
)) {
6273 /* Zero means there are no sprites to skip, so we use -1 to indicate
6274 * that all further sprites should be skipped. */
6279 /* Action 0x08 (GLS_FILESCAN) */
6280 static int ScanInfo (ByteReader
*buf
)
6282 uint8 grf_version
= buf
->ReadByte();
6283 uint32 grfid
= buf
->ReadDWord();
6284 const char *name
= buf
->ReadString();
6286 _cur
.grfconfig
->ident
.grfid
= grfid
;
6288 if (grf_version
< 2 || grf_version
> 8) {
6289 SetBit(_cur
.grfconfig
->flags
, GCF_INVALID
);
6290 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
);
6293 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6294 if (GB(grfid
, 0, 8) == 0xFF) SetBit(_cur
.grfconfig
->flags
, GCF_SYSTEM
);
6296 _cur
.grfconfig
->name
->add (0x7F, grfid
, false, name
);
6298 if (buf
->HasData()) {
6299 const char *info
= buf
->ReadString();
6300 _cur
.grfconfig
->info
->add (0x7F, grfid
, true, info
);
6303 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6308 static int GRFInfo (ByteReader
*buf
)
6310 /* <08> <version> <grf-id> <name> <info>
6312 * B version newgrf version, currently 06
6313 * 4*B grf-id globally unique ID of this .grf file
6314 * S name name of this .grf set
6315 * S info string describing the set, and e.g. author and copyright */
6317 uint8 version
= buf
->ReadByte();
6318 uint32 grfid
= buf
->ReadDWord();
6319 const char *name
= buf
->ReadString();
6321 if (_cur
.stage
< GLS_RESERVE
&& _cur
.grfconfig
->status
!= GCS_UNKNOWN
) {
6322 DisableCur (STR_NEWGRF_ERROR_MULTIPLE_ACTION_8
);
6326 if (_cur
.grffile
->grfid
!= grfid
) {
6327 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
));
6328 _cur
.grffile
->grfid
= grfid
;
6331 _cur
.grffile
->grf_version
= version
;
6332 _cur
.grfconfig
->status
= _cur
.stage
< GLS_RESERVE
? GCS_INITIALISED
: GCS_ACTIVATED
;
6334 /* Do swap the GRFID for displaying purposes since people expect that */
6335 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
);
6341 static int SpriteReplace (ByteReader
*buf
)
6343 /* <0A> <num-sets> <set1> [<set2> ...]
6344 * <set>: <num-sprites> <first-sprite>
6346 * B num-sets How many sets of sprites to replace.
6348 * B num-sprites How many sprites are in this set
6349 * W first-sprite First sprite number to replace */
6351 uint8 num_sets
= buf
->ReadByte();
6353 for (uint i
= 0; i
< num_sets
; i
++) {
6354 uint8 num_sprites
= buf
->ReadByte();
6355 uint16 first_sprite
= buf
->ReadWord();
6357 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6358 i
, num_sprites
, first_sprite
6361 for (uint j
= 0; j
< num_sprites
; j
++) {
6362 int load_index
= first_sprite
+ j
;
6364 LoadNextSprite(load_index
, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
); // XXX
6366 /* Shore sprites now located at different addresses.
6367 * So detect when the old ones get replaced. */
6368 if (IsInsideMM(load_index
, SPR_ORIGINALSHORE_START
, SPR_ORIGINALSHORE_END
+ 1)) {
6369 if (_loaded_newgrf_features
.shore
!= SHORE_REPLACE_ACTION_5
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_A
;
6377 /* Action 0x0A (SKIP) */
6378 static int SkipActA (ByteReader
*buf
)
6380 uint8 num_sets
= buf
->ReadByte();
6383 for (uint i
= 0; i
< num_sets
; i
++) {
6384 /* Skip the sprites this replaces */
6385 skip
+= buf
->ReadByte();
6386 /* But ignore where they go */
6390 grfmsg (3, "SkipActA: Skipping %d sprites", skip
);
6396 static int GRFLoadError (ByteReader
*buf
)
6398 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6400 * B severity 00: notice, contine loading grf file
6401 * 01: warning, continue loading grf file
6402 * 02: error, but continue loading grf file, and attempt
6403 * loading grf again when loading or starting next game
6404 * 03: error, abort loading and prevent loading again in
6405 * the future (only when restarting the patch)
6406 * B language-id see action 4, use 1F for built-in error messages
6407 * B message-id message to show, see below
6408 * S message for custom messages (message-id FF), text of the message
6409 * not present for built-in messages.
6410 * V data additional data for built-in (or custom) messages
6411 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6413 static const StringID msgstr
[] = {
6414 STR_NEWGRF_ERROR_VERSION_NUMBER
,
6415 STR_NEWGRF_ERROR_DOS_OR_WINDOWS
,
6416 STR_NEWGRF_ERROR_UNSET_SWITCH
,
6417 STR_NEWGRF_ERROR_INVALID_PARAMETER
,
6418 STR_NEWGRF_ERROR_LOAD_BEFORE
,
6419 STR_NEWGRF_ERROR_LOAD_AFTER
,
6420 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER
,
6423 static const StringID sevstr
[] = {
6424 STR_NEWGRF_ERROR_MSG_INFO
,
6425 STR_NEWGRF_ERROR_MSG_WARNING
,
6426 STR_NEWGRF_ERROR_MSG_ERROR
,
6427 STR_NEWGRF_ERROR_MSG_FATAL
6430 byte severity
= buf
->ReadByte();
6431 byte lang
= buf
->ReadByte();
6432 byte message_id
= buf
->ReadByte();
6434 /* Skip the error if it isn't valid for the current language. */
6435 if (!CheckGrfLangID(lang
, _cur
.grffile
->grf_version
)) return 0;
6437 /* Skip the error until the activation stage unless bit 7 of the severity
6439 if (!HasBit(severity
, 7) && _cur
.stage
== GLS_INIT
) {
6440 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur
.stage
);
6443 ClrBit(severity
, 7);
6445 if (severity
>= lengthof(sevstr
)) {
6446 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity
);
6448 } else if (severity
== 3) {
6449 /* This is a fatal error, so make sure the GRF is deactivated and no
6450 * more of it gets loaded. */
6453 /* Make sure we show fatal errors, instead of silly infos from before */
6454 delete _cur
.grfconfig
->error
;
6455 _cur
.grfconfig
->error
= NULL
;
6458 if (message_id
>= lengthof(msgstr
) && message_id
!= 0xFF) {
6459 grfmsg(7, "GRFLoadError: Invalid message id.");
6461 } else if (!buf
->HasData (2)) {
6462 grfmsg(7, "GRFLoadError: No message data supplied.");
6464 } else if (_cur
.grfconfig
->error
== NULL
) {
6465 /* For now we can only show one message per newgrf file. */
6466 GRFError
*error
= new GRFError (sevstr
[severity
]);
6468 if (message_id
!= 0xFF) {
6469 error
->message
= msgstr
[message_id
];
6470 } else if (buf
->HasData()) {
6471 /* This is a custom error message. */
6472 const char *message
= buf
->ReadString();
6473 error
->custom_message
= TranslateTTDPatchCodes (_cur
.grffile
->grfid
, lang
, true, message
, SCC_RAW_STRING_POINTER
);
6475 grfmsg(7, "GRFLoadError: No custom message supplied.");
6476 error
->custom_message
= xstrdup("");
6479 if (buf
->HasData()) {
6480 const char *data
= buf
->ReadString();
6481 error
->data
= TranslateTTDPatchCodes(_cur
.grffile
->grfid
, lang
, true, data
);
6483 grfmsg(7, "GRFLoadError: No message data supplied.");
6484 error
->data
= xstrdup("");
6487 /* Only two parameter numbers can be used in the string. */
6488 for (uint i
= 0; i
< lengthof(error
->param_value
) && buf
->HasData(); i
++) {
6489 uint param_number
= buf
->ReadByte();
6490 error
->param_value
[i
] = _cur
.grffile
->GetParam(param_number
);
6493 _cur
.grfconfig
->error
= error
;
6496 return (severity
== 3) ? -1 : 0;
6500 static int GRFComment (ByteReader
*buf
)
6502 /* <0C> [<ignored...>]
6504 * V ignored Anything following the 0C is ignored */
6506 if (buf
->HasData()) grfmsg (2, "GRFComment: %s", buf
->ReadString());
6511 /* Action 0x0D (GLS_SAFETYSCAN) */
6512 static int SafeParamSet (ByteReader
*buf
)
6514 uint8 target
= buf
->ReadByte();
6516 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6517 if (target
< 0x80 || target
== 0x9E) return 0;
6519 /* GRM could be unsafe, but as here it can only happen after other GRFs
6520 * are loaded, it should be okay. If the GRF tried to use the slots it
6521 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6522 * sprites is considered safe. */
6524 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
6526 /* Skip remainder of GRF */
6531 static uint32
GetPatchVariable(uint8 param
)
6534 /* start year - 1920 */
6535 case 0x0B: return max(_settings_game
.game_creation
.starting_year
, ORIGINAL_BASE_YEAR
) - ORIGINAL_BASE_YEAR
;
6537 /* freight trains weight factor */
6538 case 0x0E: return _settings_game
.vehicle
.freight_trains
;
6540 /* empty wagon speed increase */
6541 case 0x0F: return 0;
6543 /* plane speed factor; our patch option is reversed from TTDPatch's,
6544 * the following is good for 1x, 2x and 4x (most common?) and...
6545 * well not really for 3x. */
6547 switch (_settings_game
.vehicle
.plane_speed
) {
6556 /* 2CC colourmap base sprite */
6557 case 0x11: return SPR_2CCMAP_BASE
;
6559 /* map size: format = -MABXYSS
6560 * M : the type of map
6561 * bit 0 : set : squared map. Bit 1 is now not relevant
6562 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6563 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6564 * clear : X is the bigger edge.
6565 * A : minimum edge(log2) of the map
6566 * B : maximum edge(log2) of the map
6567 * XY : edges(log2) of each side of the map.
6568 * SS : combination of both X and Y, thus giving the size(log2) of the map
6572 byte log_X
= MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6573 byte log_Y
= MapLogY() - 6;
6574 byte max_edge
= max(log_X
, log_Y
);
6576 if (log_X
== log_Y
) { // we have a squared map, since both edges are identical
6577 SetBit(map_bits
, 0);
6579 if (max_edge
== log_Y
) SetBit(map_bits
, 1); // edge Y been the biggest, mark it
6582 return (map_bits
<< 24) | (min(log_X
, log_Y
) << 20) | (max_edge
<< 16) |
6583 (log_X
<< 12) | (log_Y
<< 8) | (log_X
+ log_Y
);
6586 /* The maximum height of the map. */
6588 return _settings_game
.construction
.max_heightlevel
;
6590 /* Extra foundations base sprite */
6592 return SPR_SLOPES_BASE
;
6594 /* Shore base sprite */
6596 return SPR_SHORE_BASE
;
6599 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param
);
6605 static bool PerformGRM (uint32
*grm
, uint16 num_ids
, uint16 count
,
6606 uint8 op
, uint8 target
, uint32
*res
, const char *type
)
6612 /* Return GRFID of set that reserved ID */
6613 *res
= grm
[_cur
.grffile
->GetParam(target
)];
6617 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6618 if (op
== 2 || op
== 3) start
= _cur
.grffile
->GetParam(target
);
6620 for (uint i
= start
; i
< num_ids
; i
++) {
6624 if (op
== 2 || op
== 3) break;
6629 if (size
== count
) break;
6632 if (size
== count
) {
6633 /* Got the slot... */
6634 if (op
== 0 || op
== 3) {
6635 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count
, type
, start
);
6636 for (uint i
= 0; i
< count
; i
++) grm
[start
+ i
] = _cur
.grffile
->grfid
;
6642 /* Unable to allocate */
6643 if (op
!= 4 && op
!= 5) {
6644 /* Deactivate GRF */
6645 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count
, type
);
6646 DisableCur (STR_NEWGRF_ERROR_GRM_FAILED
);
6650 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count
, type
);
6656 /** Action 0x0D: Set parameter */
6657 static int ParamSet (ByteReader
*buf
)
6659 /* <0D> <target> <operation> <source1> <source2> [<data>]
6661 * B target parameter number where result is stored
6662 * B operation operation to perform, see below
6663 * B source1 first source operand
6664 * B source2 second source operand
6665 * D data data to use in the calculation, not necessary
6666 * if both source1 and source2 refer to actual parameters
6669 * 00 Set parameter equal to source1
6670 * 01 Addition, source1 + source2
6671 * 02 Subtraction, source1 - source2
6672 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6673 * 04 Signed multiplication, source1 * source2 (both signed)
6674 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6675 * signed quantity; left shift if positive and right shift if
6676 * negative, source1 is unsigned)
6677 * 06 Signed bit shift, source1 by source2
6678 * (source2 like in 05, and source1 as well)
6681 uint8 target
= buf
->ReadByte();
6682 uint8 oper
= buf
->ReadByte();
6683 uint32 src1
= buf
->ReadByte();
6684 uint32 src2
= buf
->ReadByte();
6687 if (buf
->HasData (4)) data
= buf
->ReadDWord();
6689 /* You can add 80 to the operation to make it apply only if the target
6690 * is not defined yet. In this respect, a parameter is taken to be
6691 * defined if any of the following applies:
6692 * - it has been set to any value in the newgrf(w).cfg parameter list
6693 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6694 * an earlier action D */
6695 if (HasBit(oper
, 7)) {
6696 if (target
< 0x80 && target
< _cur
.grffile
->param_end
) {
6697 grfmsg(7, "ParamSet: Param %u already defined, skipping", target
);
6701 oper
= GB(oper
, 0, 7);
6705 /* The source1 and source2 operands refer to the grf parameter number
6706 * like in action 6 and 7. In addition, they can refer to the special
6707 * variables available in action 7, or they can be FF to use the value
6708 * of <data>. If referring to parameters that are undefined, a value
6709 * of 0 is used instead. */
6710 src1
= (src1
== 0xFF) ? data
: GetParamVal(src1
, NULL
);
6711 src2
= (src2
== 0xFF) ? data
: GetParamVal(src2
, NULL
);
6712 } else if (GB(data
, 0, 8) != 0xFF) {
6713 /* Read another GRF File's parameter */
6714 const GRFFile
*file
= GetFileByGRFID(data
);
6715 GRFConfig
*c
= GetGRFConfig(data
);
6716 if (c
!= NULL
&& HasBit(c
->flags
, GCF_STATIC
) && !HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
) && _networking
) {
6717 /* Disable the read GRF if it is a static NewGRF. */
6718 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c
);
6720 } else if (file
== NULL
|| c
== NULL
|| c
->status
== GCS_DISABLED
) {
6722 } else if (src1
== 0xFE) {
6725 src1
= file
->GetParam(src1
);
6727 } else if (data
== 0x0000FFFF) {
6728 /* Patch variables */
6729 src1
= GetPatchVariable(src1
);
6731 /* GRF Resource Management */
6733 uint8 feature
= GB(data
, 8, 8);
6734 uint16 count
= GB(data
, 16, 16);
6736 if (_cur
.stage
== GLS_RESERVE
) {
6737 if (feature
== 0x08) {
6738 /* General sprites */
6740 /* Check if the allocated sprites will fit below the original sprite limit */
6741 if (_cur
.spriteid
+ count
>= 16384) {
6742 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count
);
6743 DisableCur (STR_NEWGRF_ERROR_GRM_FAILED
);
6747 /* Reserve space at the current sprite ID */
6748 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count
, _cur
.spriteid
);
6749 _grm_sprites
[GRFLocation(_cur
.grffile
->grfid
, _cur
.nfo_line
)] = _cur
.spriteid
;
6750 _cur
.spriteid
+= count
;
6753 /* Ignore GRM result during reservation */
6755 } else if (_cur
.stage
== GLS_ACTIVATION
) {
6757 case 0x00: // Trains
6758 case 0x01: // Road Vehicles
6760 case 0x03: // Aircraft
6761 if (!_settings_game
.vehicle
.dynamic_engines
) {
6762 if (!PerformGRM (&_grm_engines
[_engine_offsets
[feature
]], _engine_counts
[feature
], count
, op
, target
, &src1
, "vehicles")) {
6766 /* GRM does not apply for dynamic engine allocation. */
6770 src1
= _cur
.grffile
->GetParam(target
);
6780 case 0x08: // General sprites
6783 /* Return space reserved during reservation stage */
6784 src1
= _grm_sprites
[GRFLocation(_cur
.grffile
->grfid
, _cur
.nfo_line
)];
6785 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1
);
6789 src1
= _cur
.spriteid
;
6793 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op
);
6799 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6800 if (!PerformGRM (_grm_cargoes
, NUM_CARGO
* 2, count
, op
, target
, &src1
, "cargoes")) {
6805 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature
); return 0;
6808 /* Ignore GRM during initialization */
6813 /* TODO: You can access the parameters of another GRF file by using
6814 * source2=FE, source1=the other GRF's parameter number and data=GRF
6815 * ID. This is only valid with operation 00 (set). If the GRF ID
6816 * cannot be found, a value of 0 is used for the parameter value
6838 res
= (int32
)src1
* (int32
)src2
;
6842 if ((int32
)src2
< 0) {
6843 res
= src1
>> -(int32
)src2
;
6845 res
= src1
<< (src2
& 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6850 if ((int32
)src2
< 0) {
6851 res
= (int32
)src1
>> -(int32
)src2
;
6853 res
= (int32
)src1
<< (src2
& 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6857 case 0x07: // Bitwise AND
6861 case 0x08: // Bitwise OR
6865 case 0x09: // Unsigned division
6873 case 0x0A: // Signed divison
6877 res
= (int32
)src1
/ (int32
)src2
;
6881 case 0x0B: // Unsigned modulo
6889 case 0x0C: // Signed modulo
6893 res
= (int32
)src1
% (int32
)src2
;
6897 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper
); return 0;
6901 case 0x8E: // Y-Offset for train sprites
6902 _cur
.grffile
->traininfo_vehicle_pitch
= res
;
6905 case 0x8F: { // Rail track type cost factors
6906 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
6907 _railtypes
[RAILTYPE_RAIL
].cost_multiplier
= GB(res
, 0, 8);
6908 if (_settings_game
.vehicle
.disable_elrails
) {
6909 _railtypes
[RAILTYPE_ELECTRIC
].cost_multiplier
= GB(res
, 0, 8);
6910 _railtypes
[RAILTYPE_MONO
].cost_multiplier
= GB(res
, 8, 8);
6912 _railtypes
[RAILTYPE_ELECTRIC
].cost_multiplier
= GB(res
, 8, 8);
6913 _railtypes
[RAILTYPE_MONO
].cost_multiplier
= GB(res
, 16, 8);
6915 _railtypes
[RAILTYPE_MAGLEV
].cost_multiplier
= GB(res
, 16, 8);
6919 /* @todo implement */
6920 case 0x93: // Tile refresh offset to left
6921 case 0x94: // Tile refresh offset to right
6922 case 0x95: // Tile refresh offset upwards
6923 case 0x96: // Tile refresh offset downwards
6924 case 0x97: // Snow line height
6925 case 0x99: // Global ID offset
6926 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target
);
6929 case 0x9E: // Miscellaneous GRF features
6930 /* Set train list engine width */
6931 _cur
.grffile
->traininfo_vehicle_width
= HasBit(res
, GMB_TRAIN_WIDTH_32_PIXELS
) ? VEHICLEINFO_FULL_VEHICLE_WIDTH
: TRAININFO_DEFAULT_VEHICLE_WIDTH
;
6932 /* Remove the local flags from the global flags */
6933 ClrBit(res
, GMB_TRAIN_WIDTH_32_PIXELS
);
6935 /* Only copy safe bits for static grfs */
6936 if (HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
)) {
6937 uint32 safe_bits
= 0;
6938 SetBit(safe_bits
, GMB_SECOND_ROCKY_TILE_SET
);
6940 _misc_grf_features
= (_misc_grf_features
& ~safe_bits
) | (res
& safe_bits
);
6942 _misc_grf_features
= res
;
6946 case 0x9F: // locale-dependent settings
6947 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target
);
6951 if (target
< 0x80) {
6952 _cur
.grffile
->param
[target
] = res
;
6953 /* param is zeroed by default */
6954 if (target
+ 1U > _cur
.grffile
->param_end
) _cur
.grffile
->param_end
= target
+ 1;
6956 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target
);
6964 /* Action 0x0E (GLS_SAFETYSCAN) */
6965 static int SafeGRFInhibit (ByteReader
*buf
)
6967 /* <0E> <num> <grfids...>
6969 * B num Number of GRFIDs that follow
6970 * D grfids GRFIDs of the files to deactivate */
6972 uint8 num
= buf
->ReadByte();
6974 for (uint i
= 0; i
< num
; i
++) {
6975 uint32 grfid
= buf
->ReadDWord();
6977 /* GRF is unsafe it if tries to deactivate other GRFs */
6978 if (grfid
!= _cur
.grfconfig
->ident
.grfid
) {
6979 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
6981 /* Skip remainder of GRF */
6990 static int GRFInhibit (ByteReader
*buf
)
6992 /* <0E> <num> <grfids...>
6994 * B num Number of GRFIDs that follow
6995 * D grfids GRFIDs of the files to deactivate */
6997 uint8 num
= buf
->ReadByte();
6999 for (uint i
= 0; i
< num
; i
++) {
7000 uint32 grfid
= buf
->ReadDWord();
7001 GRFConfig
*file
= GetGRFConfig(grfid
);
7003 /* Unset activation flag */
7004 if (file
!= NULL
&& file
!= _cur
.grfconfig
) {
7005 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file
->filename
);
7006 DisableGrf (STR_NEWGRF_ERROR_FORCEFULLY_DISABLED
, file
);
7013 /** Action 0x0F - Define Town names */
7014 static int FeatureTownName (ByteReader
*buf
)
7016 /* <0F> <id> <style-name> <num-parts> <parts>
7018 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
7019 * V style-name Name of the style (only for final definition)
7020 * B num-parts Number of parts in this definition
7021 * V parts The parts */
7023 uint32 grfid
= _cur
.grffile
->grfid
;
7025 GRFTownName
*townname
= AddGRFTownName(grfid
);
7027 byte id
= buf
->ReadByte();
7028 grfmsg(6, "FeatureTownName: definition 0x%02X", id
& 0x7F);
7030 if (HasBit(id
, 7)) {
7031 /* Final definition */
7033 bool new_scheme
= _cur
.grffile
->grf_version
>= 7;
7035 byte lang
= buf
->ReadByte();
7037 byte nb_gen
= townname
->nb_gen
;
7041 const char *name
= buf
->ReadString();
7043 char *lang_name
= TranslateTTDPatchCodes(grfid
, lang
, false, name
);
7044 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang
, lang_name
);
7047 townname
->name
[nb_gen
] = AddGRFString(grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
7049 lang
= buf
->ReadByte();
7050 } while (lang
!= 0);
7051 townname
->id
[nb_gen
] = id
;
7055 byte nb
= buf
->ReadByte();
7056 grfmsg(6, "FeatureTownName: %u parts", nb
);
7058 townname
->nbparts
[id
] = nb
;
7059 townname
->partlist
[id
] = xcalloct
<NamePartList
>(nb
);
7061 for (int i
= 0; i
< nb
; i
++) {
7062 byte nbtext
= buf
->ReadByte();
7063 townname
->partlist
[id
][i
].bitstart
= buf
->ReadByte();
7064 townname
->partlist
[id
][i
].bitcount
= buf
->ReadByte();
7065 townname
->partlist
[id
][i
].maxprob
= 0;
7066 townname
->partlist
[id
][i
].partcount
= nbtext
;
7067 townname
->partlist
[id
][i
].parts
= xcalloct
<NamePart
>(nbtext
);
7068 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
);
7070 for (int j
= 0; j
< nbtext
; j
++) {
7071 byte prob
= buf
->ReadByte();
7073 if (HasBit(prob
, 7)) {
7074 byte ref_id
= buf
->ReadByte();
7076 if (townname
->nbparts
[ref_id
] == 0) {
7077 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id
);
7078 DelGRFTownName(grfid
);
7079 DisableCur (STR_NEWGRF_ERROR_INVALID_ID
);
7083 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i
, j
, ref_id
, prob
& 0x7F);
7084 townname
->partlist
[id
][i
].parts
[j
].data
.id
= ref_id
;
7086 const char *text
= buf
->ReadString();
7087 townname
->partlist
[id
][i
].parts
[j
].data
.text
= TranslateTTDPatchCodes(grfid
, 0, false, text
);
7088 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i
, j
, townname
->partlist
[id
][i
].parts
[j
].data
.text
, prob
);
7090 townname
->partlist
[id
][i
].parts
[j
].prob
= prob
;
7091 townname
->partlist
[id
][i
].maxprob
+= GB(prob
, 0, 7);
7093 grfmsg(6, "FeatureTownName: part %d, total probability %d", i
, townname
->partlist
[id
][i
].maxprob
);
7099 /** Action 0x10 - Define goto label */
7100 static int DefineGotoLabel (ByteReader
*buf
)
7102 /* <10> <label> [<comment>]
7104 * B label The label to define
7105 * V comment Optional comment - ignored */
7107 byte nfo_label
= buf
->ReadByte();
7109 GRFLabel
*label
= xmalloct
<GRFLabel
>();
7110 label
->label
= nfo_label
;
7111 label
->nfo_line
= _cur
.nfo_line
;
7112 label
->pos
= FioGetPos();
7115 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7116 if (_cur
.grffile
->label
== NULL
) {
7117 _cur
.grffile
->label
= label
;
7119 /* Attach the label to the end of the list */
7121 for (l
= _cur
.grffile
->label
; l
->next
!= NULL
; l
= l
->next
) {}
7125 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label
->label
);
7131 * Process a sound import from another GRF file.
7132 * @param sound Destination for sound.
7134 static void ImportGRFSound(SoundEntry
*sound
)
7136 const GRFFile
*file
;
7137 uint32 grfid
= FioReadDword();
7138 SoundID sound_id
= FioReadWord();
7140 file
= GetFileByGRFID(grfid
);
7141 if (file
== NULL
|| file
->sound_offset
== 0) {
7142 grfmsg(1, "ImportGRFSound: Source file not available");
7146 if (sound_id
>= file
->num_sounds
) {
7147 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id
);
7151 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id
, file
->sound_offset
+ sound_id
, grfid
);
7153 *sound
= *GetSound(file
->sound_offset
+ sound_id
);
7155 /* Reset volume and priority, which TTDPatch doesn't copy */
7156 sound
->volume
= 128;
7157 sound
->priority
= 0;
7161 * Load a sound from a file.
7162 * @param offs File offset to read sound from.
7163 * @param sound Destination for sound.
7165 static void LoadGRFSound(size_t offs
, SoundEntry
*sound
)
7167 /* Set default volume and priority */
7168 sound
->volume
= 0x80;
7169 sound
->priority
= 0;
7171 if (offs
!= SIZE_MAX
) {
7172 /* Sound is present in the NewGRF. */
7173 sound
->file_slot
= _cur
.file_index
;
7174 sound
->file_offset
= offs
;
7175 sound
->grf_container_ver
= _cur
.grf_container_ver
;
7180 static int GRFSound (ByteReader
*buf
)
7184 * W num Number of sound files that follow */
7186 uint16 num
= buf
->ReadWord();
7187 if (num
== 0) return 0;
7190 if (_cur
.grffile
->sound_offset
== 0) {
7191 _cur
.grffile
->sound_offset
= GetNumSounds();
7192 _cur
.grffile
->num_sounds
= num
;
7193 sound
= AllocateSound(num
);
7195 sound
= GetSound(_cur
.grffile
->sound_offset
);
7198 for (int i
= 0; i
< num
; i
++) {
7201 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7202 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7203 bool invalid
= i
>= _cur
.grffile
->num_sounds
;
7205 size_t offs
= FioGetPos();
7207 uint32 len
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
7208 byte type
= FioReadByte();
7210 if (_cur
.grf_container_ver
>= 2 && type
== 0xFD) {
7211 /* Reference to sprite section. */
7213 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7215 } else if (len
!= 4) {
7216 grfmsg(1, "GRFSound: Invalid sprite section import");
7219 uint32 id
= FioReadDword();
7220 if (_cur
.stage
== GLS_INIT
) LoadGRFSound(GetGRFSpriteOffset(id
), sound
+ i
);
7226 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7227 SkipSpriteData (type
, len
);
7232 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7236 byte action
= FioReadByte();
7239 /* Allocate sound only in init stage. */
7240 if (_cur
.stage
== GLS_INIT
) {
7241 if (_cur
.grf_container_ver
>= 2) {
7242 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7244 LoadGRFSound(offs
, sound
+ i
);
7247 FioSkipBytes(len
- 1); // already read <action>
7251 if (_cur
.stage
== GLS_ACTIVATION
) {
7252 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7253 * importing sounds, so this is probably all wrong... */
7254 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7255 ImportGRFSound(sound
+ i
);
7257 FioSkipBytes(len
- 1); // already read <action>
7262 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action
);
7263 FioSkipBytes(len
- 1); // already read <action>
7271 /* Action 0x11 (SKIP) */
7272 static int SkipAct11 (ByteReader
*buf
)
7276 * W num Number of sound files that follow */
7278 int skip
= buf
->ReadWord();
7279 grfmsg (3, "SkipAct11: Skipping %d sprites", skip
);
7284 static int LoadFontGlyph (ByteReader
*buf
)
7286 /* <12> <num_def> <font_size> <num_char> <base_char>
7288 * B num_def Number of definitions
7289 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7290 * B num_char Number of consecutive glyphs
7291 * W base_char First character index */
7293 uint8 num_def
= buf
->ReadByte();
7295 for (uint i
= 0; i
< num_def
; i
++) {
7296 FontSize size
= (FontSize
)buf
->ReadByte();
7297 uint8 num_char
= buf
->ReadByte();
7298 uint16 base_char
= buf
->ReadWord();
7301 if (size
>= FS_END
) {
7302 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size
);
7305 fc
= FontCache::Get (size
);
7308 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char
, base_char
, size
);
7310 for (uint c
= 0; c
< num_char
; c
++) {
7311 if (fc
!= NULL
) fc
->SetUnicodeGlyph (base_char
+ c
, _cur
.spriteid
);
7313 LoadNextSprite(_cur
.spriteid
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
7320 /** Action 0x12 (SKIP) */
7321 static int SkipAct12 (ByteReader
*buf
)
7323 /* <12> <num_def> <font_size> <num_char> <base_char>
7325 * B num_def Number of definitions
7326 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7327 * B num_char Number of consecutive glyphs
7328 * W base_char First character index */
7330 uint8 num_def
= buf
->ReadByte();
7333 for (uint i
= 0; i
< num_def
; i
++) {
7334 /* Ignore 'size' byte */
7337 /* Sum up number of characters */
7338 skip
+= buf
->ReadByte();
7340 /* Ignore 'base_char' word */
7344 grfmsg (3, "SkipAct12: Skipping %d sprites", skip
);
7350 static int TranslateGRFStrings (ByteReader
*buf
)
7352 /* <13> <grfid> <num-ent> <offset> <text...>
7354 * 4*B grfid The GRFID of the file whose texts are to be translated
7355 * B num-ent Number of strings
7356 * W offset First text ID
7357 * S text... Zero-terminated strings */
7359 uint32 grfid
= buf
->ReadDWord();
7360 const GRFConfig
*c
= GetGRFConfig(grfid
);
7361 if (c
== NULL
|| (c
->status
!= GCS_INITIALISED
&& c
->status
!= GCS_ACTIVATED
)) {
7362 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid
));
7366 if (c
->status
== GCS_INITIALISED
) {
7367 /* If the file is not active but will be activated later, give an error
7368 * and disable this file. */
7369 GRFError
*error
= DisableCur (STR_NEWGRF_ERROR_LOAD_AFTER
);
7372 GetString (tmp
, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE
);
7373 error
->data
= xstrdup(tmp
);
7378 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7379 * to be added as a generic string, thus the language id of 0x7F. For this to work
7380 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7381 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7382 * not change anything if a string has been provided specifically for this language. */
7383 byte language
= _cur
.grffile
->grf_version
>= 8 ? buf
->ReadByte() : 0x7F;
7384 byte num_strings
= buf
->ReadByte();
7385 uint16 first_id
= buf
->ReadWord();
7387 if (!((first_id
>= 0xD000 && first_id
+ num_strings
<= 0xD400) || (first_id
>= 0xD800 && first_id
+ num_strings
<= 0xE000))) {
7388 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id
, num_strings
);
7392 for (uint i
= 0; i
< num_strings
&& buf
->HasData(); i
++) {
7393 const char *string
= buf
->ReadString();
7395 if (StrEmpty(string
)) {
7396 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7400 AddGRFString(grfid
, first_id
+ i
, language
, true, true, string
, STR_UNDEFINED
);
7406 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7407 static bool ChangeGRFName(byte langid
, const char *str
)
7409 _cur
.grfconfig
->name
->add (langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7413 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7414 static bool ChangeGRFDescription(byte langid
, const char *str
)
7416 _cur
.grfconfig
->info
->add (langid
, _cur
.grfconfig
->ident
.grfid
, true, str
);
7420 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7421 static bool ChangeGRFURL(byte langid
, const char *str
)
7423 _cur
.grfconfig
->url
->add (langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7427 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7428 static bool ChangeGRFNumUsedParams(size_t len
, ByteReader
*buf
)
7431 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len
);
7434 _cur
.grfconfig
->num_valid_params
= min(buf
->ReadByte(), lengthof(_cur
.grfconfig
->param
));
7439 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7440 static bool ChangeGRFPalette(size_t len
, ByteReader
*buf
)
7443 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len
);
7446 char data
= buf
->ReadByte();
7447 GRFPalette pal
= GRFP_GRF_UNSET
;
7450 case 'A': pal
= GRFP_GRF_ANY
; break;
7451 case 'W': pal
= GRFP_GRF_WINDOWS
; break;
7452 case 'D': pal
= GRFP_GRF_DOS
; break;
7454 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data
);
7457 if (pal
!= GRFP_GRF_UNSET
) {
7458 _cur
.grfconfig
->palette
&= ~GRFP_GRF_MASK
;
7459 _cur
.grfconfig
->palette
|= pal
;
7465 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7466 static bool ChangeGRFBlitter(size_t len
, ByteReader
*buf
)
7469 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len
);
7472 char data
= buf
->ReadByte();
7473 GRFPalette pal
= GRFP_BLT_UNSET
;
7475 case '8': pal
= GRFP_BLT_UNSET
; break;
7476 case '3': pal
= GRFP_BLT_32BPP
; break;
7478 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data
);
7481 _cur
.grfconfig
->palette
&= ~GRFP_BLT_MASK
;
7482 _cur
.grfconfig
->palette
|= pal
;
7487 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7488 static bool ChangeGRFVersion(size_t len
, ByteReader
*buf
)
7491 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len
);
7494 /* Set min_loadable_version as well (default to minimal compatibility) */
7495 _cur
.grfconfig
->version
= _cur
.grfconfig
->min_loadable_version
= buf
->ReadDWord();
7500 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7501 static bool ChangeGRFMinVersion(size_t len
, ByteReader
*buf
)
7504 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len
);
7507 _cur
.grfconfig
->min_loadable_version
= buf
->ReadDWord();
7508 if (_cur
.grfconfig
->version
== 0) {
7509 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7510 _cur
.grfconfig
->min_loadable_version
= 0;
7512 if (_cur
.grfconfig
->version
< _cur
.grfconfig
->min_loadable_version
) {
7513 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur
.grfconfig
->min_loadable_version
);
7514 _cur
.grfconfig
->min_loadable_version
= _cur
.grfconfig
->version
;
7520 static GRFParameterInfo
*_cur_parameter
; ///< The parameter which info is currently changed by the newgrf.
7522 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7523 static bool ChangeGRFParamName(byte langid
, const char *str
)
7525 _cur_parameter
->name
.add (langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7529 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7530 static bool ChangeGRFParamDescription(byte langid
, const char *str
)
7532 _cur_parameter
->desc
.add (langid
, _cur
.grfconfig
->ident
.grfid
, true, str
);
7536 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7537 static bool ChangeGRFParamType(size_t len
, ByteReader
*buf
)
7540 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len
);
7543 GRFParameterType type
= (GRFParameterType
)buf
->ReadByte();
7544 if (type
< PTYPE_END
) {
7545 _cur_parameter
->type
= type
;
7547 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type
);
7553 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7554 static bool ChangeGRFParamLimits(size_t len
, ByteReader
*buf
)
7556 if (_cur_parameter
->type
!= PTYPE_UINT_ENUM
) {
7557 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7559 } else if (len
!= 8) {
7560 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len
);
7563 _cur_parameter
->min_value
= buf
->ReadDWord();
7564 _cur_parameter
->max_value
= buf
->ReadDWord();
7569 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7570 static bool ChangeGRFParamMask(size_t len
, ByteReader
*buf
)
7572 if (len
< 1 || len
> 3) {
7573 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len
);
7576 byte param_nr
= buf
->ReadByte();
7577 if (param_nr
>= lengthof(_cur
.grfconfig
->param
)) {
7578 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr
);
7581 _cur_parameter
->param_nr
= param_nr
;
7582 if (len
>= 2) _cur_parameter
->first_bit
= min(buf
->ReadByte(), 31);
7583 if (len
>= 3) _cur_parameter
->num_bit
= min(buf
->ReadByte(), 32 - _cur_parameter
->first_bit
);
7590 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7591 static bool ChangeGRFParamDefault(size_t len
, ByteReader
*buf
)
7594 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len
);
7597 _cur_parameter
->def_value
= buf
->ReadDWord();
7599 _cur
.grfconfig
->has_param_defaults
= true;
7604 * Data structure to store the allowed id/type combinations for action 14. The
7605 * data can be represented as a tree with 3 types of nodes:
7606 * 1. Branch nodes (identified by 'C' for choice).
7607 * 2. Binary leaf nodes (identified by 'B').
7608 * 3. Text leaf nodes (identified by 'T').
7610 struct AllowedSubtags
{
7611 typedef bool (*DataHandler
) (size_t, ByteReader
*); ///< Type of callback function for binary nodes
7612 typedef bool (*TextHandler
) (byte
, const char *str
); ///< Type of callback function for text nodes
7613 typedef bool (*BranchHandler
) (ByteReader
*); ///< Type of callback function for branch nodes
7615 uint32 id
; ///< The identifier for this node
7616 byte type
; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7617 byte nsub
; ///< The number of subtags, or 0 if not applicable
7619 DataHandler data
; ///< Callback function for a binary node, only valid if type == 'B'.
7620 TextHandler text
; ///< Callback function for a text node, only valid if type == 'T'.
7621 BranchHandler branch
; ///< Callback function for a branch node, only valid if type == 'C' && nsub == 0.
7622 const AllowedSubtags
*subtags
; ///< Pointer to a list of subtags, only valid if type == 'C' && nsub != 0.
7625 /** Create empty subtags object used to identify the end of a list. */
7626 CONSTEXPR
AllowedSubtags() :
7627 id(0), type(0), nsub(0), subtags(NULL
)
7631 * Create a binary leaf node.
7632 * @param id The id for this node.
7633 * @param handler The callback function to call.
7635 CONSTEXPR
AllowedSubtags (uint32 id
, DataHandler handler
) :
7636 id(id
), type('B'), nsub(0), data(handler
)
7641 * Create a text leaf node.
7642 * @param id The id for this node.
7643 * @param handler The callback function to call.
7645 CONSTEXPR
AllowedSubtags (uint32 id
, TextHandler handler
) :
7646 id(id
), type('T'), nsub(0), text(handler
)
7651 * Create a branch node with a callback handler
7652 * @param id The id for this node.
7653 * @param handler The callback function to call.
7655 CONSTEXPR
AllowedSubtags (uint32 id
, BranchHandler handler
) :
7656 id(id
), type('C'), nsub(0), branch(handler
)
7661 * Create a branch node with a list of sub-nodes.
7662 * @param id The id for this node.
7663 * @param subtags Array with all valid subtags.
7666 CONSTEXPR
AllowedSubtags (uint32 id
, const AllowedSubtags (&subtags
) [N
]) :
7667 id(id
), type('C'), nsub(N
), subtags(subtags
)
7669 assert_tcompile (N
> 0);
7670 assert_tcompile (N
<= UINT8_MAX
);
7674 static bool SkipUnknownInfo(ByteReader
*buf
, byte type
);
7675 static bool HandleNodes(ByteReader
*buf
, const AllowedSubtags
*tags
);
7678 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7679 * of some parameter values (type uint/enum) or the names of some bits
7680 * (type bitmask). In both cases the format is the same:
7681 * Each subnode should be a text node with the value/bit number as id.
7683 static bool ChangeGRFParamValueNames(ByteReader
*buf
)
7686 byte type
= buf
->ReadByte();
7687 if (type
== 0) break;
7689 uint32 id
= buf
->ReadDWord();
7690 if (type
!= 'T' || id
> _cur_parameter
->max_value
) {
7691 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7692 if (!SkipUnknownInfo(buf
, type
)) return false;
7696 byte langid
= buf
->ReadByte();
7697 const char *name_string
= buf
->ReadString();
7699 _cur_parameter
->value_names
[id
].add (langid
,
7700 _cur
.grfconfig
->ident
.grfid
, false, name_string
);
7705 /** Action14 parameter tags */
7706 static const AllowedSubtags _tags_parameters
[] = {
7707 AllowedSubtags('NAME', ChangeGRFParamName
),
7708 AllowedSubtags('DESC', ChangeGRFParamDescription
),
7709 AllowedSubtags('TYPE', ChangeGRFParamType
),
7710 AllowedSubtags('LIMI', ChangeGRFParamLimits
),
7711 AllowedSubtags('MASK', ChangeGRFParamMask
),
7712 AllowedSubtags('VALU', ChangeGRFParamValueNames
),
7713 AllowedSubtags('DFLT', ChangeGRFParamDefault
),
7718 * Callback function for 'INFO'->'PARA' to set extra information about the
7719 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7720 * the parameter number as id. The first parameter has id 0. The maximum
7721 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7723 static bool HandleParameterInfo(ByteReader
*buf
)
7726 byte type
= buf
->ReadByte();
7727 if (type
== 0) break;
7729 uint32 id
= buf
->ReadDWord();
7730 if (type
!= 'C' || id
>= _cur
.grfconfig
->num_valid_params
) {
7731 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7732 if (!SkipUnknownInfo(buf
, type
)) return false;
7736 if (id
>= _cur
.grfconfig
->param_info
.Length()) {
7737 uint num_to_add
= id
- _cur
.grfconfig
->param_info
.Length() + 1;
7738 GRFParameterInfo
**newdata
= _cur
.grfconfig
->param_info
.Append(num_to_add
);
7739 MemSetT
<GRFParameterInfo
*>(newdata
, 0, num_to_add
);
7741 if (_cur
.grfconfig
->param_info
[id
] == NULL
) {
7742 _cur
.grfconfig
->param_info
[id
] = new GRFParameterInfo(id
);
7744 _cur_parameter
= _cur
.grfconfig
->param_info
[id
];
7745 /* Read all parameter-data and process each node. */
7746 if (!HandleNodes(buf
, _tags_parameters
)) return false;
7751 /** Action14 tags for the INFO node */
7752 static const AllowedSubtags _tags_info
[] = {
7753 AllowedSubtags('NAME', ChangeGRFName
),
7754 AllowedSubtags('DESC', ChangeGRFDescription
),
7755 AllowedSubtags('URL_', ChangeGRFURL
),
7756 AllowedSubtags('NPAR', ChangeGRFNumUsedParams
),
7757 AllowedSubtags('PALS', ChangeGRFPalette
),
7758 AllowedSubtags('BLTR', ChangeGRFBlitter
),
7759 AllowedSubtags('VRSN', ChangeGRFVersion
),
7760 AllowedSubtags('MINV', ChangeGRFMinVersion
),
7761 AllowedSubtags('PARA', HandleParameterInfo
),
7765 /** Action14 root tags */
7766 static const AllowedSubtags _tags_root
[] = {
7767 AllowedSubtags('INFO', _tags_info
),
7773 * Try to skip the current node and all subnodes (if it's a branch node).
7774 * @param buf Buffer.
7775 * @param type The node type to skip.
7776 * @return True if we could skip the node, false if an error occurred.
7778 static bool SkipUnknownInfo(ByteReader
*buf
, byte type
)
7780 /* type and id are already read */
7784 byte new_type
= buf
->ReadByte();
7785 if (new_type
== 0) break;
7786 buf
->ReadDWord(); // skip the id
7787 if (!SkipUnknownInfo(buf
, new_type
)) return false;
7792 buf
->ReadByte(); // lang
7793 buf
->ReadString(); // actual text
7797 uint16 size
= buf
->ReadWord();
7810 * Handle the nodes of an Action14
7811 * @param type Type of node.
7813 * @param buf Buffer.
7814 * @param subtags Allowed subtags.
7815 * @return Whether all tags could be handled.
7817 static bool HandleNode (byte type
, uint32 id
, ByteReader
*buf
, const AllowedSubtags
*subtags
)
7819 for (const AllowedSubtags
*tag
= subtags
; tag
->type
!= 0; tag
++) {
7820 if (tag
->id
!= BSWAP32(id
) || tag
->type
!= type
) continue;
7822 default: NOT_REACHED();
7825 byte langid
= buf
->ReadByte();
7826 return tag
->text (langid
, buf
->ReadString());
7830 size_t len
= buf
->ReadWord();
7831 if (!buf
->HasData (len
)) return false;
7832 return tag
->data (len
, buf
);
7836 if (tag
->nsub
== 0) {
7837 return tag
->branch (buf
);
7839 return HandleNodes (buf
, tag
->subtags
);
7843 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type
, id
);
7844 return SkipUnknownInfo(buf
, type
);
7848 * Handle the contents of a 'C' choice of an Action14
7849 * @param buf Buffer.
7850 * @param subtags List of subtags.
7851 * @return Whether the nodes could all be handled.
7853 static bool HandleNodes (ByteReader
*buf
, const AllowedSubtags
*subtags
)
7856 byte type
= buf
->ReadByte();
7857 if (type
== 0) break;
7858 uint32 id
= buf
->ReadDWord();
7859 if (!HandleNode(type
, id
, buf
, subtags
)) return false;
7865 * Handle Action 0x14
7866 * @param buf Buffer.
7868 static int StaticGRFInfo (ByteReader
*buf
)
7870 /* <14> <type> <id> <text/data...> */
7871 HandleNodes(buf
, _tags_root
);
7876 * Set the current NewGRF as unsafe for static use
7877 * @param buf Unused.
7878 * @note Used during safety scan on unsafe actions.
7880 static int GRFUnsafe (ByteReader
*buf
)
7882 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
7884 /* Skip remainder of GRF */
7889 /** Initialize the TTDPatch flags */
7890 static void InitializeGRFSpecial()
7892 _ttdpatch_flags
[0] = ((_settings_game
.station
.never_expire_airports
? 1 : 0) << 0x0C) // keepsmallairport
7893 | (1 << 0x0D) // newairports
7894 | (1 << 0x0E) // largestations
7895 | ((_settings_game
.construction
.max_bridge_length
> 16 ? 1 : 0) << 0x0F) // longbridges
7896 | (0 << 0x10) // loadtime
7897 | (1 << 0x12) // presignals
7898 | (1 << 0x13) // extpresignals
7899 | ((_settings_game
.vehicle
.never_expire_vehicles
? 1 : 0) << 0x16) // enginespersist
7900 | (1 << 0x1B) // multihead
7901 | (1 << 0x1D) // lowmemory
7902 | (1 << 0x1E); // generalfixes
7904 _ttdpatch_flags
[1] = ((_settings_game
.economy
.station_noise_level
? 1 : 0) << 0x07) // moreairports - based on units of noise
7905 | (1 << 0x08) // mammothtrains
7906 | (1 << 0x09) // trainrefit
7907 | (0 << 0x0B) // subsidiaries
7908 | ((_settings_game
.order
.gradual_loading
? 1 : 0) << 0x0C) // gradualloading
7909 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7910 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7911 | (1 << 0x14) // bridgespeedlimits
7912 | (1 << 0x16) // eternalgame
7913 | (1 << 0x17) // newtrains
7914 | (1 << 0x18) // newrvs
7915 | (1 << 0x19) // newships
7916 | (1 << 0x1A) // newplanes
7917 | ((_settings_game
.construction
.train_signal_side
== 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7918 | ((_settings_game
.vehicle
.disable_elrails
? 0 : 1) << 0x1C); // electrifiedrailway
7920 _ttdpatch_flags
[2] = (1 << 0x01) // loadallgraphics - obsolote
7921 | (1 << 0x03) // semaphores
7922 | (1 << 0x0A) // newobjects
7923 | (0 << 0x0B) // enhancedgui
7924 | (0 << 0x0C) // newagerating
7925 | ((_settings_game
.construction
.build_on_slopes
? 1 : 0) << 0x0D) // buildonslopes
7926 | (1 << 0x0E) // fullloadany
7927 | (1 << 0x0F) // planespeed
7928 | (0 << 0x10) // moreindustriesperclimate - obsolete
7929 | (0 << 0x11) // moretoylandfeatures
7930 | (1 << 0x12) // newstations
7931 | (1 << 0x13) // tracktypecostdiff
7932 | (1 << 0x14) // manualconvert
7933 | ((_settings_game
.construction
.build_on_slopes
? 1 : 0) << 0x15) // buildoncoasts
7934 | (1 << 0x16) // canals
7935 | (1 << 0x17) // newstartyear
7936 | ((_settings_game
.vehicle
.freight_trains
> 1 ? 1 : 0) << 0x18) // freighttrains
7937 | (1 << 0x19) // newhouses
7938 | (1 << 0x1A) // newbridges
7939 | (1 << 0x1B) // newtownnames
7940 | (1 << 0x1C) // moreanimation
7941 | ((_settings_game
.vehicle
.wagon_speed_limits
? 1 : 0) << 0x1D) // wagonspeedlimits
7942 | (1 << 0x1E) // newshistory
7943 | (0 << 0x1F); // custombridgeheads
7945 _ttdpatch_flags
[3] = (0 << 0x00) // newcargodistribution
7946 | (1 << 0x01) // windowsnap
7947 | ((_settings_game
.economy
.allow_town_roads
|| _generating_world
? 0 : 1) << 0x02) // townbuildnoroad
7948 | (1 << 0x03) // pathbasedsignalling
7949 | (0 << 0x04) // aichoosechance
7950 | (1 << 0x05) // resolutionwidth
7951 | (1 << 0x06) // resolutionheight
7952 | (1 << 0x07) // newindustries
7953 | ((_settings_game
.order
.improved_load
? 1 : 0) << 0x08) // fifoloading
7954 | (0 << 0x09) // townroadbranchprob
7955 | (0 << 0x0A) // tempsnowline
7956 | (1 << 0x0B) // newcargo
7957 | (1 << 0x0C) // enhancemultiplayer
7958 | (1 << 0x0D) // onewayroads
7959 | (1 << 0x0E) // irregularstations
7960 | (1 << 0x0F) // statistics
7961 | (1 << 0x10) // newsounds
7962 | (1 << 0x11) // autoreplace
7963 | (1 << 0x12) // autoslope
7964 | (0 << 0x13) // followvehicle
7965 | (1 << 0x14) // trams
7966 | (0 << 0x15) // enhancetunnels
7967 | (1 << 0x16) // shortrvs
7968 | (1 << 0x17) // articulatedrvs
7969 | ((_settings_game
.vehicle
.dynamic_engines
? 1 : 0) << 0x18) // dynamic engines
7970 | (1 << 0x1E) // variablerunningcosts
7971 | (1 << 0x1F); // any switch is on
7974 /** Reset and clear all NewGRF stations */
7975 static void ResetCustomStations()
7977 const GRFFile
* const *end
= _grf_files
.End();
7978 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7979 StationSpec
**&stations
= (*file
)->stations
;
7980 if (stations
== NULL
) continue;
7981 for (uint i
= 0; i
< NUM_STATIONS_PER_GRF
; i
++) {
7982 if (stations
[i
] == NULL
) continue;
7983 StationSpec
*statspec
= stations
[i
];
7985 /* Release this station */
7989 /* Free and reset the station data */
7995 /** Reset and clear all NewGRF houses */
7996 static void ResetCustomHouses()
7998 const GRFFile
* const *end
= _grf_files
.End();
7999 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8000 HouseSpec
**&housespec
= (*file
)->housespec
;
8001 if (housespec
== NULL
) continue;
8002 for (uint i
= 0; i
< NUM_HOUSES_PER_GRF
; i
++) {
8011 /** Reset and clear all NewGRF airports */
8012 static void ResetCustomAirports()
8014 const GRFFile
* const *end
= _grf_files
.End();
8015 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8016 AirportSpec
**aslist
= (*file
)->airportspec
;
8017 if (aslist
!= NULL
) {
8018 for (uint i
= 0; i
< NUM_AIRPORTS_PER_GRF
; i
++) {
8019 AirportSpec
*as
= aslist
[i
];
8022 /* We need to remove the tiles layouts */
8023 for (int j
= 0; j
< as
->num_table
; j
++) {
8024 /* remove the individual layouts */
8033 (*file
)->airportspec
= NULL
;
8036 AirportTileSpec
**&airporttilespec
= (*file
)->airtspec
;
8037 if (airporttilespec
!= NULL
) {
8038 for (uint i
= 0; i
< NUM_AIRPORTTILES_PER_GRF
; i
++) {
8039 free(airporttilespec
[i
]);
8041 free(airporttilespec
);
8042 airporttilespec
= NULL
;
8047 /** Reset and clear all NewGRF industries */
8048 static void ResetCustomIndustries()
8050 const GRFFile
* const *end
= _grf_files
.End();
8051 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8052 IndustrySpec
**&industryspec
= (*file
)->industryspec
;
8053 IndustryTileSpec
**&indtspec
= (*file
)->indtspec
;
8055 /* We are verifiying both tiles and industries specs loaded from the grf file
8056 * First, let's deal with industryspec */
8057 if (industryspec
!= NULL
) {
8058 for (uint i
= 0; i
< NUM_INDUSTRYTYPES_PER_GRF
; i
++) {
8059 IndustrySpec
*ind
= industryspec
[i
];
8060 if (ind
== NULL
) continue;
8062 /* We need to remove the sounds array */
8063 if (HasBit(ind
->cleanup_flag
, CLEAN_RANDOMSOUNDS
)) {
8064 free(ind
->random_sounds
);
8067 /* We need to remove the tiles layouts */
8068 CleanIndustryTileTable(ind
);
8074 industryspec
= NULL
;
8077 if (indtspec
== NULL
) continue;
8078 for (uint i
= 0; i
< NUM_INDUSTRYTILES_PER_GRF
; i
++) {
8087 /** Reset and clear all NewObjects */
8088 static void ResetCustomObjects()
8090 const GRFFile
* const *end
= _grf_files
.End();
8091 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8092 ObjectSpec
**&objectspec
= (*file
)->objectspec
;
8093 if (objectspec
== NULL
) continue;
8094 for (uint i
= 0; i
< NUM_OBJECTS_PER_GRF
; i
++) {
8095 free(objectspec
[i
]);
8103 /** Reset and clear all NewGRFs */
8104 static void ResetNewGRF()
8106 const GRFFile
* const *end
= _grf_files
.End();
8107 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8112 _cur
.grffile
= NULL
;
8115 /** Clear all NewGRF errors */
8116 static void ResetNewGRFErrors()
8118 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
8119 if (!HasBit(c
->flags
, GCF_COPY
) && c
->error
!= NULL
) {
8127 * Reset all NewGRF loaded data
8130 void ResetNewGRFData()
8133 CleanUpGRFTownNames();
8135 /* Copy/reset original engine info data */
8138 /* Copy/reset original bridge info data */
8141 /* Reset rail type information */
8144 /* Allocate temporary refit/cargo class data */
8145 _gted
= xcalloct
<GRFTempEngineData
>(Engine::GetPoolSize());
8147 /* Fill rail type label temporary data for default trains */
8149 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_TRAIN
) {
8150 _gted
[e
->index
].railtypelabel
= GetRailTypeInfo(e
->u
.rail
.railtype
)->label
;
8153 /* Reset GRM reservations */
8154 memset(&_grm_engines
, 0, sizeof(_grm_engines
));
8155 memset(&_grm_cargoes
, 0, sizeof(_grm_cargoes
));
8157 /* Reset generic feature callback lists */
8158 ResetGenericCallbacks();
8160 /* Reset price base data */
8161 ResetPriceBaseMultipliers();
8163 /* Reset the curencies array */
8166 /* Reset the house array */
8167 ResetCustomHouses();
8170 /* Reset the industries structures*/
8171 ResetCustomIndustries();
8174 /* Reset the objects. */
8175 ObjectClass::Reset();
8176 ResetCustomObjects();
8179 /* Reset station classes */
8180 StationClass::Reset();
8181 ResetCustomStations();
8183 /* Reset airport-related structures */
8184 AirportClass::Reset();
8185 ResetCustomAirports();
8186 AirportSpec::ResetAirports();
8187 AirportTileSpec::ResetAirportTiles();
8189 /* Reset canal sprite groups and flags */
8190 memset(_water_feature
, 0, sizeof(_water_feature
));
8192 /* Reset the snowline table. */
8195 /* Reset NewGRF files */
8198 /* Reset NewGRF errors. */
8199 ResetNewGRFErrors();
8201 /* Set up the default cargo types */
8202 SetupCargoForClimate(_settings_game
.game_creation
.landscape
);
8204 /* Reset misc GRF features and train list display variables */
8205 _misc_grf_features
= 0;
8207 _loaded_newgrf_features
.has_2CC
= false;
8208 _loaded_newgrf_features
.used_liveries
= 1 << LS_DEFAULT
;
8209 _loaded_newgrf_features
.has_newhouses
= false;
8210 _loaded_newgrf_features
.has_newindustries
= false;
8211 _loaded_newgrf_features
.shore
= SHORE_REPLACE_NONE
;
8213 /* Clear all GRF overrides */
8214 _grf_id_overrides
.clear();
8216 InitializeSoundPool();
8217 SpriteGroup::clear();
8221 * Reset NewGRF data which is stored persistently in savegames.
8223 void ResetPersistentNewGRFData()
8225 /* Reset override managers */
8226 _engine_mngr
.ResetToDefaultMapping();
8227 _house_mngr
.ResetMapping();
8228 _industry_mngr
.ResetMapping();
8229 _industile_mngr
.ResetMapping();
8230 _airport_mngr
.ResetMapping();
8231 _airporttile_mngr
.ResetMapping();
8235 * Construct the Cargo Mapping
8236 * @note This is the reverse of a cargo translation table
8238 static void BuildCargoTranslationMap()
8240 memset(_cur
.grffile
->cargo_map
, 0xFF, sizeof(_cur
.grffile
->cargo_map
));
8242 for (CargoID c
= 0; c
< NUM_CARGO
; c
++) {
8243 const CargoSpec
*cs
= CargoSpec::Get(c
);
8244 if (!cs
->IsValid()) continue;
8246 if (_cur
.grffile
->cargo_list
.Length() == 0) {
8247 /* Default translation table, so just a straight mapping to bitnum */
8248 _cur
.grffile
->cargo_map
[c
] = cs
->bitnum
;
8250 /* Check the translation table for this cargo's label */
8251 int index
= _cur
.grffile
->cargo_list
.FindIndex(cs
->label
);
8252 if (index
>= 0) _cur
.grffile
->cargo_map
[c
] = index
;
8258 * Constructor for GRFFile
8259 * @param config GRFConfig to copy name, grfid and parameters from.
8261 GRFFile::GRFFile(const GRFConfig
*config
)
8263 this->filename
= xstrdup(config
->filename
);
8264 this->grfid
= config
->ident
.grfid
;
8266 /* Initialise local settings to defaults */
8267 this->traininfo_vehicle_pitch
= 0;
8268 this->traininfo_vehicle_width
= TRAININFO_DEFAULT_VEHICLE_WIDTH
;
8270 /* Mark price_base_multipliers as 'not set' */
8271 for (Price i
= PR_BEGIN
; i
< PR_END
; i
++) {
8272 this->price_base_multipliers
[i
] = INVALID_PRICE_MODIFIER
;
8275 /* Initialise rail type map with default rail types */
8276 memset(this->railtype_map
, INVALID_RAILTYPE
, sizeof(this->railtype_map
));
8277 this->railtype_map
[0] = RAILTYPE_RAIL
;
8278 this->railtype_map
[1] = RAILTYPE_ELECTRIC
;
8279 this->railtype_map
[2] = RAILTYPE_MONO
;
8280 this->railtype_map
[3] = RAILTYPE_MAGLEV
;
8282 /* Copy the initial parameter list
8283 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8284 assert_compile(lengthof(this->param
) == lengthof(config
->param
) && lengthof(this->param
) == 0x80);
8286 assert(config
->num_params
<= lengthof(config
->param
));
8287 this->param_end
= config
->num_params
;
8288 if (this->param_end
> 0) {
8289 MemCpyT(this->param
, config
->param
, this->param_end
);
8295 free(this->filename
);
8296 delete[] this->language_map
;
8301 * List of what cargo labels are refittable for the given the vehicle-type.
8302 * Only currently active labels are applied.
8304 static const CargoLabel _default_refitmasks_rail
[] = {
8305 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8306 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8307 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8311 static const CargoLabel _default_refitmasks_road
[] = {
8314 static const CargoLabel _default_refitmasks_ships
[] = {
8315 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8316 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8317 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8321 static const CargoLabel _default_refitmasks_aircraft
[] = {
8322 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8323 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8326 static const CargoLabel
* const _default_refitmasks
[] = {
8327 _default_refitmasks_rail
,
8328 _default_refitmasks_road
,
8329 _default_refitmasks_ships
,
8330 _default_refitmasks_aircraft
,
8335 * Precalculate refit masks from cargo classes for all vehicles.
8337 static void CalculateRefitMasks()
8341 FOR_ALL_ENGINES(e
) {
8342 EngineID engine
= e
->index
;
8343 EngineInfo
*ei
= &e
->info
;
8344 bool only_defaultcargo
; ///< Set if the vehicle shall carry only the default cargo
8346 /* Did the newgrf specify any refitting? If not, use defaults. */
8347 if (_gted
[engine
].refittability
!= GRFTempEngineData::UNSET
) {
8349 uint32 not_mask
= 0;
8350 uint32 xor_mask
= ei
->refit_mask
;
8352 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8353 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8354 only_defaultcargo
= _gted
[engine
].refittability
== GRFTempEngineData::EMPTY
;
8356 if (_gted
[engine
].cargo_allowed
!= 0) {
8357 /* Build up the list of cargo types from the set cargo classes. */
8358 const CargoSpec
*cs
;
8359 FOR_ALL_CARGOSPECS(cs
) {
8360 if (_gted
[engine
].cargo_allowed
& cs
->classes
) SetBit(mask
, cs
->Index());
8361 if (_gted
[engine
].cargo_disallowed
& cs
->classes
) SetBit(not_mask
, cs
->Index());
8365 ei
->refit_mask
= ((mask
& ~not_mask
) ^ xor_mask
) & _cargo_mask
;
8367 /* Apply explicit refit includes/excludes. */
8368 ei
->refit_mask
|= _gted
[engine
].ctt_include_mask
;
8369 ei
->refit_mask
&= ~_gted
[engine
].ctt_exclude_mask
;
8371 uint32 xor_mask
= 0;
8373 /* Don't apply default refit mask to wagons nor engines with no capacity */
8374 if (e
->type
!= VEH_TRAIN
|| (e
->u
.rail
.capacity
!= 0 && e
->u
.rail
.railveh_type
!= RAILVEH_WAGON
)) {
8375 const CargoLabel
*cl
= _default_refitmasks
[e
->type
];
8376 for (uint i
= 0;; i
++) {
8377 if (cl
[i
] == 0) break;
8379 CargoID cargo
= GetCargoIDByLabel(cl
[i
]);
8380 if (cargo
== CT_INVALID
) continue;
8382 SetBit(xor_mask
, cargo
);
8386 ei
->refit_mask
= xor_mask
& _cargo_mask
;
8388 /* If the mask is zero, the vehicle shall only carry the default cargo */
8389 only_defaultcargo
= (ei
->refit_mask
== 0);
8392 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8393 if (!HasBit(_cargo_mask
, ei
->cargo_type
)) ei
->cargo_type
= CT_INVALID
;
8395 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8396 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8397 if (!only_defaultcargo
&& (e
->type
!= VEH_SHIP
|| e
->u
.ship
.old_refittable
) && ei
->cargo_type
!= CT_INVALID
&& !HasBit(ei
->refit_mask
, ei
->cargo_type
)) {
8398 ei
->cargo_type
= CT_INVALID
;
8401 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8402 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8403 if (ei
->cargo_type
== CT_INVALID
&& ei
->refit_mask
!= 0) {
8404 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8405 const uint8
*cargo_map_for_first_refittable
= NULL
;
8407 const GRFFile
*file
= _gted
[engine
].defaultcargo_grf
;
8408 if (file
== NULL
) file
= e
->GetGRF();
8409 if (file
!= NULL
&& file
->grf_version
>= 8 && file
->cargo_list
.Length() != 0) {
8410 cargo_map_for_first_refittable
= file
->cargo_map
;
8414 if (cargo_map_for_first_refittable
!= NULL
) {
8415 /* Use first refittable cargo from cargo translation table */
8416 byte best_local_slot
= 0xFF;
8418 FOR_EACH_SET_CARGO_ID(cargo_type
, ei
->refit_mask
) {
8419 byte local_slot
= cargo_map_for_first_refittable
[cargo_type
];
8420 if (local_slot
< best_local_slot
) {
8421 best_local_slot
= local_slot
;
8422 ei
->cargo_type
= cargo_type
;
8427 if (ei
->cargo_type
== CT_INVALID
) {
8428 /* Use first refittable cargo slot */
8429 ei
->cargo_type
= (CargoID
)FindFirstBit(ei
->refit_mask
);
8432 if (ei
->cargo_type
== CT_INVALID
) ei
->climates
= 0;
8434 /* Clear refit_mask for not refittable ships */
8435 if (e
->type
== VEH_SHIP
&& !e
->u
.ship
.old_refittable
) {
8441 /** Set to use the correct action0 properties for each canal feature */
8442 static void FinaliseCanals()
8444 for (uint i
= 0; i
< CF_END
; i
++) {
8445 if (_water_feature
[i
].grffile
!= NULL
) {
8446 _water_feature
[i
].callback_mask
= _water_feature
[i
].grffile
->canal_local_properties
[i
].callback_mask
;
8447 _water_feature
[i
].flags
= _water_feature
[i
].grffile
->canal_local_properties
[i
].flags
;
8452 /** Check for invalid engines */
8453 static void FinaliseEngineArray()
8457 FOR_ALL_ENGINES(e
) {
8458 if (e
->GetGRF() == NULL
) {
8459 const EngineIDMapping
&eid
= _engine_mngr
[e
->index
];
8460 if (eid
.grfid
!= INVALID_GRFID
|| eid
.internal_id
!= eid
.substitute_id
) {
8461 e
->info
.string_id
= STR_NEWGRF_INVALID_ENGINE
;
8465 /* When the train does not set property 27 (misc flags), but it
8466 * is overridden by a NewGRF graphically we want to disable the
8467 * flipping possibility. */
8468 if (e
->type
== VEH_TRAIN
&& !_gted
[e
->index
].prop27_set
&& e
->GetGRF() != NULL
&& is_custom_sprite(e
->u
.rail
.image_index
)) {
8469 ClrBit(e
->info
.misc_flags
, EF_RAIL_FLIPS
);
8472 /* Skip wagons, there livery is defined via the engine */
8473 if (e
->type
!= VEH_TRAIN
|| e
->u
.rail
.railveh_type
!= RAILVEH_WAGON
) {
8474 LiveryScheme ls
= GetEngineLiveryScheme(e
->index
, INVALID_ENGINE
, NULL
);
8475 SetBit(_loaded_newgrf_features
.used_liveries
, ls
);
8476 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8478 if (e
->type
== VEH_TRAIN
) {
8479 SetBit(_loaded_newgrf_features
.used_liveries
, LS_FREIGHT_WAGON
);
8486 SetBit(_loaded_newgrf_features
.used_liveries
, LS_PASSENGER_WAGON_STEAM
+ ls
- LS_STEAM
);
8491 SetBit(_loaded_newgrf_features
.used_liveries
, LS_PASSENGER_WAGON_DIESEL
+ ls
- LS_DMU
);
8494 default: NOT_REACHED();
8501 /** Check for invalid cargoes */
8502 static void FinaliseCargoArray()
8504 for (CargoID c
= 0; c
< NUM_CARGO
; c
++) {
8505 CargoSpec
*cs
= CargoSpec::Get(c
);
8506 if (!cs
->IsValid()) {
8507 cs
->name
= cs
->name_single
= cs
->units_volume
= STR_NEWGRF_INVALID_CARGO
;
8508 cs
->quantifier
= STR_NEWGRF_INVALID_CARGO_QUANTITY
;
8509 cs
->abbrev
= STR_NEWGRF_INVALID_CARGO_ABBREV
;
8515 * Check if a given housespec is valid and disable it if it's not.
8516 * The housespecs that follow it are used to check the validity of
8518 * @param hs The housespec to check.
8519 * @param next1 The housespec that follows \c hs.
8520 * @param next2 The housespec that follows \c next1.
8521 * @param next3 The housespec that follows \c next2.
8522 * @param filename The filename of the newgrf this house was defined in.
8523 * @return Whether the given housespec is valid.
8525 static bool IsHouseSpecValid(HouseSpec
*hs
, const HouseSpec
*next1
, const HouseSpec
*next2
, const HouseSpec
*next3
, const char *filename
)
8527 if (((hs
->building_flags
& BUILDING_HAS_2_TILES
) != 0 &&
8528 (next1
== NULL
|| !next1
->enabled
|| (next1
->building_flags
& BUILDING_HAS_1_TILE
) != 0)) ||
8529 ((hs
->building_flags
& BUILDING_HAS_4_TILES
) != 0 &&
8530 (next2
== NULL
|| !next2
->enabled
|| (next2
->building_flags
& BUILDING_HAS_1_TILE
) != 0 ||
8531 next3
== NULL
|| !next3
->enabled
|| (next3
->building_flags
& BUILDING_HAS_1_TILE
) != 0))) {
8532 hs
->enabled
= false;
8533 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
);
8537 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8538 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8539 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8540 if (((hs
->building_flags
& BUILDING_HAS_2_TILES
) != 0 && next1
->population
!= 0) ||
8541 ((hs
->building_flags
& BUILDING_HAS_4_TILES
) != 0 && (next2
->population
!= 0 || next3
->population
!= 0))) {
8542 hs
->enabled
= false;
8543 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
);
8547 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8548 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8549 if (filename
!= NULL
&& (hs
->building_flags
& BUILDING_HAS_1_TILE
) != (HouseSpec::Get(hs
->grf_prop
.subst_id
)->building_flags
& BUILDING_HAS_1_TILE
)) {
8550 hs
->enabled
= false;
8551 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
);
8555 /* Make sure that additional parts of multitile houses are not available. */
8556 if ((hs
->building_flags
& BUILDING_HAS_1_TILE
) == 0 && (hs
->building_availability
& HZ_ZONALL
) != 0 && (hs
->building_availability
& HZ_CLIMALL
) != 0) {
8557 hs
->enabled
= false;
8558 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
);
8566 * Make sure there is at least one house available in the year 0 for the given
8568 * @param bitmask The climate to check for. Exactly one climate bit should be
8571 static void EnsureEarlyHouses (HouseZones climate_mask
)
8573 for (uint z
= 0; z
< HZB_END
; z
++) {
8574 HouseZones bitmask
= (HouseZones
)(1U << z
) | climate_mask
;
8575 Year min_year
= MAX_YEAR
;
8577 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8578 const HouseSpec
*hs
= HouseSpec::Get(i
);
8579 if (hs
== NULL
|| !hs
->enabled
) continue;
8580 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
8581 if (hs
->min_year
< min_year
) min_year
= hs
->min_year
;
8584 if (min_year
== 0) continue;
8586 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8587 HouseSpec
*hs
= HouseSpec::Get(i
);
8588 if (hs
== NULL
|| !hs
->enabled
) continue;
8589 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
8590 if (hs
->min_year
== min_year
) hs
->min_year
= 0;
8596 * Add all new houses to the house array. House properties can be set at any
8597 * time in the GRF file, so we can only add a house spec to the house array
8598 * after the file has finished loading. We also need to check the dates, due to
8599 * the TTDPatch behaviour described below that we need to emulate.
8601 static void FinaliseHouseArray()
8603 /* If there are no houses with start dates before 1930, then all houses
8604 * with start dates of 1930 have them reset to 0. This is in order to be
8605 * compatible with TTDPatch, where if no houses have start dates before
8606 * 1930 and the date is before 1930, the game pretends that this is 1930.
8607 * If there have been any houses defined with start dates before 1930 then
8608 * the dates are left alone.
8609 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8610 * minimum introduction date to 0.
8612 const GRFFile
* const *end
= _grf_files
.End();
8613 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8614 HouseSpec
**&housespec
= (*file
)->housespec
;
8615 if (housespec
== NULL
) continue;
8617 for (int i
= 0; i
< NUM_HOUSES_PER_GRF
; i
++) {
8618 HouseSpec
*hs
= housespec
[i
];
8620 if (hs
== NULL
) continue;
8622 const HouseSpec
*next1
= (i
+ 1 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 1] : NULL
);
8623 const HouseSpec
*next2
= (i
+ 2 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 2] : NULL
);
8624 const HouseSpec
*next3
= (i
+ 3 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 3] : NULL
);
8626 if (!IsHouseSpecValid(hs
, next1
, next2
, next3
, (*file
)->filename
)) continue;
8628 _house_mngr
.SetEntitySpec(hs
);
8632 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8633 HouseSpec
*hs
= HouseSpec::Get(i
);
8634 const HouseSpec
*next1
= (i
+ 1 < NUM_HOUSES
? HouseSpec::Get(i
+ 1) : NULL
);
8635 const HouseSpec
*next2
= (i
+ 2 < NUM_HOUSES
? HouseSpec::Get(i
+ 2) : NULL
);
8636 const HouseSpec
*next3
= (i
+ 3 < NUM_HOUSES
? HouseSpec::Get(i
+ 3) : NULL
);
8638 /* We need to check all houses again to we are sure that multitile houses
8639 * did get consecutive IDs and none of the parts are missing. */
8640 if (!IsHouseSpecValid(hs
, next1
, next2
, next3
, NULL
)) {
8641 /* GetHouseNorthPart checks 3 houses that are directly before
8642 * it in the house pool. If any of those houses have multi-tile
8643 * flags set it assumes it's part of a multitile house. Since
8644 * we can have invalid houses in the pool marked as disabled, we
8645 * don't want to have them influencing valid tiles. As such set
8646 * building_flags to zero here to make sure any house following
8647 * this one in the pool is properly handled as 1x1 house. */
8648 hs
->building_flags
= TILE_NO_FLAG
;
8652 HouseZones climate_mask
= (HouseZones
)(1 << (_settings_game
.game_creation
.landscape
+ 12));
8653 EnsureEarlyHouses (climate_mask
);
8655 if (_settings_game
.game_creation
.landscape
== LT_ARCTIC
) {
8656 EnsureEarlyHouses (HZ_SUBARTC_ABOVE
);
8661 * Add all new industries to the industry array. Industry properties can be set at any
8662 * time in the GRF file, so we can only add a industry spec to the industry array
8663 * after the file has finished loading.
8665 static void FinaliseIndustriesArray()
8667 const GRFFile
* const *end
= _grf_files
.End();
8668 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8669 IndustrySpec
**&industryspec
= (*file
)->industryspec
;
8670 IndustryTileSpec
**&indtspec
= (*file
)->indtspec
;
8671 if (industryspec
!= NULL
) {
8672 for (int i
= 0; i
< NUM_INDUSTRYTYPES_PER_GRF
; i
++) {
8673 IndustrySpec
*indsp
= industryspec
[i
];
8675 if (indsp
!= NULL
&& indsp
->enabled
) {
8677 /* process the conversion of text at the end, so to be sure everything will be fine
8678 * and available. Check if it does not return undefind marker, which is a very good sign of a
8679 * substitute industry who has not changed the string been examined, thus using it as such */
8680 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->name
);
8681 if (strid
!= STR_UNDEFINED
) indsp
->name
= strid
;
8683 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->closure_text
);
8684 if (strid
!= STR_UNDEFINED
) indsp
->closure_text
= strid
;
8686 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->production_up_text
);
8687 if (strid
!= STR_UNDEFINED
) indsp
->production_up_text
= strid
;
8689 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->production_down_text
);
8690 if (strid
!= STR_UNDEFINED
) indsp
->production_down_text
= strid
;
8692 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->new_industry_text
);
8693 if (strid
!= STR_UNDEFINED
) indsp
->new_industry_text
= strid
;
8695 if (indsp
->station_name
!= STR_NULL
) {
8696 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8697 * station's name. Don't want to lose the value, therefore, do not process. */
8698 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->station_name
);
8699 if (strid
!= STR_UNDEFINED
) indsp
->station_name
= strid
;
8702 _industry_mngr
.SetEntitySpec(indsp
);
8703 _loaded_newgrf_features
.has_newindustries
= true;
8708 if (indtspec
!= NULL
) {
8709 for (int i
= 0; i
< NUM_INDUSTRYTILES_PER_GRF
; i
++) {
8710 IndustryTileSpec
*indtsp
= indtspec
[i
];
8711 if (indtsp
!= NULL
) {
8712 _industile_mngr
.SetEntitySpec(indtsp
);
8718 for (uint j
= 0; j
< NUM_INDUSTRYTYPES
; j
++) {
8719 IndustrySpec
*indsp
= &_industry_specs
[j
];
8720 if (indsp
->enabled
&& indsp
->grf_prop
.grffile
!= NULL
) {
8721 for (uint i
= 0; i
< 3; i
++) {
8722 indsp
->conflicting
[i
] = MapNewGRFIndustryType(indsp
->conflicting
[i
], indsp
->grf_prop
.grffile
->grfid
);
8725 if (!indsp
->enabled
) {
8726 indsp
->name
= STR_NEWGRF_INVALID_INDUSTRYTYPE
;
8732 * Add all new objects to the object array. Object properties can be set at any
8733 * time in the GRF file, so we can only add an object spec to the object array
8734 * after the file has finished loading.
8736 static void FinaliseObjectsArray()
8738 const GRFFile
* const *end
= _grf_files
.End();
8739 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8740 ObjectSpec
**&objectspec
= (*file
)->objectspec
;
8741 if (objectspec
!= NULL
) {
8742 for (int i
= 0; i
< NUM_OBJECTS_PER_GRF
; i
++) {
8743 if (objectspec
[i
] != NULL
&& objectspec
[i
]->grf_prop
.grffile
!= NULL
&& objectspec
[i
]->enabled
) {
8744 _object_mngr
.SetEntitySpec(objectspec
[i
]);
8752 * Add all new airports to the airport array. Airport properties can be set at any
8753 * time in the GRF file, so we can only add a airport spec to the airport array
8754 * after the file has finished loading.
8756 static void FinaliseAirportsArray()
8758 const GRFFile
* const *end
= _grf_files
.End();
8759 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8760 AirportSpec
**&airportspec
= (*file
)->airportspec
;
8761 if (airportspec
!= NULL
) {
8762 for (int i
= 0; i
< NUM_AIRPORTS_PER_GRF
; i
++) {
8763 if (airportspec
[i
] != NULL
&& airportspec
[i
]->enabled
) {
8764 _airport_mngr
.SetEntitySpec(airportspec
[i
]);
8769 AirportTileSpec
**&airporttilespec
= (*file
)->airtspec
;
8770 if (airporttilespec
!= NULL
) {
8771 for (uint i
= 0; i
< NUM_AIRPORTTILES_PER_GRF
; i
++) {
8772 if (airporttilespec
[i
] != NULL
&& airporttilespec
[i
]->enabled
) {
8773 _airporttile_mngr
.SetEntitySpec(airporttilespec
[i
]);
8780 /* Here we perform initial decoding of some special sprites (as are they
8781 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8782 * partial implementation yet).
8783 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8784 * a crafted invalid GRF file. We should tell that to the user somehow, or
8785 * better make this more robust in the future. */
8786 static int DecodeSpecialSprite (byte
*buf
, uint num
, GrfLoadingStage stage
)
8788 /* XXX: There is a difference between staged loading in TTDPatch and
8789 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8790 * during stage 1, whilst action 3 is carried out during stage 2 (to
8791 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8792 * IDs are valid only within a given set (action 1) block, and may be
8793 * overwritten after action 3 associates them. But overwriting happens
8794 * in an earlier stage than associating, so... We just process actions
8795 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8797 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8798 * is not in memory and scanning the file every time would be too expensive.
8799 * In other stages we skip action 0x10 since it's already dealt with. */
8800 static const SpecialSpriteHandler handlers
[][GLS_END
] = {
8801 /* 0x00 */ { NULL
, SafeChangeInfo
, NULL
, NULL
, ReserveChangeInfo
, FeatureChangeInfo
, },
8802 /* 0x01 */ { SkipAct1
, SkipAct1
, SkipAct1
, SkipAct1
, SkipAct1
, NewSpriteSet
, },
8803 /* 0x02 */ { NULL
, NULL
, NULL
, NULL
, NULL
, NewSpriteGroup
, },
8804 /* 0x03 */ { NULL
, GRFUnsafe
, NULL
, NULL
, NULL
, FeatureMapSpriteGroup
, },
8805 /* 0x04 */ { NULL
, NULL
, NULL
, NULL
, NULL
, FeatureNewName
, },
8806 /* 0x05 */ { SkipAct5
, SkipAct5
, SkipAct5
, SkipAct5
, SkipAct5
, GraphicsNew
, },
8807 /* 0x06 */ { NULL
, NULL
, NULL
, CfgApply
, CfgApply
, CfgApply
, },
8808 /* 0x07 */ { NULL
, NULL
, NULL
, NULL
, SkipIf
, SkipIf
, },
8809 /* 0x08 */ { ScanInfo
, NULL
, NULL
, GRFInfo
, GRFInfo
, GRFInfo
, },
8810 /* 0x09 */ { NULL
, NULL
, NULL
, SkipIf
, SkipIf
, SkipIf
, },
8811 /* 0x0A */ { SkipActA
, SkipActA
, SkipActA
, SkipActA
, SkipActA
, SpriteReplace
, },
8812 /* 0x0B */ { NULL
, NULL
, NULL
, GRFLoadError
, GRFLoadError
, GRFLoadError
, },
8813 /* 0x0C */ { NULL
, NULL
, NULL
, GRFComment
, NULL
, GRFComment
, },
8814 /* 0x0D */ { NULL
, SafeParamSet
, NULL
, ParamSet
, ParamSet
, ParamSet
, },
8815 /* 0x0E */ { NULL
, SafeGRFInhibit
, NULL
, GRFInhibit
, GRFInhibit
, GRFInhibit
, },
8816 /* 0x0F */ { NULL
, GRFUnsafe
, NULL
, FeatureTownName
, NULL
, NULL
, },
8817 /* 0x10 */ { NULL
, NULL
, DefineGotoLabel
, NULL
, NULL
, NULL
, },
8818 /* 0x11 */ { SkipAct11
,GRFUnsafe
, SkipAct11
, GRFSound
, SkipAct11
, GRFSound
, },
8819 /* 0x12 */ { SkipAct12
, SkipAct12
, SkipAct12
, SkipAct12
, SkipAct12
, LoadFontGlyph
, },
8820 /* 0x13 */ { NULL
, NULL
, NULL
, NULL
, NULL
, TranslateGRFStrings
, },
8821 /* 0x14 */ { StaticGRFInfo
, NULL
, NULL
, NULL
, NULL
, NULL
, },
8824 GRFLocation
location(_cur
.grfconfig
->ident
.grfid
, _cur
.nfo_line
);
8826 GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.find(location
);
8827 if (it
== _grf_line_to_action6_sprite_override
.end()) {
8828 /* No preloaded sprite to work with; read the
8829 * pseudo sprite content. */
8830 FioReadBlock(buf
, num
);
8832 /* Use the preloaded sprite data. */
8833 buf
= it
->second
.get();
8834 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8836 /* Skip the real (original) content of this action. */
8837 FioSeekTo(num
, SEEK_CUR
);
8840 ByteReader
br(buf
, buf
+ num
);
8841 ByteReader
*bufp
= &br
;
8844 byte action
= bufp
->ReadByte();
8846 if (action
== 0xFF) {
8847 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8848 } else if (action
== 0xFE) {
8849 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8850 } else if (action
>= lengthof(handlers
)) {
8851 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action
);
8852 } else if (handlers
[action
][stage
] == NULL
) {
8853 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action
, stage
);
8855 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action
, stage
);
8856 return handlers
[action
][stage
](bufp
);
8859 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8860 DisableCur (STR_NEWGRF_ERROR_READ_BOUNDS
);
8868 /** Signature of a container version 2 GRF. */
8869 extern const byte _grf_cont_v2_sig
[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8872 * Read the header of a GRF header.
8873 * @param header Struct to fill with data.
8874 * @return Whether the header is valid.
8876 bool ReadGRFHeader (GRFHeader
*header
)
8878 size_t pos
= FioGetPos();
8880 if (FioReadWord() != 0) {
8881 /* Container version 1 has no header, rewind to start. */
8882 FioSeekTo (pos
, SEEK_SET
);
8884 header
->version
= 1;
8885 header
->sprite_offset
= 0;
8887 /* Check for GRF container version 2, which is identified by the
8888 * bytes '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8889 for (uint i
= 0; i
< lengthof(_grf_cont_v2_sig
); i
++) {
8890 if (FioReadByte() != _grf_cont_v2_sig
[i
]) return false;
8893 header
->version
= 2;
8894 uint32 offset
= FioReadDword();
8895 header
->sprite_offset
= offset
+ FioGetPos();
8897 /* Read compression value. */
8898 if (FioReadByte() != 0) return false;
8905 * Load a particular NewGRF.
8906 * @param config The configuration of the to be loaded NewGRF.
8907 * @param file_index The Fio index of the first NewGRF to load.
8908 * @param stage The loading stage of the NewGRF.
8909 * @param subdir The sub directory to find the NewGRF in.
8911 void LoadNewGRFFile(GRFConfig
*config
, uint file_index
, GrfLoadingStage stage
, Subdirectory subdir
)
8913 assert (file_index
< MAX_FILE_SLOTS
);
8915 const char *filename
= config
->filename
;
8917 FioOpenFile(file_index
, filename
, subdir
);
8918 _cur
.file_index
= file_index
; // XXX
8919 _palette_remap_grf
[_cur
.file_index
] = (config
->palette
& GRFP_USE_MASK
);
8921 _cur
.grfconfig
= config
;
8923 DEBUG(grf
, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename
);
8926 if (!ReadGRFHeader (&header
)) {
8927 DEBUG(grf
, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8931 _cur
.grf_container_ver
= header
.version
;
8933 if (stage
== GLS_INIT
|| stage
== GLS_ACTIVATION
) {
8934 /* We need the sprite offsets in the init stage for NewGRF sounds
8935 * and in the activation stage for real sprites. */
8936 ReadGRFSpriteOffsets (&header
);
8939 /* Skip the first sprite; we don't care about how many sprites this
8940 * does contain; newest TTDPatches and George's longvehicles don't
8941 * neither, apparently. */
8942 uint32 num
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
8943 if (num
== 4 && FioReadByte() == 0xFF) {
8946 DEBUG(grf
, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8950 _cur
.ClearDataForNextFile();
8952 ReusableBuffer
<byte
> buf
;
8953 int skip_sprites
= 0;
8955 while ((num
= (_cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord())) != 0) {
8956 byte type
= FioReadByte();
8959 if (skip_sprites
!= 0) {
8966 /* Reference to data section. Container version >= 2 only. */
8967 skip_real
= (_cur
.grf_container_ver
< 2);
8975 SkipSpriteData (type
, num
);
8982 } else if (type
== 0xFF) {
8983 skip_sprites
= DecodeSpecialSprite (buf
.Allocate(num
), num
, stage
);
8985 /* Stop all processing if we are to skip the remaining sprites */
8986 if (skip_sprites
== -1) break;
8989 grfmsg (0, "LoadNewGRFFile: Unexpected sprite, disabling");
8990 DisableCur (STR_NEWGRF_ERROR_UNEXPECTED_SPRITE
);
8997 * Relocates the old shore sprites at new positions.
8999 * 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)
9000 * 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)
9001 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
9003 static void ActivateOldShore()
9005 /* Use default graphics, if no shore sprites were loaded.
9006 * Should not happen, as the base set's extra grf should include some. */
9007 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_NONE
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_A
;
9009 if (_loaded_newgrf_features
.shore
!= SHORE_REPLACE_ACTION_5
) {
9010 for (uint i
= 0; i
< lengthof(shore_sprites_1
); i
++) {
9011 DupSprite (shore_sprites_1
[i
].old
, shore_sprites_1
[i
].spr
);
9015 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_ACTION_A
) {
9016 for (uint i
= 0; i
< lengthof(shore_sprites_2
); i
++) {
9017 DupSprite (shore_sprites_2
[i
].old
, shore_sprites_2
[i
].spr
);
9023 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
9025 static void FinalisePriceBaseMultipliers()
9027 extern const PriceBaseSpec _price_base_specs
[];
9028 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
9029 static const uint32 override_features
= (1 << GSF_TRAINS
) | (1 << GSF_ROADVEHICLES
) | (1 << GSF_SHIPS
) | (1 << GSF_AIRCRAFT
);
9031 /* Evaluate grf overrides */
9032 int num_grfs
= _grf_files
.Length();
9033 int *grf_overrides
= AllocaM(int, num_grfs
);
9034 for (int i
= 0; i
< num_grfs
; i
++) {
9035 grf_overrides
[i
] = -1;
9037 GRFFile
*source
= _grf_files
[i
];
9038 uint32 override
= _grf_id_overrides
[source
->grfid
];
9039 if (override
== 0) continue;
9041 GRFFile
*dest
= GetFileByGRFID(override
);
9042 if (dest
== NULL
) continue;
9044 grf_overrides
[i
] = _grf_files
.FindIndex(dest
);
9045 assert(grf_overrides
[i
] >= 0);
9048 /* Override features and price base multipliers of earlier loaded grfs */
9049 for (int i
= 0; i
< num_grfs
; i
++) {
9050 if (grf_overrides
[i
] < 0 || grf_overrides
[i
] >= i
) continue;
9051 GRFFile
*source
= _grf_files
[i
];
9052 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9054 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9055 source
->grf_features
|= features
;
9056 dest
->grf_features
|= features
;
9058 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9059 /* No price defined -> nothing to do */
9060 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
) || source
->price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) continue;
9061 DEBUG(grf
, 3, "'%s' overrides price base multiplier %d of '%s'", source
->filename
, p
, dest
->filename
);
9062 dest
->price_base_multipliers
[p
] = source
->price_base_multipliers
[p
];
9066 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9067 for (int i
= num_grfs
- 1; i
>= 0; i
--) {
9068 if (grf_overrides
[i
] < 0 || grf_overrides
[i
] <= i
) continue;
9069 GRFFile
*source
= _grf_files
[i
];
9070 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9072 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9073 source
->grf_features
|= features
;
9074 dest
->grf_features
|= features
;
9076 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9077 /* Already a price defined -> nothing to do */
9078 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
) || dest
->price_base_multipliers
[p
] != INVALID_PRICE_MODIFIER
) continue;
9079 DEBUG(grf
, 3, "Price base multiplier %d from '%s' propagated to '%s'", p
, source
->filename
, dest
->filename
);
9080 dest
->price_base_multipliers
[p
] = source
->price_base_multipliers
[p
];
9084 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9085 for (int i
= 0; i
< num_grfs
; i
++) {
9086 if (grf_overrides
[i
] < 0) continue;
9087 GRFFile
*source
= _grf_files
[i
];
9088 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9090 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9091 source
->grf_features
|= features
;
9092 dest
->grf_features
|= features
;
9094 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9095 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
)) continue;
9096 if (source
->price_base_multipliers
[p
] != dest
->price_base_multipliers
[p
]) {
9097 DEBUG(grf
, 3, "Price base multiplier %d from '%s' propagated to '%s'", p
, dest
->filename
, source
->filename
);
9099 source
->price_base_multipliers
[p
] = dest
->price_base_multipliers
[p
];
9103 /* Apply fallback prices for grf version < 8 */
9104 const GRFFile
* const *end
= _grf_files
.End();
9105 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
9106 if ((*file
)->grf_version
>= 8) continue;
9107 PriceMultipliers
&price_base_multipliers
= (*file
)->price_base_multipliers
;
9108 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9109 Price fallback_price
= _price_base_specs
[p
].fallback_price
;
9110 if (fallback_price
!= INVALID_PRICE
&& price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) {
9111 /* No price multiplier has been set.
9112 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9113 price_base_multipliers
[p
] = price_base_multipliers
[fallback_price
];
9118 /* Decide local/global scope of price base multipliers */
9119 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
9120 PriceMultipliers
&price_base_multipliers
= (*file
)->price_base_multipliers
;
9121 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9122 if (price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) {
9123 /* No multiplier was set; set it to a neutral value */
9124 price_base_multipliers
[p
] = 0;
9126 if (!HasBit((*file
)->grf_features
, _price_base_specs
[p
].grf_feature
)) {
9127 /* The grf does not define any objects of the feature,
9128 * so it must be a difficulty setting. Apply it globally */
9129 DEBUG(grf
, 3, "'%s' sets global price base multiplier %d", (*file
)->filename
, p
);
9130 SetPriceBaseMultiplier(p
, price_base_multipliers
[p
]);
9131 price_base_multipliers
[p
] = 0;
9133 DEBUG(grf
, 3, "'%s' sets local price base multiplier %d", (*file
)->filename
, p
);
9140 extern void InitGRFTownGeneratorNames();
9142 /** Finish loading NewGRFs and execute needed post-processing */
9143 static void AfterLoadGRFs()
9145 for (StringIDMapping
*it
= _string_to_grf_mapping
.Begin(); it
!= _string_to_grf_mapping
.End(); it
++) {
9146 *it
->target
= MapGRFStringID(it
->grfid
, it
->source
);
9148 _string_to_grf_mapping
.Clear();
9150 /* Free the action 6 override sprites. */
9151 _grf_line_to_action6_sprite_override
.clear();
9153 /* Polish cargoes */
9154 FinaliseCargoArray();
9156 /* Pre-calculate all refit masks after loading GRF files. */
9157 CalculateRefitMasks();
9159 /* Polish engines */
9160 FinaliseEngineArray();
9162 /* Set the actually used Canal properties */
9165 /* Add all new houses to the house array. */
9166 FinaliseHouseArray();
9168 /* Add all new industries to the industry array. */
9169 FinaliseIndustriesArray();
9171 /* Add all new objects to the object array. */
9172 FinaliseObjectsArray();
9174 InitializeSortedCargoSpecs();
9176 /* Sort the list of industry types. */
9177 SortIndustryTypes();
9179 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9180 BuildIndustriesLegend();
9182 /* Build the routemap legend, based on the available cargos */
9183 BuildLinkStatsLegend();
9185 /* Add all new airports to the airports array. */
9186 FinaliseAirportsArray();
9189 /* Update the townname generators list */
9190 InitGRFTownGeneratorNames();
9192 /* Run all queued vehicle list order changes */
9193 CommitVehicleListOrderChanges();
9195 /* Load old shore sprites in new position, if they were replaced by ActionA */
9198 /* Set up custom rail types */
9202 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_ROAD
) {
9203 if (_gted
[e
->index
].rv_max_speed
!= 0) {
9204 /* Set RV maximum speed from the mph/0.8 unit value */
9205 e
->u
.road
.max_speed
= _gted
[e
->index
].rv_max_speed
* 4;
9209 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_TRAIN
) {
9210 RailType railtype
= GetRailTypeByLabel(_gted
[e
->index
].railtypelabel
);
9211 if (railtype
== INVALID_RAILTYPE
) {
9212 /* Rail type is not available, so disable this engine */
9213 e
->info
.climates
= 0;
9215 e
->u
.rail
.railtype
= railtype
;
9219 SetYearEngineAgingStops();
9221 FinalisePriceBaseMultipliers();
9223 /* Deallocate temporary loading data */
9225 _grm_sprites
.clear();
9229 * Load all the NewGRFs.
9230 * @param load_index The offset for the first sprite to add.
9231 * @param file_index The Fio index of the first NewGRF to load.
9232 * @param num_baseset Number of NewGRFs at the front of the list to look up in the baseset dir instead of the newgrf dir.
9234 void LoadNewGRF(uint load_index
, uint file_index
, uint num_baseset
)
9236 /* In case of networking we need to "sync" the start values
9237 * so all NewGRFs are loaded equally. For this we use the
9238 * start date of the game and we set the counters, etc. to
9239 * 0 so they're the same too. */
9241 Year year
= _cur_year
;
9242 DateFract date_fract
= _date_fract
;
9243 uint16 tick_counter
= _tick_counter
;
9244 byte display_opt
= _display_opt
;
9247 _cur_year
= _settings_game
.game_creation
.starting_year
;
9248 _date
= ConvertYMDToDate(_cur_year
, 0, 1);
9254 InitializeGRFSpecial();
9259 * Reset the status of all files, so we can 'retry' to load them.
9260 * This is needed when one for example rearranges the NewGRFs in-game
9261 * and a previously disabled NewGRF becomes useable. If it would not
9262 * be reset, the NewGRF would remain disabled even though it should
9263 * have been enabled.
9265 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9266 if (c
->status
!= GCS_NOT_FOUND
) c
->status
= GCS_UNKNOWN
;
9269 _cur
.spriteid
= load_index
;
9271 /* Load newgrf sprites
9272 * in each loading stage, (try to) open each file specified in the config
9273 * and load information from it. */
9274 uint num_non_static
= 0;
9275 for (GrfLoadingStage stage
= GLS_LABELSCAN
; stage
<= GLS_ACTIVATION
; stage
++) {
9276 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9277 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9278 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9279 if (c
->status
== GCS_ACTIVATED
) c
->status
= GCS_INITIALISED
;
9282 if (stage
== GLS_RESERVE
) {
9283 static const uint32 overrides
[][2] = {
9284 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9285 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9286 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9288 for (size_t i
= 0; i
< lengthof(overrides
); i
++) {
9289 SetNewGRFOverride(BSWAP32(overrides
[i
][0]), BSWAP32(overrides
[i
][1]));
9293 uint slot
= file_index
;
9296 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9297 if (c
->status
== GCS_DISABLED
|| c
->status
== GCS_NOT_FOUND
) continue;
9298 if (stage
> GLS_INIT
&& HasBit(c
->flags
, GCF_INIT_ONLY
)) continue;
9300 Subdirectory subdir
= slot
< file_index
+ num_baseset
? BASESET_DIR
: NEWGRF_DIR
;
9301 if (!FioCheckFileExists(c
->filename
, subdir
)) {
9302 DEBUG(grf
, 0, "NewGRF file is missing '%s'; disabling", c
->filename
);
9303 c
->status
= GCS_NOT_FOUND
;
9307 /* A .grf file is activated only if it was active
9308 * when the game was started. If a game is loaded,
9309 * only its active .grfs will be reactivated, unless
9310 * "loadallgraphics on" is used. A .grf file is
9311 * considered active if its action 8 has been
9312 * processed, i.e. its action 8 hasn't been skipped
9313 * using an action 7.
9315 * During activation, only actions 0, 1, 2, 3, 4, 5,
9316 * 7, 8, 9, 0A and 0B are carried out. All others
9317 * are ignored, because they only need to be
9318 * processed once at initialization. */
9320 _cur
.grffile
= GetFileByFilename (c
->filename
);
9321 if (stage
== GLS_LABELSCAN
) {
9322 if (_cur
.grffile
== NULL
) {
9323 _cur
.grffile
= new GRFFile (c
);
9324 *_grf_files
.Append() = _cur
.grffile
;
9327 bool disable
= false;
9328 if (slot
== MAX_FILE_SLOTS
) {
9329 DEBUG(grf
, 0, "'%s' is not loaded as the maximum number of file slots has been reached", c
->filename
);
9331 } else if (!HasBit(c
->flags
, GCF_STATIC
) && !HasBit(c
->flags
, GCF_SYSTEM
)) {
9332 if (num_non_static
== NETWORK_MAX_GRF_COUNT
) {
9333 DEBUG(grf
, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c
->filename
);
9340 c
->status
= GCS_DISABLED
;
9341 c
->error
= new GRFError (STR_NEWGRF_ERROR_MSG_FATAL
, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED
);
9345 if (_cur
.grffile
== NULL
) usererror ("File '%s' lost in cache.\n", c
->filename
);
9346 if (stage
== GLS_RESERVE
&& c
->status
!= GCS_INITIALISED
) return;
9347 if (stage
== GLS_ACTIVATION
&& !HasBit(c
->flags
, GCF_RESERVED
)) return;
9350 assert (slot
< MAX_FILE_SLOTS
);
9352 LoadNewGRFFile(c
, slot
++, stage
, subdir
);
9353 if (stage
== GLS_RESERVE
) {
9354 SetBit(c
->flags
, GCF_RESERVED
);
9355 } else if (stage
== GLS_ACTIVATION
) {
9356 ClrBit(c
->flags
, GCF_RESERVED
);
9357 assert(GetFileByGRFID(c
->ident
.grfid
) == _cur
.grffile
);
9358 ClearTemporaryNewGRFData(_cur
.grffile
);
9359 BuildCargoTranslationMap();
9360 DEBUG(sprite
, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur
.spriteid
);
9361 } else if (stage
== GLS_INIT
&& HasBit(c
->flags
, GCF_INIT_ONLY
)) {
9362 /* We're not going to activate this, so free whatever data we allocated */
9363 ClearTemporaryNewGRFData(_cur
.grffile
);
9368 /* Pseudo sprite processing is finished; free temporary stuff */
9369 _cur
.ClearDataForNextFile();
9371 /* Call any functions that should be run after GRFs have been loaded. */
9374 /* Now revert back to the original situation */
9377 _date_fract
= date_fract
;
9378 _tick_counter
= tick_counter
;
9379 _display_opt
= display_opt
;