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"
24 #include "fontcache.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"
42 #include "string_func.h"
43 #include "network/network.h"
45 #include "smallmap_gui.h"
48 #include "vehicle_func.h"
50 #include "vehicle_base.h"
52 #include "table/strings.h"
53 #include "table/build_industry.h"
55 #include "safeguards.h"
57 /* TTDPatch extended GRF format codec
58 * (c) Petr Baudis 2004 (GPL'd)
59 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
61 * Contains portions of documentation by TTDPatch team.
62 * Thanks especially to Josef Drexler for the documentation as well as a lot
63 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
64 * served as subject to the initial testing of this codec. */
66 /** List of all loaded GRF files */
67 static 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 /* Kind of return values when processing certain actions */
105 int skip_sprites
; ///< Number of psuedo sprites to skip before processing the next one. (-1 to skip to end of file)
107 /* Currently referenceable spritegroups */
108 SpriteGroup
*spritegroups
[MAX_SPRITEGROUP
+ 1];
110 /** Clear temporary data before processing the next file in the current loading stage */
111 void ClearDataForNextFile()
114 this->skip_sprites
= 0;
116 for (uint i
= 0; i
< GSF_END
; i
++) {
117 this->spritesets
[i
].clear();
120 memset(this->spritegroups
, 0, sizeof(this->spritegroups
));
124 * Records new spritesets.
125 * @param feature GrfSpecFeature the set is defined for.
126 * @param first_sprite SpriteID of the first sprite in the set.
127 * @param first_set First spriteset to define.
128 * @param numsets Number of sets to define.
129 * @param numents Number of sprites per set to define.
131 void AddSpriteSets(byte feature
, SpriteID first_sprite
, uint first_set
, uint numsets
, uint numents
)
133 assert(feature
< GSF_END
);
134 for (uint i
= 0; i
< numsets
; i
++) {
135 SpriteSet
&set
= this->spritesets
[feature
][first_set
+ i
];
136 set
.sprite
= first_sprite
+ i
* numents
;
137 set
.num_sprites
= numents
;
142 * Check whether there are any valid spritesets for a feature.
143 * @param feature GrfSpecFeature to check.
144 * @return true if there are any valid sets.
145 * @note Spritesets with zero sprites are valid to allow callback-failures.
147 bool HasValidSpriteSets(byte feature
) const
149 assert(feature
< GSF_END
);
150 return !this->spritesets
[feature
].empty();
154 * Check whether a specific set is defined.
155 * @param feature GrfSpecFeature to check.
156 * @param set Set to check.
157 * @return true if the set is valid.
158 * @note Spritesets with zero sprites are valid to allow callback-failures.
160 bool IsValidSpriteSet(byte feature
, uint set
) const
162 assert(feature
< GSF_END
);
163 return this->spritesets
[feature
].find(set
) != this->spritesets
[feature
].end();
167 * Returns the first sprite of a spriteset.
168 * @param feature GrfSpecFeature to query.
169 * @param set Set to query.
170 * @return First sprite of the set.
172 SpriteID
GetSprite(byte feature
, uint set
) const
174 assert(IsValidSpriteSet(feature
, set
));
175 return this->spritesets
[feature
].find(set
)->second
.sprite
;
179 * Returns the number of sprites in a spriteset
180 * @param feature GrfSpecFeature to query.
181 * @param set Set to query.
182 * @return Number of sprites in the set.
184 uint
GetNumEnts(byte feature
, uint set
) const
186 assert(IsValidSpriteSet(feature
, set
));
187 return this->spritesets
[feature
].find(set
)->second
.num_sprites
;
191 static GrfProcessingState _cur
;
195 * Helper to check whether an image index is valid for a particular NewGRF vehicle.
196 * @param <T> The type of vehicle.
197 * @param image_index The image index to check.
198 * @return True iff the image index is valid, or 0xFD (use new graphics).
200 template <VehicleType T
>
201 static inline bool IsValidNewGRFImageIndex(uint8 image_index
)
203 return image_index
== 0xFD || IsValidImageIndex
<T
>(image_index
);
206 class OTTDByteReaderSignal
{ };
208 /** Class to read from a NewGRF file */
215 ByteReader(byte
*data
, byte
*end
) : data(data
), end(end
) { }
217 inline byte
ReadByte()
219 if (data
< end
) return *(data
)++;
220 throw OTTDByteReaderSignal();
225 uint16 val
= ReadByte();
226 return val
| (ReadByte() << 8);
229 uint16
ReadExtendedByte()
231 uint16 val
= ReadByte();
232 return val
== 0xFF ? ReadWord() : val
;
237 uint32 val
= ReadWord();
238 return val
| (ReadWord() << 16);
241 uint32
ReadVarSize(byte size
)
244 case 1: return ReadByte();
245 case 2: return ReadWord();
246 case 4: return ReadDWord();
253 const char *ReadString()
255 char *string
= reinterpret_cast<char *>(data
);
256 size_t string_length
= ttd_strnlen(string
, Remaining());
258 if (string_length
== Remaining()) {
259 /* String was not NUL terminated, so make sure it is now. */
260 string
[string_length
- 1] = '\0';
261 grfmsg(7, "String was not terminated with a zero byte.");
263 /* Increase the string length to include the NUL byte. */
271 inline size_t Remaining() const
276 inline bool HasData(size_t count
= 1) const
278 return data
+ count
<= end
;
286 inline void Skip(size_t len
)
289 /* It is valid to move the buffer to exactly the end of the data,
290 * as there may not be any more data read. */
291 if (data
> end
) throw OTTDByteReaderSignal();
295 typedef void (*SpecialSpriteHandler
)(ByteReader
*buf
);
297 static const uint NUM_STATIONS_PER_GRF
= 255; ///< Number of StationSpecs per NewGRF; limited to 255 to allow extending Action3 with an extended byte later on.
299 /** Temporary engine data used when loading only */
300 struct GRFTempEngineData
{
301 /** Summary state of refittability properties */
303 UNSET
= 0, ///< No properties assigned. Default refit masks shall be activated.
304 EMPTY
, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
305 NONEMPTY
, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
308 uint16 cargo_allowed
;
309 uint16 cargo_disallowed
;
310 RailTypeLabel railtypelabel
;
311 const GRFFile
*defaultcargo_grf
; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
312 Refittability refittability
; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
313 bool prop27_set
; ///< Did the NewGRF set property 27 (misc flags)?
314 uint8 rv_max_speed
; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
315 uint32 ctt_include_mask
; ///< Cargo types always included in the refit mask.
316 uint32 ctt_exclude_mask
; ///< Cargo types always excluded from the refit mask.
319 * Update the summary refittability on setting a refittability property.
320 * @param non_empty true if the GRF sets the vehicle to be refittable.
322 void UpdateRefittability(bool non_empty
)
325 this->refittability
= NONEMPTY
;
326 } else if (this->refittability
== UNSET
) {
327 this->refittability
= EMPTY
;
332 static GRFTempEngineData
*_gted
; ///< Temporary engine data used during NewGRF loading
335 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
336 * GRM for vehicles is only used if dynamic engine allocation is disabled,
337 * so 256 is the number of original engines. */
338 static uint32 _grm_engines
[256];
340 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
341 static uint32 _grm_cargoes
[NUM_CARGO
* 2];
347 GRFLocation(uint32 grfid
, uint32 nfoline
) : grfid(grfid
), nfoline(nfoline
) { }
349 bool operator<(const GRFLocation
&other
) const
351 return this->grfid
< other
.grfid
|| (this->grfid
== other
.grfid
&& this->nfoline
< other
.nfoline
);
354 bool operator == (const GRFLocation
&other
) const
356 return this->grfid
== other
.grfid
&& this->nfoline
== other
.nfoline
;
360 static std::map
<GRFLocation
, SpriteID
> _grm_sprites
;
361 typedef std::map
<GRFLocation
, byte
*> GRFLineToSpriteOverride
;
362 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override
;
365 * DEBUG() function dedicated to newGRF debugging messages
366 * Function is essentially the same as DEBUG(grf, severity, ...) with the
367 * addition of file:line information when parsing grf files.
368 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
369 * loading/parsing grf files, not for runtime debug messages as there
370 * is no file information available during that time.
371 * @param severity debugging severity level, see debug.h
372 * @param str message in printf() format
374 void CDECL
grfmsg(int severity
, const char *str
, ...)
380 vseprintf(buf
, lastof(buf
), str
, va
);
383 DEBUG(grf
, severity
, "[%s:%d] %s", _cur
.grfconfig
->filename
, _cur
.nfo_line
, buf
);
387 * Obtain a NewGRF file by its grfID
388 * @param grfid The grfID to obtain the file for
391 static GRFFile
*GetFileByGRFID(uint32 grfid
)
393 const GRFFile
* const *end
= _grf_files
.End();
394 for (GRFFile
* const *file
= _grf_files
.Begin(); file
!= end
; file
++) {
395 if ((*file
)->grfid
== grfid
) return *file
;
401 * Obtain a NewGRF file by its filename
402 * @param filename The filename to obtain the file for.
405 static GRFFile
*GetFileByFilename(const char *filename
)
407 const GRFFile
* const *end
= _grf_files
.End();
408 for (GRFFile
* const *file
= _grf_files
.Begin(); file
!= end
; file
++) {
409 if (strcmp((*file
)->filename
, filename
) == 0) return *file
;
414 /** Reset all NewGRFData that was used only while processing data */
415 static void ClearTemporaryNewGRFData(GRFFile
*gf
)
417 /* Clear the GOTO labels used for GRF processing */
418 for (GRFLabel
*l
= gf
->label
; l
!= NULL
;) {
419 GRFLabel
*l2
= l
->next
;
428 * @param message Error message or STR_NULL.
429 * @param config GRFConfig to disable, NULL for current.
430 * @return Error message of the GRF for further customisation.
432 static GRFError
*DisableGrf(StringID message
= STR_NULL
, GRFConfig
*config
= NULL
)
435 if (config
!= NULL
) {
436 file
= GetFileByGRFID(config
->ident
.grfid
);
438 config
= _cur
.grfconfig
;
442 config
->status
= GCS_DISABLED
;
443 if (file
!= NULL
) ClearTemporaryNewGRFData(file
);
444 if (config
== _cur
.grfconfig
) _cur
.skip_sprites
= -1;
446 if (message
!= STR_NULL
) {
447 delete config
->error
;
448 config
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, message
);
449 if (config
== _cur
.grfconfig
) config
->error
->param_value
[0] = _cur
.nfo_line
;
452 return config
->error
;
456 * Information for mapping static StringIDs.
458 struct StringIDMapping
{
459 uint32 grfid
; ///< Source NewGRF.
460 StringID source
; ///< Source StringID (GRF local).
461 StringID
*target
; ///< Destination for mapping result.
463 typedef SmallVector
<StringIDMapping
, 16> StringIDMappingVector
;
464 static StringIDMappingVector _string_to_grf_mapping
;
467 * Record a static StringID for getting translated later.
468 * @param source Source StringID (GRF local).
469 * @param target Destination for the mapping result.
471 static void AddStringForMapping(StringID source
, StringID
*target
)
473 *target
= STR_UNDEFINED
;
474 StringIDMapping
*item
= _string_to_grf_mapping
.Append();
475 item
->grfid
= _cur
.grffile
->grfid
;
476 item
->source
= source
;
477 item
->target
= target
;
481 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
482 * string IDs, but only for the ones we are aware off; the rest
483 * like likely unused and will show a warning.
484 * @param str the string ID to convert
485 * @return the converted string ID
487 static StringID
TTDPStringIDToOTTDStringIDMapping(StringID str
)
489 /* StringID table for TextIDs 0x4E->0x6D */
490 static const StringID units_volume
[] = {
491 STR_ITEMS
, STR_PASSENGERS
, STR_TONS
, STR_BAGS
,
492 STR_LITERS
, STR_ITEMS
, STR_CRATES
, STR_TONS
,
493 STR_TONS
, STR_TONS
, STR_TONS
, STR_BAGS
,
494 STR_TONS
, STR_TONS
, STR_TONS
, STR_BAGS
,
495 STR_TONS
, STR_TONS
, STR_BAGS
, STR_LITERS
,
496 STR_TONS
, STR_LITERS
, STR_TONS
, STR_ITEMS
,
497 STR_BAGS
, STR_LITERS
, STR_TONS
, STR_ITEMS
,
498 STR_TONS
, STR_ITEMS
, STR_LITERS
, STR_ITEMS
501 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
502 assert(!IsInsideMM(str
, 0xD000, 0xD7FF));
504 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
505 assert_compile(stringend - stringid == end - begin); \
506 if (str >= begin && str <= end) return str + (stringid - begin)
508 /* We have some changes in our cargo strings, resulting in some missing. */
509 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING
, STR_CARGO_PLURAL_FIZZY_DRINKS
);
510 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING
, STR_CARGO_SINGULAR_FIZZY_DRINK
);
511 if (str
>= 0x004E && str
<= 0x006D) return units_volume
[str
- 0x004E];
512 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING
, STR_QUANTITY_FIZZY_DRINKS
);
513 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING
, STR_ABBREV_FIZZY_DRINKS
);
514 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE
, STR_COLOUR_WHITE
);
516 /* Map building names according to our lang file changes. There are several
517 * ranges of house ids, all of which need to be remapped to allow newgrfs
518 * to use original house names. */
519 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1
, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1
);
520 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1
, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1
);
521 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1
, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1
);
523 /* Same thing for industries */
524 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE
, STR_INDUSTRY_NAME_SUGAR_MINE
);
525 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION
, STR_NEWS_INDUSTRY_PLANTED
);
526 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL
, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES
);
527 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL
, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM
);
528 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL
, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM
);
531 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY
;
532 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED
;
533 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED
;
535 #undef TEXTID_TO_STRINGID
537 if (str
== STR_NULL
) return STR_EMPTY
;
539 DEBUG(grf
, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str
);
545 * Used when setting an object's property to map to the GRF's strings
546 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
547 * @param grfid Id of the grf file.
548 * @param str StringID that we want to have the equivalent in OoenTTD.
549 * @return The properly adjusted StringID.
551 StringID
MapGRFStringID(uint32 grfid
, StringID str
)
553 if (IsInsideMM(str
, 0xD800, 0xE000)) {
554 /* General text provided by NewGRF.
555 * In the specs this is called the 0xDCxx range (misc presistent texts),
556 * but we meanwhile extended the range to 0xD800-0xDFFF.
557 * Note: We are not involved in the "persistent" business, since we do not store
558 * any NewGRF strings in savegames. */
559 return GetGRFStringID(grfid
, str
);
560 } else if (IsInsideMM(str
, 0xD000, 0xD800)) {
561 /* Callback text provided by NewGRF.
562 * In the specs this is called the 0xD0xx range (misc graphics texts).
563 * These texts can be returned by various callbacks.
565 * Due to how TTDP implements the GRF-local- to global-textid translation
566 * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
567 * We do not care about that difference and just mask out the 0x400 bit.
570 return GetGRFStringID(grfid
, str
);
572 /* The NewGRF wants to include/reference an original TTD string.
573 * Try our best to find an equivalent one. */
574 return TTDPStringIDToOTTDStringIDMapping(str
);
578 static std::map
<uint32
, uint32
> _grf_id_overrides
;
581 * Set the override for a NewGRF
582 * @param source_grfid The grfID which wants to override another NewGRF.
583 * @param target_grfid The grfID which is being overridden.
585 static void SetNewGRFOverride(uint32 source_grfid
, uint32 target_grfid
)
587 _grf_id_overrides
[source_grfid
] = target_grfid
;
588 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid
), BSWAP32(target_grfid
));
592 * Returns the engine associated to a certain internal_id, resp. allocates it.
593 * @param file NewGRF that wants to change the engine.
594 * @param type Vehicle type.
595 * @param internal_id Engine ID inside the NewGRF.
596 * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04).
597 * @return The requested engine.
599 static Engine
*GetNewEngine(const GRFFile
*file
, VehicleType type
, uint16 internal_id
, bool static_access
= false)
601 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
602 * them use the same engine slots. */
603 uint32 scope_grfid
= INVALID_GRFID
; // If not using dynamic_engines, all newgrfs share their ID range
604 if (_settings_game
.vehicle
.dynamic_engines
) {
605 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
606 scope_grfid
= file
->grfid
;
607 uint32 override
= _grf_id_overrides
[file
->grfid
];
609 scope_grfid
= override
;
610 const GRFFile
*grf_match
= GetFileByGRFID(override
);
611 if (grf_match
== NULL
) {
612 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file
->grfid
), BSWAP32(override
));
614 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file
->grfid
), BSWAP32(override
));
618 /* Check if the engine is registered in the override manager */
619 EngineID engine
= _engine_mngr
.GetID(type
, internal_id
, scope_grfid
);
620 if (engine
!= INVALID_ENGINE
) {
621 Engine
*e
= Engine::Get(engine
);
622 if (e
->grf_prop
.grffile
== NULL
) e
->grf_prop
.grffile
= file
;
627 /* Check if there is an unreserved slot */
628 EngineID engine
= _engine_mngr
.GetID(type
, internal_id
, INVALID_GRFID
);
629 if (engine
!= INVALID_ENGINE
) {
630 Engine
*e
= Engine::Get(engine
);
632 if (e
->grf_prop
.grffile
== NULL
) {
633 e
->grf_prop
.grffile
= file
;
634 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e
->index
, BSWAP32(file
->grfid
), type
, internal_id
);
637 /* Reserve the engine slot */
638 if (!static_access
) {
639 EngineIDMapping
*eid
= _engine_mngr
.Get(engine
);
640 eid
->grfid
= scope_grfid
; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
646 if (static_access
) return NULL
;
648 if (!Engine::CanAllocateItem()) {
649 grfmsg(0, "Can't allocate any more engines");
653 size_t engine_pool_size
= Engine::GetPoolSize();
655 /* ... it's not, so create a new one based off an existing engine */
656 Engine
*e
= new Engine(type
, internal_id
);
657 e
->grf_prop
.grffile
= file
;
659 /* Reserve the engine slot */
660 assert(_engine_mngr
.Length() == e
->index
);
661 EngineIDMapping
*eid
= _engine_mngr
.Append();
663 eid
->grfid
= scope_grfid
; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
664 eid
->internal_id
= internal_id
;
665 eid
->substitute_id
= min(internal_id
, _engine_counts
[type
]); // substitute_id == _engine_counts[subtype] means "no substitute"
667 if (engine_pool_size
!= Engine::GetPoolSize()) {
668 /* Resize temporary engine data ... */
669 _gted
= ReallocT(_gted
, Engine::GetPoolSize());
671 /* and blank the new block. */
672 size_t len
= (Engine::GetPoolSize() - engine_pool_size
) * sizeof(*_gted
);
673 memset(_gted
+ engine_pool_size
, 0, len
);
675 if (type
== VEH_TRAIN
) {
676 _gted
[e
->index
].railtypelabel
= GetRailTypeInfo(e
->u
.rail
.railtype
)->label
;
679 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e
->index
, BSWAP32(file
->grfid
), type
, internal_id
);
685 * Return the ID of a new engine
686 * @param file The NewGRF file providing the engine.
687 * @param type The Vehicle type.
688 * @param internal_id NewGRF-internal ID of the engine.
689 * @return The new EngineID.
690 * @note depending on the dynamic_engine setting and a possible override
691 * property the grfID may be unique or overwriting or partially re-defining
692 * properties of an existing engine.
694 EngineID
GetNewEngineID(const GRFFile
*file
, VehicleType type
, uint16 internal_id
)
696 uint32 scope_grfid
= INVALID_GRFID
; // If not using dynamic_engines, all newgrfs share their ID range
697 if (_settings_game
.vehicle
.dynamic_engines
) {
698 scope_grfid
= file
->grfid
;
699 uint32 override
= _grf_id_overrides
[file
->grfid
];
700 if (override
!= 0) scope_grfid
= override
;
703 return _engine_mngr
.GetID(type
, internal_id
, scope_grfid
);
707 * Map the colour modifiers of TTDPatch to those that Open is using.
708 * @param grf_sprite Pointer to the structure been modified.
710 static void MapSpriteMappingRecolour(PalSpriteID
*grf_sprite
)
712 if (HasBit(grf_sprite
->pal
, 14)) {
713 ClrBit(grf_sprite
->pal
, 14);
714 SetBit(grf_sprite
->sprite
, SPRITE_MODIFIER_OPAQUE
);
717 if (HasBit(grf_sprite
->sprite
, 14)) {
718 ClrBit(grf_sprite
->sprite
, 14);
719 SetBit(grf_sprite
->sprite
, PALETTE_MODIFIER_TRANSPARENT
);
722 if (HasBit(grf_sprite
->sprite
, 15)) {
723 ClrBit(grf_sprite
->sprite
, 15);
724 SetBit(grf_sprite
->sprite
, PALETTE_MODIFIER_COLOUR
);
729 * Read a sprite and a palette from the GRF and convert them into a format
730 * suitable to OpenTTD.
731 * @param buf Input stream.
732 * @param read_flags Whether to read TileLayoutFlags.
733 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
734 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
735 * @param feature GrfSpecFeature to use spritesets from.
736 * @param [out] grf_sprite Read sprite and palette.
737 * @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
738 * @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
739 * @return Read TileLayoutFlags.
741 static TileLayoutFlags
ReadSpriteLayoutSprite(ByteReader
*buf
, bool read_flags
, bool invert_action1_flag
, bool use_cur_spritesets
, int feature
, PalSpriteID
*grf_sprite
, uint16
*max_sprite_offset
= NULL
, uint16
*max_palette_offset
= NULL
)
743 grf_sprite
->sprite
= buf
->ReadWord();
744 grf_sprite
->pal
= buf
->ReadWord();
745 TileLayoutFlags flags
= read_flags
? (TileLayoutFlags
)buf
->ReadWord() : TLF_NOTHING
;
747 MapSpriteMappingRecolour(grf_sprite
);
749 bool custom_sprite
= HasBit(grf_sprite
->pal
, 15) != invert_action1_flag
;
750 ClrBit(grf_sprite
->pal
, 15);
752 /* Use sprite from Action 1 */
753 uint index
= GB(grf_sprite
->sprite
, 0, 14);
754 if (use_cur_spritesets
&& (!_cur
.IsValidSpriteSet(feature
, index
) || _cur
.GetNumEnts(feature
, index
) == 0)) {
755 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index
);
756 grf_sprite
->sprite
= SPR_IMG_QUERY
;
757 grf_sprite
->pal
= PAL_NONE
;
759 SpriteID sprite
= use_cur_spritesets
? _cur
.GetSprite(feature
, index
) : index
;
760 if (max_sprite_offset
!= NULL
) *max_sprite_offset
= use_cur_spritesets
? _cur
.GetNumEnts(feature
, index
) : UINT16_MAX
;
761 SB(grf_sprite
->sprite
, 0, SPRITE_WIDTH
, sprite
);
762 SetBit(grf_sprite
->sprite
, SPRITE_MODIFIER_CUSTOM_SPRITE
);
764 } else if ((flags
& TLF_SPRITE_VAR10
) && !(flags
& TLF_SPRITE_REG_FLAGS
)) {
765 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
766 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
770 if (flags
& TLF_CUSTOM_PALETTE
) {
771 /* Use palette from Action 1 */
772 uint index
= GB(grf_sprite
->pal
, 0, 14);
773 if (use_cur_spritesets
&& (!_cur
.IsValidSpriteSet(feature
, index
) || _cur
.GetNumEnts(feature
, index
) == 0)) {
774 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index
);
775 grf_sprite
->pal
= PAL_NONE
;
777 SpriteID sprite
= use_cur_spritesets
? _cur
.GetSprite(feature
, index
) : index
;
778 if (max_palette_offset
!= NULL
) *max_palette_offset
= use_cur_spritesets
? _cur
.GetNumEnts(feature
, index
) : UINT16_MAX
;
779 SB(grf_sprite
->pal
, 0, SPRITE_WIDTH
, sprite
);
780 SetBit(grf_sprite
->pal
, SPRITE_MODIFIER_CUSTOM_SPRITE
);
782 } else if ((flags
& TLF_PALETTE_VAR10
) && !(flags
& TLF_PALETTE_REG_FLAGS
)) {
783 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
784 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
792 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
793 * @param buf Input stream.
794 * @param flags TileLayoutFlags to process.
795 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
796 * @param dts Sprite layout to insert data into.
797 * @param index Sprite index to process; 0 for ground sprite.
799 static void ReadSpriteLayoutRegisters(ByteReader
*buf
, TileLayoutFlags flags
, bool is_parent
, NewGRFSpriteLayout
*dts
, uint index
)
801 if (!(flags
& TLF_DRAWING_FLAGS
)) return;
803 if (dts
->registers
== NULL
) dts
->AllocateRegisters();
804 TileLayoutRegisters
®s
= const_cast<TileLayoutRegisters
&>(dts
->registers
[index
]);
805 regs
.flags
= flags
& TLF_DRAWING_FLAGS
;
807 if (flags
& TLF_DODRAW
) regs
.dodraw
= buf
->ReadByte();
808 if (flags
& TLF_SPRITE
) regs
.sprite
= buf
->ReadByte();
809 if (flags
& TLF_PALETTE
) regs
.palette
= buf
->ReadByte();
812 if (flags
& TLF_BB_XY_OFFSET
) {
813 regs
.delta
.parent
[0] = buf
->ReadByte();
814 regs
.delta
.parent
[1] = buf
->ReadByte();
816 if (flags
& TLF_BB_Z_OFFSET
) regs
.delta
.parent
[2] = buf
->ReadByte();
818 if (flags
& TLF_CHILD_X_OFFSET
) regs
.delta
.child
[0] = buf
->ReadByte();
819 if (flags
& TLF_CHILD_Y_OFFSET
) regs
.delta
.child
[1] = buf
->ReadByte();
822 if (flags
& TLF_SPRITE_VAR10
) {
823 regs
.sprite_var10
= buf
->ReadByte();
824 if (regs
.sprite_var10
> TLR_MAX_VAR10
) {
825 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs
.sprite_var10
, TLR_MAX_VAR10
);
826 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
831 if (flags
& TLF_PALETTE_VAR10
) {
832 regs
.palette_var10
= buf
->ReadByte();
833 if (regs
.palette_var10
> TLR_MAX_VAR10
) {
834 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs
.palette_var10
, TLR_MAX_VAR10
);
835 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
842 * Read a spritelayout from the GRF.
844 * @param num_building_sprites Number of building sprites to read
845 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
846 * @param feature GrfSpecFeature to use spritesets from.
847 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
848 * @param no_z_position Whether bounding boxes have no Z offset
849 * @param dts Layout container to output into
850 * @return True on error (GRF was disabled).
852 static bool ReadSpriteLayout(ByteReader
*buf
, uint num_building_sprites
, bool use_cur_spritesets
, byte feature
, bool allow_var10
, bool no_z_position
, NewGRFSpriteLayout
*dts
)
854 bool has_flags
= HasBit(num_building_sprites
, 6);
855 ClrBit(num_building_sprites
, 6);
856 TileLayoutFlags valid_flags
= TLF_KNOWN_FLAGS
;
857 if (!allow_var10
) valid_flags
&= ~TLF_VAR10_FLAGS
;
858 dts
->Allocate(num_building_sprites
); // allocate before reading groundsprite flags
860 uint16
*max_sprite_offset
= AllocaM(uint16
, num_building_sprites
+ 1);
861 uint16
*max_palette_offset
= AllocaM(uint16
, num_building_sprites
+ 1);
862 MemSetT(max_sprite_offset
, 0, num_building_sprites
+ 1);
863 MemSetT(max_palette_offset
, 0, num_building_sprites
+ 1);
866 TileLayoutFlags flags
= ReadSpriteLayoutSprite(buf
, has_flags
, false, use_cur_spritesets
, feature
, &dts
->ground
, max_sprite_offset
, max_palette_offset
);
867 if (_cur
.skip_sprites
< 0) return true;
869 if (flags
& ~(valid_flags
& ~TLF_NON_GROUND_FLAGS
)) {
870 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags
& ~(valid_flags
& ~TLF_NON_GROUND_FLAGS
));
871 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
875 ReadSpriteLayoutRegisters(buf
, flags
, false, dts
, 0);
876 if (_cur
.skip_sprites
< 0) return true;
878 for (uint i
= 0; i
< num_building_sprites
; i
++) {
879 DrawTileSeqStruct
*seq
= const_cast<DrawTileSeqStruct
*>(&dts
->seq
[i
]);
881 flags
= ReadSpriteLayoutSprite(buf
, has_flags
, false, use_cur_spritesets
, feature
, &seq
->image
, max_sprite_offset
+ i
+ 1, max_palette_offset
+ i
+ 1);
882 if (_cur
.skip_sprites
< 0) return true;
884 if (flags
& ~valid_flags
) {
885 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags
& ~valid_flags
);
886 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
890 seq
->delta_x
= buf
->ReadByte();
891 seq
->delta_y
= buf
->ReadByte();
893 if (!no_z_position
) seq
->delta_z
= buf
->ReadByte();
895 if (seq
->IsParentSprite()) {
896 seq
->size_x
= buf
->ReadByte();
897 seq
->size_y
= buf
->ReadByte();
898 seq
->size_z
= buf
->ReadByte();
901 ReadSpriteLayoutRegisters(buf
, flags
, seq
->IsParentSprite(), dts
, i
+ 1);
902 if (_cur
.skip_sprites
< 0) return true;
905 /* Check if the number of sprites per spriteset is consistent */
906 bool is_consistent
= true;
907 dts
->consistent_max_offset
= 0;
908 for (uint i
= 0; i
< num_building_sprites
+ 1; i
++) {
909 if (max_sprite_offset
[i
] > 0) {
910 if (dts
->consistent_max_offset
== 0) {
911 dts
->consistent_max_offset
= max_sprite_offset
[i
];
912 } else if (dts
->consistent_max_offset
!= max_sprite_offset
[i
]) {
913 is_consistent
= false;
917 if (max_palette_offset
[i
] > 0) {
918 if (dts
->consistent_max_offset
== 0) {
919 dts
->consistent_max_offset
= max_palette_offset
[i
];
920 } else if (dts
->consistent_max_offset
!= max_palette_offset
[i
]) {
921 is_consistent
= false;
927 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
928 assert(use_cur_spritesets
|| (is_consistent
&& (dts
->consistent_max_offset
== 0 || dts
->consistent_max_offset
== UINT16_MAX
)));
930 if (!is_consistent
|| dts
->registers
!= NULL
) {
931 dts
->consistent_max_offset
= 0;
932 if (dts
->registers
== NULL
) dts
->AllocateRegisters();
934 for (uint i
= 0; i
< num_building_sprites
+ 1; i
++) {
935 TileLayoutRegisters
®s
= const_cast<TileLayoutRegisters
&>(dts
->registers
[i
]);
936 regs
.max_sprite_offset
= max_sprite_offset
[i
];
937 regs
.max_palette_offset
= max_palette_offset
[i
];
945 * Translate the refit mask.
947 static uint32
TranslateRefitMask(uint32 refit_mask
)
951 FOR_EACH_SET_BIT(bit
, refit_mask
) {
952 CargoID cargo
= GetCargoTranslation(bit
, _cur
.grffile
, true);
953 if (cargo
!= CT_INVALID
) SetBit(result
, cargo
);
959 * Converts TTD(P) Base Price pointers into the enum used by OTTD
960 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
961 * @param base_pointer TTD(P) Base Price Pointer
962 * @param error_location Function name for grf error messages
963 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
965 static void ConvertTTDBasePrice(uint32 base_pointer
, const char *error_location
, Price
*index
)
967 /* Special value for 'none' */
968 if (base_pointer
== 0) {
969 *index
= INVALID_PRICE
;
973 static const uint32 start
= 0x4B34; ///< Position of first base price
974 static const uint32 size
= 6; ///< Size of each base price record
976 if (base_pointer
< start
|| (base_pointer
- start
) % size
!= 0 || (base_pointer
- start
) / size
>= PR_END
) {
977 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location
, base_pointer
);
981 *index
= (Price
)((base_pointer
- start
) / size
);
984 /** Possible return values for the FeatureChangeInfo functions */
985 enum ChangeInfoResult
{
986 CIR_SUCCESS
, ///< Variable was parsed and read
987 CIR_DISABLED
, ///< GRF was disabled due to error
988 CIR_UNHANDLED
, ///< Variable was parsed but unread
989 CIR_UNKNOWN
, ///< Variable is unknown
990 CIR_INVALID_ID
, ///< Attempt to modify an invalid ID
993 typedef ChangeInfoResult (*VCI_Handler
)(uint engine
, int numinfo
, int prop
, ByteReader
*buf
);
996 * Define properties common to all vehicles
997 * @param ei Engine info.
998 * @param prop The property to change.
999 * @param buf The property value.
1000 * @return ChangeInfoResult.
1002 static ChangeInfoResult
CommonVehicleChangeInfo(EngineInfo
*ei
, int prop
, ByteReader
*buf
)
1005 case 0x00: // Introduction date
1006 ei
->base_intro
= buf
->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR
;
1009 case 0x02: // Decay speed
1010 ei
->decay_speed
= buf
->ReadByte();
1013 case 0x03: // Vehicle life
1014 ei
->lifelength
= buf
->ReadByte();
1017 case 0x04: // Model life
1018 ei
->base_life
= buf
->ReadByte();
1021 case 0x06: // Climates available
1022 ei
->climates
= buf
->ReadByte();
1025 case PROP_VEHICLE_LOAD_AMOUNT
: // 0x07 Loading speed
1026 /* Amount of cargo loaded during a vehicle's "loading tick" */
1027 ei
->load_amount
= buf
->ReadByte();
1038 * Define properties for rail vehicles
1039 * @param engine :ocal ID of the first vehicle.
1040 * @param numinfo Number of subsequent IDs to change the property for.
1041 * @param prop The property to change.
1042 * @param buf The property value.
1043 * @return ChangeInfoResult.
1045 static ChangeInfoResult
RailVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1047 ChangeInfoResult ret
= CIR_SUCCESS
;
1049 for (int i
= 0; i
< numinfo
; i
++) {
1050 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_TRAIN
, engine
+ i
);
1051 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1053 EngineInfo
*ei
= &e
->info
;
1054 RailVehicleInfo
*rvi
= &e
->u
.rail
;
1057 case 0x05: { // Track type
1058 uint8 tracktype
= buf
->ReadByte();
1060 if (tracktype
< _cur
.grffile
->railtype_list
.Length()) {
1061 _gted
[e
->index
].railtypelabel
= _cur
.grffile
->railtype_list
[tracktype
];
1065 switch (tracktype
) {
1066 case 0: _gted
[e
->index
].railtypelabel
= rvi
->engclass
>= 2 ? RAILTYPE_ELECTRIC_LABEL
: RAILTYPE_RAIL_LABEL
; break;
1067 case 1: _gted
[e
->index
].railtypelabel
= RAILTYPE_MONO_LABEL
; break;
1068 case 2: _gted
[e
->index
].railtypelabel
= RAILTYPE_MAGLEV_LABEL
; break;
1070 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype
);
1076 case 0x08: // AI passenger service
1077 /* Tells the AI that this engine is designed for
1078 * passenger services and shouldn't be used for freight. */
1079 rvi
->ai_passenger_only
= buf
->ReadByte();
1082 case PROP_TRAIN_SPEED
: { // 0x09 Speed (1 unit is 1 km-ish/h)
1083 uint16 speed
= buf
->ReadWord();
1084 if (speed
== 0xFFFF) speed
= 0;
1086 rvi
->max_speed
= speed
;
1090 case PROP_TRAIN_POWER
: // 0x0B Power
1091 rvi
->power
= buf
->ReadWord();
1093 /* Set engine / wagon state based on power */
1094 if (rvi
->power
!= 0) {
1095 if (rvi
->railveh_type
== RAILVEH_WAGON
) {
1096 rvi
->railveh_type
= RAILVEH_SINGLEHEAD
;
1099 rvi
->railveh_type
= RAILVEH_WAGON
;
1103 case PROP_TRAIN_RUNNING_COST_FACTOR
: // 0x0D Running cost factor
1104 rvi
->running_cost
= buf
->ReadByte();
1107 case 0x0E: // Running cost base
1108 ConvertTTDBasePrice(buf
->ReadDWord(), "RailVehicleChangeInfo", &rvi
->running_cost_class
);
1111 case 0x12: { // Sprite ID
1112 uint8 spriteid
= buf
->ReadByte();
1113 uint8 orig_spriteid
= spriteid
;
1115 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1116 * as an array index, so we need it to be half the original value. */
1117 if (spriteid
< 0xFD) spriteid
>>= 1;
1119 if (IsValidNewGRFImageIndex
<VEH_TRAIN
>(spriteid
)) {
1120 rvi
->image_index
= spriteid
;
1122 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1123 rvi
->image_index
= 0;
1128 case 0x13: { // Dual-headed
1129 uint8 dual
= buf
->ReadByte();
1132 rvi
->railveh_type
= RAILVEH_MULTIHEAD
;
1134 rvi
->railveh_type
= rvi
->power
== 0 ?
1135 RAILVEH_WAGON
: RAILVEH_SINGLEHEAD
;
1140 case PROP_TRAIN_CARGO_CAPACITY
: // 0x14 Cargo capacity
1141 rvi
->capacity
= buf
->ReadByte();
1144 case 0x15: { // Cargo type
1145 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1146 uint8 ctype
= buf
->ReadByte();
1148 if (ctype
== 0xFF) {
1149 /* 0xFF is specified as 'use first refittable' */
1150 ei
->cargo_type
= CT_INVALID
;
1151 } else if (_cur
.grffile
->grf_version
>= 8) {
1152 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1153 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1154 } else if (ctype
< NUM_CARGO
) {
1155 /* Use untranslated cargo. */
1156 ei
->cargo_type
= ctype
;
1158 ei
->cargo_type
= CT_INVALID
;
1159 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1164 case PROP_TRAIN_WEIGHT
: // 0x16 Weight
1165 SB(rvi
->weight
, 0, 8, buf
->ReadByte());
1168 case PROP_TRAIN_COST_FACTOR
: // 0x17 Cost factor
1169 rvi
->cost_factor
= buf
->ReadByte();
1172 case 0x18: // AI rank
1173 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1177 case 0x19: { // Engine traction type
1178 /* What do the individual numbers mean?
1179 * 0x00 .. 0x07: Steam
1180 * 0x08 .. 0x27: Diesel
1181 * 0x28 .. 0x31: Electric
1182 * 0x32 .. 0x37: Monorail
1183 * 0x38 .. 0x41: Maglev
1185 uint8 traction
= buf
->ReadByte();
1186 EngineClass engclass
;
1188 if (traction
<= 0x07) {
1189 engclass
= EC_STEAM
;
1190 } else if (traction
<= 0x27) {
1191 engclass
= EC_DIESEL
;
1192 } else if (traction
<= 0x31) {
1193 engclass
= EC_ELECTRIC
;
1194 } else if (traction
<= 0x37) {
1195 engclass
= EC_MONORAIL
;
1196 } else if (traction
<= 0x41) {
1197 engclass
= EC_MAGLEV
;
1202 if (_cur
.grffile
->railtype_list
.Length() == 0) {
1203 /* Use traction type to select between normal and electrified
1204 * rail only when no translation list is in place. */
1205 if (_gted
[e
->index
].railtypelabel
== RAILTYPE_RAIL_LABEL
&& engclass
>= EC_ELECTRIC
) _gted
[e
->index
].railtypelabel
= RAILTYPE_ELECTRIC_LABEL
;
1206 if (_gted
[e
->index
].railtypelabel
== RAILTYPE_ELECTRIC_LABEL
&& engclass
< EC_ELECTRIC
) _gted
[e
->index
].railtypelabel
= RAILTYPE_RAIL_LABEL
;
1209 rvi
->engclass
= engclass
;
1213 case 0x1A: // Alter purchase list sort order
1214 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1217 case 0x1B: // Powered wagons power bonus
1218 rvi
->pow_wag_power
= buf
->ReadWord();
1221 case 0x1C: // Refit cost
1222 ei
->refit_cost
= buf
->ReadByte();
1225 case 0x1D: { // Refit cargo
1226 uint32 mask
= buf
->ReadDWord();
1227 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1228 ei
->refit_mask
= TranslateRefitMask(mask
);
1229 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1233 case 0x1E: // Callback
1234 ei
->callback_mask
= buf
->ReadByte();
1237 case PROP_TRAIN_TRACTIVE_EFFORT
: // 0x1F Tractive effort coefficient
1238 rvi
->tractive_effort
= buf
->ReadByte();
1241 case 0x20: // Air drag
1242 rvi
->air_drag
= buf
->ReadByte();
1245 case PROP_TRAIN_SHORTEN_FACTOR
: // 0x21 Shorter vehicle
1246 rvi
->shorten_factor
= buf
->ReadByte();
1249 case 0x22: // Visual effect
1250 rvi
->visual_effect
= buf
->ReadByte();
1251 /* Avoid accidentally setting visual_effect to the default value
1252 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1253 if (rvi
->visual_effect
== VE_DEFAULT
) {
1254 assert(HasBit(rvi
->visual_effect
, VE_DISABLE_EFFECT
));
1255 SB(rvi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1259 case 0x23: // Powered wagons weight bonus
1260 rvi
->pow_wag_weight
= buf
->ReadByte();
1263 case 0x24: { // High byte of vehicle weight
1264 byte weight
= buf
->ReadByte();
1267 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight
<< 8);
1269 SB(rvi
->weight
, 8, 8, weight
);
1274 case PROP_TRAIN_USER_DATA
: // 0x25 User-defined bit mask to set when checking veh. var. 42
1275 rvi
->user_def_data
= buf
->ReadByte();
1278 case 0x26: // Retire vehicle early
1279 ei
->retire_early
= buf
->ReadByte();
1282 case 0x27: // Miscellaneous flags
1283 ei
->misc_flags
= buf
->ReadByte();
1284 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1285 _gted
[e
->index
].prop27_set
= true;
1288 case 0x28: // Cargo classes allowed
1289 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1290 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1291 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1294 case 0x29: // Cargo classes disallowed
1295 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1296 _gted
[e
->index
].UpdateRefittability(false);
1299 case 0x2A: // Long format introduction date (days since year 0)
1300 ei
->base_intro
= buf
->ReadDWord();
1303 case PROP_TRAIN_CARGO_AGE_PERIOD
: // 0x2B Cargo aging period
1304 ei
->cargo_age_period
= buf
->ReadWord();
1307 case 0x2C: // CTT refit include list
1308 case 0x2D: { // CTT refit exclude list
1309 uint8 count
= buf
->ReadByte();
1310 _gted
[e
->index
].UpdateRefittability(prop
== 0x2C && count
!= 0);
1311 if (prop
== 0x2C) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1312 uint32
&ctt
= prop
== 0x2C ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1315 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1316 if (ctype
== CT_INVALID
) continue;
1323 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1332 * Define properties for road vehicles
1333 * @param engine Local ID of the first vehicle.
1334 * @param numinfo Number of subsequent IDs to change the property for.
1335 * @param prop The property to change.
1336 * @param buf The property value.
1337 * @return ChangeInfoResult.
1339 static ChangeInfoResult
RoadVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1341 ChangeInfoResult ret
= CIR_SUCCESS
;
1343 for (int i
= 0; i
< numinfo
; i
++) {
1344 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_ROAD
, engine
+ i
);
1345 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1347 EngineInfo
*ei
= &e
->info
;
1348 RoadVehicleInfo
*rvi
= &e
->u
.road
;
1351 case 0x08: // Speed (1 unit is 0.5 kmh)
1352 rvi
->max_speed
= buf
->ReadByte();
1355 case PROP_ROADVEH_RUNNING_COST_FACTOR
: // 0x09 Running cost factor
1356 rvi
->running_cost
= buf
->ReadByte();
1359 case 0x0A: // Running cost base
1360 ConvertTTDBasePrice(buf
->ReadDWord(), "RoadVehicleChangeInfo", &rvi
->running_cost_class
);
1363 case 0x0E: { // Sprite ID
1364 uint8 spriteid
= buf
->ReadByte();
1365 uint8 orig_spriteid
= spriteid
;
1367 /* cars have different custom id in the GRF file */
1368 if (spriteid
== 0xFF) spriteid
= 0xFD;
1370 if (spriteid
< 0xFD) spriteid
>>= 1;
1372 if (IsValidNewGRFImageIndex
<VEH_ROAD
>(spriteid
)) {
1373 rvi
->image_index
= spriteid
;
1375 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1376 rvi
->image_index
= 0;
1381 case PROP_ROADVEH_CARGO_CAPACITY
: // 0x0F Cargo capacity
1382 rvi
->capacity
= buf
->ReadByte();
1385 case 0x10: { // Cargo type
1386 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1387 uint8 ctype
= buf
->ReadByte();
1389 if (ctype
== 0xFF) {
1390 /* 0xFF is specified as 'use first refittable' */
1391 ei
->cargo_type
= CT_INVALID
;
1392 } else if (_cur
.grffile
->grf_version
>= 8) {
1393 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1394 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1395 } else if (ctype
< NUM_CARGO
) {
1396 /* Use untranslated cargo. */
1397 ei
->cargo_type
= ctype
;
1399 ei
->cargo_type
= CT_INVALID
;
1400 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1405 case PROP_ROADVEH_COST_FACTOR
: // 0x11 Cost factor
1406 rvi
->cost_factor
= buf
->ReadByte();
1410 rvi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1413 case PROP_ROADVEH_POWER
: // Power in units of 10 HP.
1414 rvi
->power
= buf
->ReadByte();
1417 case PROP_ROADVEH_WEIGHT
: // Weight in units of 1/4 tons.
1418 rvi
->weight
= buf
->ReadByte();
1421 case PROP_ROADVEH_SPEED
: // Speed in mph/0.8
1422 _gted
[e
->index
].rv_max_speed
= buf
->ReadByte();
1425 case 0x16: { // Cargoes available for refitting
1426 uint32 mask
= buf
->ReadDWord();
1427 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1428 ei
->refit_mask
= TranslateRefitMask(mask
);
1429 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1433 case 0x17: // Callback mask
1434 ei
->callback_mask
= buf
->ReadByte();
1437 case PROP_ROADVEH_TRACTIVE_EFFORT
: // Tractive effort coefficient in 1/256.
1438 rvi
->tractive_effort
= buf
->ReadByte();
1441 case 0x19: // Air drag
1442 rvi
->air_drag
= buf
->ReadByte();
1445 case 0x1A: // Refit cost
1446 ei
->refit_cost
= buf
->ReadByte();
1449 case 0x1B: // Retire vehicle early
1450 ei
->retire_early
= buf
->ReadByte();
1453 case 0x1C: // Miscellaneous flags
1454 ei
->misc_flags
= buf
->ReadByte();
1455 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1458 case 0x1D: // Cargo classes allowed
1459 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1460 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1461 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1464 case 0x1E: // Cargo classes disallowed
1465 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1466 _gted
[e
->index
].UpdateRefittability(false);
1469 case 0x1F: // Long format introduction date (days since year 0)
1470 ei
->base_intro
= buf
->ReadDWord();
1473 case 0x20: // Alter purchase list sort order
1474 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1477 case 0x21: // Visual effect
1478 rvi
->visual_effect
= buf
->ReadByte();
1479 /* Avoid accidentally setting visual_effect to the default value
1480 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1481 if (rvi
->visual_effect
== VE_DEFAULT
) {
1482 assert(HasBit(rvi
->visual_effect
, VE_DISABLE_EFFECT
));
1483 SB(rvi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1487 case PROP_ROADVEH_CARGO_AGE_PERIOD
: // 0x22 Cargo aging period
1488 ei
->cargo_age_period
= buf
->ReadWord();
1491 case PROP_ROADVEH_SHORTEN_FACTOR
: // 0x23 Shorter vehicle
1492 rvi
->shorten_factor
= buf
->ReadByte();
1495 case 0x24: // CTT refit include list
1496 case 0x25: { // CTT refit exclude list
1497 uint8 count
= buf
->ReadByte();
1498 _gted
[e
->index
].UpdateRefittability(prop
== 0x24 && count
!= 0);
1499 if (prop
== 0x24) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1500 uint32
&ctt
= prop
== 0x24 ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1503 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1504 if (ctype
== CT_INVALID
) continue;
1511 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1520 * Define properties for ships
1521 * @param engine Local ID of the first vehicle.
1522 * @param numinfo Number of subsequent IDs to change the property for.
1523 * @param prop The property to change.
1524 * @param buf The property value.
1525 * @return ChangeInfoResult.
1527 static ChangeInfoResult
ShipVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1529 ChangeInfoResult ret
= CIR_SUCCESS
;
1531 for (int i
= 0; i
< numinfo
; i
++) {
1532 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_SHIP
, engine
+ i
);
1533 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1535 EngineInfo
*ei
= &e
->info
;
1536 ShipVehicleInfo
*svi
= &e
->u
.ship
;
1539 case 0x08: { // Sprite ID
1540 uint8 spriteid
= buf
->ReadByte();
1541 uint8 orig_spriteid
= spriteid
;
1543 /* ships have different custom id in the GRF file */
1544 if (spriteid
== 0xFF) spriteid
= 0xFD;
1546 if (spriteid
< 0xFD) spriteid
>>= 1;
1548 if (IsValidNewGRFImageIndex
<VEH_SHIP
>(spriteid
)) {
1549 svi
->image_index
= spriteid
;
1551 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1552 svi
->image_index
= 0;
1557 case 0x09: // Refittable
1558 svi
->old_refittable
= (buf
->ReadByte() != 0);
1561 case PROP_SHIP_COST_FACTOR
: // 0x0A Cost factor
1562 svi
->cost_factor
= buf
->ReadByte();
1565 case PROP_SHIP_SPEED
: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1566 svi
->max_speed
= buf
->ReadByte();
1569 case 0x0C: { // Cargo type
1570 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1571 uint8 ctype
= buf
->ReadByte();
1573 if (ctype
== 0xFF) {
1574 /* 0xFF is specified as 'use first refittable' */
1575 ei
->cargo_type
= CT_INVALID
;
1576 } else if (_cur
.grffile
->grf_version
>= 8) {
1577 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1578 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1579 } else if (ctype
< NUM_CARGO
) {
1580 /* Use untranslated cargo. */
1581 ei
->cargo_type
= ctype
;
1583 ei
->cargo_type
= CT_INVALID
;
1584 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1589 case PROP_SHIP_CARGO_CAPACITY
: // 0x0D Cargo capacity
1590 svi
->capacity
= buf
->ReadWord();
1593 case PROP_SHIP_RUNNING_COST_FACTOR
: // 0x0F Running cost factor
1594 svi
->running_cost
= buf
->ReadByte();
1598 svi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1601 case 0x11: { // Cargoes available for refitting
1602 uint32 mask
= buf
->ReadDWord();
1603 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1604 ei
->refit_mask
= TranslateRefitMask(mask
);
1605 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1609 case 0x12: // Callback mask
1610 ei
->callback_mask
= buf
->ReadByte();
1613 case 0x13: // Refit cost
1614 ei
->refit_cost
= buf
->ReadByte();
1617 case 0x14: // Ocean speed fraction
1618 svi
->ocean_speed_frac
= buf
->ReadByte();
1621 case 0x15: // Canal speed fraction
1622 svi
->canal_speed_frac
= buf
->ReadByte();
1625 case 0x16: // Retire vehicle early
1626 ei
->retire_early
= buf
->ReadByte();
1629 case 0x17: // Miscellaneous flags
1630 ei
->misc_flags
= buf
->ReadByte();
1631 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1634 case 0x18: // Cargo classes allowed
1635 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1636 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1637 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1640 case 0x19: // Cargo classes disallowed
1641 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1642 _gted
[e
->index
].UpdateRefittability(false);
1645 case 0x1A: // Long format introduction date (days since year 0)
1646 ei
->base_intro
= buf
->ReadDWord();
1649 case 0x1B: // Alter purchase list sort order
1650 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1653 case 0x1C: // Visual effect
1654 svi
->visual_effect
= buf
->ReadByte();
1655 /* Avoid accidentally setting visual_effect to the default value
1656 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1657 if (svi
->visual_effect
== VE_DEFAULT
) {
1658 assert(HasBit(svi
->visual_effect
, VE_DISABLE_EFFECT
));
1659 SB(svi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1663 case PROP_SHIP_CARGO_AGE_PERIOD
: // 0x1D Cargo aging period
1664 ei
->cargo_age_period
= buf
->ReadWord();
1667 case 0x1E: // CTT refit include list
1668 case 0x1F: { // CTT refit exclude list
1669 uint8 count
= buf
->ReadByte();
1670 _gted
[e
->index
].UpdateRefittability(prop
== 0x1E && count
!= 0);
1671 if (prop
== 0x1E) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1672 uint32
&ctt
= prop
== 0x1E ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1675 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1676 if (ctype
== CT_INVALID
) continue;
1683 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1692 * Define properties for aircraft
1693 * @param engine Local ID of the aircraft.
1694 * @param numinfo Number of subsequent IDs to change the property for.
1695 * @param prop The property to change.
1696 * @param buf The property value.
1697 * @return ChangeInfoResult.
1699 static ChangeInfoResult
AircraftVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1701 ChangeInfoResult ret
= CIR_SUCCESS
;
1703 for (int i
= 0; i
< numinfo
; i
++) {
1704 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_AIRCRAFT
, engine
+ i
);
1705 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1707 EngineInfo
*ei
= &e
->info
;
1708 AircraftVehicleInfo
*avi
= &e
->u
.air
;
1711 case 0x08: { // Sprite ID
1712 uint8 spriteid
= buf
->ReadByte();
1713 uint8 orig_spriteid
= spriteid
;
1715 /* aircraft have different custom id in the GRF file */
1716 if (spriteid
== 0xFF) spriteid
= 0xFD;
1718 if (spriteid
< 0xFD) spriteid
>>= 1;
1720 if (IsValidNewGRFImageIndex
<VEH_AIRCRAFT
>(spriteid
)) {
1721 avi
->image_index
= spriteid
;
1723 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1724 avi
->image_index
= 0;
1729 case 0x09: // Helicopter
1730 if (buf
->ReadByte() == 0) {
1731 avi
->subtype
= AIR_HELI
;
1733 SB(avi
->subtype
, 0, 1, 1); // AIR_CTOL
1738 SB(avi
->subtype
, 1, 1, (buf
->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1741 case PROP_AIRCRAFT_COST_FACTOR
: // 0x0B Cost factor
1742 avi
->cost_factor
= buf
->ReadByte();
1745 case PROP_AIRCRAFT_SPEED
: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1746 avi
->max_speed
= (buf
->ReadByte() * 128) / 10;
1749 case 0x0D: // Acceleration
1750 avi
->acceleration
= buf
->ReadByte();
1753 case PROP_AIRCRAFT_RUNNING_COST_FACTOR
: // 0x0E Running cost factor
1754 avi
->running_cost
= buf
->ReadByte();
1757 case PROP_AIRCRAFT_PASSENGER_CAPACITY
: // 0x0F Passenger capacity
1758 avi
->passenger_capacity
= buf
->ReadWord();
1761 case PROP_AIRCRAFT_MAIL_CAPACITY
: // 0x11 Mail capacity
1762 avi
->mail_capacity
= buf
->ReadByte();
1766 avi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1769 case 0x13: { // Cargoes available for refitting
1770 uint32 mask
= buf
->ReadDWord();
1771 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1772 ei
->refit_mask
= TranslateRefitMask(mask
);
1773 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1777 case 0x14: // Callback mask
1778 ei
->callback_mask
= buf
->ReadByte();
1781 case 0x15: // Refit cost
1782 ei
->refit_cost
= buf
->ReadByte();
1785 case 0x16: // Retire vehicle early
1786 ei
->retire_early
= buf
->ReadByte();
1789 case 0x17: // Miscellaneous flags
1790 ei
->misc_flags
= buf
->ReadByte();
1791 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1794 case 0x18: // Cargo classes allowed
1795 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1796 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1797 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1800 case 0x19: // Cargo classes disallowed
1801 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1802 _gted
[e
->index
].UpdateRefittability(false);
1805 case 0x1A: // Long format introduction date (days since year 0)
1806 ei
->base_intro
= buf
->ReadDWord();
1809 case 0x1B: // Alter purchase list sort order
1810 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1813 case PROP_AIRCRAFT_CARGO_AGE_PERIOD
: // 0x1C Cargo aging period
1814 ei
->cargo_age_period
= buf
->ReadWord();
1817 case 0x1D: // CTT refit include list
1818 case 0x1E: { // CTT refit exclude list
1819 uint8 count
= buf
->ReadByte();
1820 _gted
[e
->index
].UpdateRefittability(prop
== 0x1D && count
!= 0);
1821 if (prop
== 0x1D) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1822 uint32
&ctt
= prop
== 0x1D ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1825 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1826 if (ctype
== CT_INVALID
) continue;
1832 case PROP_AIRCRAFT_RANGE
: // 0x1F Max aircraft range
1833 avi
->max_range
= buf
->ReadWord();
1837 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1846 * Define properties for stations
1847 * @param stdid StationID of the first station tile.
1848 * @param numinfo Number of subsequent station tiles to change the property for.
1849 * @param prop The property to change.
1850 * @param buf The property value.
1851 * @return ChangeInfoResult.
1853 static ChangeInfoResult
StationChangeInfo(uint stid
, int numinfo
, int prop
, ByteReader
*buf
)
1855 ChangeInfoResult ret
= CIR_SUCCESS
;
1857 if (stid
+ numinfo
> NUM_STATIONS_PER_GRF
) {
1858 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid
+ numinfo
, NUM_STATIONS_PER_GRF
);
1859 return CIR_INVALID_ID
;
1862 /* Allocate station specs if necessary */
1863 if (_cur
.grffile
->stations
== NULL
) _cur
.grffile
->stations
= CallocT
<StationSpec
*>(NUM_STATIONS_PER_GRF
);
1865 for (int i
= 0; i
< numinfo
; i
++) {
1866 StationSpec
*statspec
= _cur
.grffile
->stations
[stid
+ i
];
1868 /* Check that the station we are modifying is defined. */
1869 if (statspec
== NULL
&& prop
!= 0x08) {
1870 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid
+ i
);
1871 return CIR_INVALID_ID
;
1875 case 0x08: { // Class ID
1876 StationSpec
**spec
= &_cur
.grffile
->stations
[stid
+ i
];
1878 /* Property 0x08 is special; it is where the station is allocated */
1879 if (*spec
== NULL
) *spec
= CallocT
<StationSpec
>(1);
1881 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1882 uint32 classid
= buf
->ReadDWord();
1883 (*spec
)->cls_id
= StationClass::Allocate(BSWAP32(classid
));
1887 case 0x09: // Define sprite layout
1888 statspec
->tiles
= buf
->ReadExtendedByte();
1889 delete[] statspec
->renderdata
; // delete earlier loaded stuff
1890 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
1892 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
1893 NewGRFSpriteLayout
*dts
= &statspec
->renderdata
[t
];
1894 dts
->consistent_max_offset
= UINT16_MAX
; // Spritesets are unknown, so no limit.
1896 if (buf
->HasData(4) && *(uint32
*)buf
->Data() == 0) {
1898 extern const DrawTileSprites _station_display_datas_rail
[8];
1899 dts
->Clone(&_station_display_datas_rail
[t
% 8]);
1903 ReadSpriteLayoutSprite(buf
, false, false, false, GSF_STATIONS
, &dts
->ground
);
1904 /* On error, bail out immediately. Temporary GRF data was already freed */
1905 if (_cur
.skip_sprites
< 0) return CIR_DISABLED
;
1907 static SmallVector
<DrawTileSeqStruct
, 8> tmp_layout
;
1910 /* no relative bounding box support */
1911 DrawTileSeqStruct
*dtss
= tmp_layout
.Append();
1914 dtss
->delta_x
= buf
->ReadByte();
1915 if (dtss
->IsTerminator()) break;
1916 dtss
->delta_y
= buf
->ReadByte();
1917 dtss
->delta_z
= buf
->ReadByte();
1918 dtss
->size_x
= buf
->ReadByte();
1919 dtss
->size_y
= buf
->ReadByte();
1920 dtss
->size_z
= buf
->ReadByte();
1922 ReadSpriteLayoutSprite(buf
, false, true, false, GSF_STATIONS
, &dtss
->image
);
1923 /* On error, bail out immediately. Temporary GRF data was already freed */
1924 if (_cur
.skip_sprites
< 0) return CIR_DISABLED
;
1926 dts
->Clone(tmp_layout
.Begin());
1930 case 0x0A: { // Copy sprite layout
1931 byte srcid
= buf
->ReadByte();
1932 const StationSpec
*srcstatspec
= _cur
.grffile
->stations
[srcid
];
1934 if (srcstatspec
== NULL
) {
1935 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid
, stid
+ i
);
1939 delete[] statspec
->renderdata
; // delete earlier loaded stuff
1941 statspec
->tiles
= srcstatspec
->tiles
;
1942 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
1943 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
1944 statspec
->renderdata
[t
].Clone(&srcstatspec
->renderdata
[t
]);
1949 case 0x0B: // Callback mask
1950 statspec
->callback_mask
= buf
->ReadByte();
1953 case 0x0C: // Disallowed number of platforms
1954 statspec
->disallowed_platforms
= buf
->ReadByte();
1957 case 0x0D: // Disallowed platform lengths
1958 statspec
->disallowed_lengths
= buf
->ReadByte();
1961 case 0x0E: // Define custom layout
1962 statspec
->copied_layouts
= false;
1964 while (buf
->HasData()) {
1965 byte length
= buf
->ReadByte();
1966 byte number
= buf
->ReadByte();
1967 StationLayout layout
;
1970 if (length
== 0 || number
== 0) break;
1972 if (length
> statspec
->lengths
) {
1973 statspec
->platforms
= ReallocT(statspec
->platforms
, length
);
1974 memset(statspec
->platforms
+ statspec
->lengths
, 0, length
- statspec
->lengths
);
1976 statspec
->layouts
= ReallocT(statspec
->layouts
, length
);
1977 memset(statspec
->layouts
+ statspec
->lengths
, 0,
1978 (length
- statspec
->lengths
) * sizeof(*statspec
->layouts
));
1980 statspec
->lengths
= length
;
1982 l
= length
- 1; // index is zero-based
1984 if (number
> statspec
->platforms
[l
]) {
1985 statspec
->layouts
[l
] = ReallocT(statspec
->layouts
[l
], number
);
1986 /* We expect NULL being 0 here, but C99 guarantees that. */
1987 memset(statspec
->layouts
[l
] + statspec
->platforms
[l
], 0,
1988 (number
- statspec
->platforms
[l
]) * sizeof(**statspec
->layouts
));
1990 statspec
->platforms
[l
] = number
;
1994 layout
= MallocT
<byte
>(length
* number
);
1996 for (l
= 0; l
< length
; l
++) {
1997 for (p
= 0; p
< number
; p
++) {
1998 layout
[l
* number
+ p
] = buf
->ReadByte();
2008 free(statspec
->layouts
[l
][p
]);
2009 statspec
->layouts
[l
][p
] = layout
;
2013 case 0x0F: { // Copy custom layout
2014 byte srcid
= buf
->ReadByte();
2015 const StationSpec
*srcstatspec
= _cur
.grffile
->stations
[srcid
];
2017 if (srcstatspec
== NULL
) {
2018 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid
, stid
+ i
);
2022 statspec
->lengths
= srcstatspec
->lengths
;
2023 statspec
->platforms
= srcstatspec
->platforms
;
2024 statspec
->layouts
= srcstatspec
->layouts
;
2025 statspec
->copied_layouts
= true;
2029 case 0x10: // Little/lots cargo threshold
2030 statspec
->cargo_threshold
= buf
->ReadWord();
2033 case 0x11: // Pylon placement
2034 statspec
->pylons
= buf
->ReadByte();
2037 case 0x12: // Cargo types for random triggers
2038 statspec
->cargo_triggers
= buf
->ReadDWord();
2039 if (_cur
.grffile
->grf_version
>= 7) {
2040 statspec
->cargo_triggers
= TranslateRefitMask(statspec
->cargo_triggers
);
2044 case 0x13: // General flags
2045 statspec
->flags
= buf
->ReadByte();
2048 case 0x14: // Overhead wire placement
2049 statspec
->wires
= buf
->ReadByte();
2052 case 0x15: // Blocked tiles
2053 statspec
->blocked
= buf
->ReadByte();
2056 case 0x16: // Animation info
2057 statspec
->animation
.frames
= buf
->ReadByte();
2058 statspec
->animation
.status
= buf
->ReadByte();
2061 case 0x17: // Animation speed
2062 statspec
->animation
.speed
= buf
->ReadByte();
2065 case 0x18: // Animation triggers
2066 statspec
->animation
.triggers
= buf
->ReadWord();
2069 case 0x1A: // Advanced sprite layout
2070 statspec
->tiles
= buf
->ReadExtendedByte();
2071 delete[] statspec
->renderdata
; // delete earlier loaded stuff
2072 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
2074 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
2075 NewGRFSpriteLayout
*dts
= &statspec
->renderdata
[t
];
2076 uint num_building_sprites
= buf
->ReadByte();
2077 /* On error, bail out immediately. Temporary GRF data was already freed */
2078 if (ReadSpriteLayout(buf
, num_building_sprites
, false, GSF_STATIONS
, true, false, dts
)) return CIR_DISABLED
;
2092 * Define properties for water features
2093 * @param id Type of the first water feature.
2094 * @param numinfo Number of subsequent water feature ids to change the property for.
2095 * @param prop The property to change.
2096 * @param buf The property value.
2097 * @return ChangeInfoResult.
2099 static ChangeInfoResult
CanalChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
2101 ChangeInfoResult ret
= CIR_SUCCESS
;
2103 if (id
+ numinfo
> CF_END
) {
2104 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id
+ numinfo
, CF_END
);
2105 return CIR_INVALID_ID
;
2108 for (int i
= 0; i
< numinfo
; i
++) {
2109 CanalProperties
*cp
= &_cur
.grffile
->canal_local_properties
[id
+ i
];
2113 cp
->callback_mask
= buf
->ReadByte();
2117 cp
->flags
= buf
->ReadByte();
2130 * Define properties for bridges
2131 * @param brid BridgeID of the bridge.
2132 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2133 * @param prop The property to change.
2134 * @param buf The property value.
2135 * @return ChangeInfoResult.
2137 static ChangeInfoResult
BridgeChangeInfo(uint brid
, int numinfo
, int prop
, ByteReader
*buf
)
2139 ChangeInfoResult ret
= CIR_SUCCESS
;
2141 if (brid
+ numinfo
> MAX_BRIDGES
) {
2142 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid
+ numinfo
, MAX_BRIDGES
);
2143 return CIR_INVALID_ID
;
2146 for (int i
= 0; i
< numinfo
; i
++) {
2147 BridgeSpec
*bridge
= &_bridge
[brid
+ i
];
2150 case 0x08: { // Year of availability
2151 /* We treat '0' as always available */
2152 byte year
= buf
->ReadByte();
2153 bridge
->avail_year
= (year
> 0 ? ORIGINAL_BASE_YEAR
+ year
: 0);
2157 case 0x09: // Minimum length
2158 bridge
->min_length
= buf
->ReadByte();
2161 case 0x0A: // Maximum length
2162 bridge
->max_length
= buf
->ReadByte();
2163 if (bridge
->max_length
> 16) bridge
->max_length
= 0xFFFF;
2166 case 0x0B: // Cost factor
2167 bridge
->price
= buf
->ReadByte();
2170 case 0x0C: // Maximum speed
2171 bridge
->speed
= buf
->ReadWord();
2174 case 0x0D: { // Bridge sprite tables
2175 byte tableid
= buf
->ReadByte();
2176 byte numtables
= buf
->ReadByte();
2178 if (bridge
->sprite_table
== NULL
) {
2179 /* Allocate memory for sprite table pointers and zero out */
2180 bridge
->sprite_table
= CallocT
<PalSpriteID
*>(7);
2183 for (; numtables
-- != 0; tableid
++) {
2184 if (tableid
>= 7) { // skip invalid data
2185 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid
);
2186 for (byte sprite
= 0; sprite
< 32; sprite
++) buf
->ReadDWord();
2190 if (bridge
->sprite_table
[tableid
] == NULL
) {
2191 bridge
->sprite_table
[tableid
] = MallocT
<PalSpriteID
>(32);
2194 for (byte sprite
= 0; sprite
< 32; sprite
++) {
2195 SpriteID image
= buf
->ReadWord();
2196 PaletteID pal
= buf
->ReadWord();
2198 bridge
->sprite_table
[tableid
][sprite
].sprite
= image
;
2199 bridge
->sprite_table
[tableid
][sprite
].pal
= pal
;
2201 MapSpriteMappingRecolour(&bridge
->sprite_table
[tableid
][sprite
]);
2207 case 0x0E: // Flags; bit 0 - disable far pillars
2208 bridge
->flags
= buf
->ReadByte();
2211 case 0x0F: // Long format year of availability (year since year 0)
2212 bridge
->avail_year
= Clamp(buf
->ReadDWord(), MIN_YEAR
, MAX_YEAR
);
2215 case 0x10: { // purchase string
2216 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2217 if (newone
!= STR_UNDEFINED
) bridge
->material
= newone
;
2221 case 0x11: // description of bridge with rails or roads
2223 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2224 if (newone
!= STR_UNDEFINED
) bridge
->transport_name
[prop
- 0x11] = newone
;
2228 case 0x13: // 16 bits cost multiplier
2229 bridge
->price
= buf
->ReadWord();
2242 * Ignore a house property
2243 * @param prop Property to read.
2244 * @param buf Property value.
2245 * @return ChangeInfoResult.
2247 static ChangeInfoResult
IgnoreTownHouseProperty(int prop
, ByteReader
*buf
)
2249 ChangeInfoResult ret
= CIR_SUCCESS
;
2286 for (uint j
= 0; j
< 4; j
++) buf
->ReadByte();
2290 byte count
= buf
->ReadByte();
2291 for (byte j
= 0; j
< count
; j
++) buf
->ReadByte();
2303 * Define properties for houses
2304 * @param hid HouseID of the house.
2305 * @param numinfo Number of subsequent houseIDs to change the property for.
2306 * @param prop The property to change.
2307 * @param buf The property value.
2308 * @return ChangeInfoResult.
2310 static ChangeInfoResult
TownHouseChangeInfo(uint hid
, int numinfo
, int prop
, ByteReader
*buf
)
2312 ChangeInfoResult ret
= CIR_SUCCESS
;
2314 if (hid
+ numinfo
> NUM_HOUSES_PER_GRF
) {
2315 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid
+ numinfo
, NUM_HOUSES_PER_GRF
);
2316 return CIR_INVALID_ID
;
2319 /* Allocate house specs if they haven't been allocated already. */
2320 if (_cur
.grffile
->housespec
== NULL
) {
2321 _cur
.grffile
->housespec
= CallocT
<HouseSpec
*>(NUM_HOUSES_PER_GRF
);
2324 for (int i
= 0; i
< numinfo
; i
++) {
2325 HouseSpec
*housespec
= _cur
.grffile
->housespec
[hid
+ i
];
2327 if (prop
!= 0x08 && housespec
== NULL
) {
2328 /* If the house property 08 is not yet set, ignore this property */
2329 ChangeInfoResult cir
= IgnoreTownHouseProperty(prop
, buf
);
2330 if (cir
> ret
) ret
= cir
;
2335 case 0x08: { // Substitute building type, and definition of a new house
2336 HouseSpec
**house
= &_cur
.grffile
->housespec
[hid
+ i
];
2337 byte subs_id
= buf
->ReadByte();
2339 if (subs_id
== 0xFF) {
2340 /* Instead of defining a new house, a substitute house id
2341 * of 0xFF disables the old house with the current id. */
2342 HouseSpec::Get(hid
+ i
)->enabled
= false;
2344 } else if (subs_id
>= NEW_HOUSE_OFFSET
) {
2345 /* The substitute id must be one of the original houses. */
2346 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id
, hid
+ i
);
2350 /* Allocate space for this house. */
2351 if (*house
== NULL
) *house
= CallocT
<HouseSpec
>(1);
2355 MemCpyT(housespec
, HouseSpec::Get(subs_id
));
2357 housespec
->enabled
= true;
2358 housespec
->grf_prop
.local_id
= hid
+ i
;
2359 housespec
->grf_prop
.subst_id
= subs_id
;
2360 housespec
->grf_prop
.grffile
= _cur
.grffile
;
2361 housespec
->random_colour
[0] = 0x04; // those 4 random colours are the base colour
2362 housespec
->random_colour
[1] = 0x08; // for all new houses
2363 housespec
->random_colour
[2] = 0x0C; // they stand for red, blue, orange and green
2364 housespec
->random_colour
[3] = 0x06;
2366 /* Make sure that the third cargo type is valid in this
2367 * climate. This can cause problems when copying the properties
2368 * of a house that accepts food, where the new house is valid
2369 * in the temperate climate. */
2370 if (!CargoSpec::Get(housespec
->accepts_cargo
[2])->IsValid()) {
2371 housespec
->cargo_acceptance
[2] = 0;
2374 _loaded_newgrf_features
.has_newhouses
= true;
2378 case 0x09: // Building flags
2379 housespec
->building_flags
= (BuildingFlags
)buf
->ReadByte();
2382 case 0x0A: { // Availability years
2383 uint16 years
= buf
->ReadWord();
2384 housespec
->min_year
= GB(years
, 0, 8) > 150 ? MAX_YEAR
: ORIGINAL_BASE_YEAR
+ GB(years
, 0, 8);
2385 housespec
->max_year
= GB(years
, 8, 8) > 150 ? MAX_YEAR
: ORIGINAL_BASE_YEAR
+ GB(years
, 8, 8);
2389 case 0x0B: // Population
2390 housespec
->population
= buf
->ReadByte();
2393 case 0x0C: // Mail generation multiplier
2394 housespec
->mail_generation
= buf
->ReadByte();
2397 case 0x0D: // Passenger acceptance
2398 case 0x0E: // Mail acceptance
2399 housespec
->cargo_acceptance
[prop
- 0x0D] = buf
->ReadByte();
2402 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2403 int8 goods
= buf
->ReadByte();
2405 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2406 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2407 CargoID cid
= (goods
>= 0) ? ((_settings_game
.game_creation
.landscape
== LT_TOYLAND
) ? CT_CANDY
: CT_GOODS
) :
2408 ((_settings_game
.game_creation
.landscape
== LT_TOYLAND
) ? CT_FIZZY_DRINKS
: CT_FOOD
);
2410 /* Make sure the cargo type is valid in this climate. */
2411 if (!CargoSpec::Get(cid
)->IsValid()) goods
= 0;
2413 housespec
->accepts_cargo
[2] = cid
;
2414 housespec
->cargo_acceptance
[2] = abs(goods
); // but we do need positive value here
2418 case 0x10: // Local authority rating decrease on removal
2419 housespec
->remove_rating_decrease
= buf
->ReadWord();
2422 case 0x11: // Removal cost multiplier
2423 housespec
->removal_cost
= buf
->ReadByte();
2426 case 0x12: // Building name ID
2427 AddStringForMapping(buf
->ReadWord(), &housespec
->building_name
);
2430 case 0x13: // Building availability mask
2431 housespec
->building_availability
= (HouseZones
)buf
->ReadWord();
2434 case 0x14: // House callback mask
2435 housespec
->callback_mask
|= buf
->ReadByte();
2438 case 0x15: { // House override byte
2439 byte override
= buf
->ReadByte();
2441 /* The house being overridden must be an original house. */
2442 if (override
>= NEW_HOUSE_OFFSET
) {
2443 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override
, hid
+ i
);
2447 _house_mngr
.Add(hid
+ i
, _cur
.grffile
->grfid
, override
);
2451 case 0x16: // Periodic refresh multiplier
2452 housespec
->processing_time
= min(buf
->ReadByte(), 63);
2455 case 0x17: // Four random colours to use
2456 for (uint j
= 0; j
< 4; j
++) housespec
->random_colour
[j
] = buf
->ReadByte();
2459 case 0x18: // Relative probability of appearing
2460 housespec
->probability
= buf
->ReadByte();
2463 case 0x19: // Extra flags
2464 housespec
->extra_flags
= (HouseExtraFlags
)buf
->ReadByte();
2467 case 0x1A: // Animation frames
2468 housespec
->animation
.frames
= buf
->ReadByte();
2469 housespec
->animation
.status
= GB(housespec
->animation
.frames
, 7, 1);
2470 SB(housespec
->animation
.frames
, 7, 1, 0);
2473 case 0x1B: // Animation speed
2474 housespec
->animation
.speed
= Clamp(buf
->ReadByte(), 2, 16);
2477 case 0x1C: // Class of the building type
2478 housespec
->class_id
= AllocateHouseClassID(buf
->ReadByte(), _cur
.grffile
->grfid
);
2481 case 0x1D: // Callback mask part 2
2482 housespec
->callback_mask
|= (buf
->ReadByte() << 8);
2485 case 0x1E: { // Accepted cargo types
2486 uint32 cargotypes
= buf
->ReadDWord();
2488 /* Check if the cargo types should not be changed */
2489 if (cargotypes
== 0xFFFFFFFF) break;
2491 for (uint j
= 0; j
< 3; j
++) {
2492 /* Get the cargo number from the 'list' */
2493 uint8 cargo_part
= GB(cargotypes
, 8 * j
, 8);
2494 CargoID cargo
= GetCargoTranslation(cargo_part
, _cur
.grffile
);
2496 if (cargo
== CT_INVALID
) {
2497 /* Disable acceptance of invalid cargo type */
2498 housespec
->cargo_acceptance
[j
] = 0;
2500 housespec
->accepts_cargo
[j
] = cargo
;
2506 case 0x1F: // Minimum life span
2507 housespec
->minimum_life
= buf
->ReadByte();
2510 case 0x20: { // Cargo acceptance watch list
2511 byte count
= buf
->ReadByte();
2512 for (byte j
= 0; j
< count
; j
++) {
2513 CargoID cargo
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
2514 if (cargo
!= CT_INVALID
) SetBit(housespec
->watched_cargoes
, cargo
);
2519 case 0x21: // long introduction year
2520 housespec
->min_year
= buf
->ReadWord();
2523 case 0x22: // long maximum year
2524 housespec
->max_year
= buf
->ReadWord();
2537 * Get the language map associated with a given NewGRF and language.
2538 * @param grfid The NewGRF to get the map for.
2539 * @param language_id The (NewGRF) language ID to get the map for.
2540 * @return The LanguageMap, or NULL if it couldn't be found.
2542 /* static */ const LanguageMap
*LanguageMap::GetLanguageMap(uint32 grfid
, uint8 language_id
)
2544 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2545 const GRFFile
*grffile
= GetFileByGRFID(grfid
);
2546 return (grffile
!= NULL
&& grffile
->language_map
!= NULL
&& language_id
< MAX_LANG
) ? &grffile
->language_map
[language_id
] : NULL
;
2550 * Load a cargo- or railtype-translation table.
2551 * @param gvid ID of the global variable. This is basically only checked for zerones.
2552 * @param numinfo Number of subsequent IDs to change the property for.
2553 * @param buf The property value.
2554 * @param [in,out] translation_table Storage location for the translation table.
2555 * @param name Name of the table for debug output.
2556 * @return ChangeInfoResult.
2558 template <typename T
>
2559 static ChangeInfoResult
LoadTranslationTable(uint gvid
, int numinfo
, ByteReader
*buf
, T
&translation_table
, const char *name
)
2562 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name
);
2563 return CIR_INVALID_ID
;
2566 translation_table
.Clear();
2567 for (int i
= 0; i
< numinfo
; i
++) {
2568 uint32 item
= buf
->ReadDWord();
2569 *translation_table
.Append() = BSWAP32(item
);
2576 * Define properties for global variables
2577 * @param gvid ID of the global variable.
2578 * @param numinfo Number of subsequent IDs to change the property for.
2579 * @param prop The property to change.
2580 * @param buf The property value.
2581 * @return ChangeInfoResult.
2583 static ChangeInfoResult
GlobalVarChangeInfo(uint gvid
, int numinfo
, int prop
, ByteReader
*buf
)
2585 /* Properties which are handled as a whole */
2587 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2588 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->cargo_list
, "Cargo");
2590 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2591 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->railtype_list
, "Rail type");
2597 /* Properties which are handled per item */
2598 ChangeInfoResult ret
= CIR_SUCCESS
;
2599 for (int i
= 0; i
< numinfo
; i
++) {
2601 case 0x08: { // Cost base factor
2602 int factor
= buf
->ReadByte();
2603 uint price
= gvid
+ i
;
2605 if (price
< PR_END
) {
2606 _cur
.grffile
->price_base_multipliers
[price
] = min
<int>(factor
- 8, MAX_PRICE_MODIFIER
);
2608 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price
);
2613 case 0x0A: { // Currency display names
2614 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2615 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2617 if ((newone
!= STR_UNDEFINED
) && (curidx
< CURRENCY_END
)) {
2618 _currency_specs
[curidx
].name
= newone
;
2623 case 0x0B: { // Currency multipliers
2624 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2625 uint32 rate
= buf
->ReadDWord();
2627 if (curidx
< CURRENCY_END
) {
2628 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2629 * which OTTD does not. For this reason, divide grf value by 1000,
2630 * to be compatible */
2631 _currency_specs
[curidx
].rate
= rate
/ 1000;
2633 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx
);
2638 case 0x0C: { // Currency options
2639 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2640 uint16 options
= buf
->ReadWord();
2642 if (curidx
< CURRENCY_END
) {
2643 _currency_specs
[curidx
].separator
[0] = GB(options
, 0, 8);
2644 _currency_specs
[curidx
].separator
[1] = '\0';
2645 /* By specifying only one bit, we prevent errors,
2646 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2647 _currency_specs
[curidx
].symbol_pos
= GB(options
, 8, 1);
2649 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx
);
2654 case 0x0D: { // Currency prefix symbol
2655 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2656 uint32 tempfix
= buf
->ReadDWord();
2658 if (curidx
< CURRENCY_END
) {
2659 memcpy(_currency_specs
[curidx
].prefix
, &tempfix
, 4);
2660 _currency_specs
[curidx
].prefix
[4] = 0;
2662 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx
);
2667 case 0x0E: { // Currency suffix symbol
2668 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2669 uint32 tempfix
= buf
->ReadDWord();
2671 if (curidx
< CURRENCY_END
) {
2672 memcpy(&_currency_specs
[curidx
].suffix
, &tempfix
, 4);
2673 _currency_specs
[curidx
].suffix
[4] = 0;
2675 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx
);
2680 case 0x0F: { // Euro introduction dates
2681 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2682 Year year_euro
= buf
->ReadWord();
2684 if (curidx
< CURRENCY_END
) {
2685 _currency_specs
[curidx
].to_euro
= year_euro
;
2687 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx
);
2692 case 0x10: // Snow line height table
2693 if (numinfo
> 1 || IsSnowLineSet()) {
2694 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo
);
2695 } else if (buf
->Remaining() < SNOW_LINE_MONTHS
* SNOW_LINE_DAYS
) {
2696 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf
->Remaining());
2698 byte table
[SNOW_LINE_MONTHS
][SNOW_LINE_DAYS
];
2700 for (uint i
= 0; i
< SNOW_LINE_MONTHS
; i
++) {
2701 for (uint j
= 0; j
< SNOW_LINE_DAYS
; j
++) {
2702 table
[i
][j
] = buf
->ReadByte();
2703 if (_cur
.grffile
->grf_version
>= 8) {
2704 if (table
[i
][j
] != 0xFF) table
[i
][j
] = table
[i
][j
] * (1 + _settings_game
.construction
.max_heightlevel
) / 256;
2706 if (table
[i
][j
] >= 128) {
2710 table
[i
][j
] = table
[i
][j
] * (1 + _settings_game
.construction
.max_heightlevel
) / 128;
2719 case 0x11: // GRF match for engine allocation
2720 /* This is loaded during the reservation stage, so just skip it here. */
2721 /* Each entry is 8 bytes. */
2725 case 0x13: // Gender translation table
2726 case 0x14: // Case translation table
2727 case 0x15: { // Plural form translation
2728 uint curidx
= gvid
+ i
; // The current index, i.e. language.
2729 const LanguageMetadata
*lang
= curidx
< MAX_LANG
? GetLanguage(curidx
) : NULL
;
2731 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx
);
2732 /* Skip over the data. */
2736 while (buf
->ReadByte() != 0) {
2743 if (_cur
.grffile
->language_map
== NULL
) _cur
.grffile
->language_map
= new LanguageMap
[MAX_LANG
];
2746 uint plural_form
= buf
->ReadByte();
2747 if (plural_form
>= LANGUAGE_MAX_PLURAL
) {
2748 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form
);
2750 _cur
.grffile
->language_map
[curidx
].plural_form
= plural_form
;
2755 byte newgrf_id
= buf
->ReadByte(); // The NewGRF (custom) identifier.
2756 while (newgrf_id
!= 0) {
2757 const char *name
= buf
->ReadString(); // The name for the OpenTTD identifier.
2759 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2760 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2761 * is just a subset of UTF8, or they need the bigger UTF8 characters
2762 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2764 size_t len
= Utf8Decode(&c
, name
);
2765 if (c
== NFO_UTF8_IDENTIFIER
) name
+= len
;
2767 LanguageMap::Mapping map
;
2768 map
.newgrf_id
= newgrf_id
;
2770 map
.openttd_id
= lang
->GetGenderIndex(name
);
2771 if (map
.openttd_id
>= MAX_NUM_GENDERS
) {
2772 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name
);
2774 *_cur
.grffile
->language_map
[curidx
].gender_map
.Append() = map
;
2777 map
.openttd_id
= lang
->GetCaseIndex(name
);
2778 if (map
.openttd_id
>= MAX_NUM_CASES
) {
2779 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name
);
2781 *_cur
.grffile
->language_map
[curidx
].case_map
.Append() = map
;
2784 newgrf_id
= buf
->ReadByte();
2798 static ChangeInfoResult
GlobalVarReserveInfo(uint gvid
, int numinfo
, int prop
, ByteReader
*buf
)
2800 /* Properties which are handled as a whole */
2802 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2803 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->cargo_list
, "Cargo");
2805 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2806 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->railtype_list
, "Rail type");
2812 /* Properties which are handled per item */
2813 ChangeInfoResult ret
= CIR_SUCCESS
;
2814 for (int i
= 0; i
< numinfo
; i
++) {
2816 case 0x08: // Cost base factor
2817 case 0x15: // Plural form translation
2821 case 0x0A: // Currency display names
2822 case 0x0C: // Currency options
2823 case 0x0F: // Euro introduction dates
2827 case 0x0B: // Currency multipliers
2828 case 0x0D: // Currency prefix symbol
2829 case 0x0E: // Currency suffix symbol
2833 case 0x10: // Snow line height table
2834 buf
->Skip(SNOW_LINE_MONTHS
* SNOW_LINE_DAYS
);
2837 case 0x11: { // GRF match for engine allocation
2838 uint32 s
= buf
->ReadDWord();
2839 uint32 t
= buf
->ReadDWord();
2840 SetNewGRFOverride(s
, t
);
2844 case 0x13: // Gender translation table
2845 case 0x14: // Case translation table
2846 while (buf
->ReadByte() != 0) {
2862 * Define properties for cargoes
2863 * @param cid Local ID of the cargo.
2864 * @param numinfo Number of subsequent IDs to change the property for.
2865 * @param prop The property to change.
2866 * @param buf The property value.
2867 * @return ChangeInfoResult.
2869 static ChangeInfoResult
CargoChangeInfo(uint cid
, int numinfo
, int prop
, ByteReader
*buf
)
2871 ChangeInfoResult ret
= CIR_SUCCESS
;
2873 if (cid
+ numinfo
> NUM_CARGO
) {
2874 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid
+ numinfo
, NUM_CARGO
- 1);
2875 return CIR_INVALID_ID
;
2878 for (int i
= 0; i
< numinfo
; i
++) {
2879 CargoSpec
*cs
= CargoSpec::Get(cid
+ i
);
2882 case 0x08: // Bit number of cargo
2883 cs
->bitnum
= buf
->ReadByte();
2884 if (cs
->IsValid()) {
2885 cs
->grffile
= _cur
.grffile
;
2886 SetBit(_cargo_mask
, cid
+ i
);
2888 ClrBit(_cargo_mask
, cid
+ i
);
2892 case 0x09: // String ID for cargo type name
2893 AddStringForMapping(buf
->ReadWord(), &cs
->name
);
2896 case 0x0A: // String for 1 unit of cargo
2897 AddStringForMapping(buf
->ReadWord(), &cs
->name_single
);
2900 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2901 case 0x1B: // String for cargo units
2902 /* String for units of cargo. This is different in OpenTTD
2903 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2904 * Property 1B is used to set OpenTTD's behaviour. */
2905 AddStringForMapping(buf
->ReadWord(), &cs
->units_volume
);
2908 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2909 case 0x1C: // String for any amount of cargo
2910 /* Strings for an amount of cargo. This is different in OpenTTD
2911 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2912 * Property 1C is used to set OpenTTD's behaviour. */
2913 AddStringForMapping(buf
->ReadWord(), &cs
->quantifier
);
2916 case 0x0D: // String for two letter cargo abbreviation
2917 AddStringForMapping(buf
->ReadWord(), &cs
->abbrev
);
2920 case 0x0E: // Sprite ID for cargo icon
2921 cs
->sprite
= buf
->ReadWord();
2924 case 0x0F: // Weight of one unit of cargo
2925 cs
->weight
= buf
->ReadByte();
2928 case 0x10: // Used for payment calculation
2929 cs
->transit_days
[0] = buf
->ReadByte();
2932 case 0x11: // Used for payment calculation
2933 cs
->transit_days
[1] = buf
->ReadByte();
2936 case 0x12: // Base cargo price
2937 cs
->initial_payment
= buf
->ReadDWord();
2940 case 0x13: // Colour for station rating bars
2941 cs
->rating_colour
= buf
->ReadByte();
2944 case 0x14: // Colour for cargo graph
2945 cs
->legend_colour
= buf
->ReadByte();
2948 case 0x15: // Freight status
2949 cs
->is_freight
= (buf
->ReadByte() != 0);
2952 case 0x16: // Cargo classes
2953 cs
->classes
= buf
->ReadWord();
2956 case 0x17: // Cargo label
2957 cs
->label
= buf
->ReadDWord();
2958 cs
->label
= BSWAP32(cs
->label
);
2961 case 0x18: { // Town growth substitute type
2962 uint8 substitute_type
= buf
->ReadByte();
2964 switch (substitute_type
) {
2965 case 0x00: cs
->town_effect
= TE_PASSENGERS
; break;
2966 case 0x02: cs
->town_effect
= TE_MAIL
; break;
2967 case 0x05: cs
->town_effect
= TE_GOODS
; break;
2968 case 0x09: cs
->town_effect
= TE_WATER
; break;
2969 case 0x0B: cs
->town_effect
= TE_FOOD
; break;
2971 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type
);
2973 case 0xFF: cs
->town_effect
= TE_NONE
; break;
2978 case 0x19: // Town growth coefficient
2979 cs
->multipliertowngrowth
= buf
->ReadWord();
2982 case 0x1A: // Bitmask of callbacks to use
2983 cs
->callback_mask
= buf
->ReadByte();
2986 case 0x1D: // Vehicle capacity muliplier
2987 cs
->multiplier
= max
<uint16
>(1u, buf
->ReadWord());
3001 * Define properties for sound effects
3002 * @param sid Local ID of the sound.
3003 * @param numinfo Number of subsequent IDs to change the property for.
3004 * @param prop The property to change.
3005 * @param buf The property value.
3006 * @return ChangeInfoResult.
3008 static ChangeInfoResult
SoundEffectChangeInfo(uint sid
, int numinfo
, int prop
, ByteReader
*buf
)
3010 ChangeInfoResult ret
= CIR_SUCCESS
;
3012 if (_cur
.grffile
->sound_offset
== 0) {
3013 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3014 return CIR_INVALID_ID
;
3017 if (sid
+ numinfo
- ORIGINAL_SAMPLE_COUNT
> _cur
.grffile
->num_sounds
) {
3018 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid
+ numinfo
, ORIGINAL_SAMPLE_COUNT
+ _cur
.grffile
->num_sounds
);
3019 return CIR_INVALID_ID
;
3022 for (int i
= 0; i
< numinfo
; i
++) {
3023 SoundEntry
*sound
= GetSound(sid
+ i
+ _cur
.grffile
->sound_offset
- ORIGINAL_SAMPLE_COUNT
);
3026 case 0x08: // Relative volume
3027 sound
->volume
= buf
->ReadByte();
3030 case 0x09: // Priority
3031 sound
->priority
= buf
->ReadByte();
3034 case 0x0A: { // Override old sound
3035 SoundID orig_sound
= buf
->ReadByte();
3037 if (orig_sound
>= ORIGINAL_SAMPLE_COUNT
) {
3038 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound
, ORIGINAL_SAMPLE_COUNT
);
3040 SoundEntry
*old_sound
= GetSound(orig_sound
);
3042 /* Literally copy the data of the new sound over the original */
3043 *old_sound
= *sound
;
3058 * Ignore an industry tile property
3059 * @param prop The property to ignore.
3060 * @param buf The property value.
3061 * @return ChangeInfoResult.
3063 static ChangeInfoResult
IgnoreIndustryTileProperty(int prop
, ByteReader
*buf
)
3065 ChangeInfoResult ret
= CIR_SUCCESS
;
3092 * Define properties for industry tiles
3093 * @param indtid Local ID of the industry tile.
3094 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3095 * @param prop The property to change.
3096 * @param buf The property value.
3097 * @return ChangeInfoResult.
3099 static ChangeInfoResult
IndustrytilesChangeInfo(uint indtid
, int numinfo
, int prop
, ByteReader
*buf
)
3101 ChangeInfoResult ret
= CIR_SUCCESS
;
3103 if (indtid
+ numinfo
> NUM_INDUSTRYTILES_PER_GRF
) {
3104 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid
+ numinfo
, NUM_INDUSTRYTILES_PER_GRF
);
3105 return CIR_INVALID_ID
;
3108 /* Allocate industry tile specs if they haven't been allocated already. */
3109 if (_cur
.grffile
->indtspec
== NULL
) {
3110 _cur
.grffile
->indtspec
= CallocT
<IndustryTileSpec
*>(NUM_INDUSTRYTILES_PER_GRF
);
3113 for (int i
= 0; i
< numinfo
; i
++) {
3114 IndustryTileSpec
*tsp
= _cur
.grffile
->indtspec
[indtid
+ i
];
3116 if (prop
!= 0x08 && tsp
== NULL
) {
3117 ChangeInfoResult cir
= IgnoreIndustryTileProperty(prop
, buf
);
3118 if (cir
> ret
) ret
= cir
;
3123 case 0x08: { // Substitute industry tile type
3124 IndustryTileSpec
**tilespec
= &_cur
.grffile
->indtspec
[indtid
+ i
];
3125 byte subs_id
= buf
->ReadByte();
3127 if (subs_id
>= NEW_INDUSTRYTILEOFFSET
) {
3128 /* The substitute id must be one of the original industry tile. */
3129 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id
, indtid
+ i
);
3133 /* Allocate space for this industry. */
3134 if (*tilespec
== NULL
) {
3135 *tilespec
= CallocT
<IndustryTileSpec
>(1);
3138 memcpy(tsp
, &_industry_tile_specs
[subs_id
], sizeof(_industry_tile_specs
[subs_id
]));
3139 tsp
->enabled
= true;
3141 /* A copied tile should not have the animation infos copied too.
3142 * The anim_state should be left untouched, though
3143 * It is up to the author to animate them himself */
3144 tsp
->anim_production
= INDUSTRYTILE_NOANIM
;
3145 tsp
->anim_next
= INDUSTRYTILE_NOANIM
;
3147 tsp
->grf_prop
.local_id
= indtid
+ i
;
3148 tsp
->grf_prop
.subst_id
= subs_id
;
3149 tsp
->grf_prop
.grffile
= _cur
.grffile
;
3150 _industile_mngr
.AddEntityID(indtid
+ i
, _cur
.grffile
->grfid
, subs_id
); // pre-reserve the tile slot
3155 case 0x09: { // Industry tile override
3156 byte ovrid
= buf
->ReadByte();
3158 /* The industry being overridden must be an original industry. */
3159 if (ovrid
>= NEW_INDUSTRYTILEOFFSET
) {
3160 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid
, indtid
+ i
);
3164 _industile_mngr
.Add(indtid
+ i
, _cur
.grffile
->grfid
, ovrid
);
3168 case 0x0A: // Tile acceptance
3171 uint16 acctp
= buf
->ReadWord();
3172 tsp
->accepts_cargo
[prop
- 0x0A] = GetCargoTranslation(GB(acctp
, 0, 8), _cur
.grffile
);
3173 tsp
->acceptance
[prop
- 0x0A] = GB(acctp
, 8, 8);
3177 case 0x0D: // Land shape flags
3178 tsp
->slopes_refused
= (Slope
)buf
->ReadByte();
3181 case 0x0E: // Callback mask
3182 tsp
->callback_mask
= buf
->ReadByte();
3185 case 0x0F: // Animation information
3186 tsp
->animation
.frames
= buf
->ReadByte();
3187 tsp
->animation
.status
= buf
->ReadByte();
3190 case 0x10: // Animation speed
3191 tsp
->animation
.speed
= buf
->ReadByte();
3194 case 0x11: // Triggers for callback 25
3195 tsp
->animation
.triggers
= buf
->ReadByte();
3198 case 0x12: // Special flags
3199 tsp
->special_flags
= (IndustryTileSpecialFlags
)buf
->ReadByte();
3212 * Ignore an industry property
3213 * @param prop The property to ignore.
3214 * @param buf The property value.
3215 * @return ChangeInfoResult.
3217 static ChangeInfoResult
IgnoreIndustryProperty(int prop
, ByteReader
*buf
)
3219 ChangeInfoResult ret
= CIR_SUCCESS
;
3257 byte num_table
= buf
->ReadByte();
3258 for (byte j
= 0; j
< num_table
; j
++) {
3259 for (uint k
= 0;; k
++) {
3260 byte x
= buf
->ReadByte();
3261 if (x
== 0xFE && k
== 0) {
3267 byte y
= buf
->ReadByte();
3268 if (x
== 0 && y
== 0x80) break;
3270 byte gfx
= buf
->ReadByte();
3271 if (gfx
== 0xFE) buf
->ReadWord();
3278 for (byte j
= 0; j
< 3; j
++) buf
->ReadByte();
3282 byte number_of_sounds
= buf
->ReadByte();
3283 for (uint8 j
= 0; j
< number_of_sounds
; j
++) {
3297 * Validate the industry layout; e.g. to prevent duplicate tiles.
3298 * @param layout The layout to check.
3299 * @param size The size of the layout.
3300 * @return True if the layout is deemed valid.
3302 static bool ValidateIndustryLayout(const IndustryTileTable
*layout
, int size
)
3304 for (int i
= 0; i
< size
- 1; i
++) {
3305 for (int j
= i
+ 1; j
< size
; j
++) {
3306 if (layout
[i
].ti
.x
== layout
[j
].ti
.x
&&
3307 layout
[i
].ti
.y
== layout
[j
].ti
.y
) {
3315 /** Clean the tile table of the IndustrySpec if it's needed. */
3316 static void CleanIndustryTileTable(IndustrySpec
*ind
)
3318 if (HasBit(ind
->cleanup_flag
, CLEAN_TILELAYOUT
) && ind
->table
!= NULL
) {
3319 for (int j
= 0; j
< ind
->num_table
; j
++) {
3320 /* remove the individual layouts */
3321 free(ind
->table
[j
]);
3323 /* remove the layouts pointers */
3330 * Define properties for industries
3331 * @param indid Local ID of the industry.
3332 * @param numinfo Number of subsequent industry IDs to change the property for.
3333 * @param prop The property to change.
3334 * @param buf The property value.
3335 * @return ChangeInfoResult.
3337 static ChangeInfoResult
IndustriesChangeInfo(uint indid
, int numinfo
, int prop
, ByteReader
*buf
)
3339 ChangeInfoResult ret
= CIR_SUCCESS
;
3341 if (indid
+ numinfo
> NUM_INDUSTRYTYPES_PER_GRF
) {
3342 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid
+ numinfo
, NUM_INDUSTRYTYPES_PER_GRF
);
3343 return CIR_INVALID_ID
;
3346 /* Allocate industry specs if they haven't been allocated already. */
3347 if (_cur
.grffile
->industryspec
== NULL
) {
3348 _cur
.grffile
->industryspec
= CallocT
<IndustrySpec
*>(NUM_INDUSTRYTYPES_PER_GRF
);
3351 for (int i
= 0; i
< numinfo
; i
++) {
3352 IndustrySpec
*indsp
= _cur
.grffile
->industryspec
[indid
+ i
];
3354 if (prop
!= 0x08 && indsp
== NULL
) {
3355 ChangeInfoResult cir
= IgnoreIndustryProperty(prop
, buf
);
3356 if (cir
> ret
) ret
= cir
;
3361 case 0x08: { // Substitute industry type
3362 IndustrySpec
**indspec
= &_cur
.grffile
->industryspec
[indid
+ i
];
3363 byte subs_id
= buf
->ReadByte();
3365 if (subs_id
== 0xFF) {
3366 /* Instead of defining a new industry, a substitute industry id
3367 * of 0xFF disables the old industry with the current id. */
3368 _industry_specs
[indid
+ i
].enabled
= false;
3370 } else if (subs_id
>= NEW_INDUSTRYOFFSET
) {
3371 /* The substitute id must be one of the original industry. */
3372 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id
, indid
+ i
);
3376 /* Allocate space for this industry.
3377 * Only need to do it once. If ever it is called again, it should not
3379 if (*indspec
== NULL
) {
3380 *indspec
= CallocT
<IndustrySpec
>(1);
3383 memcpy(indsp
, &_origin_industry_specs
[subs_id
], sizeof(_industry_specs
[subs_id
]));
3384 indsp
->enabled
= true;
3385 indsp
->grf_prop
.local_id
= indid
+ i
;
3386 indsp
->grf_prop
.subst_id
= subs_id
;
3387 indsp
->grf_prop
.grffile
= _cur
.grffile
;
3388 /* If the grf industry needs to check its surounding upon creation, it should
3389 * rely on callbacks, not on the original placement functions */
3390 indsp
->check_proc
= CHECK_NOTHING
;
3395 case 0x09: { // Industry type override
3396 byte ovrid
= buf
->ReadByte();
3398 /* The industry being overridden must be an original industry. */
3399 if (ovrid
>= NEW_INDUSTRYOFFSET
) {
3400 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid
, indid
+ i
);
3403 indsp
->grf_prop
.override
= ovrid
;
3404 _industry_mngr
.Add(indid
+ i
, _cur
.grffile
->grfid
, ovrid
);
3408 case 0x0A: { // Set industry layout(s)
3409 byte new_num_layouts
= buf
->ReadByte(); // Number of layaouts
3410 /* We read the total size in bytes, but we can't rely on the
3411 * newgrf to provide a sane value. First assume the value is
3412 * sane but later on we make sure we enlarge the array if the
3413 * newgrf contains more data. Each tile uses either 3 or 5
3414 * bytes, so to play it safe we assume 3. */
3415 uint32 def_num_tiles
= buf
->ReadDWord() / 3 + 1;
3416 IndustryTileTable
**tile_table
= CallocT
<IndustryTileTable
*>(new_num_layouts
); // Table with tiles to compose an industry
3417 IndustryTileTable
*itt
= CallocT
<IndustryTileTable
>(def_num_tiles
); // Temporary array to read the tile layouts from the GRF
3419 const IndustryTileTable
*copy_from
;
3422 for (byte j
= 0; j
< new_num_layouts
; j
++) {
3423 for (uint k
= 0;; k
++) {
3424 if (k
>= def_num_tiles
) {
3425 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid
);
3426 /* Size reported by newgrf was not big enough so enlarge the array. */
3428 itt
= ReallocT
<IndustryTileTable
>(itt
, def_num_tiles
);
3431 itt
[k
].ti
.x
= buf
->ReadByte(); // Offsets from northermost tile
3433 if (itt
[k
].ti
.x
== 0xFE && k
== 0) {
3434 /* This means we have to borrow the layout from an old industry */
3435 IndustryType type
= buf
->ReadByte(); // industry holding required layout
3436 byte laynbr
= buf
->ReadByte(); // layout number to borrow
3438 copy_from
= _origin_industry_specs
[type
].table
[laynbr
];
3439 for (size
= 1;; size
++) {
3440 if (copy_from
[size
- 1].ti
.x
== -0x80 && copy_from
[size
- 1].ti
.y
== 0) break;
3445 itt
[k
].ti
.y
= buf
->ReadByte(); // Or table definition finalisation
3447 if (itt
[k
].ti
.x
== 0 && itt
[k
].ti
.y
== 0x80) {
3448 /* Not the same terminator. The one we are using is rather
3449 x = -80, y = x . So, adjust it. */
3450 itt
[k
].ti
.x
= -0x80;
3459 itt
[k
].gfx
= buf
->ReadByte();
3461 if (itt
[k
].gfx
== 0xFE) {
3462 /* Use a new tile from this GRF */
3463 int local_tile_id
= buf
->ReadWord();
3465 /* Read the ID from the _industile_mngr. */
3466 int tempid
= _industile_mngr
.GetID(local_tile_id
, _cur
.grffile
->grfid
);
3468 if (tempid
== INVALID_INDUSTRYTILE
) {
3469 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id
, indid
);
3471 /* Declared as been valid, can be used */
3472 itt
[k
].gfx
= tempid
;
3476 } else if (itt
[k
].gfx
== 0xFF) {
3477 itt
[k
].ti
.x
= (int8
)GB(itt
[k
].ti
.x
, 0, 8);
3478 itt
[k
].ti
.y
= (int8
)GB(itt
[k
].ti
.y
, 0, 8);
3480 /* When there were only 256x256 maps, TileIndex was a uint16 and
3481 * itt[k].ti was just a TileIndexDiff that was added to it.
3482 * As such negative "x" values were shifted into the "y" position.
3483 * x = -1, y = 1 -> x = 255, y = 0
3484 * Since GRF version 8 the position is interpreted as pair of independent int8.
3485 * For GRF version < 8 we need to emulate the old shifting behaviour.
3487 if (_cur
.grffile
->grf_version
< 8 && itt
[k
].ti
.x
< 0) itt
[k
].ti
.y
+= 1;
3491 if (!ValidateIndustryLayout(copy_from
, size
)) {
3492 /* The industry layout was not valid, so skip this one. */
3493 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid
);
3497 tile_table
[j
] = CallocT
<IndustryTileTable
>(size
);
3498 memcpy(tile_table
[j
], copy_from
, sizeof(*copy_from
) * size
);
3502 for (int i
= 0; i
< new_num_layouts
; i
++) {
3503 free(tile_table
[i
]);
3510 /* Clean the tile table if it was already set by a previous prop A. */
3511 CleanIndustryTileTable(indsp
);
3512 /* Install final layout construction in the industry spec */
3513 indsp
->num_table
= new_num_layouts
;
3514 indsp
->table
= tile_table
;
3515 SetBit(indsp
->cleanup_flag
, CLEAN_TILELAYOUT
);
3520 case 0x0B: // Industry production flags
3521 indsp
->life_type
= (IndustryLifeType
)buf
->ReadByte();
3524 case 0x0C: // Industry closure message
3525 AddStringForMapping(buf
->ReadWord(), &indsp
->closure_text
);
3528 case 0x0D: // Production increase message
3529 AddStringForMapping(buf
->ReadWord(), &indsp
->production_up_text
);
3532 case 0x0E: // Production decrease message
3533 AddStringForMapping(buf
->ReadWord(), &indsp
->production_down_text
);
3536 case 0x0F: // Fund cost multiplier
3537 indsp
->cost_multiplier
= buf
->ReadByte();
3540 case 0x10: // Production cargo types
3541 for (byte j
= 0; j
< 2; j
++) {
3542 indsp
->produced_cargo
[j
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3546 case 0x11: // Acceptance cargo types
3547 for (byte j
= 0; j
< 3; j
++) {
3548 indsp
->accepts_cargo
[j
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3550 buf
->ReadByte(); // Unnused, eat it up
3553 case 0x12: // Production multipliers
3555 indsp
->production_rate
[prop
- 0x12] = buf
->ReadByte();
3558 case 0x14: // Minimal amount of cargo distributed
3559 indsp
->minimal_cargo
= buf
->ReadByte();
3562 case 0x15: { // Random sound effects
3563 indsp
->number_of_sounds
= buf
->ReadByte();
3564 uint8
*sounds
= MallocT
<uint8
>(indsp
->number_of_sounds
);
3567 for (uint8 j
= 0; j
< indsp
->number_of_sounds
; j
++) {
3568 sounds
[j
] = buf
->ReadByte();
3575 if (HasBit(indsp
->cleanup_flag
, CLEAN_RANDOMSOUNDS
)) {
3576 free(indsp
->random_sounds
);
3578 indsp
->random_sounds
= sounds
;
3579 SetBit(indsp
->cleanup_flag
, CLEAN_RANDOMSOUNDS
);
3583 case 0x16: // Conflicting industry types
3584 for (byte j
= 0; j
< 3; j
++) indsp
->conflicting
[j
] = buf
->ReadByte();
3587 case 0x17: // Probability in random game
3588 indsp
->appear_creation
[_settings_game
.game_creation
.landscape
] = buf
->ReadByte();
3591 case 0x18: // Probability during gameplay
3592 indsp
->appear_ingame
[_settings_game
.game_creation
.landscape
] = buf
->ReadByte();
3595 case 0x19: // Map colour
3596 indsp
->map_colour
= buf
->ReadByte();
3599 case 0x1A: // Special industry flags to define special behavior
3600 indsp
->behaviour
= (IndustryBehaviour
)buf
->ReadDWord();
3603 case 0x1B: // New industry text ID
3604 AddStringForMapping(buf
->ReadWord(), &indsp
->new_industry_text
);
3607 case 0x1C: // Input cargo multipliers for the three input cargo types
3610 uint32 multiples
= buf
->ReadDWord();
3611 indsp
->input_cargo_multiplier
[prop
- 0x1C][0] = GB(multiples
, 0, 16);
3612 indsp
->input_cargo_multiplier
[prop
- 0x1C][1] = GB(multiples
, 16, 16);
3616 case 0x1F: // Industry name
3617 AddStringForMapping(buf
->ReadWord(), &indsp
->name
);
3620 case 0x20: // Prospecting success chance
3621 indsp
->prospecting_chance
= buf
->ReadDWord();
3624 case 0x21: // Callback mask
3625 case 0x22: { // Callback additional mask
3626 byte aflag
= buf
->ReadByte();
3627 SB(indsp
->callback_mask
, (prop
- 0x21) * 8, 8, aflag
);
3631 case 0x23: // removal cost multiplier
3632 indsp
->removal_cost_multiplier
= buf
->ReadDWord();
3635 case 0x24: { // name for nearby station
3636 uint16 str
= buf
->ReadWord();
3638 indsp
->station_name
= STR_NULL
;
3640 AddStringForMapping(str
, &indsp
->station_name
);
3655 * Create a copy of the tile table so it can be freed later
3657 * @param as The AirportSpec to copy the arrays of.
3659 static void DuplicateTileTable(AirportSpec
*as
)
3661 AirportTileTable
**table_list
= MallocT
<AirportTileTable
*>(as
->num_table
);
3662 for (int i
= 0; i
< as
->num_table
; i
++) {
3664 const AirportTileTable
*it
= as
->table
[0];
3667 } while ((++it
)->ti
.x
!= -0x80);
3668 table_list
[i
] = MallocT
<AirportTileTable
>(num_tiles
);
3669 MemCpyT(table_list
[i
], as
->table
[i
], num_tiles
);
3671 as
->table
= table_list
;
3672 HangarTileTable
*depot_table
= MallocT
<HangarTileTable
>(as
->nof_depots
);
3673 MemCpyT(depot_table
, as
->depot_table
, as
->nof_depots
);
3674 as
->depot_table
= depot_table
;
3678 * Define properties for airports
3679 * @param airport Local ID of the airport.
3680 * @param numinfo Number of subsequent airport IDs to change the property for.
3681 * @param prop The property to change.
3682 * @param buf The property value.
3683 * @return ChangeInfoResult.
3685 static ChangeInfoResult
AirportChangeInfo(uint airport
, int numinfo
, int prop
, ByteReader
*buf
)
3687 ChangeInfoResult ret
= CIR_SUCCESS
;
3689 if (airport
+ numinfo
> NUM_AIRPORTS_PER_GRF
) {
3690 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport
+ numinfo
, NUM_AIRPORTS_PER_GRF
);
3691 return CIR_INVALID_ID
;
3694 /* Allocate industry specs if they haven't been allocated already. */
3695 if (_cur
.grffile
->airportspec
== NULL
) {
3696 _cur
.grffile
->airportspec
= CallocT
<AirportSpec
*>(NUM_AIRPORTS_PER_GRF
);
3699 for (int i
= 0; i
< numinfo
; i
++) {
3700 AirportSpec
*as
= _cur
.grffile
->airportspec
[airport
+ i
];
3702 if (as
== NULL
&& prop
!= 0x08 && prop
!= 0x09) {
3703 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport
+ i
);
3704 return CIR_INVALID_ID
;
3708 case 0x08: { // Modify original airport
3709 byte subs_id
= buf
->ReadByte();
3711 if (subs_id
== 0xFF) {
3712 /* Instead of defining a new airport, an airport id
3713 * of 0xFF disables the old airport with the current id. */
3714 AirportSpec::GetWithoutOverride(airport
+ i
)->enabled
= false;
3716 } else if (subs_id
>= NEW_AIRPORT_OFFSET
) {
3717 /* The substitute id must be one of the original airports. */
3718 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id
, airport
+ i
);
3722 AirportSpec
**spec
= &_cur
.grffile
->airportspec
[airport
+ i
];
3723 /* Allocate space for this airport.
3724 * Only need to do it once. If ever it is called again, it should not
3726 if (*spec
== NULL
) {
3727 *spec
= MallocT
<AirportSpec
>(1);
3730 memcpy(as
, AirportSpec::GetWithoutOverride(subs_id
), sizeof(*as
));
3732 as
->grf_prop
.local_id
= airport
+ i
;
3733 as
->grf_prop
.subst_id
= subs_id
;
3734 as
->grf_prop
.grffile
= _cur
.grffile
;
3735 /* override the default airport */
3736 _airport_mngr
.Add(airport
+ i
, _cur
.grffile
->grfid
, subs_id
);
3737 /* Create a copy of the original tiletable so it can be freed later. */
3738 DuplicateTileTable(as
);
3743 case 0x0A: { // Set airport layout
3744 as
->num_table
= buf
->ReadByte(); // Number of layaouts
3745 as
->rotation
= MallocT
<Direction
>(as
->num_table
);
3746 uint32 defsize
= buf
->ReadDWord(); // Total size of the definition
3747 AirportTileTable
**tile_table
= CallocT
<AirportTileTable
*>(as
->num_table
); // Table with tiles to compose the airport
3748 AirportTileTable
*att
= CallocT
<AirportTileTable
>(defsize
); // Temporary array to read the tile layouts from the GRF
3750 const AirportTileTable
*copy_from
;
3752 for (byte j
= 0; j
< as
->num_table
; j
++) {
3753 const_cast<Direction
&>(as
->rotation
[j
]) = (Direction
)buf
->ReadByte();
3754 for (int k
= 0;; k
++) {
3755 att
[k
].ti
.x
= buf
->ReadByte(); // Offsets from northermost tile
3756 att
[k
].ti
.y
= buf
->ReadByte();
3758 if (att
[k
].ti
.x
== 0 && att
[k
].ti
.y
== 0x80) {
3759 /* Not the same terminator. The one we are using is rather
3760 * x = -80, y = 0 . So, adjust it. */
3761 att
[k
].ti
.x
= -0x80;
3770 att
[k
].gfx
= buf
->ReadByte();
3772 if (att
[k
].gfx
== 0xFE) {
3773 /* Use a new tile from this GRF */
3774 int local_tile_id
= buf
->ReadWord();
3776 /* Read the ID from the _airporttile_mngr. */
3777 uint16 tempid
= _airporttile_mngr
.GetID(local_tile_id
, _cur
.grffile
->grfid
);
3779 if (tempid
== INVALID_AIRPORTTILE
) {
3780 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id
, airport
+ i
);
3782 /* Declared as been valid, can be used */
3783 att
[k
].gfx
= tempid
;
3787 } else if (att
[k
].gfx
== 0xFF) {
3788 att
[k
].ti
.x
= (int8
)GB(att
[k
].ti
.x
, 0, 8);
3789 att
[k
].ti
.y
= (int8
)GB(att
[k
].ti
.y
, 0, 8);
3792 if (as
->rotation
[j
] == DIR_E
|| as
->rotation
[j
] == DIR_W
) {
3793 as
->size_x
= max
<byte
>(as
->size_x
, att
[k
].ti
.y
+ 1);
3794 as
->size_y
= max
<byte
>(as
->size_y
, att
[k
].ti
.x
+ 1);
3796 as
->size_x
= max
<byte
>(as
->size_x
, att
[k
].ti
.x
+ 1);
3797 as
->size_y
= max
<byte
>(as
->size_y
, att
[k
].ti
.y
+ 1);
3800 tile_table
[j
] = CallocT
<AirportTileTable
>(size
);
3801 memcpy(tile_table
[j
], copy_from
, sizeof(*copy_from
) * size
);
3803 /* Install final layout construction in the airport spec */
3804 as
->table
= tile_table
;
3807 for (int i
= 0; i
< as
->num_table
; i
++) {
3808 free(tile_table
[i
]);
3818 as
->min_year
= buf
->ReadWord();
3819 as
->max_year
= buf
->ReadWord();
3820 if (as
->max_year
== 0xFFFF) as
->max_year
= MAX_YEAR
;
3824 as
->ttd_airport_type
= (TTDPAirportType
)buf
->ReadByte();
3828 as
->catchment
= Clamp(buf
->ReadByte(), 1, MAX_CATCHMENT
);
3832 as
->noise_level
= buf
->ReadByte();
3836 AddStringForMapping(buf
->ReadWord(), &as
->name
);
3839 case 0x11: // Maintenance cost factor
3840 as
->maintenance_cost
= buf
->ReadWord();
3853 * Ignore properties for objects
3854 * @param prop The property to ignore.
3855 * @param buf The property value.
3856 * @return ChangeInfoResult.
3858 static ChangeInfoResult
IgnoreObjectProperty(uint prop
, ByteReader
*buf
)
3860 ChangeInfoResult ret
= CIR_SUCCESS
;
3897 * Define properties for objects
3898 * @param id Local ID of the object.
3899 * @param numinfo Number of subsequent objectIDs to change the property for.
3900 * @param prop The property to change.
3901 * @param buf The property value.
3902 * @return ChangeInfoResult.
3904 static ChangeInfoResult
ObjectChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
3906 ChangeInfoResult ret
= CIR_SUCCESS
;
3908 if (id
+ numinfo
> NUM_OBJECTS_PER_GRF
) {
3909 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id
+ numinfo
, NUM_OBJECTS_PER_GRF
);
3910 return CIR_INVALID_ID
;
3913 /* Allocate object specs if they haven't been allocated already. */
3914 if (_cur
.grffile
->objectspec
== NULL
) {
3915 _cur
.grffile
->objectspec
= CallocT
<ObjectSpec
*>(NUM_OBJECTS_PER_GRF
);
3918 for (int i
= 0; i
< numinfo
; i
++) {
3919 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[id
+ i
];
3921 if (prop
!= 0x08 && spec
== NULL
) {
3922 /* If the object property 08 is not yet set, ignore this property */
3923 ChangeInfoResult cir
= IgnoreObjectProperty(prop
, buf
);
3924 if (cir
> ret
) ret
= cir
;
3929 case 0x08: { // Class ID
3930 ObjectSpec
**ospec
= &_cur
.grffile
->objectspec
[id
+ i
];
3932 /* Allocate space for this object. */
3933 if (*ospec
== NULL
) {
3934 *ospec
= CallocT
<ObjectSpec
>(1);
3935 (*ospec
)->views
= 1; // Default for NewGRFs that don't set it.
3938 /* Swap classid because we read it in BE. */
3939 uint32 classid
= buf
->ReadDWord();
3940 (*ospec
)->cls_id
= ObjectClass::Allocate(BSWAP32(classid
));
3941 (*ospec
)->enabled
= true;
3945 case 0x09: { // Class name
3946 ObjectClass
*objclass
= ObjectClass::Get(spec
->cls_id
);
3947 AddStringForMapping(buf
->ReadWord(), &objclass
->name
);
3951 case 0x0A: // Object name
3952 AddStringForMapping(buf
->ReadWord(), &spec
->name
);
3955 case 0x0B: // Climate mask
3956 spec
->climate
= buf
->ReadByte();
3960 spec
->size
= buf
->ReadByte();
3963 case 0x0D: // Build cost multipler
3964 spec
->build_cost_multiplier
= buf
->ReadByte();
3965 spec
->clear_cost_multiplier
= spec
->build_cost_multiplier
;
3968 case 0x0E: // Introduction date
3969 spec
->introduction_date
= buf
->ReadDWord();
3972 case 0x0F: // End of life
3973 spec
->end_of_life_date
= buf
->ReadDWord();
3977 spec
->flags
= (ObjectFlags
)buf
->ReadWord();
3978 _loaded_newgrf_features
.has_2CC
|= (spec
->flags
& OBJECT_FLAG_2CC_COLOUR
) != 0;
3981 case 0x11: // Animation info
3982 spec
->animation
.frames
= buf
->ReadByte();
3983 spec
->animation
.status
= buf
->ReadByte();
3986 case 0x12: // Animation speed
3987 spec
->animation
.speed
= buf
->ReadByte();
3990 case 0x13: // Animation triggers
3991 spec
->animation
.triggers
= buf
->ReadWord();
3994 case 0x14: // Removal cost multiplier
3995 spec
->clear_cost_multiplier
= buf
->ReadByte();
3998 case 0x15: // Callback mask
3999 spec
->callback_mask
= buf
->ReadWord();
4002 case 0x16: // Building height
4003 spec
->height
= buf
->ReadByte();
4007 spec
->views
= buf
->ReadByte();
4008 if (spec
->views
!= 1 && spec
->views
!= 2 && spec
->views
!= 4) {
4009 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec
->views
, id
+ i
);
4014 case 0x18: // Amount placed on 256^2 map on map creation
4015 spec
->generate_amount
= buf
->ReadByte();
4028 * Define properties for railtypes
4029 * @param id ID of the railtype.
4030 * @param numinfo Number of subsequent IDs to change the property for.
4031 * @param prop The property to change.
4032 * @param buf The property value.
4033 * @return ChangeInfoResult.
4035 static ChangeInfoResult
RailTypeChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4037 ChangeInfoResult ret
= CIR_SUCCESS
;
4039 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
4041 if (id
+ numinfo
> RAILTYPE_END
) {
4042 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id
+ numinfo
, RAILTYPE_END
);
4043 return CIR_INVALID_ID
;
4046 for (int i
= 0; i
< numinfo
; i
++) {
4047 RailType rt
= _cur
.grffile
->railtype_map
[id
+ i
];
4048 if (rt
== INVALID_RAILTYPE
) return CIR_INVALID_ID
;
4050 RailtypeInfo
*rti
= &_railtypes
[rt
];
4053 case 0x08: // Label of rail type
4054 /* Skipped here as this is loaded during reservation stage. */
4058 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4059 uint16 str
= buf
->ReadWord();
4060 AddStringForMapping(str
, &rti
->strings
.toolbar_caption
);
4061 if (_cur
.grffile
->grf_version
< 8) {
4062 AddStringForMapping(str
, &rti
->strings
.name
);
4067 case 0x0A: // Menu text of railtype
4068 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.menu_text
);
4071 case 0x0B: // Build window caption
4072 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.build_caption
);
4075 case 0x0C: // Autoreplace text
4076 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.replace_text
);
4079 case 0x0D: // New locomotive text
4080 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.new_loco
);
4083 case 0x0E: // Compatible railtype list
4084 case 0x0F: // Powered railtype list
4085 case 0x18: // Railtype list required for date introduction
4086 case 0x19: // Introduced railtype list
4088 /* Rail type compatibility bits are added to the existing bits
4089 * to allow multiple GRFs to modify compatibility with the
4090 * default rail types. */
4091 int n
= buf
->ReadByte();
4092 for (int j
= 0; j
!= n
; j
++) {
4093 RailTypeLabel label
= buf
->ReadDWord();
4094 RailType rt
= GetRailTypeByLabel(BSWAP32(label
), false);
4095 if (rt
!= INVALID_RAILTYPE
) {
4097 case 0x0F: SetBit(rti
->powered_railtypes
, rt
); FALLTHROUGH
; // Powered implies compatible.
4098 case 0x0E: SetBit(rti
->compatible_railtypes
, rt
); break;
4099 case 0x18: SetBit(rti
->introduction_required_railtypes
, rt
); break;
4100 case 0x19: SetBit(rti
->introduces_railtypes
, rt
); break;
4107 case 0x10: // Rail Type flags
4108 rti
->flags
= (RailTypeFlags
)buf
->ReadByte();
4111 case 0x11: // Curve speed advantage
4112 rti
->curve_speed
= buf
->ReadByte();
4115 case 0x12: // Station graphic
4116 rti
->fallback_railtype
= Clamp(buf
->ReadByte(), 0, 2);
4119 case 0x13: // Construction cost factor
4120 rti
->cost_multiplier
= buf
->ReadWord();
4123 case 0x14: // Speed limit
4124 rti
->max_speed
= buf
->ReadWord();
4127 case 0x15: // Acceleration model
4128 rti
->acceleration_type
= Clamp(buf
->ReadByte(), 0, 2);
4131 case 0x16: // Map colour
4132 rti
->map_colour
= buf
->ReadByte();
4135 case 0x17: // Introduction date
4136 rti
->introduction_date
= buf
->ReadDWord();
4139 case 0x1A: // Sort order
4140 rti
->sorting_order
= buf
->ReadByte();
4143 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4144 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.name
);
4147 case 0x1C: // Maintenance cost factor
4148 rti
->maintenance_multiplier
= buf
->ReadWord();
4151 case 0x1D: // Alternate rail type label list
4152 /* Skipped here as this is loaded during reservation stage. */
4153 for (int j
= buf
->ReadByte(); j
!= 0; j
--) buf
->ReadDWord();
4165 static ChangeInfoResult
RailTypeReserveInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4167 ChangeInfoResult ret
= CIR_SUCCESS
;
4169 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
4171 if (id
+ numinfo
> RAILTYPE_END
) {
4172 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id
+ numinfo
, RAILTYPE_END
);
4173 return CIR_INVALID_ID
;
4176 for (int i
= 0; i
< numinfo
; i
++) {
4178 case 0x08: // Label of rail type
4180 RailTypeLabel rtl
= buf
->ReadDWord();
4183 RailType rt
= GetRailTypeByLabel(rtl
, false);
4184 if (rt
== INVALID_RAILTYPE
) {
4185 /* Set up new rail type */
4186 rt
= AllocateRailType(rtl
);
4189 _cur
.grffile
->railtype_map
[id
+ i
] = rt
;
4193 case 0x09: // Toolbar caption of railtype
4194 case 0x0A: // Menu text
4195 case 0x0B: // Build window caption
4196 case 0x0C: // Autoreplace text
4197 case 0x0D: // New loco
4198 case 0x13: // Construction cost
4199 case 0x14: // Speed limit
4200 case 0x1B: // Name of railtype
4201 case 0x1C: // Maintenance cost factor
4205 case 0x1D: // Alternate rail type label list
4206 if (_cur
.grffile
->railtype_map
[id
+ i
] != INVALID_RAILTYPE
) {
4207 int n
= buf
->ReadByte();
4208 for (int j
= 0; j
!= n
; j
++) {
4209 *_railtypes
[_cur
.grffile
->railtype_map
[id
+ i
]].alternate_labels
.Append() = BSWAP32(buf
->ReadDWord());
4213 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id
+ i
);
4216 case 0x0E: // Compatible railtype list
4217 case 0x0F: // Powered railtype list
4218 case 0x18: // Railtype list required for date introduction
4219 case 0x19: // Introduced railtype list
4220 for (int j
= buf
->ReadByte(); j
!= 0; j
--) buf
->ReadDWord();
4223 case 0x10: // Rail Type flags
4224 case 0x11: // Curve speed advantage
4225 case 0x12: // Station graphic
4226 case 0x15: // Acceleration model
4227 case 0x16: // Map colour
4228 case 0x1A: // Sort order
4232 case 0x17: // Introduction date
4245 static ChangeInfoResult
AirportTilesChangeInfo(uint airtid
, int numinfo
, int prop
, ByteReader
*buf
)
4247 ChangeInfoResult ret
= CIR_SUCCESS
;
4249 if (airtid
+ numinfo
> NUM_AIRPORTTILES_PER_GRF
) {
4250 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid
+ numinfo
, NUM_AIRPORTTILES_PER_GRF
);
4251 return CIR_INVALID_ID
;
4254 /* Allocate airport tile specs if they haven't been allocated already. */
4255 if (_cur
.grffile
->airtspec
== NULL
) {
4256 _cur
.grffile
->airtspec
= CallocT
<AirportTileSpec
*>(NUM_AIRPORTTILES_PER_GRF
);
4259 for (int i
= 0; i
< numinfo
; i
++) {
4260 AirportTileSpec
*tsp
= _cur
.grffile
->airtspec
[airtid
+ i
];
4262 if (prop
!= 0x08 && tsp
== NULL
) {
4263 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid
+ i
);
4264 return CIR_INVALID_ID
;
4268 case 0x08: { // Substitute airport tile type
4269 AirportTileSpec
**tilespec
= &_cur
.grffile
->airtspec
[airtid
+ i
];
4270 byte subs_id
= buf
->ReadByte();
4272 if (subs_id
>= NEW_AIRPORTTILE_OFFSET
) {
4273 /* The substitute id must be one of the original airport tiles. */
4274 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id
, airtid
+ i
);
4278 /* Allocate space for this airport tile. */
4279 if (*tilespec
== NULL
) {
4280 *tilespec
= CallocT
<AirportTileSpec
>(1);
4283 memcpy(tsp
, AirportTileSpec::Get(subs_id
), sizeof(AirportTileSpec
));
4284 tsp
->enabled
= true;
4286 tsp
->animation
.status
= ANIM_STATUS_NO_ANIMATION
;
4288 tsp
->grf_prop
.local_id
= airtid
+ i
;
4289 tsp
->grf_prop
.subst_id
= subs_id
;
4290 tsp
->grf_prop
.grffile
= _cur
.grffile
;
4291 _airporttile_mngr
.AddEntityID(airtid
+ i
, _cur
.grffile
->grfid
, subs_id
); // pre-reserve the tile slot
4296 case 0x09: { // Airport tile override
4297 byte override
= buf
->ReadByte();
4299 /* The airport tile being overridden must be an original airport tile. */
4300 if (override
>= NEW_AIRPORTTILE_OFFSET
) {
4301 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override
, airtid
+ i
);
4305 _airporttile_mngr
.Add(airtid
+ i
, _cur
.grffile
->grfid
, override
);
4309 case 0x0E: // Callback mask
4310 tsp
->callback_mask
= buf
->ReadByte();
4313 case 0x0F: // Animation information
4314 tsp
->animation
.frames
= buf
->ReadByte();
4315 tsp
->animation
.status
= buf
->ReadByte();
4318 case 0x10: // Animation speed
4319 tsp
->animation
.speed
= buf
->ReadByte();
4322 case 0x11: // Animation triggers
4323 tsp
->animation
.triggers
= buf
->ReadByte();
4335 static bool HandleChangeInfoResult(const char *caller
, ChangeInfoResult cir
, uint8 feature
, uint8 property
)
4338 default: NOT_REACHED();
4341 /* Error has already been printed; just stop parsing */
4348 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller
, property
, feature
);
4352 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller
, property
, feature
);
4355 case CIR_INVALID_ID
: {
4356 /* No debug message for an invalid ID, as it has already been output */
4357 GRFError
*error
= DisableGrf(cir
== CIR_INVALID_ID
? STR_NEWGRF_ERROR_INVALID_ID
: STR_NEWGRF_ERROR_UNKNOWN_PROPERTY
);
4358 if (cir
!= CIR_INVALID_ID
) error
->param_value
[1] = property
;
4365 static void FeatureChangeInfo(ByteReader
*buf
)
4367 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4370 * B num-props how many properties to change per vehicle/station
4371 * B num-info how many vehicles/stations to change
4372 * E id ID of first vehicle/station to change, if num-info is
4373 * greater than one, this one and the following
4374 * vehicles/stations will be changed
4375 * B property what property to change, depends on the feature
4376 * V new-info new bytes of info (variable size; depends on properties) */
4378 static const VCI_Handler handler
[] = {
4379 /* GSF_TRAINS */ RailVehicleChangeInfo
,
4380 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo
,
4381 /* GSF_SHIPS */ ShipVehicleChangeInfo
,
4382 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo
,
4383 /* GSF_STATIONS */ StationChangeInfo
,
4384 /* GSF_CANALS */ CanalChangeInfo
,
4385 /* GSF_BRIDGES */ BridgeChangeInfo
,
4386 /* GSF_HOUSES */ TownHouseChangeInfo
,
4387 /* GSF_GLOBALVAR */ GlobalVarChangeInfo
,
4388 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo
,
4389 /* GSF_INDUSTRIES */ IndustriesChangeInfo
,
4390 /* GSF_CARGOES */ NULL
, // Cargo is handled during reservation
4391 /* GSF_SOUNDFX */ SoundEffectChangeInfo
,
4392 /* GSF_AIRPORTS */ AirportChangeInfo
,
4393 /* GSF_SIGNALS */ NULL
,
4394 /* GSF_OBJECTS */ ObjectChangeInfo
,
4395 /* GSF_RAILTYPES */ RailTypeChangeInfo
,
4396 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo
,
4399 uint8 feature
= buf
->ReadByte();
4400 uint8 numprops
= buf
->ReadByte();
4401 uint numinfo
= buf
->ReadByte();
4402 uint engine
= buf
->ReadExtendedByte();
4404 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4405 feature
, numprops
, engine
, numinfo
);
4407 if (feature
>= lengthof(handler
) || handler
[feature
] == NULL
) {
4408 if (feature
!= GSF_CARGOES
) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature
);
4412 /* Mark the feature as used by the grf */
4413 SetBit(_cur
.grffile
->grf_features
, feature
);
4415 while (numprops
-- && buf
->HasData()) {
4416 uint8 prop
= buf
->ReadByte();
4418 ChangeInfoResult cir
= handler
[feature
](engine
, numinfo
, prop
, buf
);
4419 if (HandleChangeInfoResult("FeatureChangeInfo", cir
, feature
, prop
)) return;
4423 /* Action 0x00 (GLS_SAFETYSCAN) */
4424 static void SafeChangeInfo(ByteReader
*buf
)
4426 uint8 feature
= buf
->ReadByte();
4427 uint8 numprops
= buf
->ReadByte();
4428 uint numinfo
= buf
->ReadByte();
4429 buf
->ReadExtendedByte(); // id
4431 if (feature
== GSF_BRIDGES
&& numprops
== 1) {
4432 uint8 prop
= buf
->ReadByte();
4433 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4434 * is considered safe. */
4435 if (prop
== 0x0D) return;
4436 } else if (feature
== GSF_GLOBALVAR
&& numprops
== 1) {
4437 uint8 prop
= buf
->ReadByte();
4438 /* Engine ID Mappings are safe, if the source is static */
4440 bool is_safe
= true;
4441 for (uint i
= 0; i
< numinfo
; i
++) {
4442 uint32 s
= buf
->ReadDWord();
4443 buf
->ReadDWord(); // dest
4444 const GRFConfig
*grfconfig
= GetGRFConfig(s
);
4445 if (grfconfig
!= NULL
&& !HasBit(grfconfig
->flags
, GCF_STATIC
)) {
4450 if (is_safe
) return;
4454 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
4456 /* Skip remainder of GRF */
4457 _cur
.skip_sprites
= -1;
4460 /* Action 0x00 (GLS_RESERVE) */
4461 static void ReserveChangeInfo(ByteReader
*buf
)
4463 uint8 feature
= buf
->ReadByte();
4465 if (feature
!= GSF_CARGOES
&& feature
!= GSF_GLOBALVAR
&& feature
!= GSF_RAILTYPES
) return;
4467 uint8 numprops
= buf
->ReadByte();
4468 uint8 numinfo
= buf
->ReadByte();
4469 uint8 index
= buf
->ReadExtendedByte();
4471 while (numprops
-- && buf
->HasData()) {
4472 uint8 prop
= buf
->ReadByte();
4473 ChangeInfoResult cir
= CIR_SUCCESS
;
4476 default: NOT_REACHED();
4478 cir
= CargoChangeInfo(index
, numinfo
, prop
, buf
);
4482 cir
= GlobalVarReserveInfo(index
, numinfo
, prop
, buf
);
4486 cir
= RailTypeReserveInfo(index
, numinfo
, prop
, buf
);
4490 if (HandleChangeInfoResult("ReserveChangeInfo", cir
, feature
, prop
)) return;
4495 static void NewSpriteSet(ByteReader
*buf
)
4497 /* Basic format: <01> <feature> <num-sets> <num-ent>
4498 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4500 * B feature feature to define sprites for
4501 * 0, 1, 2, 3: veh-type, 4: train stations
4502 * E first-set first sprite set to define
4503 * B num-sets number of sprite sets (extended byte in extended format)
4504 * E num-ent how many entries per sprite set
4505 * For vehicles, this is the number of different
4506 * vehicle directions in each sprite set
4507 * Set num-dirs=8, unless your sprites are symmetric.
4508 * In that case, use num-dirs=4.
4511 uint8 feature
= buf
->ReadByte();
4512 uint16 num_sets
= buf
->ReadByte();
4513 uint16 first_set
= 0;
4515 if (num_sets
== 0 && buf
->HasData(3)) {
4516 /* Extended Action1 format.
4517 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4518 first_set
= buf
->ReadExtendedByte();
4519 num_sets
= buf
->ReadExtendedByte();
4521 uint16 num_ents
= buf
->ReadExtendedByte();
4523 _cur
.AddSpriteSets(feature
, _cur
.spriteid
, first_set
, num_sets
, num_ents
);
4525 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4526 _cur
.spriteid
, feature
, num_sets
, num_ents
, num_sets
* num_ents
4529 for (int i
= 0; i
< num_sets
* num_ents
; i
++) {
4531 LoadNextSprite(_cur
.spriteid
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
4535 /* Action 0x01 (SKIP) */
4536 static void SkipAct1(ByteReader
*buf
)
4539 uint16 num_sets
= buf
->ReadByte();
4541 if (num_sets
== 0 && buf
->HasData(3)) {
4542 /* Extended Action1 format.
4543 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4544 buf
->ReadExtendedByte(); // first_set
4545 num_sets
= buf
->ReadExtendedByte();
4547 uint16 num_ents
= buf
->ReadExtendedByte();
4549 _cur
.skip_sprites
= num_sets
* num_ents
;
4551 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur
.skip_sprites
);
4554 /* Helper function to either create a callback or link to a previously
4555 * defined spritegroup. */
4556 static const SpriteGroup
*GetGroupFromGroupID(byte setid
, byte type
, uint16 groupid
)
4558 if (HasBit(groupid
, 15)) {
4559 assert(CallbackResultSpriteGroup::CanAllocateItem());
4560 return new CallbackResultSpriteGroup(groupid
, _cur
.grffile
->grf_version
>= 8);
4563 if (groupid
> MAX_SPRITEGROUP
|| _cur
.spritegroups
[groupid
] == NULL
) {
4564 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid
, type
, groupid
);
4568 return _cur
.spritegroups
[groupid
];
4572 * Helper function to either create a callback or a result sprite group.
4573 * @param feature GrfSpecFeature to define spritegroup for.
4574 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4575 * @param type Type of the currently being parsed Action2. (only for debug output)
4576 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4577 * @return Created spritegroup.
4579 static const SpriteGroup
*CreateGroupFromGroupID(byte feature
, byte setid
, byte type
, uint16 spriteid
)
4581 if (HasBit(spriteid
, 15)) {
4582 assert(CallbackResultSpriteGroup::CanAllocateItem());
4583 return new CallbackResultSpriteGroup(spriteid
, _cur
.grffile
->grf_version
>= 8);
4586 if (!_cur
.IsValidSpriteSet(feature
, spriteid
)) {
4587 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid
, type
, spriteid
);
4591 SpriteID spriteset_start
= _cur
.GetSprite(feature
, spriteid
);
4592 uint num_sprites
= _cur
.GetNumEnts(feature
, spriteid
);
4594 /* Ensure that the sprites are loeded */
4595 assert(spriteset_start
+ num_sprites
<= _cur
.spriteid
);
4597 assert(ResultSpriteGroup::CanAllocateItem());
4598 return new ResultSpriteGroup(spriteset_start
, num_sprites
);
4602 static void NewSpriteGroup(ByteReader
*buf
)
4604 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4606 * B feature see action 1
4607 * B set-id ID of this particular definition
4608 * B type/num-entries
4609 * if 80 or greater, this is a randomized or variational
4610 * list definition, see below
4611 * otherwise it specifies a number of entries, the exact
4612 * meaning depends on the feature
4613 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4614 SpriteGroup
*act_group
= NULL
;
4616 uint8 feature
= buf
->ReadByte();
4617 uint8 setid
= buf
->ReadByte();
4618 uint8 type
= buf
->ReadByte();
4620 /* Sprite Groups are created here but they are allocated from a pool, so
4621 * we do not need to delete anything if there is an exception from the
4625 /* Deterministic Sprite Group */
4626 case 0x81: // Self scope, byte
4627 case 0x82: // Parent scope, byte
4628 case 0x85: // Self scope, word
4629 case 0x86: // Parent scope, word
4630 case 0x89: // Self scope, dword
4631 case 0x8A: // Parent scope, dword
4636 assert(DeterministicSpriteGroup::CanAllocateItem());
4637 DeterministicSpriteGroup
*group
= new DeterministicSpriteGroup();
4639 group
->var_scope
= HasBit(type
, 1) ? VSG_SCOPE_PARENT
: VSG_SCOPE_SELF
;
4641 switch (GB(type
, 2, 2)) {
4642 default: NOT_REACHED();
4643 case 0: group
->size
= DSG_SIZE_BYTE
; varsize
= 1; break;
4644 case 1: group
->size
= DSG_SIZE_WORD
; varsize
= 2; break;
4645 case 2: group
->size
= DSG_SIZE_DWORD
; varsize
= 4; break;
4648 static SmallVector
<DeterministicSpriteGroupAdjust
, 16> adjusts
;
4651 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4652 * from the outset, so we shall have to keep reallocing. */
4654 DeterministicSpriteGroupAdjust
*adjust
= adjusts
.Append();
4656 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4657 adjust
->operation
= adjusts
.Length() == 1 ? DSGA_OP_ADD
: (DeterministicSpriteGroupAdjustOperation
)buf
->ReadByte();
4658 adjust
->variable
= buf
->ReadByte();
4659 if (adjust
->variable
== 0x7E) {
4660 /* Link subroutine group */
4661 adjust
->subroutine
= GetGroupFromGroupID(setid
, type
, buf
->ReadByte());
4663 adjust
->parameter
= IsInsideMM(adjust
->variable
, 0x60, 0x80) ? buf
->ReadByte() : 0;
4666 varadjust
= buf
->ReadByte();
4667 adjust
->shift_num
= GB(varadjust
, 0, 5);
4668 adjust
->type
= (DeterministicSpriteGroupAdjustType
)GB(varadjust
, 6, 2);
4669 adjust
->and_mask
= buf
->ReadVarSize(varsize
);
4671 if (adjust
->type
!= DSGA_TYPE_NONE
) {
4672 adjust
->add_val
= buf
->ReadVarSize(varsize
);
4673 adjust
->divmod_val
= buf
->ReadVarSize(varsize
);
4675 adjust
->add_val
= 0;
4676 adjust
->divmod_val
= 0;
4679 /* Continue reading var adjusts while bit 5 is set. */
4680 } while (HasBit(varadjust
, 5));
4682 group
->num_adjusts
= adjusts
.Length();
4683 group
->adjusts
= MallocT
<DeterministicSpriteGroupAdjust
>(group
->num_adjusts
);
4684 MemCpyT(group
->adjusts
, adjusts
.Begin(), group
->num_adjusts
);
4686 group
->num_ranges
= buf
->ReadByte();
4687 if (group
->num_ranges
> 0) group
->ranges
= CallocT
<DeterministicSpriteGroupRange
>(group
->num_ranges
);
4689 for (uint i
= 0; i
< group
->num_ranges
; i
++) {
4690 group
->ranges
[i
].group
= GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4691 group
->ranges
[i
].low
= buf
->ReadVarSize(varsize
);
4692 group
->ranges
[i
].high
= buf
->ReadVarSize(varsize
);
4695 group
->default_group
= GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4699 /* Randomized Sprite Group */
4700 case 0x80: // Self scope
4701 case 0x83: // Parent scope
4702 case 0x84: // Relative scope
4704 assert(RandomizedSpriteGroup::CanAllocateItem());
4705 RandomizedSpriteGroup
*group
= new RandomizedSpriteGroup();
4707 group
->var_scope
= HasBit(type
, 1) ? VSG_SCOPE_PARENT
: VSG_SCOPE_SELF
;
4709 if (HasBit(type
, 2)) {
4710 if (feature
<= GSF_AIRCRAFT
) group
->var_scope
= VSG_SCOPE_RELATIVE
;
4711 group
->count
= buf
->ReadByte();
4714 uint8 triggers
= buf
->ReadByte();
4715 group
->triggers
= GB(triggers
, 0, 7);
4716 group
->cmp_mode
= HasBit(triggers
, 7) ? RSG_CMP_ALL
: RSG_CMP_ANY
;
4717 group
->lowest_randbit
= buf
->ReadByte();
4718 group
->num_groups
= buf
->ReadByte();
4719 group
->groups
= CallocT
<const SpriteGroup
*>(group
->num_groups
);
4721 for (uint i
= 0; i
< group
->num_groups
; i
++) {
4722 group
->groups
[i
] = GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4728 /* Neither a variable or randomized sprite group... must be a real group */
4733 case GSF_ROADVEHICLES
:
4742 byte num_loaded
= type
;
4743 byte num_loading
= buf
->ReadByte();
4745 if (!_cur
.HasValidSpriteSets(feature
)) {
4746 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4750 assert(RealSpriteGroup::CanAllocateItem());
4751 RealSpriteGroup
*group
= new RealSpriteGroup();
4754 group
->num_loaded
= num_loaded
;
4755 group
->num_loading
= num_loading
;
4756 if (num_loaded
> 0) group
->loaded
= CallocT
<const SpriteGroup
*>(num_loaded
);
4757 if (num_loading
> 0) group
->loading
= CallocT
<const SpriteGroup
*>(num_loading
);
4759 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4760 setid
, num_loaded
, num_loading
);
4762 for (uint i
= 0; i
< num_loaded
; i
++) {
4763 uint16 spriteid
= buf
->ReadWord();
4764 group
->loaded
[i
] = CreateGroupFromGroupID(feature
, setid
, type
, spriteid
);
4765 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i
, spriteid
);
4768 for (uint i
= 0; i
< num_loading
; i
++) {
4769 uint16 spriteid
= buf
->ReadWord();
4770 group
->loading
[i
] = CreateGroupFromGroupID(feature
, setid
, type
, spriteid
);
4771 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i
, spriteid
);
4778 case GSF_AIRPORTTILES
:
4780 case GSF_INDUSTRYTILES
: {
4781 byte num_building_sprites
= max((uint8
)1, type
);
4783 assert(TileLayoutSpriteGroup::CanAllocateItem());
4784 TileLayoutSpriteGroup
*group
= new TileLayoutSpriteGroup();
4787 /* On error, bail out immediately. Temporary GRF data was already freed */
4788 if (ReadSpriteLayout(buf
, num_building_sprites
, true, feature
, false, type
== 0, &group
->dts
)) return;
4792 case GSF_INDUSTRIES
: {
4794 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type
);
4798 assert(IndustryProductionSpriteGroup::CanAllocateItem());
4799 IndustryProductionSpriteGroup
*group
= new IndustryProductionSpriteGroup();
4801 group
->version
= type
;
4803 for (uint i
= 0; i
< 3; i
++) {
4804 group
->subtract_input
[i
] = (int16
)buf
->ReadWord(); // signed
4806 for (uint i
= 0; i
< 2; i
++) {
4807 group
->add_output
[i
] = buf
->ReadWord(); // unsigned
4809 group
->again
= buf
->ReadByte();
4811 for (uint i
= 0; i
< 3; i
++) {
4812 group
->subtract_input
[i
] = buf
->ReadByte();
4814 for (uint i
= 0; i
< 2; i
++) {
4815 group
->add_output
[i
] = buf
->ReadByte();
4817 group
->again
= buf
->ReadByte();
4822 /* Loading of Tile Layout and Production Callback groups would happen here */
4823 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature
);
4828 _cur
.spritegroups
[setid
] = act_group
;
4831 static CargoID
TranslateCargo(uint8 feature
, uint8 ctype
)
4833 if (feature
== GSF_OBJECTS
) {
4836 case 0xFF: return CT_PURCHASE_OBJECT
;
4838 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype
);
4842 /* Special cargo types for purchase list and stations */
4843 if (feature
== GSF_STATIONS
&& ctype
== 0xFE) return CT_DEFAULT_NA
;
4844 if (ctype
== 0xFF) return CT_PURCHASE
;
4846 if (_cur
.grffile
->cargo_list
.Length() == 0) {
4847 /* No cargo table, so use bitnum values */
4849 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype
);
4853 const CargoSpec
*cs
;
4854 FOR_ALL_CARGOSPECS(cs
) {
4855 if (cs
->bitnum
== ctype
) {
4856 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype
, cs
->Index());
4861 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype
);
4865 /* Check if the cargo type is out of bounds of the cargo translation table */
4866 if (ctype
>= _cur
.grffile
->cargo_list
.Length()) {
4867 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype
, _cur
.grffile
->cargo_list
.Length() - 1);
4871 /* Look up the cargo label from the translation table */
4872 CargoLabel cl
= _cur
.grffile
->cargo_list
[ctype
];
4874 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype
);
4878 ctype
= GetCargoIDByLabel(cl
);
4879 if (ctype
== CT_INVALID
) {
4880 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));
4884 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
);
4889 static bool IsValidGroupID(uint16 groupid
, const char *function
)
4891 if (groupid
> MAX_SPRITEGROUP
|| _cur
.spritegroups
[groupid
] == NULL
) {
4892 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function
, groupid
);
4899 static void VehicleMapSpriteGroup(ByteReader
*buf
, byte feature
, uint8 idcount
)
4901 static EngineID
*last_engines
;
4902 static uint last_engines_count
;
4903 bool wagover
= false;
4905 /* Test for 'wagon override' flag */
4906 if (HasBit(idcount
, 7)) {
4908 /* Strip off the flag */
4909 idcount
= GB(idcount
, 0, 7);
4911 if (last_engines_count
== 0) {
4912 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4916 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4917 last_engines_count
, idcount
);
4919 if (last_engines_count
!= idcount
) {
4920 last_engines
= ReallocT(last_engines
, idcount
);
4921 last_engines_count
= idcount
;
4925 EngineID
*engines
= AllocaM(EngineID
, idcount
);
4926 for (uint i
= 0; i
< idcount
; i
++) {
4927 Engine
*e
= GetNewEngine(_cur
.grffile
, (VehicleType
)feature
, buf
->ReadExtendedByte());
4929 /* No engine could be allocated?!? Deal with it. Okay,
4930 * this might look bad. Also make sure this NewGRF
4931 * gets disabled, as a half loaded one is bad. */
4932 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID
, 0, 0);
4936 engines
[i
] = e
->index
;
4937 if (!wagover
) last_engines
[i
] = engines
[i
];
4940 uint8 cidcount
= buf
->ReadByte();
4941 for (uint c
= 0; c
< cidcount
; c
++) {
4942 uint8 ctype
= buf
->ReadByte();
4943 uint16 groupid
= buf
->ReadWord();
4944 if (!IsValidGroupID(groupid
, "VehicleMapSpriteGroup")) continue;
4946 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c
, ctype
, groupid
);
4948 ctype
= TranslateCargo(feature
, ctype
);
4949 if (ctype
== CT_INVALID
) continue;
4951 for (uint i
= 0; i
< idcount
; i
++) {
4952 EngineID engine
= engines
[i
];
4954 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i
, engine
);
4957 SetWagonOverrideSprites(engine
, ctype
, _cur
.spritegroups
[groupid
], last_engines
, last_engines_count
);
4959 SetCustomEngineSprites(engine
, ctype
, _cur
.spritegroups
[groupid
]);
4964 uint16 groupid
= buf
->ReadWord();
4965 if (!IsValidGroupID(groupid
, "VehicleMapSpriteGroup")) return;
4967 grfmsg(8, "-- Default group id 0x%04X", groupid
);
4969 for (uint i
= 0; i
< idcount
; i
++) {
4970 EngineID engine
= engines
[i
];
4973 SetWagonOverrideSprites(engine
, CT_DEFAULT
, _cur
.spritegroups
[groupid
], last_engines
, last_engines_count
);
4975 SetCustomEngineSprites(engine
, CT_DEFAULT
, _cur
.spritegroups
[groupid
]);
4976 SetEngineGRF(engine
, _cur
.grffile
);
4982 static void CanalMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
4984 CanalFeature
*cfs
= AllocaM(CanalFeature
, idcount
);
4985 for (uint i
= 0; i
< idcount
; i
++) {
4986 cfs
[i
] = (CanalFeature
)buf
->ReadByte();
4989 uint8 cidcount
= buf
->ReadByte();
4990 buf
->Skip(cidcount
* 3);
4992 uint16 groupid
= buf
->ReadWord();
4993 if (!IsValidGroupID(groupid
, "CanalMapSpriteGroup")) return;
4995 for (uint i
= 0; i
< idcount
; i
++) {
4996 CanalFeature cf
= cfs
[i
];
4999 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf
);
5003 _water_feature
[cf
].grffile
= _cur
.grffile
;
5004 _water_feature
[cf
].group
= _cur
.spritegroups
[groupid
];
5009 static void StationMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5011 uint8
*stations
= AllocaM(uint8
, idcount
);
5012 for (uint i
= 0; i
< idcount
; i
++) {
5013 stations
[i
] = buf
->ReadByte();
5016 uint8 cidcount
= buf
->ReadByte();
5017 for (uint c
= 0; c
< cidcount
; c
++) {
5018 uint8 ctype
= buf
->ReadByte();
5019 uint16 groupid
= buf
->ReadWord();
5020 if (!IsValidGroupID(groupid
, "StationMapSpriteGroup")) continue;
5022 ctype
= TranslateCargo(GSF_STATIONS
, ctype
);
5023 if (ctype
== CT_INVALID
) continue;
5025 for (uint i
= 0; i
< idcount
; i
++) {
5026 StationSpec
*statspec
= _cur
.grffile
->stations
== NULL
? NULL
: _cur
.grffile
->stations
[stations
[i
]];
5028 if (statspec
== NULL
) {
5029 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations
[i
]);
5033 statspec
->grf_prop
.spritegroup
[ctype
] = _cur
.spritegroups
[groupid
];
5037 uint16 groupid
= buf
->ReadWord();
5038 if (!IsValidGroupID(groupid
, "StationMapSpriteGroup")) return;
5040 for (uint i
= 0; i
< idcount
; i
++) {
5041 StationSpec
*statspec
= _cur
.grffile
->stations
== NULL
? NULL
: _cur
.grffile
->stations
[stations
[i
]];
5043 if (statspec
== NULL
) {
5044 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations
[i
]);
5048 if (statspec
->grf_prop
.grffile
!= NULL
) {
5049 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations
[i
]);
5053 statspec
->grf_prop
.spritegroup
[CT_DEFAULT
] = _cur
.spritegroups
[groupid
];
5054 statspec
->grf_prop
.grffile
= _cur
.grffile
;
5055 statspec
->grf_prop
.local_id
= stations
[i
];
5056 StationClass::Assign(statspec
);
5061 static void TownHouseMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5063 uint8
*houses
= AllocaM(uint8
, idcount
);
5064 for (uint i
= 0; i
< idcount
; i
++) {
5065 houses
[i
] = buf
->ReadByte();
5068 /* Skip the cargo type section, we only care about the default group */
5069 uint8 cidcount
= buf
->ReadByte();
5070 buf
->Skip(cidcount
* 3);
5072 uint16 groupid
= buf
->ReadWord();
5073 if (!IsValidGroupID(groupid
, "TownHouseMapSpriteGroup")) return;
5075 if (_cur
.grffile
->housespec
== NULL
) {
5076 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5080 for (uint i
= 0; i
< idcount
; i
++) {
5081 HouseSpec
*hs
= _cur
.grffile
->housespec
[houses
[i
]];
5084 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses
[i
]);
5088 hs
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5092 static void IndustryMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5094 uint8
*industries
= AllocaM(uint8
, idcount
);
5095 for (uint i
= 0; i
< idcount
; i
++) {
5096 industries
[i
] = buf
->ReadByte();
5099 /* Skip the cargo type section, we only care about the default group */
5100 uint8 cidcount
= buf
->ReadByte();
5101 buf
->Skip(cidcount
* 3);
5103 uint16 groupid
= buf
->ReadWord();
5104 if (!IsValidGroupID(groupid
, "IndustryMapSpriteGroup")) return;
5106 if (_cur
.grffile
->industryspec
== NULL
) {
5107 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5111 for (uint i
= 0; i
< idcount
; i
++) {
5112 IndustrySpec
*indsp
= _cur
.grffile
->industryspec
[industries
[i
]];
5114 if (indsp
== NULL
) {
5115 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries
[i
]);
5119 indsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5123 static void IndustrytileMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5125 uint8
*indtiles
= AllocaM(uint8
, idcount
);
5126 for (uint i
= 0; i
< idcount
; i
++) {
5127 indtiles
[i
] = buf
->ReadByte();
5130 /* Skip the cargo type section, we only care about the default group */
5131 uint8 cidcount
= buf
->ReadByte();
5132 buf
->Skip(cidcount
* 3);
5134 uint16 groupid
= buf
->ReadWord();
5135 if (!IsValidGroupID(groupid
, "IndustrytileMapSpriteGroup")) return;
5137 if (_cur
.grffile
->indtspec
== NULL
) {
5138 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5142 for (uint i
= 0; i
< idcount
; i
++) {
5143 IndustryTileSpec
*indtsp
= _cur
.grffile
->indtspec
[indtiles
[i
]];
5145 if (indtsp
== NULL
) {
5146 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles
[i
]);
5150 indtsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5154 static void CargoMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5156 CargoID
*cargoes
= AllocaM(CargoID
, idcount
);
5157 for (uint i
= 0; i
< idcount
; i
++) {
5158 cargoes
[i
] = buf
->ReadByte();
5161 /* Skip the cargo type section, we only care about the default group */
5162 uint8 cidcount
= buf
->ReadByte();
5163 buf
->Skip(cidcount
* 3);
5165 uint16 groupid
= buf
->ReadWord();
5166 if (!IsValidGroupID(groupid
, "CargoMapSpriteGroup")) return;
5168 for (uint i
= 0; i
< idcount
; i
++) {
5169 CargoID cid
= cargoes
[i
];
5171 if (cid
>= NUM_CARGO
) {
5172 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid
);
5176 CargoSpec
*cs
= CargoSpec::Get(cid
);
5177 cs
->grffile
= _cur
.grffile
;
5178 cs
->group
= _cur
.spritegroups
[groupid
];
5182 static void ObjectMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5184 if (_cur
.grffile
->objectspec
== NULL
) {
5185 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5189 uint8
*objects
= AllocaM(uint8
, idcount
);
5190 for (uint i
= 0; i
< idcount
; i
++) {
5191 objects
[i
] = buf
->ReadByte();
5194 uint8 cidcount
= buf
->ReadByte();
5195 for (uint c
= 0; c
< cidcount
; c
++) {
5196 uint8 ctype
= buf
->ReadByte();
5197 uint16 groupid
= buf
->ReadWord();
5198 if (!IsValidGroupID(groupid
, "ObjectMapSpriteGroup")) continue;
5200 ctype
= TranslateCargo(GSF_OBJECTS
, ctype
);
5201 if (ctype
== CT_INVALID
) continue;
5203 for (uint i
= 0; i
< idcount
; i
++) {
5204 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[objects
[i
]];
5207 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects
[i
]);
5211 spec
->grf_prop
.spritegroup
[ctype
] = _cur
.spritegroups
[groupid
];
5215 uint16 groupid
= buf
->ReadWord();
5216 if (!IsValidGroupID(groupid
, "ObjectMapSpriteGroup")) return;
5218 for (uint i
= 0; i
< idcount
; i
++) {
5219 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[objects
[i
]];
5222 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects
[i
]);
5226 if (spec
->grf_prop
.grffile
!= NULL
) {
5227 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects
[i
]);
5231 spec
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5232 spec
->grf_prop
.grffile
= _cur
.grffile
;
5233 spec
->grf_prop
.local_id
= objects
[i
];
5237 static void RailTypeMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5239 uint8
*railtypes
= AllocaM(uint8
, idcount
);
5240 for (uint i
= 0; i
< idcount
; i
++) {
5241 railtypes
[i
] = _cur
.grffile
->railtype_map
[buf
->ReadByte()];
5244 uint8 cidcount
= buf
->ReadByte();
5245 for (uint c
= 0; c
< cidcount
; c
++) {
5246 uint8 ctype
= buf
->ReadByte();
5247 uint16 groupid
= buf
->ReadWord();
5248 if (!IsValidGroupID(groupid
, "RailTypeMapSpriteGroup")) continue;
5250 if (ctype
>= RTSG_END
) continue;
5252 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
5253 for (uint i
= 0; i
< idcount
; i
++) {
5254 if (railtypes
[i
] != INVALID_RAILTYPE
) {
5255 RailtypeInfo
*rti
= &_railtypes
[railtypes
[i
]];
5257 rti
->grffile
[ctype
] = _cur
.grffile
;
5258 rti
->group
[ctype
] = _cur
.spritegroups
[groupid
];
5263 /* Railtypes do not use the default group. */
5267 static void AirportMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5269 uint8
*airports
= AllocaM(uint8
, idcount
);
5270 for (uint i
= 0; i
< idcount
; i
++) {
5271 airports
[i
] = buf
->ReadByte();
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
, "AirportMapSpriteGroup")) return;
5281 if (_cur
.grffile
->airportspec
== NULL
) {
5282 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5286 for (uint i
= 0; i
< idcount
; i
++) {
5287 AirportSpec
*as
= _cur
.grffile
->airportspec
[airports
[i
]];
5290 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports
[i
]);
5294 as
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5298 static void AirportTileMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5300 uint8
*airptiles
= AllocaM(uint8
, idcount
);
5301 for (uint i
= 0; i
< idcount
; i
++) {
5302 airptiles
[i
] = buf
->ReadByte();
5305 /* Skip the cargo type section, we only care about the default group */
5306 uint8 cidcount
= buf
->ReadByte();
5307 buf
->Skip(cidcount
* 3);
5309 uint16 groupid
= buf
->ReadWord();
5310 if (!IsValidGroupID(groupid
, "AirportTileMapSpriteGroup")) return;
5312 if (_cur
.grffile
->airtspec
== NULL
) {
5313 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5317 for (uint i
= 0; i
< idcount
; i
++) {
5318 AirportTileSpec
*airtsp
= _cur
.grffile
->airtspec
[airptiles
[i
]];
5320 if (airtsp
== NULL
) {
5321 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles
[i
]);
5325 airtsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5331 static void FeatureMapSpriteGroup(ByteReader
*buf
)
5333 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5334 * id-list := [<id>] [id-list]
5335 * cargo-list := <cargo-type> <cid> [cargo-list]
5337 * B feature see action 0
5338 * B n-id bits 0-6: how many IDs this definition applies to
5339 * bit 7: if set, this is a wagon override definition (see below)
5340 * B ids the IDs for which this definition applies
5341 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5342 * can be zero, in that case the def-cid is used always
5343 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5344 * W cid cargo ID (sprite group ID) for this type of cargo
5345 * W def-cid default cargo ID (sprite group ID) */
5347 uint8 feature
= buf
->ReadByte();
5348 uint8 idcount
= buf
->ReadByte();
5350 /* If idcount is zero, this is a feature callback */
5352 /* Skip number of cargo ids? */
5354 uint16 groupid
= buf
->ReadWord();
5355 if (!IsValidGroupID(groupid
, "FeatureMapSpriteGroup")) return;
5357 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature
);
5359 AddGenericCallback(feature
, _cur
.grffile
, _cur
.spritegroups
[groupid
]);
5363 /* Mark the feature as used by the grf (generic callbacks do not count) */
5364 SetBit(_cur
.grffile
->grf_features
, feature
);
5366 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature
, idcount
);
5370 case GSF_ROADVEHICLES
:
5373 VehicleMapSpriteGroup(buf
, feature
, idcount
);
5377 CanalMapSpriteGroup(buf
, idcount
);
5381 StationMapSpriteGroup(buf
, idcount
);
5385 TownHouseMapSpriteGroup(buf
, idcount
);
5388 case GSF_INDUSTRIES
:
5389 IndustryMapSpriteGroup(buf
, idcount
);
5392 case GSF_INDUSTRYTILES
:
5393 IndustrytileMapSpriteGroup(buf
, idcount
);
5397 CargoMapSpriteGroup(buf
, idcount
);
5401 AirportMapSpriteGroup(buf
, idcount
);
5405 ObjectMapSpriteGroup(buf
, idcount
);
5409 RailTypeMapSpriteGroup(buf
, idcount
);
5412 case GSF_AIRPORTTILES
:
5413 AirportTileMapSpriteGroup(buf
, idcount
);
5417 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature
);
5423 static void FeatureNewName(ByteReader
*buf
)
5425 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5427 * B veh-type see action 0 (as 00..07, + 0A
5428 * But IF veh-type = 48, then generic text
5429 * B language-id If bit 6 is set, This is the extended language scheme,
5430 * with up to 64 language.
5431 * Otherwise, it is a mapping where set bits have meaning
5432 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5433 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5434 * B num-veh number of vehicles which are getting a new name
5435 * B/W offset number of the first vehicle that gets a new name
5436 * Byte : ID of vehicle to change
5437 * Word : ID of string to change/add
5438 * S data new texts, each of them zero-terminated, after
5439 * which the next name begins. */
5441 bool new_scheme
= _cur
.grffile
->grf_version
>= 7;
5443 uint8 feature
= buf
->ReadByte();
5444 uint8 lang
= buf
->ReadByte();
5445 uint8 num
= buf
->ReadByte();
5446 bool generic
= HasBit(lang
, 7);
5449 id
= buf
->ReadWord();
5450 } else if (feature
<= GSF_AIRCRAFT
) {
5451 id
= buf
->ReadExtendedByte();
5453 id
= buf
->ReadByte();
5458 uint16 endid
= id
+ num
;
5460 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5461 id
, endid
, feature
, lang
);
5463 for (; id
< endid
&& buf
->HasData(); id
++) {
5464 const char *name
= buf
->ReadString();
5465 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id
, name
);
5469 case GSF_ROADVEHICLES
:
5473 Engine
*e
= GetNewEngine(_cur
.grffile
, (VehicleType
)feature
, id
, HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
));
5474 if (e
== NULL
) break;
5475 StringID string
= AddGRFString(_cur
.grffile
->grfid
, e
->index
, lang
, new_scheme
, false, name
, e
->info
.string_id
);
5476 e
->info
.string_id
= string
;
5478 AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, true, name
, STR_UNDEFINED
);
5483 if (IsInsideMM(id
, 0xD000, 0xD400) || IsInsideMM(id
, 0xD800, 0xE000)) {
5484 AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, true, name
, STR_UNDEFINED
);
5488 switch (GB(id
, 8, 8)) {
5489 case 0xC4: // Station class name
5490 if (_cur
.grffile
->stations
== NULL
|| _cur
.grffile
->stations
[GB(id
, 0, 8)] == NULL
) {
5491 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id
, 0, 8));
5493 StationClassID cls_id
= _cur
.grffile
->stations
[GB(id
, 0, 8)]->cls_id
;
5494 StationClass::Get(cls_id
)->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5498 case 0xC5: // Station name
5499 if (_cur
.grffile
->stations
== NULL
|| _cur
.grffile
->stations
[GB(id
, 0, 8)] == NULL
) {
5500 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id
, 0, 8));
5502 _cur
.grffile
->stations
[GB(id
, 0, 8)]->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5506 case 0xC7: // Airporttile name
5507 if (_cur
.grffile
->airtspec
== NULL
|| _cur
.grffile
->airtspec
[GB(id
, 0, 8)] == NULL
) {
5508 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id
, 0, 8));
5510 _cur
.grffile
->airtspec
[GB(id
, 0, 8)]->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5514 case 0xC9: // House name
5515 if (_cur
.grffile
->housespec
== NULL
|| _cur
.grffile
->housespec
[GB(id
, 0, 8)] == NULL
) {
5516 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id
, 0, 8));
5518 _cur
.grffile
->housespec
[GB(id
, 0, 8)]->building_name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5523 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id
);
5532 * Sanitize incoming sprite offsets for Action 5 graphics replacements.
5533 * @param num The number of sprites to load.
5534 * @param offset Offset from the base.
5535 * @param max_sprites The maximum number of sprites that can be loaded in this action 5.
5536 * @param name Used for error warnings.
5537 * @return The number of sprites that is going to be skipped.
5539 static uint16
SanitizeSpriteOffset(uint16
& num
, uint16 offset
, int max_sprites
, const char *name
)
5542 if (offset
>= max_sprites
) {
5543 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name
, max_sprites
);
5544 uint orig_num
= num
;
5549 if (offset
+ num
> max_sprites
) {
5550 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name
);
5551 uint orig_num
= num
;
5552 num
= max(max_sprites
- offset
, 0);
5553 return orig_num
- num
;
5560 /** The type of action 5 type. */
5561 enum Action5BlockType
{
5562 A5BLOCK_FIXED
, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5563 A5BLOCK_ALLOW_OFFSET
, ///< Allow replacing any subset by specifiing an offset.
5564 A5BLOCK_INVALID
, ///< unknown/not-implemented type
5566 /** Information about a single action 5 type. */
5567 struct Action5Type
{
5568 Action5BlockType block_type
; ///< How is this Action5 type processed?
5569 SpriteID sprite_base
; ///< Load the sprites starting from this sprite.
5570 uint16 min_sprites
; ///< If the Action5 contains less sprites, the whole block will be ignored.
5571 uint16 max_sprites
; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5572 const char *name
; ///< Name for error messages.
5575 /** The information about action 5 types. */
5576 static const Action5Type _action5_types
[] = {
5577 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5578 /* 0x00 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x00" },
5579 /* 0x01 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x01" },
5580 /* 0x02 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x02" },
5581 /* 0x03 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x03" },
5582 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET
, SPR_SIGNALS_BASE
, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT
, "Signal graphics" },
5583 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ELRAIL_BASE
, 1, ELRAIL_SPRITE_COUNT
, "Rail catenary graphics" },
5584 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET
, SPR_SLOPES_BASE
, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT
, "Foundation graphics" },
5585 /* 0x07 */ { A5BLOCK_INVALID
, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5586 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET
, SPR_CANALS_BASE
, 1, CANALS_SPRITE_COUNT
, "Canal graphics" },
5587 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ONEWAY_BASE
, 1, ONEWAY_SPRITE_COUNT
, "One way road graphics" },
5588 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET
, SPR_2CCMAP_BASE
, 1, TWOCCMAP_SPRITE_COUNT
, "2CC colour maps" },
5589 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET
, SPR_TRAMWAY_BASE
, 1, TRAMWAY_SPRITE_COUNT
, "Tramway graphics" },
5590 /* 0x0C */ { A5BLOCK_INVALID
, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5591 /* 0x0D */ { A5BLOCK_FIXED
, SPR_SHORE_BASE
, 16, SPR_SHORE_SPRITE_COUNT
, "Shore graphics" },
5592 /* 0x0E */ { A5BLOCK_INVALID
, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5593 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET
, SPR_TRACKS_FOR_SLOPES_BASE
, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT
, "Sloped rail track" },
5594 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AIRPORTX_BASE
, 1, AIRPORTX_SPRITE_COUNT
, "Airport graphics" },
5595 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ROADSTOP_BASE
, 1, ROADSTOP_SPRITE_COUNT
, "Road stop graphics" },
5596 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AQUEDUCT_BASE
, 1, AQUEDUCT_SPRITE_COUNT
, "Aqueduct graphics" },
5597 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AUTORAIL_BASE
, 1, AUTORAIL_SPRITE_COUNT
, "Autorail graphics" },
5598 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET
, SPR_FLAGS_BASE
, 1, FLAGS_SPRITE_COUNT
, "Flag graphics" },
5599 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET
, SPR_OPENTTD_BASE
, 1, OPENTTD_SPRITE_COUNT
, "OpenTTD GUI graphics" },
5600 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AIRPORT_PREVIEW_BASE
, 1, SPR_AIRPORT_PREVIEW_COUNT
, "Airport preview graphics" },
5601 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET
, SPR_RAILTYPE_TUNNEL_BASE
, 1, RAILTYPE_TUNNEL_BASE_COUNT
, "Railtype tunnel base" },
5602 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET
, SPR_PALETTE_BASE
, 1, PALETTE_SPRITE_COUNT
, "Palette" },
5606 static void GraphicsNew(ByteReader
*buf
)
5608 /* <05> <graphics-type> <num-sprites> <other data...>
5610 * B graphics-type What set of graphics the sprites define.
5611 * E num-sprites How many sprites are in this set?
5612 * V other data Graphics type specific data. Currently unused. */
5615 uint8 type
= buf
->ReadByte();
5616 uint16 num
= buf
->ReadExtendedByte();
5617 uint16 offset
= HasBit(type
, 7) ? buf
->ReadExtendedByte() : 0;
5618 ClrBit(type
, 7); // Clear the high bit as that only indicates whether there is an offset.
5620 if ((type
== 0x0D) && (num
== 10) && HasBit(_cur
.grfconfig
->flags
, GCF_SYSTEM
)) {
5621 /* Special not-TTDP-compatible case used in openttd.grf
5622 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5623 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5624 LoadNextSprite(SPR_SHORE_BASE
+ 0, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_S
5625 LoadNextSprite(SPR_SHORE_BASE
+ 5, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_W
5626 LoadNextSprite(SPR_SHORE_BASE
+ 7, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_WSE
5627 LoadNextSprite(SPR_SHORE_BASE
+ 10, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_N
5628 LoadNextSprite(SPR_SHORE_BASE
+ 11, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_NWS
5629 LoadNextSprite(SPR_SHORE_BASE
+ 13, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_ENW
5630 LoadNextSprite(SPR_SHORE_BASE
+ 14, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_SEN
5631 LoadNextSprite(SPR_SHORE_BASE
+ 15, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_E
5632 LoadNextSprite(SPR_SHORE_BASE
+ 16, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_EW
5633 LoadNextSprite(SPR_SHORE_BASE
+ 17, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_NS
5634 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_NONE
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ONLY_NEW
;
5638 /* Supported type? */
5639 if ((type
>= lengthof(_action5_types
)) || (_action5_types
[type
].block_type
== A5BLOCK_INVALID
)) {
5640 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type
, num
);
5641 _cur
.skip_sprites
= num
;
5645 const Action5Type
*action5_type
= &_action5_types
[type
];
5647 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5648 * except for the long version of the shore type:
5649 * Ignore offset if not allowed */
5650 if ((action5_type
->block_type
!= A5BLOCK_ALLOW_OFFSET
) && (offset
!= 0)) {
5651 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type
->name
, type
);
5655 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5656 * This does not make sense, if <offset> is allowed */
5657 if ((action5_type
->block_type
== A5BLOCK_FIXED
) && (num
< action5_type
->min_sprites
)) {
5658 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
);
5659 _cur
.skip_sprites
= num
;
5663 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5664 uint16 skip_num
= SanitizeSpriteOffset(num
, offset
, action5_type
->max_sprites
, action5_type
->name
);
5665 SpriteID replace
= action5_type
->sprite_base
+ offset
;
5667 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5668 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
);
5670 for (; num
> 0; num
--) {
5672 LoadNextSprite(replace
== 0 ? _cur
.spriteid
++ : replace
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
5675 if (type
== 0x0D) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_5
;
5677 _cur
.skip_sprites
= skip_num
;
5680 /* Action 0x05 (SKIP) */
5681 static void SkipAct5(ByteReader
*buf
)
5683 /* Ignore type byte */
5686 /* Skip the sprites of this action */
5687 _cur
.skip_sprites
= buf
->ReadExtendedByte();
5689 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur
.skip_sprites
);
5693 * Reads a variable common to VarAction2 and Action7/9/D.
5695 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5696 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5698 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5699 * @param value returns the value of the variable.
5700 * @param grffile NewGRF querying the variable
5701 * @return true iff the variable is known and the value is returned in 'value'.
5703 bool GetGlobalVariable(byte param
, uint32
*value
, const GRFFile
*grffile
)
5706 case 0x00: // current date
5707 *value
= max(_date
- DAYS_TILL_ORIGINAL_BASE_YEAR
, 0);
5710 case 0x01: // current year
5711 *value
= Clamp(_cur_year
, ORIGINAL_BASE_YEAR
, ORIGINAL_MAX_YEAR
) - ORIGINAL_BASE_YEAR
;
5714 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)
5716 ConvertDateToYMD(_date
, &ymd
);
5717 Date start_of_year
= ConvertYMDToDate(ymd
.year
, 0, 1);
5718 *value
= ymd
.month
| (ymd
.day
- 1) << 8 | (IsLeapYear(ymd
.year
) ? 1 << 15 : 0) | (_date
- start_of_year
) << 16;
5722 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5723 *value
= _settings_game
.game_creation
.landscape
;
5726 case 0x06: // road traffic side, bit 4 clear=left, set=right
5727 *value
= _settings_game
.vehicle
.road_side
<< 4;
5730 case 0x09: // date fraction
5731 *value
= _date_fract
* 885;
5734 case 0x0A: // animation counter
5735 *value
= _tick_counter
;
5738 case 0x0B: { // TTDPatch version
5741 uint revision
= 1; // special case: 2.0.1 is 2.0.10
5743 *value
= (major
<< 24) | (minor
<< 20) | (revision
<< 16) | build
;
5747 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5748 *value
= _cur
.grfconfig
->palette
& GRFP_USE_MASK
;
5751 case 0x0E: // Y-offset for train sprites
5752 *value
= _cur
.grffile
->traininfo_vehicle_pitch
;
5755 case 0x0F: // Rail track type cost factors
5757 SB(*value
, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL
)->cost_multiplier
); // normal rail
5758 if (_settings_game
.vehicle
.disable_elrails
) {
5759 /* skip elrail multiplier - disabled */
5760 SB(*value
, 8, 8, GetRailTypeInfo(RAILTYPE_MONO
)->cost_multiplier
); // monorail
5762 SB(*value
, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC
)->cost_multiplier
); // electified railway
5763 /* Skip monorail multiplier - no space in result */
5765 SB(*value
, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV
)->cost_multiplier
); // maglev
5768 case 0x11: // current rail tool type
5769 *value
= 0; // constant fake value to avoid desync
5772 case 0x12: // Game mode
5773 *value
= _game_mode
;
5776 /* case 0x13: // Tile refresh offset to left not implemented */
5777 /* case 0x14: // Tile refresh offset to right not implemented */
5778 /* case 0x15: // Tile refresh offset upwards not implemented */
5779 /* case 0x16: // Tile refresh offset downwards not implemented */
5780 /* case 0x17: // temperate snow line not implemented */
5782 case 0x1A: // Always -1
5786 case 0x1B: // Display options
5787 *value
= 0x3F; // constant fake value to avoid desync
5790 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5794 case 0x1E: // Miscellaneous GRF features
5795 *value
= _misc_grf_features
;
5797 /* Add the local flags */
5798 assert(!HasBit(*value
, GMB_TRAIN_WIDTH_32_PIXELS
));
5799 if (_cur
.grffile
->traininfo_vehicle_width
== VEHICLEINFO_FULL_VEHICLE_WIDTH
) SetBit(*value
, GMB_TRAIN_WIDTH_32_PIXELS
);
5802 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5804 case 0x20: { // snow line height
5805 byte snowline
= GetSnowLine();
5806 if (_settings_game
.game_creation
.landscape
== LT_ARCTIC
&& snowline
<= _settings_game
.construction
.max_heightlevel
) {
5807 *value
= Clamp(snowline
* (grffile
->grf_version
>= 8 ? 1 : TILE_HEIGHT
), 0, 0xFE);
5815 case 0x21: // OpenTTD version
5816 *value
= _openttd_newgrf_version
;
5819 case 0x22: // difficulty level
5823 case 0x23: // long format date
5827 case 0x24: // long format year
5831 default: return false;
5835 static uint32
GetParamVal(byte param
, uint32
*cond_val
)
5837 /* First handle variable common with VarAction2 */
5839 if (GetGlobalVariable(param
- 0x80, &value
, _cur
.grffile
)) return value
;
5841 /* Non-common variable */
5843 case 0x84: { // GRF loading stage
5846 if (_cur
.stage
> GLS_INIT
) SetBit(res
, 0);
5847 if (_cur
.stage
== GLS_RESERVE
) SetBit(res
, 8);
5848 if (_cur
.stage
== GLS_ACTIVATION
) SetBit(res
, 9);
5852 case 0x85: // TTDPatch flags, only for bit tests
5853 if (cond_val
== NULL
) {
5854 /* Supported in Action 0x07 and 0x09, not 0x0D */
5857 uint32 param_val
= _ttdpatch_flags
[*cond_val
/ 0x20];
5862 case 0x88: // GRF ID check
5865 /* case 0x99: Global ID offset not implemented */
5869 if (param
< 0x80) return _cur
.grffile
->GetParam(param
);
5871 /* In-game variable. */
5872 grfmsg(1, "Unsupported in-game variable 0x%02X", param
);
5878 static void CfgApply(ByteReader
*buf
)
5880 /* <06> <param-num> <param-size> <offset> ... <FF>
5882 * B param-num Number of parameter to substitute (First = "zero")
5883 * Ignored if that parameter was not specified in newgrf.cfg
5884 * B param-size How many bytes to replace. If larger than 4, the
5885 * bytes of the following parameter are used. In that
5886 * case, nothing is applied unless *all* parameters
5888 * B offset Offset into data from beginning of next sprite
5889 * to place where parameter is to be stored. */
5891 /* Preload the next sprite */
5892 size_t pos
= FioGetPos();
5893 uint32 num
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
5894 uint8 type
= FioReadByte();
5895 byte
*preload_sprite
= NULL
;
5897 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5899 preload_sprite
= MallocT
<byte
>(num
);
5900 FioReadBlock(preload_sprite
, num
);
5903 /* Reset the file position to the start of the next sprite */
5904 FioSeekTo(pos
, SEEK_SET
);
5907 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5908 free(preload_sprite
);
5912 GRFLocation
location(_cur
.grfconfig
->ident
.grfid
, _cur
.nfo_line
+ 1);
5913 GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.find(location
);
5914 if (it
!= _grf_line_to_action6_sprite_override
.end()) {
5915 free(preload_sprite
);
5916 preload_sprite
= _grf_line_to_action6_sprite_override
[location
];
5918 _grf_line_to_action6_sprite_override
[location
] = preload_sprite
;
5921 /* Now perform the Action 0x06 on our data. */
5930 /* Read the parameter to apply. 0xFF indicates no more data to change. */
5931 param_num
= buf
->ReadByte();
5932 if (param_num
== 0xFF) break;
5934 /* Get the size of the parameter to use. If the size covers multiple
5935 * double words, sequential parameter values are used. */
5936 param_size
= buf
->ReadByte();
5938 /* Bit 7 of param_size indicates we should add to the original value
5939 * instead of replacing it. */
5940 add_value
= HasBit(param_size
, 7);
5941 param_size
= GB(param_size
, 0, 7);
5943 /* Where to apply the data to within the pseudo sprite data. */
5944 offset
= buf
->ReadExtendedByte();
5946 /* If the parameter is a GRF parameter (not an internal variable) check
5947 * if it (and all further sequential parameters) has been defined. */
5948 if (param_num
< 0x80 && (param_num
+ (param_size
- 1) / 4) >= _cur
.grffile
->param_end
) {
5949 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num
+ (param_size
- 1) / 4));
5953 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size
, param_num
, offset
);
5956 for (i
= 0; i
< param_size
&& offset
+ i
< num
; i
++) {
5957 uint32 value
= GetParamVal(param_num
+ i
/ 4, NULL
);
5958 /* Reset carry flag for each iteration of the variable (only really
5959 * matters if param_size is greater than 4) */
5960 if (i
% 4 == 0) carry
= false;
5963 uint new_value
= preload_sprite
[offset
+ i
] + GB(value
, (i
% 4) * 8, 8) + (carry
? 1 : 0);
5964 preload_sprite
[offset
+ i
] = GB(new_value
, 0, 8);
5965 /* Check if the addition overflowed */
5966 carry
= new_value
>= 256;
5968 preload_sprite
[offset
+ i
] = GB(value
, (i
% 4) * 8, 8);
5975 * Disable a static NewGRF when it is influencing another (non-static)
5976 * NewGRF as this could cause desyncs.
5978 * We could just tell the NewGRF querying that the file doesn't exist,
5979 * but that might give unwanted results. Disabling the NewGRF gives the
5980 * best result as no NewGRF author can complain about that.
5981 * @param c The NewGRF to disable.
5983 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig
*c
)
5985 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC
, c
);
5986 error
->data
= stredup(_cur
.grfconfig
->GetName());
5991 static void SkipIf(ByteReader
*buf
)
5993 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6000 /* TODO: More params. More condition types. */
6001 uint32 cond_val
= 0;
6005 uint8 param
= buf
->ReadByte();
6006 uint8 paramsize
= buf
->ReadByte();
6007 uint8 condtype
= buf
->ReadByte();
6010 /* Always 1 for bit tests, the given value should be ignored. */
6014 switch (paramsize
) {
6015 case 8: cond_val
= buf
->ReadDWord(); mask
= buf
->ReadDWord(); break;
6016 case 4: cond_val
= buf
->ReadDWord(); mask
= 0xFFFFFFFF; break;
6017 case 2: cond_val
= buf
->ReadWord(); mask
= 0x0000FFFF; break;
6018 case 1: cond_val
= buf
->ReadByte(); mask
= 0x000000FF; break;
6022 if (param
< 0x80 && _cur
.grffile
->param_end
<= param
) {
6023 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param
);
6027 uint32 param_val
= GetParamVal(param
, &cond_val
);
6029 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype
, param_val
, cond_val
);
6032 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6033 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6034 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6035 * So, when the condition type is one of those, the specific variable
6036 * 0x88 code is skipped, so the "general" code for the cargo
6037 * availability conditions kicks in.
6039 if (param
== 0x88 && (condtype
< 0x0B || condtype
> 0x0E)) {
6042 GRFConfig
*c
= GetGRFConfig(cond_val
, mask
);
6044 if (c
!= NULL
&& HasBit(c
->flags
, GCF_STATIC
) && !HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
) && _networking
) {
6045 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c
);
6049 if (condtype
!= 10 && c
== NULL
) {
6050 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val
));
6055 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6056 case 0x06: // Is GRFID active?
6057 result
= c
->status
== GCS_ACTIVATED
;
6060 case 0x07: // Is GRFID non-active?
6061 result
= c
->status
!= GCS_ACTIVATED
;
6064 case 0x08: // GRFID is not but will be active?
6065 result
= c
->status
== GCS_INITIALISED
;
6068 case 0x09: // GRFID is or will be active?
6069 result
= c
->status
== GCS_ACTIVATED
|| c
->status
== GCS_INITIALISED
;
6072 case 0x0A: // GRFID is not nor will be active
6073 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6074 result
= c
== NULL
|| c
->status
== GCS_DISABLED
|| c
->status
== GCS_NOT_FOUND
;
6077 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype
); return;
6080 /* Parameter or variable tests */
6082 case 0x00: result
= !!(param_val
& (1 << cond_val
));
6084 case 0x01: result
= !(param_val
& (1 << cond_val
));
6086 case 0x02: result
= (param_val
& mask
) == cond_val
;
6088 case 0x03: result
= (param_val
& mask
) != cond_val
;
6090 case 0x04: result
= (param_val
& mask
) < cond_val
;
6092 case 0x05: result
= (param_val
& mask
) > cond_val
;
6094 case 0x0B: result
= GetCargoIDByLabel(BSWAP32(cond_val
)) == CT_INVALID
;
6096 case 0x0C: result
= GetCargoIDByLabel(BSWAP32(cond_val
)) != CT_INVALID
;
6098 case 0x0D: result
= GetRailTypeByLabel(BSWAP32(cond_val
)) == INVALID_RAILTYPE
;
6100 case 0x0E: result
= GetRailTypeByLabel(BSWAP32(cond_val
)) != INVALID_RAILTYPE
;
6103 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype
); return;
6108 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6112 uint8 numsprites
= buf
->ReadByte();
6114 /* numsprites can be a GOTO label if it has been defined in the GRF
6115 * file. The jump will always be the first matching label that follows
6116 * the current nfo_line. If no matching label is found, the first matching
6117 * label in the file is used. */
6118 GRFLabel
*choice
= NULL
;
6119 for (GRFLabel
*label
= _cur
.grffile
->label
; label
!= NULL
; label
= label
->next
) {
6120 if (label
->label
!= numsprites
) continue;
6122 /* Remember a goto before the current line */
6123 if (choice
== NULL
) choice
= label
;
6124 /* If we find a label here, this is definitely good */
6125 if (label
->nfo_line
> _cur
.nfo_line
) {
6131 if (choice
!= NULL
) {
6132 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice
->label
, choice
->nfo_line
);
6133 FioSeekTo(choice
->pos
, SEEK_SET
);
6134 _cur
.nfo_line
= choice
->nfo_line
;
6138 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites
);
6139 _cur
.skip_sprites
= numsprites
;
6140 if (_cur
.skip_sprites
== 0) {
6141 /* Zero means there are no sprites to skip, so
6142 * we use -1 to indicate that all further
6143 * sprites should be skipped. */
6144 _cur
.skip_sprites
= -1;
6146 /* If an action 8 hasn't been encountered yet, disable the grf. */
6147 if (_cur
.grfconfig
->status
!= (_cur
.stage
< GLS_RESERVE
? GCS_INITIALISED
: GCS_ACTIVATED
)) {
6154 /* Action 0x08 (GLS_FILESCAN) */
6155 static void ScanInfo(ByteReader
*buf
)
6157 uint8 grf_version
= buf
->ReadByte();
6158 uint32 grfid
= buf
->ReadDWord();
6159 const char *name
= buf
->ReadString();
6161 _cur
.grfconfig
->ident
.grfid
= grfid
;
6163 if (grf_version
< 2 || grf_version
> 8) {
6164 SetBit(_cur
.grfconfig
->flags
, GCF_INVALID
);
6165 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
);
6168 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6169 if (GB(grfid
, 0, 8) == 0xFF) SetBit(_cur
.grfconfig
->flags
, GCF_SYSTEM
);
6171 AddGRFTextToList(&_cur
.grfconfig
->name
->text
, 0x7F, grfid
, false, name
);
6173 if (buf
->HasData()) {
6174 const char *info
= buf
->ReadString();
6175 AddGRFTextToList(&_cur
.grfconfig
->info
->text
, 0x7F, grfid
, true, info
);
6178 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6179 _cur
.skip_sprites
= -1;
6183 static void GRFInfo(ByteReader
*buf
)
6185 /* <08> <version> <grf-id> <name> <info>
6187 * B version newgrf version, currently 06
6188 * 4*B grf-id globally unique ID of this .grf file
6189 * S name name of this .grf set
6190 * S info string describing the set, and e.g. author and copyright */
6192 uint8 version
= buf
->ReadByte();
6193 uint32 grfid
= buf
->ReadDWord();
6194 const char *name
= buf
->ReadString();
6196 if (_cur
.stage
< GLS_RESERVE
&& _cur
.grfconfig
->status
!= GCS_UNKNOWN
) {
6197 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8
);
6201 if (_cur
.grffile
->grfid
!= grfid
) {
6202 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
));
6203 _cur
.grffile
->grfid
= grfid
;
6206 _cur
.grffile
->grf_version
= version
;
6207 _cur
.grfconfig
->status
= _cur
.stage
< GLS_RESERVE
? GCS_INITIALISED
: GCS_ACTIVATED
;
6209 /* Do swap the GRFID for displaying purposes since people expect that */
6210 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
);
6214 static void SpriteReplace(ByteReader
*buf
)
6216 /* <0A> <num-sets> <set1> [<set2> ...]
6217 * <set>: <num-sprites> <first-sprite>
6219 * B num-sets How many sets of sprites to replace.
6221 * B num-sprites How many sprites are in this set
6222 * W first-sprite First sprite number to replace */
6224 uint8 num_sets
= buf
->ReadByte();
6226 for (uint i
= 0; i
< num_sets
; i
++) {
6227 uint8 num_sprites
= buf
->ReadByte();
6228 uint16 first_sprite
= buf
->ReadWord();
6230 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6231 i
, num_sprites
, first_sprite
6234 for (uint j
= 0; j
< num_sprites
; j
++) {
6235 int load_index
= first_sprite
+ j
;
6237 LoadNextSprite(load_index
, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
); // XXX
6239 /* Shore sprites now located at different addresses.
6240 * So detect when the old ones get replaced. */
6241 if (IsInsideMM(load_index
, SPR_ORIGINALSHORE_START
, SPR_ORIGINALSHORE_END
+ 1)) {
6242 if (_loaded_newgrf_features
.shore
!= SHORE_REPLACE_ACTION_5
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_A
;
6248 /* Action 0x0A (SKIP) */
6249 static void SkipActA(ByteReader
*buf
)
6251 uint8 num_sets
= buf
->ReadByte();
6253 for (uint i
= 0; i
< num_sets
; i
++) {
6254 /* Skip the sprites this replaces */
6255 _cur
.skip_sprites
+= buf
->ReadByte();
6256 /* But ignore where they go */
6260 grfmsg(3, "SkipActA: Skipping %d sprites", _cur
.skip_sprites
);
6264 static void GRFLoadError(ByteReader
*buf
)
6266 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6268 * B severity 00: notice, contine loading grf file
6269 * 01: warning, continue loading grf file
6270 * 02: error, but continue loading grf file, and attempt
6271 * loading grf again when loading or starting next game
6272 * 03: error, abort loading and prevent loading again in
6273 * the future (only when restarting the patch)
6274 * B language-id see action 4, use 1F for built-in error messages
6275 * B message-id message to show, see below
6276 * S message for custom messages (message-id FF), text of the message
6277 * not present for built-in messages.
6278 * V data additional data for built-in (or custom) messages
6279 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6281 static const StringID msgstr
[] = {
6282 STR_NEWGRF_ERROR_VERSION_NUMBER
,
6283 STR_NEWGRF_ERROR_DOS_OR_WINDOWS
,
6284 STR_NEWGRF_ERROR_UNSET_SWITCH
,
6285 STR_NEWGRF_ERROR_INVALID_PARAMETER
,
6286 STR_NEWGRF_ERROR_LOAD_BEFORE
,
6287 STR_NEWGRF_ERROR_LOAD_AFTER
,
6288 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER
,
6291 static const StringID sevstr
[] = {
6292 STR_NEWGRF_ERROR_MSG_INFO
,
6293 STR_NEWGRF_ERROR_MSG_WARNING
,
6294 STR_NEWGRF_ERROR_MSG_ERROR
,
6295 STR_NEWGRF_ERROR_MSG_FATAL
6298 byte severity
= buf
->ReadByte();
6299 byte lang
= buf
->ReadByte();
6300 byte message_id
= buf
->ReadByte();
6302 /* Skip the error if it isn't valid for the current language. */
6303 if (!CheckGrfLangID(lang
, _cur
.grffile
->grf_version
)) return;
6305 /* Skip the error until the activation stage unless bit 7 of the severity
6307 if (!HasBit(severity
, 7) && _cur
.stage
== GLS_INIT
) {
6308 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur
.stage
);
6311 ClrBit(severity
, 7);
6313 if (severity
>= lengthof(sevstr
)) {
6314 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity
);
6316 } else if (severity
== 3) {
6317 /* This is a fatal error, so make sure the GRF is deactivated and no
6318 * more of it gets loaded. */
6321 /* Make sure we show fatal errors, instead of silly infos from before */
6322 delete _cur
.grfconfig
->error
;
6323 _cur
.grfconfig
->error
= NULL
;
6326 if (message_id
>= lengthof(msgstr
) && message_id
!= 0xFF) {
6327 grfmsg(7, "GRFLoadError: Invalid message id.");
6331 if (buf
->Remaining() <= 1) {
6332 grfmsg(7, "GRFLoadError: No message data supplied.");
6336 /* For now we can only show one message per newgrf file. */
6337 if (_cur
.grfconfig
->error
!= NULL
) return;
6339 GRFError
*error
= new GRFError(sevstr
[severity
]);
6341 if (message_id
== 0xFF) {
6342 /* This is a custom error message. */
6343 if (buf
->HasData()) {
6344 const char *message
= buf
->ReadString();
6346 error
->custom_message
= TranslateTTDPatchCodes(_cur
.grffile
->grfid
, lang
, true, message
, NULL
, SCC_RAW_STRING_POINTER
);
6348 grfmsg(7, "GRFLoadError: No custom message supplied.");
6349 error
->custom_message
= stredup("");
6352 error
->message
= msgstr
[message_id
];
6355 if (buf
->HasData()) {
6356 const char *data
= buf
->ReadString();
6358 error
->data
= TranslateTTDPatchCodes(_cur
.grffile
->grfid
, lang
, true, data
);
6360 grfmsg(7, "GRFLoadError: No message data supplied.");
6361 error
->data
= stredup("");
6364 /* Only two parameter numbers can be used in the string. */
6365 for (uint i
= 0; i
< lengthof(error
->param_value
) && buf
->HasData(); i
++) {
6366 uint param_number
= buf
->ReadByte();
6367 error
->param_value
[i
] = _cur
.grffile
->GetParam(param_number
);
6370 _cur
.grfconfig
->error
= error
;
6374 static void GRFComment(ByteReader
*buf
)
6376 /* <0C> [<ignored...>]
6378 * V ignored Anything following the 0C is ignored */
6380 if (!buf
->HasData()) return;
6382 const char *text
= buf
->ReadString();
6383 grfmsg(2, "GRFComment: %s", text
);
6386 /* Action 0x0D (GLS_SAFETYSCAN) */
6387 static void SafeParamSet(ByteReader
*buf
)
6389 uint8 target
= buf
->ReadByte();
6391 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6392 if (target
< 0x80 || target
== 0x9E) return;
6394 /* GRM could be unsafe, but as here it can only happen after other GRFs
6395 * are loaded, it should be okay. If the GRF tried to use the slots it
6396 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6397 * sprites is considered safe. */
6399 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
6401 /* Skip remainder of GRF */
6402 _cur
.skip_sprites
= -1;
6406 static uint32
GetPatchVariable(uint8 param
)
6409 /* start year - 1920 */
6410 case 0x0B: return max(_settings_game
.game_creation
.starting_year
, ORIGINAL_BASE_YEAR
) - ORIGINAL_BASE_YEAR
;
6412 /* freight trains weight factor */
6413 case 0x0E: return _settings_game
.vehicle
.freight_trains
;
6415 /* empty wagon speed increase */
6416 case 0x0F: return 0;
6418 /* plane speed factor; our patch option is reversed from TTDPatch's,
6419 * the following is good for 1x, 2x and 4x (most common?) and...
6420 * well not really for 3x. */
6422 switch (_settings_game
.vehicle
.plane_speed
) {
6431 /* 2CC colourmap base sprite */
6432 case 0x11: return SPR_2CCMAP_BASE
;
6434 /* map size: format = -MABXYSS
6435 * M : the type of map
6436 * bit 0 : set : squared map. Bit 1 is now not relevant
6437 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6438 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6439 * clear : X is the bigger edge.
6440 * A : minimum edge(log2) of the map
6441 * B : maximum edge(log2) of the map
6442 * XY : edges(log2) of each side of the map.
6443 * SS : combination of both X and Y, thus giving the size(log2) of the map
6447 byte log_X
= MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6448 byte log_Y
= MapLogY() - 6;
6449 byte max_edge
= max(log_X
, log_Y
);
6451 if (log_X
== log_Y
) { // we have a squared map, since both edges are identical
6452 SetBit(map_bits
, 0);
6454 if (max_edge
== log_Y
) SetBit(map_bits
, 1); // edge Y been the biggest, mark it
6457 return (map_bits
<< 24) | (min(log_X
, log_Y
) << 20) | (max_edge
<< 16) |
6458 (log_X
<< 12) | (log_Y
<< 8) | (log_X
+ log_Y
);
6461 /* The maximum height of the map. */
6463 return _settings_game
.construction
.max_heightlevel
;
6465 /* Extra foundations base sprite */
6467 return SPR_SLOPES_BASE
;
6469 /* Shore base sprite */
6471 return SPR_SHORE_BASE
;
6474 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param
);
6480 static uint32
PerformGRM(uint32
*grm
, uint16 num_ids
, uint16 count
, uint8 op
, uint8 target
, const char *type
)
6486 /* Return GRFID of set that reserved ID */
6487 return grm
[_cur
.grffile
->GetParam(target
)];
6490 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6491 if (op
== 2 || op
== 3) start
= _cur
.grffile
->GetParam(target
);
6493 for (uint i
= start
; i
< num_ids
; i
++) {
6497 if (op
== 2 || op
== 3) break;
6502 if (size
== count
) break;
6505 if (size
== count
) {
6506 /* Got the slot... */
6507 if (op
== 0 || op
== 3) {
6508 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count
, type
, start
);
6509 for (uint i
= 0; i
< count
; i
++) grm
[start
+ i
] = _cur
.grffile
->grfid
;
6514 /* Unable to allocate */
6515 if (op
!= 4 && op
!= 5) {
6516 /* Deactivate GRF */
6517 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count
, type
);
6518 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED
);
6522 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count
, type
);
6527 /** Action 0x0D: Set parameter */
6528 static void ParamSet(ByteReader
*buf
)
6530 /* <0D> <target> <operation> <source1> <source2> [<data>]
6532 * B target parameter number where result is stored
6533 * B operation operation to perform, see below
6534 * B source1 first source operand
6535 * B source2 second source operand
6536 * D data data to use in the calculation, not necessary
6537 * if both source1 and source2 refer to actual parameters
6540 * 00 Set parameter equal to source1
6541 * 01 Addition, source1 + source2
6542 * 02 Subtraction, source1 - source2
6543 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6544 * 04 Signed multiplication, source1 * source2 (both signed)
6545 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6546 * signed quantity; left shift if positive and right shift if
6547 * negative, source1 is unsigned)
6548 * 06 Signed bit shift, source1 by source2
6549 * (source2 like in 05, and source1 as well)
6552 uint8 target
= buf
->ReadByte();
6553 uint8 oper
= buf
->ReadByte();
6554 uint32 src1
= buf
->ReadByte();
6555 uint32 src2
= buf
->ReadByte();
6558 if (buf
->Remaining() >= 4) data
= buf
->ReadDWord();
6560 /* You can add 80 to the operation to make it apply only if the target
6561 * is not defined yet. In this respect, a parameter is taken to be
6562 * defined if any of the following applies:
6563 * - it has been set to any value in the newgrf(w).cfg parameter list
6564 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6565 * an earlier action D */
6566 if (HasBit(oper
, 7)) {
6567 if (target
< 0x80 && target
< _cur
.grffile
->param_end
) {
6568 grfmsg(7, "ParamSet: Param %u already defined, skipping", target
);
6572 oper
= GB(oper
, 0, 7);
6576 if (GB(data
, 0, 8) == 0xFF) {
6577 if (data
== 0x0000FFFF) {
6578 /* Patch variables */
6579 src1
= GetPatchVariable(src1
);
6581 /* GRF Resource Management */
6583 uint8 feature
= GB(data
, 8, 8);
6584 uint16 count
= GB(data
, 16, 16);
6586 if (_cur
.stage
== GLS_RESERVE
) {
6587 if (feature
== 0x08) {
6588 /* General sprites */
6590 /* Check if the allocated sprites will fit below the original sprite limit */
6591 if (_cur
.spriteid
+ count
>= 16384) {
6592 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count
);
6593 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED
);
6597 /* Reserve space at the current sprite ID */
6598 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count
, _cur
.spriteid
);
6599 _grm_sprites
[GRFLocation(_cur
.grffile
->grfid
, _cur
.nfo_line
)] = _cur
.spriteid
;
6600 _cur
.spriteid
+= count
;
6603 /* Ignore GRM result during reservation */
6605 } else if (_cur
.stage
== GLS_ACTIVATION
) {
6607 case 0x00: // Trains
6608 case 0x01: // Road Vehicles
6610 case 0x03: // Aircraft
6611 if (!_settings_game
.vehicle
.dynamic_engines
) {
6612 src1
= PerformGRM(&_grm_engines
[_engine_offsets
[feature
]], _engine_counts
[feature
], count
, op
, target
, "vehicles");
6613 if (_cur
.skip_sprites
== -1) return;
6615 /* GRM does not apply for dynamic engine allocation. */
6619 src1
= _cur
.grffile
->GetParam(target
);
6629 case 0x08: // General sprites
6632 /* Return space reserved during reservation stage */
6633 src1
= _grm_sprites
[GRFLocation(_cur
.grffile
->grfid
, _cur
.nfo_line
)];
6634 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1
);
6638 src1
= _cur
.spriteid
;
6642 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op
);
6648 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6649 src1
= PerformGRM(_grm_cargoes
, NUM_CARGO
* 2, count
, op
, target
, "cargoes");
6650 if (_cur
.skip_sprites
== -1) return;
6653 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature
); return;
6656 /* Ignore GRM during initialization */
6661 /* Read another GRF File's parameter */
6662 const GRFFile
*file
= GetFileByGRFID(data
);
6663 GRFConfig
*c
= GetGRFConfig(data
);
6664 if (c
!= NULL
&& HasBit(c
->flags
, GCF_STATIC
) && !HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
) && _networking
) {
6665 /* Disable the read GRF if it is a static NewGRF. */
6666 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c
);
6668 } else if (file
== NULL
|| c
== NULL
|| c
->status
== GCS_DISABLED
) {
6670 } else if (src1
== 0xFE) {
6673 src1
= file
->GetParam(src1
);
6677 /* The source1 and source2 operands refer to the grf parameter number
6678 * like in action 6 and 7. In addition, they can refer to the special
6679 * variables available in action 7, or they can be FF to use the value
6680 * of <data>. If referring to parameters that are undefined, a value
6681 * of 0 is used instead. */
6682 src1
= (src1
== 0xFF) ? data
: GetParamVal(src1
, NULL
);
6683 src2
= (src2
== 0xFF) ? data
: GetParamVal(src2
, NULL
);
6686 /* TODO: You can access the parameters of another GRF file by using
6687 * source2=FE, source1=the other GRF's parameter number and data=GRF
6688 * ID. This is only valid with operation 00 (set). If the GRF ID
6689 * cannot be found, a value of 0 is used for the parameter value
6711 res
= (int32
)src1
* (int32
)src2
;
6715 if ((int32
)src2
< 0) {
6716 res
= src1
>> -(int32
)src2
;
6718 res
= src1
<< (src2
& 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6723 if ((int32
)src2
< 0) {
6724 res
= (int32
)src1
>> -(int32
)src2
;
6726 res
= (int32
)src1
<< (src2
& 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6730 case 0x07: // Bitwise AND
6734 case 0x08: // Bitwise OR
6738 case 0x09: // Unsigned division
6746 case 0x0A: // Signed divison
6750 res
= (int32
)src1
/ (int32
)src2
;
6754 case 0x0B: // Unsigned modulo
6762 case 0x0C: // Signed modulo
6766 res
= (int32
)src1
% (int32
)src2
;
6770 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper
); return;
6774 case 0x8E: // Y-Offset for train sprites
6775 _cur
.grffile
->traininfo_vehicle_pitch
= res
;
6778 case 0x8F: { // Rail track type cost factors
6779 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
6780 _railtypes
[RAILTYPE_RAIL
].cost_multiplier
= GB(res
, 0, 8);
6781 if (_settings_game
.vehicle
.disable_elrails
) {
6782 _railtypes
[RAILTYPE_ELECTRIC
].cost_multiplier
= GB(res
, 0, 8);
6783 _railtypes
[RAILTYPE_MONO
].cost_multiplier
= GB(res
, 8, 8);
6785 _railtypes
[RAILTYPE_ELECTRIC
].cost_multiplier
= GB(res
, 8, 8);
6786 _railtypes
[RAILTYPE_MONO
].cost_multiplier
= GB(res
, 16, 8);
6788 _railtypes
[RAILTYPE_MAGLEV
].cost_multiplier
= GB(res
, 16, 8);
6792 /* @todo implement */
6793 case 0x93: // Tile refresh offset to left
6794 case 0x94: // Tile refresh offset to right
6795 case 0x95: // Tile refresh offset upwards
6796 case 0x96: // Tile refresh offset downwards
6797 case 0x97: // Snow line height
6798 case 0x99: // Global ID offset
6799 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target
);
6802 case 0x9E: // Miscellaneous GRF features
6803 /* Set train list engine width */
6804 _cur
.grffile
->traininfo_vehicle_width
= HasBit(res
, GMB_TRAIN_WIDTH_32_PIXELS
) ? VEHICLEINFO_FULL_VEHICLE_WIDTH
: TRAININFO_DEFAULT_VEHICLE_WIDTH
;
6805 /* Remove the local flags from the global flags */
6806 ClrBit(res
, GMB_TRAIN_WIDTH_32_PIXELS
);
6808 /* Only copy safe bits for static grfs */
6809 if (HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
)) {
6810 uint32 safe_bits
= 0;
6811 SetBit(safe_bits
, GMB_SECOND_ROCKY_TILE_SET
);
6813 _misc_grf_features
= (_misc_grf_features
& ~safe_bits
) | (res
& safe_bits
);
6815 _misc_grf_features
= res
;
6819 case 0x9F: // locale-dependent settings
6820 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target
);
6824 if (target
< 0x80) {
6825 _cur
.grffile
->param
[target
] = res
;
6826 /* param is zeroed by default */
6827 if (target
+ 1U > _cur
.grffile
->param_end
) _cur
.grffile
->param_end
= target
+ 1;
6829 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target
);
6835 /* Action 0x0E (GLS_SAFETYSCAN) */
6836 static void SafeGRFInhibit(ByteReader
*buf
)
6838 /* <0E> <num> <grfids...>
6840 * B num Number of GRFIDs that follow
6841 * D grfids GRFIDs of the files to deactivate */
6843 uint8 num
= buf
->ReadByte();
6845 for (uint i
= 0; i
< num
; i
++) {
6846 uint32 grfid
= buf
->ReadDWord();
6848 /* GRF is unsafe it if tries to deactivate other GRFs */
6849 if (grfid
!= _cur
.grfconfig
->ident
.grfid
) {
6850 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
6852 /* Skip remainder of GRF */
6853 _cur
.skip_sprites
= -1;
6861 static void GRFInhibit(ByteReader
*buf
)
6863 /* <0E> <num> <grfids...>
6865 * B num Number of GRFIDs that follow
6866 * D grfids GRFIDs of the files to deactivate */
6868 uint8 num
= buf
->ReadByte();
6870 for (uint i
= 0; i
< num
; i
++) {
6871 uint32 grfid
= buf
->ReadDWord();
6872 GRFConfig
*file
= GetGRFConfig(grfid
);
6874 /* Unset activation flag */
6875 if (file
!= NULL
&& file
!= _cur
.grfconfig
) {
6876 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file
->filename
);
6877 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED
, file
);
6878 error
->data
= stredup(_cur
.grfconfig
->GetName());
6883 /** Action 0x0F - Define Town names */
6884 static void FeatureTownName(ByteReader
*buf
)
6886 /* <0F> <id> <style-name> <num-parts> <parts>
6888 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6889 * V style-name Name of the style (only for final definition)
6890 * B num-parts Number of parts in this definition
6891 * V parts The parts */
6893 uint32 grfid
= _cur
.grffile
->grfid
;
6895 GRFTownName
*townname
= AddGRFTownName(grfid
);
6897 byte id
= buf
->ReadByte();
6898 grfmsg(6, "FeatureTownName: definition 0x%02X", id
& 0x7F);
6900 if (HasBit(id
, 7)) {
6901 /* Final definition */
6903 bool new_scheme
= _cur
.grffile
->grf_version
>= 7;
6905 byte lang
= buf
->ReadByte();
6907 byte nb_gen
= townname
->nb_gen
;
6911 const char *name
= buf
->ReadString();
6913 char *lang_name
= TranslateTTDPatchCodes(grfid
, lang
, false, name
);
6914 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang
, lang_name
);
6917 townname
->name
[nb_gen
] = AddGRFString(grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
6919 lang
= buf
->ReadByte();
6920 } while (lang
!= 0);
6921 townname
->id
[nb_gen
] = id
;
6925 byte nb
= buf
->ReadByte();
6926 grfmsg(6, "FeatureTownName: %u parts", nb
);
6928 townname
->nbparts
[id
] = nb
;
6929 townname
->partlist
[id
] = CallocT
<NamePartList
>(nb
);
6931 for (int i
= 0; i
< nb
; i
++) {
6932 byte nbtext
= buf
->ReadByte();
6933 townname
->partlist
[id
][i
].bitstart
= buf
->ReadByte();
6934 townname
->partlist
[id
][i
].bitcount
= buf
->ReadByte();
6935 townname
->partlist
[id
][i
].maxprob
= 0;
6936 townname
->partlist
[id
][i
].partcount
= nbtext
;
6937 townname
->partlist
[id
][i
].parts
= CallocT
<NamePart
>(nbtext
);
6938 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
);
6940 for (int j
= 0; j
< nbtext
; j
++) {
6941 byte prob
= buf
->ReadByte();
6943 if (HasBit(prob
, 7)) {
6944 byte ref_id
= buf
->ReadByte();
6946 if (townname
->nbparts
[ref_id
] == 0) {
6947 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id
);
6948 DelGRFTownName(grfid
);
6949 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID
);
6953 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i
, j
, ref_id
, prob
& 0x7F);
6954 townname
->partlist
[id
][i
].parts
[j
].data
.id
= ref_id
;
6956 const char *text
= buf
->ReadString();
6957 townname
->partlist
[id
][i
].parts
[j
].data
.text
= TranslateTTDPatchCodes(grfid
, 0, false, text
);
6958 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i
, j
, townname
->partlist
[id
][i
].parts
[j
].data
.text
, prob
);
6960 townname
->partlist
[id
][i
].parts
[j
].prob
= prob
;
6961 townname
->partlist
[id
][i
].maxprob
+= GB(prob
, 0, 7);
6963 grfmsg(6, "FeatureTownName: part %d, total probability %d", i
, townname
->partlist
[id
][i
].maxprob
);
6967 /** Action 0x10 - Define goto label */
6968 static void DefineGotoLabel(ByteReader
*buf
)
6970 /* <10> <label> [<comment>]
6972 * B label The label to define
6973 * V comment Optional comment - ignored */
6975 byte nfo_label
= buf
->ReadByte();
6977 GRFLabel
*label
= MallocT
<GRFLabel
>(1);
6978 label
->label
= nfo_label
;
6979 label
->nfo_line
= _cur
.nfo_line
;
6980 label
->pos
= FioGetPos();
6983 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
6984 if (_cur
.grffile
->label
== NULL
) {
6985 _cur
.grffile
->label
= label
;
6987 /* Attach the label to the end of the list */
6989 for (l
= _cur
.grffile
->label
; l
->next
!= NULL
; l
= l
->next
) {}
6993 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label
->label
);
6997 * Process a sound import from another GRF file.
6998 * @param sound Destination for sound.
7000 static void ImportGRFSound(SoundEntry
*sound
)
7002 const GRFFile
*file
;
7003 uint32 grfid
= FioReadDword();
7004 SoundID sound_id
= FioReadWord();
7006 file
= GetFileByGRFID(grfid
);
7007 if (file
== NULL
|| file
->sound_offset
== 0) {
7008 grfmsg(1, "ImportGRFSound: Source file not available");
7012 if (sound_id
>= file
->num_sounds
) {
7013 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id
);
7017 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id
, file
->sound_offset
+ sound_id
, grfid
);
7019 *sound
= *GetSound(file
->sound_offset
+ sound_id
);
7021 /* Reset volume and priority, which TTDPatch doesn't copy */
7022 sound
->volume
= 128;
7023 sound
->priority
= 0;
7027 * Load a sound from a file.
7028 * @param offs File offset to read sound from.
7029 * @param sound Destination for sound.
7031 static void LoadGRFSound(size_t offs
, SoundEntry
*sound
)
7033 /* Set default volume and priority */
7034 sound
->volume
= 0x80;
7035 sound
->priority
= 0;
7037 if (offs
!= SIZE_MAX
) {
7038 /* Sound is present in the NewGRF. */
7039 sound
->file_slot
= _cur
.file_index
;
7040 sound
->file_offset
= offs
;
7041 sound
->grf_container_ver
= _cur
.grf_container_ver
;
7046 static void GRFSound(ByteReader
*buf
)
7050 * W num Number of sound files that follow */
7052 uint16 num
= buf
->ReadWord();
7053 if (num
== 0) return;
7056 if (_cur
.grffile
->sound_offset
== 0) {
7057 _cur
.grffile
->sound_offset
= GetNumSounds();
7058 _cur
.grffile
->num_sounds
= num
;
7059 sound
= AllocateSound(num
);
7061 sound
= GetSound(_cur
.grffile
->sound_offset
);
7064 for (int i
= 0; i
< num
; i
++) {
7067 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7068 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7069 bool invalid
= i
>= _cur
.grffile
->num_sounds
;
7071 size_t offs
= FioGetPos();
7073 uint32 len
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
7074 byte type
= FioReadByte();
7076 if (_cur
.grf_container_ver
>= 2 && type
== 0xFD) {
7077 /* Reference to sprite section. */
7079 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7081 } else if (len
!= 4) {
7082 grfmsg(1, "GRFSound: Invalid sprite section import");
7085 uint32 id
= FioReadDword();
7086 if (_cur
.stage
== GLS_INIT
) LoadGRFSound(GetGRFSpriteOffset(id
), sound
+ i
);
7092 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7094 SkipSpriteData(type
, len
- 8);
7099 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7103 byte action
= FioReadByte();
7106 /* Allocate sound only in init stage. */
7107 if (_cur
.stage
== GLS_INIT
) {
7108 if (_cur
.grf_container_ver
>= 2) {
7109 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7111 LoadGRFSound(offs
, sound
+ i
);
7114 FioSkipBytes(len
- 1); // already read <action>
7118 if (_cur
.stage
== GLS_ACTIVATION
) {
7119 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7120 * importing sounds, so this is probably all wrong... */
7121 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7122 ImportGRFSound(sound
+ i
);
7124 FioSkipBytes(len
- 1); // already read <action>
7129 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action
);
7130 FioSkipBytes(len
- 1); // already read <action>
7136 /* Action 0x11 (SKIP) */
7137 static void SkipAct11(ByteReader
*buf
)
7141 * W num Number of sound files that follow */
7143 _cur
.skip_sprites
= buf
->ReadWord();
7145 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur
.skip_sprites
);
7149 static void LoadFontGlyph(ByteReader
*buf
)
7151 /* <12> <num_def> <font_size> <num_char> <base_char>
7153 * B num_def Number of definitions
7154 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7155 * B num_char Number of consecutive glyphs
7156 * W base_char First character index */
7158 uint8 num_def
= buf
->ReadByte();
7160 for (uint i
= 0; i
< num_def
; i
++) {
7161 FontSize size
= (FontSize
)buf
->ReadByte();
7162 uint8 num_char
= buf
->ReadByte();
7163 uint16 base_char
= buf
->ReadWord();
7165 if (size
>= FS_END
) {
7166 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size
);
7169 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char
, base_char
, size
);
7171 for (uint c
= 0; c
< num_char
; c
++) {
7172 if (size
< FS_END
) SetUnicodeGlyph(size
, base_char
+ c
, _cur
.spriteid
);
7174 LoadNextSprite(_cur
.spriteid
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
7179 /** Action 0x12 (SKIP) */
7180 static void SkipAct12(ByteReader
*buf
)
7182 /* <12> <num_def> <font_size> <num_char> <base_char>
7184 * B num_def Number of definitions
7185 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7186 * B num_char Number of consecutive glyphs
7187 * W base_char First character index */
7189 uint8 num_def
= buf
->ReadByte();
7191 for (uint i
= 0; i
< num_def
; i
++) {
7192 /* Ignore 'size' byte */
7195 /* Sum up number of characters */
7196 _cur
.skip_sprites
+= buf
->ReadByte();
7198 /* Ignore 'base_char' word */
7202 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur
.skip_sprites
);
7206 static void TranslateGRFStrings(ByteReader
*buf
)
7208 /* <13> <grfid> <num-ent> <offset> <text...>
7210 * 4*B grfid The GRFID of the file whose texts are to be translated
7211 * B num-ent Number of strings
7212 * W offset First text ID
7213 * S text... Zero-terminated strings */
7215 uint32 grfid
= buf
->ReadDWord();
7216 const GRFConfig
*c
= GetGRFConfig(grfid
);
7217 if (c
== NULL
|| (c
->status
!= GCS_INITIALISED
&& c
->status
!= GCS_ACTIVATED
)) {
7218 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid
));
7222 if (c
->status
== GCS_INITIALISED
) {
7223 /* If the file is not active but will be activated later, give an error
7224 * and disable this file. */
7225 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER
);
7228 GetString(tmp
, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE
, lastof(tmp
));
7229 error
->data
= stredup(tmp
);
7234 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7235 * to be added as a generic string, thus the language id of 0x7F. For this to work
7236 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7237 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7238 * not change anything if a string has been provided specifically for this language. */
7239 byte language
= _cur
.grffile
->grf_version
>= 8 ? buf
->ReadByte() : 0x7F;
7240 byte num_strings
= buf
->ReadByte();
7241 uint16 first_id
= buf
->ReadWord();
7243 if (!((first_id
>= 0xD000 && first_id
+ num_strings
<= 0xD400) || (first_id
>= 0xD800 && first_id
+ num_strings
<= 0xE000))) {
7244 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id
, num_strings
);
7248 for (uint i
= 0; i
< num_strings
&& buf
->HasData(); i
++) {
7249 const char *string
= buf
->ReadString();
7251 if (StrEmpty(string
)) {
7252 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7256 AddGRFString(grfid
, first_id
+ i
, language
, true, true, string
, STR_UNDEFINED
);
7260 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7261 static bool ChangeGRFName(byte langid
, const char *str
)
7263 AddGRFTextToList(&_cur
.grfconfig
->name
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7267 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7268 static bool ChangeGRFDescription(byte langid
, const char *str
)
7270 AddGRFTextToList(&_cur
.grfconfig
->info
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, true, str
);
7274 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7275 static bool ChangeGRFURL(byte langid
, const char *str
)
7277 AddGRFTextToList(&_cur
.grfconfig
->url
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7281 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7282 static bool ChangeGRFNumUsedParams(size_t len
, ByteReader
*buf
)
7285 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len
);
7288 _cur
.grfconfig
->num_valid_params
= min(buf
->ReadByte(), lengthof(_cur
.grfconfig
->param
));
7293 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7294 static bool ChangeGRFPalette(size_t len
, ByteReader
*buf
)
7297 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len
);
7300 char data
= buf
->ReadByte();
7301 GRFPalette pal
= GRFP_GRF_UNSET
;
7304 case 'A': pal
= GRFP_GRF_ANY
; break;
7305 case 'W': pal
= GRFP_GRF_WINDOWS
; break;
7306 case 'D': pal
= GRFP_GRF_DOS
; break;
7308 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data
);
7311 if (pal
!= GRFP_GRF_UNSET
) {
7312 _cur
.grfconfig
->palette
&= ~GRFP_GRF_MASK
;
7313 _cur
.grfconfig
->palette
|= pal
;
7319 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7320 static bool ChangeGRFBlitter(size_t len
, ByteReader
*buf
)
7323 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len
);
7326 char data
= buf
->ReadByte();
7327 GRFPalette pal
= GRFP_BLT_UNSET
;
7329 case '8': pal
= GRFP_BLT_UNSET
; break;
7330 case '3': pal
= GRFP_BLT_32BPP
; break;
7332 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data
);
7335 _cur
.grfconfig
->palette
&= ~GRFP_BLT_MASK
;
7336 _cur
.grfconfig
->palette
|= pal
;
7341 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7342 static bool ChangeGRFVersion(size_t len
, ByteReader
*buf
)
7345 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len
);
7348 /* Set min_loadable_version as well (default to minimal compatibility) */
7349 _cur
.grfconfig
->version
= _cur
.grfconfig
->min_loadable_version
= buf
->ReadDWord();
7354 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7355 static bool ChangeGRFMinVersion(size_t len
, ByteReader
*buf
)
7358 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len
);
7361 _cur
.grfconfig
->min_loadable_version
= buf
->ReadDWord();
7362 if (_cur
.grfconfig
->version
== 0) {
7363 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7364 _cur
.grfconfig
->min_loadable_version
= 0;
7366 if (_cur
.grfconfig
->version
< _cur
.grfconfig
->min_loadable_version
) {
7367 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur
.grfconfig
->min_loadable_version
);
7368 _cur
.grfconfig
->min_loadable_version
= _cur
.grfconfig
->version
;
7374 static GRFParameterInfo
*_cur_parameter
; ///< The parameter which info is currently changed by the newgrf.
7376 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7377 static bool ChangeGRFParamName(byte langid
, const char *str
)
7379 AddGRFTextToList(&_cur_parameter
->name
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7383 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7384 static bool ChangeGRFParamDescription(byte langid
, const char *str
)
7386 AddGRFTextToList(&_cur_parameter
->desc
, langid
, _cur
.grfconfig
->ident
.grfid
, true, str
);
7390 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7391 static bool ChangeGRFParamType(size_t len
, ByteReader
*buf
)
7394 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len
);
7397 GRFParameterType type
= (GRFParameterType
)buf
->ReadByte();
7398 if (type
< PTYPE_END
) {
7399 _cur_parameter
->type
= type
;
7401 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type
);
7407 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7408 static bool ChangeGRFParamLimits(size_t len
, ByteReader
*buf
)
7410 if (_cur_parameter
->type
!= PTYPE_UINT_ENUM
) {
7411 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7413 } else if (len
!= 8) {
7414 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len
);
7417 _cur_parameter
->min_value
= buf
->ReadDWord();
7418 _cur_parameter
->max_value
= buf
->ReadDWord();
7423 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7424 static bool ChangeGRFParamMask(size_t len
, ByteReader
*buf
)
7426 if (len
< 1 || len
> 3) {
7427 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len
);
7430 byte param_nr
= buf
->ReadByte();
7431 if (param_nr
>= lengthof(_cur
.grfconfig
->param
)) {
7432 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr
);
7435 _cur_parameter
->param_nr
= param_nr
;
7436 if (len
>= 2) _cur_parameter
->first_bit
= min(buf
->ReadByte(), 31);
7437 if (len
>= 3) _cur_parameter
->num_bit
= min(buf
->ReadByte(), 32 - _cur_parameter
->first_bit
);
7444 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7445 static bool ChangeGRFParamDefault(size_t len
, ByteReader
*buf
)
7448 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len
);
7451 _cur_parameter
->def_value
= buf
->ReadDWord();
7453 _cur
.grfconfig
->has_param_defaults
= true;
7457 typedef bool (*DataHandler
)(size_t, ByteReader
*); ///< Type of callback function for binary nodes
7458 typedef bool (*TextHandler
)(byte
, const char *str
); ///< Type of callback function for text nodes
7459 typedef bool (*BranchHandler
)(ByteReader
*); ///< Type of callback function for branch nodes
7462 * Data structure to store the allowed id/type combinations for action 14. The
7463 * data can be represented as a tree with 3 types of nodes:
7464 * 1. Branch nodes (identified by 'C' for choice).
7465 * 2. Binary leaf nodes (identified by 'B').
7466 * 3. Text leaf nodes (identified by 'T').
7468 struct AllowedSubtags
{
7469 /** Create empty subtags object used to identify the end of a list. */
7476 * Create a binary leaf node.
7477 * @param id The id for this node.
7478 * @param handler The callback function to call.
7480 AllowedSubtags(uint32 id
, DataHandler handler
) :
7484 this->handler
.data
= handler
;
7488 * Create a text leaf node.
7489 * @param id The id for this node.
7490 * @param handler The callback function to call.
7492 AllowedSubtags(uint32 id
, TextHandler handler
) :
7496 this->handler
.text
= handler
;
7500 * Create a branch node with a callback handler
7501 * @param id The id for this node.
7502 * @param handler The callback function to call.
7504 AllowedSubtags(uint32 id
, BranchHandler handler
) :
7508 this->handler
.call_handler
= true;
7509 this->handler
.u
.branch
= handler
;
7513 * Create a branch node with a list of sub-nodes.
7514 * @param id The id for this node.
7515 * @param subtags Array with all valid subtags.
7517 AllowedSubtags(uint32 id
, AllowedSubtags
*subtags
) :
7521 this->handler
.call_handler
= false;
7522 this->handler
.u
.subtags
= subtags
;
7525 uint32 id
; ///< The identifier for this node
7526 byte type
; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7528 DataHandler data
; ///< Callback function for a binary node, only valid if type == 'B'.
7529 TextHandler text
; ///< Callback function for a text node, only valid if type == 'T'.
7532 BranchHandler branch
; ///< Callback function for a branch node, only valid if type == 'C' && call_handler.
7533 AllowedSubtags
*subtags
; ///< Pointer to a list of subtags, only valid if type == 'C' && !call_handler.
7535 bool call_handler
; ///< True if there is a callback function for this node, false if there is a list of subnodes.
7540 static bool SkipUnknownInfo(ByteReader
*buf
, byte type
);
7541 static bool HandleNodes(ByteReader
*buf
, AllowedSubtags
*tags
);
7544 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7545 * of some parameter values (type uint/enum) or the names of some bits
7546 * (type bitmask). In both cases the format is the same:
7547 * Each subnode should be a text node with the value/bit number as id.
7549 static bool ChangeGRFParamValueNames(ByteReader
*buf
)
7551 byte type
= buf
->ReadByte();
7553 uint32 id
= buf
->ReadDWord();
7554 if (type
!= 'T' || id
> _cur_parameter
->max_value
) {
7555 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7556 if (!SkipUnknownInfo(buf
, type
)) return false;
7557 type
= buf
->ReadByte();
7561 byte langid
= buf
->ReadByte();
7562 const char *name_string
= buf
->ReadString();
7564 SmallPair
<uint32
, GRFText
*> *val_name
= _cur_parameter
->value_names
.Find(id
);
7565 if (val_name
!= _cur_parameter
->value_names
.End()) {
7566 AddGRFTextToList(&val_name
->second
, langid
, _cur
.grfconfig
->ident
.grfid
, false, name_string
);
7568 GRFText
*list
= NULL
;
7569 AddGRFTextToList(&list
, langid
, _cur
.grfconfig
->ident
.grfid
, false, name_string
);
7570 _cur_parameter
->value_names
.Insert(id
, list
);
7573 type
= buf
->ReadByte();
7578 /** Action14 parameter tags */
7579 AllowedSubtags _tags_parameters
[] = {
7580 AllowedSubtags('NAME', ChangeGRFParamName
),
7581 AllowedSubtags('DESC', ChangeGRFParamDescription
),
7582 AllowedSubtags('TYPE', ChangeGRFParamType
),
7583 AllowedSubtags('LIMI', ChangeGRFParamLimits
),
7584 AllowedSubtags('MASK', ChangeGRFParamMask
),
7585 AllowedSubtags('VALU', ChangeGRFParamValueNames
),
7586 AllowedSubtags('DFLT', ChangeGRFParamDefault
),
7591 * Callback function for 'INFO'->'PARA' to set extra information about the
7592 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7593 * the parameter number as id. The first parameter has id 0. The maximum
7594 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7596 static bool HandleParameterInfo(ByteReader
*buf
)
7598 byte type
= buf
->ReadByte();
7600 uint32 id
= buf
->ReadDWord();
7601 if (type
!= 'C' || id
>= _cur
.grfconfig
->num_valid_params
) {
7602 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7603 if (!SkipUnknownInfo(buf
, type
)) return false;
7604 type
= buf
->ReadByte();
7608 if (id
>= _cur
.grfconfig
->param_info
.Length()) {
7609 uint num_to_add
= id
- _cur
.grfconfig
->param_info
.Length() + 1;
7610 GRFParameterInfo
**newdata
= _cur
.grfconfig
->param_info
.Append(num_to_add
);
7611 MemSetT
<GRFParameterInfo
*>(newdata
, 0, num_to_add
);
7613 if (_cur
.grfconfig
->param_info
[id
] == NULL
) {
7614 _cur
.grfconfig
->param_info
[id
] = new GRFParameterInfo(id
);
7616 _cur_parameter
= _cur
.grfconfig
->param_info
[id
];
7617 /* Read all parameter-data and process each node. */
7618 if (!HandleNodes(buf
, _tags_parameters
)) return false;
7619 type
= buf
->ReadByte();
7624 /** Action14 tags for the INFO node */
7625 AllowedSubtags _tags_info
[] = {
7626 AllowedSubtags('NAME', ChangeGRFName
),
7627 AllowedSubtags('DESC', ChangeGRFDescription
),
7628 AllowedSubtags('URL_', ChangeGRFURL
),
7629 AllowedSubtags('NPAR', ChangeGRFNumUsedParams
),
7630 AllowedSubtags('PALS', ChangeGRFPalette
),
7631 AllowedSubtags('BLTR', ChangeGRFBlitter
),
7632 AllowedSubtags('VRSN', ChangeGRFVersion
),
7633 AllowedSubtags('MINV', ChangeGRFMinVersion
),
7634 AllowedSubtags('PARA', HandleParameterInfo
),
7638 /** Action14 root tags */
7639 AllowedSubtags _tags_root
[] = {
7640 AllowedSubtags('INFO', _tags_info
),
7646 * Try to skip the current node and all subnodes (if it's a branch node).
7647 * @param buf Buffer.
7648 * @param type The node type to skip.
7649 * @return True if we could skip the node, false if an error occurred.
7651 static bool SkipUnknownInfo(ByteReader
*buf
, byte type
)
7653 /* type and id are already read */
7656 byte new_type
= buf
->ReadByte();
7657 while (new_type
!= 0) {
7658 buf
->ReadDWord(); // skip the id
7659 if (!SkipUnknownInfo(buf
, new_type
)) return false;
7660 new_type
= buf
->ReadByte();
7666 buf
->ReadByte(); // lang
7667 buf
->ReadString(); // actual text
7671 uint16 size
= buf
->ReadWord();
7684 * Handle the nodes of an Action14
7685 * @param type Type of node.
7687 * @param buf Buffer.
7688 * @param subtags Allowed subtags.
7689 * @return Whether all tags could be handled.
7691 static bool HandleNode(byte type
, uint32 id
, ByteReader
*buf
, AllowedSubtags subtags
[])
7694 AllowedSubtags
*tag
;
7695 while ((tag
= &subtags
[i
++])->type
!= 0) {
7696 if (tag
->id
!= BSWAP32(id
) || tag
->type
!= type
) continue;
7698 default: NOT_REACHED();
7701 byte langid
= buf
->ReadByte();
7702 return tag
->handler
.text(langid
, buf
->ReadString());
7706 size_t len
= buf
->ReadWord();
7707 if (buf
->Remaining() < len
) return false;
7708 return tag
->handler
.data(len
, buf
);
7712 if (tag
->handler
.call_handler
) {
7713 return tag
->handler
.u
.branch(buf
);
7715 return HandleNodes(buf
, tag
->handler
.u
.subtags
);
7719 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type
, id
);
7720 return SkipUnknownInfo(buf
, type
);
7724 * Handle the contents of a 'C' choice of an Action14
7725 * @param buf Buffer.
7726 * @param subtags List of subtags.
7727 * @return Whether the nodes could all be handled.
7729 static bool HandleNodes(ByteReader
*buf
, AllowedSubtags subtags
[])
7731 byte type
= buf
->ReadByte();
7733 uint32 id
= buf
->ReadDWord();
7734 if (!HandleNode(type
, id
, buf
, subtags
)) return false;
7735 type
= buf
->ReadByte();
7741 * Handle Action 0x14
7742 * @param buf Buffer.
7744 static void StaticGRFInfo(ByteReader
*buf
)
7746 /* <14> <type> <id> <text/data...> */
7747 HandleNodes(buf
, _tags_root
);
7751 * Set the current NewGRF as unsafe for static use
7752 * @param buf Unused.
7753 * @note Used during safety scan on unsafe actions.
7755 static void GRFUnsafe(ByteReader
*buf
)
7757 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
7759 /* Skip remainder of GRF */
7760 _cur
.skip_sprites
= -1;
7764 /** Initialize the TTDPatch flags */
7765 static void InitializeGRFSpecial()
7767 _ttdpatch_flags
[0] = ((_settings_game
.station
.never_expire_airports
? 1 : 0) << 0x0C) // keepsmallairport
7768 | (1 << 0x0D) // newairports
7769 | (1 << 0x0E) // largestations
7770 | ((_settings_game
.construction
.max_bridge_length
> 16 ? 1 : 0) << 0x0F) // longbridges
7771 | (0 << 0x10) // loadtime
7772 | (1 << 0x12) // presignals
7773 | (1 << 0x13) // extpresignals
7774 | ((_settings_game
.vehicle
.never_expire_vehicles
? 1 : 0) << 0x16) // enginespersist
7775 | (1 << 0x1B) // multihead
7776 | (1 << 0x1D) // lowmemory
7777 | (1 << 0x1E); // generalfixes
7779 _ttdpatch_flags
[1] = ((_settings_game
.economy
.station_noise_level
? 1 : 0) << 0x07) // moreairports - based on units of noise
7780 | (1 << 0x08) // mammothtrains
7781 | (1 << 0x09) // trainrefit
7782 | (0 << 0x0B) // subsidiaries
7783 | ((_settings_game
.order
.gradual_loading
? 1 : 0) << 0x0C) // gradualloading
7784 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7785 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7786 | (1 << 0x14) // bridgespeedlimits
7787 | (1 << 0x16) // eternalgame
7788 | (1 << 0x17) // newtrains
7789 | (1 << 0x18) // newrvs
7790 | (1 << 0x19) // newships
7791 | (1 << 0x1A) // newplanes
7792 | ((_settings_game
.construction
.train_signal_side
== 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7793 | ((_settings_game
.vehicle
.disable_elrails
? 0 : 1) << 0x1C); // electrifiedrailway
7795 _ttdpatch_flags
[2] = (1 << 0x01) // loadallgraphics - obsolote
7796 | (1 << 0x03) // semaphores
7797 | (1 << 0x0A) // newobjects
7798 | (0 << 0x0B) // enhancedgui
7799 | (0 << 0x0C) // newagerating
7800 | ((_settings_game
.construction
.build_on_slopes
? 1 : 0) << 0x0D) // buildonslopes
7801 | (1 << 0x0E) // fullloadany
7802 | (1 << 0x0F) // planespeed
7803 | (0 << 0x10) // moreindustriesperclimate - obsolete
7804 | (0 << 0x11) // moretoylandfeatures
7805 | (1 << 0x12) // newstations
7806 | (1 << 0x13) // tracktypecostdiff
7807 | (1 << 0x14) // manualconvert
7808 | ((_settings_game
.construction
.build_on_slopes
? 1 : 0) << 0x15) // buildoncoasts
7809 | (1 << 0x16) // canals
7810 | (1 << 0x17) // newstartyear
7811 | ((_settings_game
.vehicle
.freight_trains
> 1 ? 1 : 0) << 0x18) // freighttrains
7812 | (1 << 0x19) // newhouses
7813 | (1 << 0x1A) // newbridges
7814 | (1 << 0x1B) // newtownnames
7815 | (1 << 0x1C) // moreanimation
7816 | ((_settings_game
.vehicle
.wagon_speed_limits
? 1 : 0) << 0x1D) // wagonspeedlimits
7817 | (1 << 0x1E) // newshistory
7818 | (0 << 0x1F); // custombridgeheads
7820 _ttdpatch_flags
[3] = (0 << 0x00) // newcargodistribution
7821 | (1 << 0x01) // windowsnap
7822 | ((_settings_game
.economy
.allow_town_roads
|| _generating_world
? 0 : 1) << 0x02) // townbuildnoroad
7823 | (1 << 0x03) // pathbasedsignalling
7824 | (0 << 0x04) // aichoosechance
7825 | (1 << 0x05) // resolutionwidth
7826 | (1 << 0x06) // resolutionheight
7827 | (1 << 0x07) // newindustries
7828 | ((_settings_game
.order
.improved_load
? 1 : 0) << 0x08) // fifoloading
7829 | (0 << 0x09) // townroadbranchprob
7830 | (0 << 0x0A) // tempsnowline
7831 | (1 << 0x0B) // newcargo
7832 | (1 << 0x0C) // enhancemultiplayer
7833 | (1 << 0x0D) // onewayroads
7834 | (1 << 0x0E) // irregularstations
7835 | (1 << 0x0F) // statistics
7836 | (1 << 0x10) // newsounds
7837 | (1 << 0x11) // autoreplace
7838 | (1 << 0x12) // autoslope
7839 | (0 << 0x13) // followvehicle
7840 | (1 << 0x14) // trams
7841 | (0 << 0x15) // enhancetunnels
7842 | (1 << 0x16) // shortrvs
7843 | (1 << 0x17) // articulatedrvs
7844 | ((_settings_game
.vehicle
.dynamic_engines
? 1 : 0) << 0x18) // dynamic engines
7845 | (1 << 0x1E) // variablerunningcosts
7846 | (1 << 0x1F); // any switch is on
7849 /** Reset and clear all NewGRF stations */
7850 static void ResetCustomStations()
7852 const GRFFile
* const *end
= _grf_files
.End();
7853 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7854 StationSpec
**&stations
= (*file
)->stations
;
7855 if (stations
== NULL
) continue;
7856 for (uint i
= 0; i
< NUM_STATIONS_PER_GRF
; i
++) {
7857 if (stations
[i
] == NULL
) continue;
7858 StationSpec
*statspec
= stations
[i
];
7860 delete[] statspec
->renderdata
;
7862 /* Release platforms and layouts */
7863 if (!statspec
->copied_layouts
) {
7864 for (uint l
= 0; l
< statspec
->lengths
; l
++) {
7865 for (uint p
= 0; p
< statspec
->platforms
[l
]; p
++) {
7866 free(statspec
->layouts
[l
][p
]);
7868 free(statspec
->layouts
[l
]);
7870 free(statspec
->layouts
);
7871 free(statspec
->platforms
);
7874 /* Release this station */
7878 /* Free and reset the station data */
7884 /** Reset and clear all NewGRF houses */
7885 static void ResetCustomHouses()
7887 const GRFFile
* const *end
= _grf_files
.End();
7888 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7889 HouseSpec
**&housespec
= (*file
)->housespec
;
7890 if (housespec
== NULL
) continue;
7891 for (uint i
= 0; i
< NUM_HOUSES_PER_GRF
; i
++) {
7900 /** Reset and clear all NewGRF airports */
7901 static void ResetCustomAirports()
7903 const GRFFile
* const *end
= _grf_files
.End();
7904 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7905 AirportSpec
**aslist
= (*file
)->airportspec
;
7906 if (aslist
!= NULL
) {
7907 for (uint i
= 0; i
< NUM_AIRPORTS_PER_GRF
; i
++) {
7908 AirportSpec
*as
= aslist
[i
];
7911 /* We need to remove the tiles layouts */
7912 for (int j
= 0; j
< as
->num_table
; j
++) {
7913 /* remove the individual layouts */
7917 free(as
->depot_table
);
7924 (*file
)->airportspec
= NULL
;
7927 AirportTileSpec
**&airporttilespec
= (*file
)->airtspec
;
7928 if (airporttilespec
!= NULL
) {
7929 for (uint i
= 0; i
< NUM_AIRPORTTILES_PER_GRF
; i
++) {
7930 free(airporttilespec
[i
]);
7932 free(airporttilespec
);
7933 airporttilespec
= NULL
;
7938 /** Reset and clear all NewGRF industries */
7939 static void ResetCustomIndustries()
7941 const GRFFile
* const *end
= _grf_files
.End();
7942 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7943 IndustrySpec
**&industryspec
= (*file
)->industryspec
;
7944 IndustryTileSpec
**&indtspec
= (*file
)->indtspec
;
7946 /* We are verifiying both tiles and industries specs loaded from the grf file
7947 * First, let's deal with industryspec */
7948 if (industryspec
!= NULL
) {
7949 for (uint i
= 0; i
< NUM_INDUSTRYTYPES_PER_GRF
; i
++) {
7950 IndustrySpec
*ind
= industryspec
[i
];
7951 if (ind
== NULL
) continue;
7953 /* We need to remove the sounds array */
7954 if (HasBit(ind
->cleanup_flag
, CLEAN_RANDOMSOUNDS
)) {
7955 free(ind
->random_sounds
);
7958 /* We need to remove the tiles layouts */
7959 CleanIndustryTileTable(ind
);
7965 industryspec
= NULL
;
7968 if (indtspec
== NULL
) continue;
7969 for (uint i
= 0; i
< NUM_INDUSTRYTILES_PER_GRF
; i
++) {
7978 /** Reset and clear all NewObjects */
7979 static void ResetCustomObjects()
7981 const GRFFile
* const *end
= _grf_files
.End();
7982 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7983 ObjectSpec
**&objectspec
= (*file
)->objectspec
;
7984 if (objectspec
== NULL
) continue;
7985 for (uint i
= 0; i
< NUM_OBJECTS_PER_GRF
; i
++) {
7986 free(objectspec
[i
]);
7994 /** Reset and clear all NewGRFs */
7995 static void ResetNewGRF()
7997 const GRFFile
* const *end
= _grf_files
.End();
7998 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8003 _cur
.grffile
= NULL
;
8006 /** Clear all NewGRF errors */
8007 static void ResetNewGRFErrors()
8009 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
8010 if (!HasBit(c
->flags
, GCF_COPY
) && c
->error
!= NULL
) {
8018 * Reset all NewGRF loaded data
8021 void ResetNewGRFData()
8024 CleanUpGRFTownNames();
8026 /* Copy/reset original engine info data */
8029 /* Copy/reset original bridge info data */
8032 /* Reset rail type information */
8035 /* Allocate temporary refit/cargo class data */
8036 _gted
= CallocT
<GRFTempEngineData
>(Engine::GetPoolSize());
8038 /* Fill rail type label temporary data for default trains */
8040 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_TRAIN
) {
8041 _gted
[e
->index
].railtypelabel
= GetRailTypeInfo(e
->u
.rail
.railtype
)->label
;
8044 /* Reset GRM reservations */
8045 memset(&_grm_engines
, 0, sizeof(_grm_engines
));
8046 memset(&_grm_cargoes
, 0, sizeof(_grm_cargoes
));
8048 /* Reset generic feature callback lists */
8049 ResetGenericCallbacks();
8051 /* Reset price base data */
8052 ResetPriceBaseMultipliers();
8054 /* Reset the curencies array */
8057 /* Reset the house array */
8058 ResetCustomHouses();
8061 /* Reset the industries structures*/
8062 ResetCustomIndustries();
8065 /* Reset the objects. */
8066 ObjectClass::Reset();
8067 ResetCustomObjects();
8070 /* Reset station classes */
8071 StationClass::Reset();
8072 ResetCustomStations();
8074 /* Reset airport-related structures */
8075 AirportClass::Reset();
8076 ResetCustomAirports();
8077 AirportSpec::ResetAirports();
8078 AirportTileSpec::ResetAirportTiles();
8080 /* Reset canal sprite groups and flags */
8081 memset(_water_feature
, 0, sizeof(_water_feature
));
8083 /* Reset the snowline table. */
8086 /* Reset NewGRF files */
8089 /* Reset NewGRF errors. */
8090 ResetNewGRFErrors();
8092 /* Set up the default cargo types */
8093 SetupCargoForClimate(_settings_game
.game_creation
.landscape
);
8095 /* Reset misc GRF features and train list display variables */
8096 _misc_grf_features
= 0;
8098 _loaded_newgrf_features
.has_2CC
= false;
8099 _loaded_newgrf_features
.used_liveries
= 1 << LS_DEFAULT
;
8100 _loaded_newgrf_features
.has_newhouses
= false;
8101 _loaded_newgrf_features
.has_newindustries
= false;
8102 _loaded_newgrf_features
.shore
= SHORE_REPLACE_NONE
;
8104 /* Clear all GRF overrides */
8105 _grf_id_overrides
.clear();
8107 InitializeSoundPool();
8108 _spritegroup_pool
.CleanPool();
8112 * Reset NewGRF data which is stored persistently in savegames.
8114 void ResetPersistentNewGRFData()
8116 /* Reset override managers */
8117 _engine_mngr
.ResetToDefaultMapping();
8118 _house_mngr
.ResetMapping();
8119 _industry_mngr
.ResetMapping();
8120 _industile_mngr
.ResetMapping();
8121 _airport_mngr
.ResetMapping();
8122 _airporttile_mngr
.ResetMapping();
8126 * Construct the Cargo Mapping
8127 * @note This is the reverse of a cargo translation table
8129 static void BuildCargoTranslationMap()
8131 memset(_cur
.grffile
->cargo_map
, 0xFF, sizeof(_cur
.grffile
->cargo_map
));
8133 for (CargoID c
= 0; c
< NUM_CARGO
; c
++) {
8134 const CargoSpec
*cs
= CargoSpec::Get(c
);
8135 if (!cs
->IsValid()) continue;
8137 if (_cur
.grffile
->cargo_list
.Length() == 0) {
8138 /* Default translation table, so just a straight mapping to bitnum */
8139 _cur
.grffile
->cargo_map
[c
] = cs
->bitnum
;
8141 /* Check the translation table for this cargo's label */
8142 int index
= _cur
.grffile
->cargo_list
.FindIndex(cs
->label
);
8143 if (index
>= 0) _cur
.grffile
->cargo_map
[c
] = index
;
8149 * Prepare loading a NewGRF file with its config
8150 * @param config The NewGRF configuration struct with name, id, parameters and alike.
8152 static void InitNewGRFFile(const GRFConfig
*config
)
8154 GRFFile
*newfile
= GetFileByFilename(config
->filename
);
8155 if (newfile
!= NULL
) {
8156 /* We already loaded it once. */
8157 _cur
.grffile
= newfile
;
8161 newfile
= new GRFFile(config
);
8162 *_grf_files
.Append() = _cur
.grffile
= newfile
;
8166 * Constructor for GRFFile
8167 * @param config GRFConfig to copy name, grfid and parameters from.
8169 GRFFile::GRFFile(const GRFConfig
*config
)
8171 this->filename
= stredup(config
->filename
);
8172 this->grfid
= config
->ident
.grfid
;
8174 /* Initialise local settings to defaults */
8175 this->traininfo_vehicle_pitch
= 0;
8176 this->traininfo_vehicle_width
= TRAININFO_DEFAULT_VEHICLE_WIDTH
;
8178 /* Mark price_base_multipliers as 'not set' */
8179 for (Price i
= PR_BEGIN
; i
< PR_END
; i
++) {
8180 this->price_base_multipliers
[i
] = INVALID_PRICE_MODIFIER
;
8183 /* Initialise rail type map with default rail types */
8184 memset(this->railtype_map
, INVALID_RAILTYPE
, sizeof(this->railtype_map
));
8185 this->railtype_map
[0] = RAILTYPE_RAIL
;
8186 this->railtype_map
[1] = RAILTYPE_ELECTRIC
;
8187 this->railtype_map
[2] = RAILTYPE_MONO
;
8188 this->railtype_map
[3] = RAILTYPE_MAGLEV
;
8190 /* Copy the initial parameter list
8191 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8192 assert_compile(lengthof(this->param
) == lengthof(config
->param
) && lengthof(this->param
) == 0x80);
8194 assert(config
->num_params
<= lengthof(config
->param
));
8195 this->param_end
= config
->num_params
;
8196 if (this->param_end
> 0) {
8197 MemCpyT(this->param
, config
->param
, this->param_end
);
8203 free(this->filename
);
8204 delete[] this->language_map
;
8209 * List of what cargo labels are refittable for the given the vehicle-type.
8210 * Only currently active labels are applied.
8212 static const CargoLabel _default_refitmasks_rail
[] = {
8213 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8214 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8215 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8219 static const CargoLabel _default_refitmasks_road
[] = {
8222 static const CargoLabel _default_refitmasks_ships
[] = {
8223 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8224 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8225 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8229 static const CargoLabel _default_refitmasks_aircraft
[] = {
8230 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8231 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8234 static const CargoLabel
* const _default_refitmasks
[] = {
8235 _default_refitmasks_rail
,
8236 _default_refitmasks_road
,
8237 _default_refitmasks_ships
,
8238 _default_refitmasks_aircraft
,
8243 * Precalculate refit masks from cargo classes for all vehicles.
8245 static void CalculateRefitMasks()
8249 FOR_ALL_ENGINES(e
) {
8250 EngineID engine
= e
->index
;
8251 EngineInfo
*ei
= &e
->info
;
8252 bool only_defaultcargo
; ///< Set if the vehicle shall carry only the default cargo
8254 /* Did the newgrf specify any refitting? If not, use defaults. */
8255 if (_gted
[engine
].refittability
!= GRFTempEngineData::UNSET
) {
8257 uint32 not_mask
= 0;
8258 uint32 xor_mask
= ei
->refit_mask
;
8260 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8261 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8262 only_defaultcargo
= _gted
[engine
].refittability
== GRFTempEngineData::EMPTY
;
8264 if (_gted
[engine
].cargo_allowed
!= 0) {
8265 /* Build up the list of cargo types from the set cargo classes. */
8266 const CargoSpec
*cs
;
8267 FOR_ALL_CARGOSPECS(cs
) {
8268 if (_gted
[engine
].cargo_allowed
& cs
->classes
) SetBit(mask
, cs
->Index());
8269 if (_gted
[engine
].cargo_disallowed
& cs
->classes
) SetBit(not_mask
, cs
->Index());
8273 ei
->refit_mask
= ((mask
& ~not_mask
) ^ xor_mask
) & _cargo_mask
;
8275 /* Apply explicit refit includes/excludes. */
8276 ei
->refit_mask
|= _gted
[engine
].ctt_include_mask
;
8277 ei
->refit_mask
&= ~_gted
[engine
].ctt_exclude_mask
;
8279 uint32 xor_mask
= 0;
8281 /* Don't apply default refit mask to wagons nor engines with no capacity */
8282 if (e
->type
!= VEH_TRAIN
|| (e
->u
.rail
.capacity
!= 0 && e
->u
.rail
.railveh_type
!= RAILVEH_WAGON
)) {
8283 const CargoLabel
*cl
= _default_refitmasks
[e
->type
];
8284 for (uint i
= 0;; i
++) {
8285 if (cl
[i
] == 0) break;
8287 CargoID cargo
= GetCargoIDByLabel(cl
[i
]);
8288 if (cargo
== CT_INVALID
) continue;
8290 SetBit(xor_mask
, cargo
);
8294 ei
->refit_mask
= xor_mask
& _cargo_mask
;
8296 /* If the mask is zero, the vehicle shall only carry the default cargo */
8297 only_defaultcargo
= (ei
->refit_mask
== 0);
8300 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8301 if (!HasBit(_cargo_mask
, ei
->cargo_type
)) ei
->cargo_type
= CT_INVALID
;
8303 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8304 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8305 if (!only_defaultcargo
&& (e
->type
!= VEH_SHIP
|| e
->u
.ship
.old_refittable
) && ei
->cargo_type
!= CT_INVALID
&& !HasBit(ei
->refit_mask
, ei
->cargo_type
)) {
8306 ei
->cargo_type
= CT_INVALID
;
8309 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8310 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8311 if (ei
->cargo_type
== CT_INVALID
&& ei
->refit_mask
!= 0) {
8312 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8313 const uint8
*cargo_map_for_first_refittable
= NULL
;
8315 const GRFFile
*file
= _gted
[engine
].defaultcargo_grf
;
8316 if (file
== NULL
) file
= e
->GetGRF();
8317 if (file
!= NULL
&& file
->grf_version
>= 8 && file
->cargo_list
.Length() != 0) {
8318 cargo_map_for_first_refittable
= file
->cargo_map
;
8322 if (cargo_map_for_first_refittable
!= NULL
) {
8323 /* Use first refittable cargo from cargo translation table */
8324 byte best_local_slot
= 0xFF;
8326 FOR_EACH_SET_CARGO_ID(cargo_type
, ei
->refit_mask
) {
8327 byte local_slot
= cargo_map_for_first_refittable
[cargo_type
];
8328 if (local_slot
< best_local_slot
) {
8329 best_local_slot
= local_slot
;
8330 ei
->cargo_type
= cargo_type
;
8335 if (ei
->cargo_type
== CT_INVALID
) {
8336 /* Use first refittable cargo slot */
8337 ei
->cargo_type
= (CargoID
)FindFirstBit(ei
->refit_mask
);
8340 if (ei
->cargo_type
== CT_INVALID
) ei
->climates
= 0;
8342 /* Clear refit_mask for not refittable ships */
8343 if (e
->type
== VEH_SHIP
&& !e
->u
.ship
.old_refittable
) {
8349 /** Set to use the correct action0 properties for each canal feature */
8350 static void FinaliseCanals()
8352 for (uint i
= 0; i
< CF_END
; i
++) {
8353 if (_water_feature
[i
].grffile
!= NULL
) {
8354 _water_feature
[i
].callback_mask
= _water_feature
[i
].grffile
->canal_local_properties
[i
].callback_mask
;
8355 _water_feature
[i
].flags
= _water_feature
[i
].grffile
->canal_local_properties
[i
].flags
;
8360 /** Check for invalid engines */
8361 static void FinaliseEngineArray()
8365 FOR_ALL_ENGINES(e
) {
8366 if (e
->GetGRF() == NULL
) {
8367 const EngineIDMapping
&eid
= _engine_mngr
[e
->index
];
8368 if (eid
.grfid
!= INVALID_GRFID
|| eid
.internal_id
!= eid
.substitute_id
) {
8369 e
->info
.string_id
= STR_NEWGRF_INVALID_ENGINE
;
8373 /* When the train does not set property 27 (misc flags), but it
8374 * is overridden by a NewGRF graphically we want to disable the
8375 * flipping possibility. */
8376 if (e
->type
== VEH_TRAIN
&& !_gted
[e
->index
].prop27_set
&& e
->GetGRF() != NULL
&& is_custom_sprite(e
->u
.rail
.image_index
)) {
8377 ClrBit(e
->info
.misc_flags
, EF_RAIL_FLIPS
);
8380 /* Skip wagons, there livery is defined via the engine */
8381 if (e
->type
!= VEH_TRAIN
|| e
->u
.rail
.railveh_type
!= RAILVEH_WAGON
) {
8382 LiveryScheme ls
= GetEngineLiveryScheme(e
->index
, INVALID_ENGINE
, NULL
);
8383 SetBit(_loaded_newgrf_features
.used_liveries
, ls
);
8384 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8386 if (e
->type
== VEH_TRAIN
) {
8387 SetBit(_loaded_newgrf_features
.used_liveries
, LS_FREIGHT_WAGON
);
8394 SetBit(_loaded_newgrf_features
.used_liveries
, LS_PASSENGER_WAGON_STEAM
+ ls
- LS_STEAM
);
8399 SetBit(_loaded_newgrf_features
.used_liveries
, LS_PASSENGER_WAGON_DIESEL
+ ls
- LS_DMU
);
8402 default: NOT_REACHED();
8409 /** Check for invalid cargoes */
8410 static void FinaliseCargoArray()
8412 for (CargoID c
= 0; c
< NUM_CARGO
; c
++) {
8413 CargoSpec
*cs
= CargoSpec::Get(c
);
8414 if (!cs
->IsValid()) {
8415 cs
->name
= cs
->name_single
= cs
->units_volume
= STR_NEWGRF_INVALID_CARGO
;
8416 cs
->quantifier
= STR_NEWGRF_INVALID_CARGO_QUANTITY
;
8417 cs
->abbrev
= STR_NEWGRF_INVALID_CARGO_ABBREV
;
8423 * Check if a given housespec is valid and disable it if it's not.
8424 * The housespecs that follow it are used to check the validity of
8426 * @param hs The housespec to check.
8427 * @param next1 The housespec that follows \c hs.
8428 * @param next2 The housespec that follows \c next1.
8429 * @param next3 The housespec that follows \c next2.
8430 * @param filename The filename of the newgrf this house was defined in.
8431 * @return Whether the given housespec is valid.
8433 static bool IsHouseSpecValid(HouseSpec
*hs
, const HouseSpec
*next1
, const HouseSpec
*next2
, const HouseSpec
*next3
, const char *filename
)
8435 if (((hs
->building_flags
& BUILDING_HAS_2_TILES
) != 0 &&
8436 (next1
== NULL
|| !next1
->enabled
|| (next1
->building_flags
& BUILDING_HAS_1_TILE
) != 0)) ||
8437 ((hs
->building_flags
& BUILDING_HAS_4_TILES
) != 0 &&
8438 (next2
== NULL
|| !next2
->enabled
|| (next2
->building_flags
& BUILDING_HAS_1_TILE
) != 0 ||
8439 next3
== NULL
|| !next3
->enabled
|| (next3
->building_flags
& BUILDING_HAS_1_TILE
) != 0))) {
8440 hs
->enabled
= false;
8441 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
);
8445 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8446 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8447 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8448 if (((hs
->building_flags
& BUILDING_HAS_2_TILES
) != 0 && next1
->population
!= 0) ||
8449 ((hs
->building_flags
& BUILDING_HAS_4_TILES
) != 0 && (next2
->population
!= 0 || next3
->population
!= 0))) {
8450 hs
->enabled
= false;
8451 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
);
8455 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8456 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8457 if (filename
!= NULL
&& (hs
->building_flags
& BUILDING_HAS_1_TILE
) != (HouseSpec::Get(hs
->grf_prop
.subst_id
)->building_flags
& BUILDING_HAS_1_TILE
)) {
8458 hs
->enabled
= false;
8459 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
);
8463 /* Make sure that additional parts of multitile houses are not available. */
8464 if ((hs
->building_flags
& BUILDING_HAS_1_TILE
) == 0 && (hs
->building_availability
& HZ_ZONALL
) != 0 && (hs
->building_availability
& HZ_CLIMALL
) != 0) {
8465 hs
->enabled
= false;
8466 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
);
8474 * Make sure there is at least one house available in the year 0 for the given
8475 * climate / housezone combination.
8476 * @param bitmask The climate and housezone to check for. Exactly one climate
8477 * bit and one housezone bit should be set.
8479 static void EnsureEarlyHouse(HouseZones bitmask
)
8481 Year min_year
= MAX_YEAR
;
8483 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8484 HouseSpec
*hs
= HouseSpec::Get(i
);
8485 if (hs
== NULL
|| !hs
->enabled
) continue;
8486 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
8487 if (hs
->min_year
< min_year
) min_year
= hs
->min_year
;
8490 if (min_year
== 0) return;
8492 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8493 HouseSpec
*hs
= HouseSpec::Get(i
);
8494 if (hs
== NULL
|| !hs
->enabled
) continue;
8495 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
8496 if (hs
->min_year
== min_year
) hs
->min_year
= 0;
8501 * Add all new houses to the house array. House properties can be set at any
8502 * time in the GRF file, so we can only add a house spec to the house array
8503 * after the file has finished loading. We also need to check the dates, due to
8504 * the TTDPatch behaviour described below that we need to emulate.
8506 static void FinaliseHouseArray()
8508 /* If there are no houses with start dates before 1930, then all houses
8509 * with start dates of 1930 have them reset to 0. This is in order to be
8510 * compatible with TTDPatch, where if no houses have start dates before
8511 * 1930 and the date is before 1930, the game pretends that this is 1930.
8512 * If there have been any houses defined with start dates before 1930 then
8513 * the dates are left alone.
8514 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8515 * minimum introduction date to 0.
8517 const GRFFile
* const *end
= _grf_files
.End();
8518 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8519 HouseSpec
**&housespec
= (*file
)->housespec
;
8520 if (housespec
== NULL
) continue;
8522 for (int i
= 0; i
< NUM_HOUSES_PER_GRF
; i
++) {
8523 HouseSpec
*hs
= housespec
[i
];
8525 if (hs
== NULL
) continue;
8527 const HouseSpec
*next1
= (i
+ 1 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 1] : NULL
);
8528 const HouseSpec
*next2
= (i
+ 2 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 2] : NULL
);
8529 const HouseSpec
*next3
= (i
+ 3 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 3] : NULL
);
8531 if (!IsHouseSpecValid(hs
, next1
, next2
, next3
, (*file
)->filename
)) continue;
8533 _house_mngr
.SetEntitySpec(hs
);
8537 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8538 HouseSpec
*hs
= HouseSpec::Get(i
);
8539 const HouseSpec
*next1
= (i
+ 1 < NUM_HOUSES
? HouseSpec::Get(i
+ 1) : NULL
);
8540 const HouseSpec
*next2
= (i
+ 2 < NUM_HOUSES
? HouseSpec::Get(i
+ 2) : NULL
);
8541 const HouseSpec
*next3
= (i
+ 3 < NUM_HOUSES
? HouseSpec::Get(i
+ 3) : NULL
);
8543 /* We need to check all houses again to we are sure that multitile houses
8544 * did get consecutive IDs and none of the parts are missing. */
8545 if (!IsHouseSpecValid(hs
, next1
, next2
, next3
, NULL
)) {
8546 /* GetHouseNorthPart checks 3 houses that are directly before
8547 * it in the house pool. If any of those houses have multi-tile
8548 * flags set it assumes it's part of a multitile house. Since
8549 * we can have invalid houses in the pool marked as disabled, we
8550 * don't want to have them influencing valid tiles. As such set
8551 * building_flags to zero here to make sure any house following
8552 * this one in the pool is properly handled as 1x1 house. */
8553 hs
->building_flags
= TILE_NO_FLAG
;
8557 HouseZones climate_mask
= (HouseZones
)(1 << (_settings_game
.game_creation
.landscape
+ 12));
8558 EnsureEarlyHouse(HZ_ZON1
| climate_mask
);
8559 EnsureEarlyHouse(HZ_ZON2
| climate_mask
);
8560 EnsureEarlyHouse(HZ_ZON3
| climate_mask
);
8561 EnsureEarlyHouse(HZ_ZON4
| climate_mask
);
8562 EnsureEarlyHouse(HZ_ZON5
| climate_mask
);
8564 if (_settings_game
.game_creation
.landscape
== LT_ARCTIC
) {
8565 EnsureEarlyHouse(HZ_ZON1
| HZ_SUBARTC_ABOVE
);
8566 EnsureEarlyHouse(HZ_ZON2
| HZ_SUBARTC_ABOVE
);
8567 EnsureEarlyHouse(HZ_ZON3
| HZ_SUBARTC_ABOVE
);
8568 EnsureEarlyHouse(HZ_ZON4
| HZ_SUBARTC_ABOVE
);
8569 EnsureEarlyHouse(HZ_ZON5
| HZ_SUBARTC_ABOVE
);
8574 * Add all new industries to the industry array. Industry properties can be set at any
8575 * time in the GRF file, so we can only add a industry spec to the industry array
8576 * after the file has finished loading.
8578 static void FinaliseIndustriesArray()
8580 const GRFFile
* const *end
= _grf_files
.End();
8581 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8582 IndustrySpec
**&industryspec
= (*file
)->industryspec
;
8583 IndustryTileSpec
**&indtspec
= (*file
)->indtspec
;
8584 if (industryspec
!= NULL
) {
8585 for (int i
= 0; i
< NUM_INDUSTRYTYPES_PER_GRF
; i
++) {
8586 IndustrySpec
*indsp
= industryspec
[i
];
8588 if (indsp
!= NULL
&& indsp
->enabled
) {
8590 /* process the conversion of text at the end, so to be sure everything will be fine
8591 * and available. Check if it does not return undefind marker, which is a very good sign of a
8592 * substitute industry who has not changed the string been examined, thus using it as such */
8593 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->name
);
8594 if (strid
!= STR_UNDEFINED
) indsp
->name
= strid
;
8596 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->closure_text
);
8597 if (strid
!= STR_UNDEFINED
) indsp
->closure_text
= strid
;
8599 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->production_up_text
);
8600 if (strid
!= STR_UNDEFINED
) indsp
->production_up_text
= strid
;
8602 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->production_down_text
);
8603 if (strid
!= STR_UNDEFINED
) indsp
->production_down_text
= strid
;
8605 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->new_industry_text
);
8606 if (strid
!= STR_UNDEFINED
) indsp
->new_industry_text
= strid
;
8608 if (indsp
->station_name
!= STR_NULL
) {
8609 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8610 * station's name. Don't want to lose the value, therefore, do not process. */
8611 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->station_name
);
8612 if (strid
!= STR_UNDEFINED
) indsp
->station_name
= strid
;
8615 _industry_mngr
.SetEntitySpec(indsp
);
8616 _loaded_newgrf_features
.has_newindustries
= true;
8621 if (indtspec
!= NULL
) {
8622 for (int i
= 0; i
< NUM_INDUSTRYTILES_PER_GRF
; i
++) {
8623 IndustryTileSpec
*indtsp
= indtspec
[i
];
8624 if (indtsp
!= NULL
) {
8625 _industile_mngr
.SetEntitySpec(indtsp
);
8631 for (uint j
= 0; j
< NUM_INDUSTRYTYPES
; j
++) {
8632 IndustrySpec
*indsp
= &_industry_specs
[j
];
8633 if (indsp
->enabled
&& indsp
->grf_prop
.grffile
!= NULL
) {
8634 for (uint i
= 0; i
< 3; i
++) {
8635 indsp
->conflicting
[i
] = MapNewGRFIndustryType(indsp
->conflicting
[i
], indsp
->grf_prop
.grffile
->grfid
);
8638 if (!indsp
->enabled
) {
8639 indsp
->name
= STR_NEWGRF_INVALID_INDUSTRYTYPE
;
8645 * Add all new objects to the object array. Object properties can be set at any
8646 * time in the GRF file, so we can only add an object spec to the object array
8647 * after the file has finished loading.
8649 static void FinaliseObjectsArray()
8651 const GRFFile
* const *end
= _grf_files
.End();
8652 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8653 ObjectSpec
**&objectspec
= (*file
)->objectspec
;
8654 if (objectspec
!= NULL
) {
8655 for (int i
= 0; i
< NUM_OBJECTS_PER_GRF
; i
++) {
8656 if (objectspec
[i
] != NULL
&& objectspec
[i
]->grf_prop
.grffile
!= NULL
&& objectspec
[i
]->enabled
) {
8657 _object_mngr
.SetEntitySpec(objectspec
[i
]);
8665 * Add all new airports to the airport array. Airport properties can be set at any
8666 * time in the GRF file, so we can only add a airport spec to the airport array
8667 * after the file has finished loading.
8669 static void FinaliseAirportsArray()
8671 const GRFFile
* const *end
= _grf_files
.End();
8672 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8673 AirportSpec
**&airportspec
= (*file
)->airportspec
;
8674 if (airportspec
!= NULL
) {
8675 for (int i
= 0; i
< NUM_AIRPORTS_PER_GRF
; i
++) {
8676 if (airportspec
[i
] != NULL
&& airportspec
[i
]->enabled
) {
8677 _airport_mngr
.SetEntitySpec(airportspec
[i
]);
8682 AirportTileSpec
**&airporttilespec
= (*file
)->airtspec
;
8683 if (airporttilespec
!= NULL
) {
8684 for (uint i
= 0; i
< NUM_AIRPORTTILES_PER_GRF
; i
++) {
8685 if (airporttilespec
[i
] != NULL
&& airporttilespec
[i
]->enabled
) {
8686 _airporttile_mngr
.SetEntitySpec(airporttilespec
[i
]);
8693 /* Here we perform initial decoding of some special sprites (as are they
8694 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8695 * partial implementation yet).
8696 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8697 * a crafted invalid GRF file. We should tell that to the user somehow, or
8698 * better make this more robust in the future. */
8699 static void DecodeSpecialSprite(byte
*buf
, uint num
, GrfLoadingStage stage
)
8701 /* XXX: There is a difference between staged loading in TTDPatch and
8702 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8703 * during stage 1, whilst action 3 is carried out during stage 2 (to
8704 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8705 * IDs are valid only within a given set (action 1) block, and may be
8706 * overwritten after action 3 associates them. But overwriting happens
8707 * in an earlier stage than associating, so... We just process actions
8708 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8710 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8711 * is not in memory and scanning the file every time would be too expensive.
8712 * In other stages we skip action 0x10 since it's already dealt with. */
8713 static const SpecialSpriteHandler handlers
[][GLS_END
] = {
8714 /* 0x00 */ { NULL
, SafeChangeInfo
, NULL
, NULL
, ReserveChangeInfo
, FeatureChangeInfo
, },
8715 /* 0x01 */ { SkipAct1
, SkipAct1
, SkipAct1
, SkipAct1
, SkipAct1
, NewSpriteSet
, },
8716 /* 0x02 */ { NULL
, NULL
, NULL
, NULL
, NULL
, NewSpriteGroup
, },
8717 /* 0x03 */ { NULL
, GRFUnsafe
, NULL
, NULL
, NULL
, FeatureMapSpriteGroup
, },
8718 /* 0x04 */ { NULL
, NULL
, NULL
, NULL
, NULL
, FeatureNewName
, },
8719 /* 0x05 */ { SkipAct5
, SkipAct5
, SkipAct5
, SkipAct5
, SkipAct5
, GraphicsNew
, },
8720 /* 0x06 */ { NULL
, NULL
, NULL
, CfgApply
, CfgApply
, CfgApply
, },
8721 /* 0x07 */ { NULL
, NULL
, NULL
, NULL
, SkipIf
, SkipIf
, },
8722 /* 0x08 */ { ScanInfo
, NULL
, NULL
, GRFInfo
, GRFInfo
, GRFInfo
, },
8723 /* 0x09 */ { NULL
, NULL
, NULL
, SkipIf
, SkipIf
, SkipIf
, },
8724 /* 0x0A */ { SkipActA
, SkipActA
, SkipActA
, SkipActA
, SkipActA
, SpriteReplace
, },
8725 /* 0x0B */ { NULL
, NULL
, NULL
, GRFLoadError
, GRFLoadError
, GRFLoadError
, },
8726 /* 0x0C */ { NULL
, NULL
, NULL
, GRFComment
, NULL
, GRFComment
, },
8727 /* 0x0D */ { NULL
, SafeParamSet
, NULL
, ParamSet
, ParamSet
, ParamSet
, },
8728 /* 0x0E */ { NULL
, SafeGRFInhibit
, NULL
, GRFInhibit
, GRFInhibit
, GRFInhibit
, },
8729 /* 0x0F */ { NULL
, GRFUnsafe
, NULL
, FeatureTownName
, NULL
, NULL
, },
8730 /* 0x10 */ { NULL
, NULL
, DefineGotoLabel
, NULL
, NULL
, NULL
, },
8731 /* 0x11 */ { SkipAct11
,GRFUnsafe
, SkipAct11
, GRFSound
, SkipAct11
, GRFSound
, },
8732 /* 0x12 */ { SkipAct12
, SkipAct12
, SkipAct12
, SkipAct12
, SkipAct12
, LoadFontGlyph
, },
8733 /* 0x13 */ { NULL
, NULL
, NULL
, NULL
, NULL
, TranslateGRFStrings
, },
8734 /* 0x14 */ { StaticGRFInfo
, NULL
, NULL
, NULL
, NULL
, NULL
, },
8737 GRFLocation
location(_cur
.grfconfig
->ident
.grfid
, _cur
.nfo_line
);
8739 GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.find(location
);
8740 if (it
== _grf_line_to_action6_sprite_override
.end()) {
8741 /* No preloaded sprite to work with; read the
8742 * pseudo sprite content. */
8743 FioReadBlock(buf
, num
);
8745 /* Use the preloaded sprite data. */
8746 buf
= _grf_line_to_action6_sprite_override
[location
];
8747 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8749 /* Skip the real (original) content of this action. */
8750 FioSeekTo(num
, SEEK_CUR
);
8753 ByteReader
br(buf
, buf
+ num
);
8754 ByteReader
*bufp
= &br
;
8757 byte action
= bufp
->ReadByte();
8759 if (action
== 0xFF) {
8760 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8761 } else if (action
== 0xFE) {
8762 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8763 } else if (action
>= lengthof(handlers
)) {
8764 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action
);
8765 } else if (handlers
[action
][stage
] == NULL
) {
8766 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action
, stage
);
8768 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action
, stage
);
8769 handlers
[action
][stage
](bufp
);
8772 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8773 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS
);
8778 /** Signature of a container version 2 GRF. */
8779 extern const byte _grf_cont_v2_sig
[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8782 * Get the container version of the currently opened GRF file.
8783 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
8785 byte
GetGRFContainerVersion()
8787 size_t pos
= FioGetPos();
8789 if (FioReadWord() == 0) {
8790 /* Check for GRF container version 2, which is identified by the bytes
8791 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8792 for (uint i
= 0; i
< lengthof(_grf_cont_v2_sig
); i
++) {
8793 if (FioReadByte() != _grf_cont_v2_sig
[i
]) return 0; // Invalid format
8799 /* Container version 1 has no header, rewind to start. */
8800 FioSeekTo(pos
, SEEK_SET
);
8805 * Load a particular NewGRF.
8806 * @param config The configuration of the to be loaded NewGRF.
8807 * @param file_index The Fio index of the first NewGRF to load.
8808 * @param stage The loading stage of the NewGRF.
8809 * @param subdir The sub directory to find the NewGRF in.
8811 void LoadNewGRFFile(GRFConfig
*config
, uint file_index
, GrfLoadingStage stage
, Subdirectory subdir
)
8813 const char *filename
= config
->filename
;
8815 /* A .grf file is activated only if it was active when the game was
8816 * started. If a game is loaded, only its active .grfs will be
8817 * reactivated, unless "loadallgraphics on" is used. A .grf file is
8818 * considered active if its action 8 has been processed, i.e. its
8819 * action 8 hasn't been skipped using an action 7.
8821 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
8822 * carried out. All others are ignored, because they only need to be
8823 * processed once at initialization. */
8824 if (stage
!= GLS_FILESCAN
&& stage
!= GLS_SAFETYSCAN
&& stage
!= GLS_LABELSCAN
) {
8825 _cur
.grffile
= GetFileByFilename(filename
);
8826 if (_cur
.grffile
== NULL
) usererror("File '%s' lost in cache.\n", filename
);
8827 if (stage
== GLS_RESERVE
&& config
->status
!= GCS_INITIALISED
) return;
8828 if (stage
== GLS_ACTIVATION
&& !HasBit(config
->flags
, GCF_RESERVED
)) return;
8831 if (file_index
>= MAX_FILE_SLOTS
) {
8832 DEBUG(grf
, 0, "'%s' is not loaded as the maximum number of file slots has been reached", filename
);
8833 config
->status
= GCS_DISABLED
;
8834 config
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED
);
8838 FioOpenFile(file_index
, filename
, subdir
);
8839 _cur
.file_index
= file_index
; // XXX
8840 _palette_remap_grf
[_cur
.file_index
] = (config
->palette
& GRFP_USE_MASK
);
8842 _cur
.grfconfig
= config
;
8844 DEBUG(grf
, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename
);
8846 _cur
.grf_container_ver
= GetGRFContainerVersion();
8847 if (_cur
.grf_container_ver
== 0) {
8848 DEBUG(grf
, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8852 if (stage
== GLS_INIT
|| stage
== GLS_ACTIVATION
) {
8853 /* We need the sprite offsets in the init stage for NewGRF sounds
8854 * and in the activation stage for real sprites. */
8855 ReadGRFSpriteOffsets(_cur
.grf_container_ver
);
8857 /* Skip sprite section offset if present. */
8858 if (_cur
.grf_container_ver
>= 2) FioReadDword();
8861 if (_cur
.grf_container_ver
>= 2) {
8862 /* Read compression value. */
8863 byte compression
= FioReadByte();
8864 if (compression
!= 0) {
8865 DEBUG(grf
, 7, "LoadNewGRFFile: Unsupported compression format");
8870 /* Skip the first sprite; we don't care about how many sprites this
8871 * does contain; newest TTDPatches and George's longvehicles don't
8872 * neither, apparently. */
8873 uint32 num
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
8874 if (num
== 4 && FioReadByte() == 0xFF) {
8877 DEBUG(grf
, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8881 _cur
.ClearDataForNextFile();
8883 ReusableBuffer
<byte
> buf
;
8885 while ((num
= (_cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord())) != 0) {
8886 byte type
= FioReadByte();
8890 if (_cur
.skip_sprites
== 0) {
8891 DecodeSpecialSprite(buf
.Allocate(num
), num
, stage
);
8893 /* Stop all processing if we are to skip the remaining sprites */
8894 if (_cur
.skip_sprites
== -1) break;
8901 if (_cur
.skip_sprites
== 0) {
8902 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8903 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE
);
8907 if (_cur
.grf_container_ver
>= 2 && type
== 0xFD) {
8908 /* Reference to data section. Container version >= 2 only. */
8912 SkipSpriteData(type
, num
- 8);
8916 if (_cur
.skip_sprites
> 0) _cur
.skip_sprites
--;
8921 * Relocates the old shore sprites at new positions.
8923 * 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)
8924 * 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)
8925 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
8927 static void ActivateOldShore()
8929 /* Use default graphics, if no shore sprites were loaded.
8930 * Should not happen, as the base set's extra grf should include some. */
8931 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_NONE
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_A
;
8933 if (_loaded_newgrf_features
.shore
!= SHORE_REPLACE_ACTION_5
) {
8934 DupSprite(SPR_ORIGINALSHORE_START
+ 1, SPR_SHORE_BASE
+ 1); // SLOPE_W
8935 DupSprite(SPR_ORIGINALSHORE_START
+ 2, SPR_SHORE_BASE
+ 2); // SLOPE_S
8936 DupSprite(SPR_ORIGINALSHORE_START
+ 6, SPR_SHORE_BASE
+ 3); // SLOPE_SW
8937 DupSprite(SPR_ORIGINALSHORE_START
+ 0, SPR_SHORE_BASE
+ 4); // SLOPE_E
8938 DupSprite(SPR_ORIGINALSHORE_START
+ 4, SPR_SHORE_BASE
+ 6); // SLOPE_SE
8939 DupSprite(SPR_ORIGINALSHORE_START
+ 3, SPR_SHORE_BASE
+ 8); // SLOPE_N
8940 DupSprite(SPR_ORIGINALSHORE_START
+ 7, SPR_SHORE_BASE
+ 9); // SLOPE_NW
8941 DupSprite(SPR_ORIGINALSHORE_START
+ 5, SPR_SHORE_BASE
+ 12); // SLOPE_NE
8944 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_ACTION_A
) {
8945 DupSprite(SPR_FLAT_GRASS_TILE
+ 16, SPR_SHORE_BASE
+ 0); // SLOPE_STEEP_S
8946 DupSprite(SPR_FLAT_GRASS_TILE
+ 17, SPR_SHORE_BASE
+ 5); // SLOPE_STEEP_W
8947 DupSprite(SPR_FLAT_GRASS_TILE
+ 7, SPR_SHORE_BASE
+ 7); // SLOPE_WSE
8948 DupSprite(SPR_FLAT_GRASS_TILE
+ 15, SPR_SHORE_BASE
+ 10); // SLOPE_STEEP_N
8949 DupSprite(SPR_FLAT_GRASS_TILE
+ 11, SPR_SHORE_BASE
+ 11); // SLOPE_NWS
8950 DupSprite(SPR_FLAT_GRASS_TILE
+ 13, SPR_SHORE_BASE
+ 13); // SLOPE_ENW
8951 DupSprite(SPR_FLAT_GRASS_TILE
+ 14, SPR_SHORE_BASE
+ 14); // SLOPE_SEN
8952 DupSprite(SPR_FLAT_GRASS_TILE
+ 18, SPR_SHORE_BASE
+ 15); // SLOPE_STEEP_E
8954 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
8955 * If they would be used somewhen, then these grass tiles will most like not look as needed */
8956 DupSprite(SPR_FLAT_GRASS_TILE
+ 5, SPR_SHORE_BASE
+ 16); // SLOPE_EW
8957 DupSprite(SPR_FLAT_GRASS_TILE
+ 10, SPR_SHORE_BASE
+ 17); // SLOPE_NS
8962 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
8964 static void FinalisePriceBaseMultipliers()
8966 extern const PriceBaseSpec _price_base_specs
[];
8967 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
8968 static const uint32 override_features
= (1 << GSF_TRAINS
) | (1 << GSF_ROADVEHICLES
) | (1 << GSF_SHIPS
) | (1 << GSF_AIRCRAFT
);
8970 /* Evaluate grf overrides */
8971 int num_grfs
= _grf_files
.Length();
8972 int *grf_overrides
= AllocaM(int, num_grfs
);
8973 for (int i
= 0; i
< num_grfs
; i
++) {
8974 grf_overrides
[i
] = -1;
8976 GRFFile
*source
= _grf_files
[i
];
8977 uint32 override
= _grf_id_overrides
[source
->grfid
];
8978 if (override
== 0) continue;
8980 GRFFile
*dest
= GetFileByGRFID(override
);
8981 if (dest
== NULL
) continue;
8983 grf_overrides
[i
] = _grf_files
.FindIndex(dest
);
8984 assert(grf_overrides
[i
] >= 0);
8987 /* Override features and price base multipliers of earlier loaded grfs */
8988 for (int i
= 0; i
< num_grfs
; i
++) {
8989 if (grf_overrides
[i
] < 0 || grf_overrides
[i
] >= i
) continue;
8990 GRFFile
*source
= _grf_files
[i
];
8991 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
8993 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
8994 source
->grf_features
|= features
;
8995 dest
->grf_features
|= features
;
8997 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
8998 /* No price defined -> nothing to do */
8999 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
) || source
->price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) continue;
9000 DEBUG(grf
, 3, "'%s' overrides price base multiplier %d of '%s'", source
->filename
, p
, dest
->filename
);
9001 dest
->price_base_multipliers
[p
] = source
->price_base_multipliers
[p
];
9005 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9006 for (int i
= num_grfs
- 1; i
>= 0; i
--) {
9007 if (grf_overrides
[i
] < 0 || grf_overrides
[i
] <= i
) continue;
9008 GRFFile
*source
= _grf_files
[i
];
9009 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9011 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9012 source
->grf_features
|= features
;
9013 dest
->grf_features
|= features
;
9015 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9016 /* Already a price defined -> nothing to do */
9017 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
) || dest
->price_base_multipliers
[p
] != INVALID_PRICE_MODIFIER
) continue;
9018 DEBUG(grf
, 3, "Price base multiplier %d from '%s' propagated to '%s'", p
, source
->filename
, dest
->filename
);
9019 dest
->price_base_multipliers
[p
] = source
->price_base_multipliers
[p
];
9023 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9024 for (int i
= 0; i
< num_grfs
; i
++) {
9025 if (grf_overrides
[i
] < 0) continue;
9026 GRFFile
*source
= _grf_files
[i
];
9027 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9029 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9030 source
->grf_features
|= features
;
9031 dest
->grf_features
|= features
;
9033 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9034 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
)) continue;
9035 if (source
->price_base_multipliers
[p
] != dest
->price_base_multipliers
[p
]) {
9036 DEBUG(grf
, 3, "Price base multiplier %d from '%s' propagated to '%s'", p
, dest
->filename
, source
->filename
);
9038 source
->price_base_multipliers
[p
] = dest
->price_base_multipliers
[p
];
9042 /* Apply fallback prices for grf version < 8 */
9043 const GRFFile
* const *end
= _grf_files
.End();
9044 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
9045 if ((*file
)->grf_version
>= 8) continue;
9046 PriceMultipliers
&price_base_multipliers
= (*file
)->price_base_multipliers
;
9047 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9048 Price fallback_price
= _price_base_specs
[p
].fallback_price
;
9049 if (fallback_price
!= INVALID_PRICE
&& price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) {
9050 /* No price multiplier has been set.
9051 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9052 price_base_multipliers
[p
] = price_base_multipliers
[fallback_price
];
9057 /* Decide local/global scope of price base multipliers */
9058 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
9059 PriceMultipliers
&price_base_multipliers
= (*file
)->price_base_multipliers
;
9060 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9061 if (price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) {
9062 /* No multiplier was set; set it to a neutral value */
9063 price_base_multipliers
[p
] = 0;
9065 if (!HasBit((*file
)->grf_features
, _price_base_specs
[p
].grf_feature
)) {
9066 /* The grf does not define any objects of the feature,
9067 * so it must be a difficulty setting. Apply it globally */
9068 DEBUG(grf
, 3, "'%s' sets global price base multiplier %d", (*file
)->filename
, p
);
9069 SetPriceBaseMultiplier(p
, price_base_multipliers
[p
]);
9070 price_base_multipliers
[p
] = 0;
9072 DEBUG(grf
, 3, "'%s' sets local price base multiplier %d", (*file
)->filename
, p
);
9079 extern void InitGRFTownGeneratorNames();
9081 /** Finish loading NewGRFs and execute needed post-processing */
9082 static void AfterLoadGRFs()
9084 for (StringIDMapping
*it
= _string_to_grf_mapping
.Begin(); it
!= _string_to_grf_mapping
.End(); it
++) {
9085 *it
->target
= MapGRFStringID(it
->grfid
, it
->source
);
9087 _string_to_grf_mapping
.Clear();
9089 /* Free the action 6 override sprites. */
9090 for (GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.begin(); it
!= _grf_line_to_action6_sprite_override
.end(); it
++) {
9093 _grf_line_to_action6_sprite_override
.clear();
9095 /* Polish cargoes */
9096 FinaliseCargoArray();
9098 /* Pre-calculate all refit masks after loading GRF files. */
9099 CalculateRefitMasks();
9101 /* Polish engines */
9102 FinaliseEngineArray();
9104 /* Set the actually used Canal properties */
9107 /* Add all new houses to the house array. */
9108 FinaliseHouseArray();
9110 /* Add all new industries to the industry array. */
9111 FinaliseIndustriesArray();
9113 /* Add all new objects to the object array. */
9114 FinaliseObjectsArray();
9116 InitializeSortedCargoSpecs();
9118 /* Sort the list of industry types. */
9119 SortIndustryTypes();
9121 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9122 BuildIndustriesLegend();
9124 /* Build the routemap legend, based on the available cargos */
9125 BuildLinkStatsLegend();
9127 /* Add all new airports to the airports array. */
9128 FinaliseAirportsArray();
9131 /* Update the townname generators list */
9132 InitGRFTownGeneratorNames();
9134 /* Run all queued vehicle list order changes */
9135 CommitVehicleListOrderChanges();
9137 /* Load old shore sprites in new position, if they were replaced by ActionA */
9140 /* Set up custom rail types */
9144 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_ROAD
) {
9145 if (_gted
[e
->index
].rv_max_speed
!= 0) {
9146 /* Set RV maximum speed from the mph/0.8 unit value */
9147 e
->u
.road
.max_speed
= _gted
[e
->index
].rv_max_speed
* 4;
9151 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_TRAIN
) {
9152 RailType railtype
= GetRailTypeByLabel(_gted
[e
->index
].railtypelabel
);
9153 if (railtype
== INVALID_RAILTYPE
) {
9154 /* Rail type is not available, so disable this engine */
9155 e
->info
.climates
= 0;
9157 e
->u
.rail
.railtype
= railtype
;
9161 SetYearEngineAgingStops();
9163 FinalisePriceBaseMultipliers();
9165 /* Deallocate temporary loading data */
9167 _grm_sprites
.clear();
9171 * Load all the NewGRFs.
9172 * @param load_index The offset for the first sprite to add.
9173 * @param file_index The Fio index of the first NewGRF to load.
9174 * @param num_baseset Number of NewGRFs at the front of the list to look up in the baseset dir instead of the newgrf dir.
9176 void LoadNewGRF(uint load_index
, uint file_index
, uint num_baseset
)
9178 /* In case of networking we need to "sync" the start values
9179 * so all NewGRFs are loaded equally. For this we use the
9180 * start date of the game and we set the counters, etc. to
9181 * 0 so they're the same too. */
9183 Year year
= _cur_year
;
9184 DateFract date_fract
= _date_fract
;
9185 uint16 tick_counter
= _tick_counter
;
9186 byte display_opt
= _display_opt
;
9189 _cur_year
= _settings_game
.game_creation
.starting_year
;
9190 _date
= ConvertYMDToDate(_cur_year
, 0, 1);
9196 InitializeGRFSpecial();
9201 * Reset the status of all files, so we can 'retry' to load them.
9202 * This is needed when one for example rearranges the NewGRFs in-game
9203 * and a previously disabled NewGRF becomes useable. If it would not
9204 * be reset, the NewGRF would remain disabled even though it should
9205 * have been enabled.
9207 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9208 if (c
->status
!= GCS_NOT_FOUND
) c
->status
= GCS_UNKNOWN
;
9211 _cur
.spriteid
= load_index
;
9213 /* Load newgrf sprites
9214 * in each loading stage, (try to) open each file specified in the config
9215 * and load information from it. */
9216 for (GrfLoadingStage stage
= GLS_LABELSCAN
; stage
<= GLS_ACTIVATION
; stage
++) {
9217 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9218 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9219 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9220 if (c
->status
== GCS_ACTIVATED
) c
->status
= GCS_INITIALISED
;
9223 if (stage
== GLS_RESERVE
) {
9224 static const uint32 overrides
[][2] = {
9225 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9226 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9227 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9229 for (size_t i
= 0; i
< lengthof(overrides
); i
++) {
9230 SetNewGRFOverride(BSWAP32(overrides
[i
][0]), BSWAP32(overrides
[i
][1]));
9234 uint slot
= file_index
;
9235 uint num_non_static
= 0;
9238 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9239 if (c
->status
== GCS_DISABLED
|| c
->status
== GCS_NOT_FOUND
) continue;
9240 if (stage
> GLS_INIT
&& HasBit(c
->flags
, GCF_INIT_ONLY
)) continue;
9242 Subdirectory subdir
= slot
< file_index
+ num_baseset
? BASESET_DIR
: NEWGRF_DIR
;
9243 if (!FioCheckFileExists(c
->filename
, subdir
)) {
9244 DEBUG(grf
, 0, "NewGRF file is missing '%s'; disabling", c
->filename
);
9245 c
->status
= GCS_NOT_FOUND
;
9249 if (stage
== GLS_LABELSCAN
) InitNewGRFFile(c
);
9251 if (!HasBit(c
->flags
, GCF_STATIC
) && !HasBit(c
->flags
, GCF_SYSTEM
)) {
9252 if (num_non_static
== NETWORK_MAX_GRF_COUNT
) {
9253 DEBUG(grf
, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c
->filename
);
9254 c
->status
= GCS_DISABLED
;
9255 c
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED
);
9260 LoadNewGRFFile(c
, slot
++, stage
, subdir
);
9261 if (stage
== GLS_RESERVE
) {
9262 SetBit(c
->flags
, GCF_RESERVED
);
9263 } else if (stage
== GLS_ACTIVATION
) {
9264 ClrBit(c
->flags
, GCF_RESERVED
);
9265 assert(GetFileByGRFID(c
->ident
.grfid
) == _cur
.grffile
);
9266 ClearTemporaryNewGRFData(_cur
.grffile
);
9267 BuildCargoTranslationMap();
9268 DEBUG(sprite
, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur
.spriteid
);
9269 } else if (stage
== GLS_INIT
&& HasBit(c
->flags
, GCF_INIT_ONLY
)) {
9270 /* We're not going to activate this, so free whatever data we allocated */
9271 ClearTemporaryNewGRFData(_cur
.grffile
);
9276 /* Pseudo sprite processing is finished; free temporary stuff */
9277 _cur
.ClearDataForNextFile();
9279 /* Call any functions that should be run after GRFs have been loaded. */
9282 /* Now revert back to the original situation */
9285 _date_fract
= date_fract
;
9286 _tick_counter
= tick_counter
;
9287 _display_opt
= display_opt
;