1 /* $Id: newgrf.cpp 26245 2014-01-12 18:01:50Z frosch $ */
4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
10 /** @file newgrf.cpp Base of all NewGRF support. */
18 #include "fileio_func.h"
19 #include "engine_func.h"
20 #include "engine_base.h"
23 #include "newgrf_engine.h"
24 #include "newgrf_text.h"
25 #include "fontcache.h"
27 #include "landscape.h"
28 #include "newgrf_cargo.h"
29 #include "newgrf_house.h"
30 #include "newgrf_sound.h"
31 #include "newgrf_station.h"
32 #include "industrytype.h"
33 #include "newgrf_canal.h"
34 #include "newgrf_townname.h"
35 #include "newgrf_industries.h"
36 #include "newgrf_airporttiles.h"
37 #include "newgrf_airport.h"
38 #include "newgrf_object.h"
41 #include "strings_func.h"
42 #include "date_func.h"
43 #include "string_func.h"
44 #include "network/network.h"
46 #include "smallmap_gui.h"
49 #include "vehicle_func.h"
51 #include "vehicle_base.h"
53 #include "table/strings.h"
54 #include "table/build_industry.h"
56 #include "3rdparty/cpp-btree/btree_map.h"
58 #include "safeguards.h"
60 /* TTDPatch extended GRF format codec
61 * (c) Petr Baudis 2004 (GPL'd)
62 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
64 * Contains portions of documentation by TTDPatch team.
65 * Thanks especially to Josef Drexler for the documentation as well as a lot
66 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
67 * served as subject to the initial testing of this codec. */
69 /** List of all loaded GRF files */
70 static SmallVector
<GRFFile
*, 16> _grf_files
;
72 /** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
73 byte _misc_grf_features
= 0;
75 /** 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
76 static uint32 _ttdpatch_flags
[8];
78 /** Indicates which are the newgrf features currently loaded ingame */
79 GRFLoadedFeatures _loaded_newgrf_features
;
81 static const uint MAX_SPRITEGROUP
= UINT8_MAX
; ///< Maximum GRF-local ID for a spritegroup.
83 /** Temporary data during loading of GRFs */
84 struct GrfProcessingState
{
86 /** Definition of a single Action1 spriteset */
88 SpriteID sprite
; ///< SpriteID of the first sprite of the set.
89 uint num_sprites
; ///< Number of sprites in the set.
92 /** Currently referenceable spritesets */
93 btree::btree_map
<uint
, SpriteSet
> spritesets
[GSF_END
];
97 GrfLoadingStage stage
; ///< Current loading stage
98 SpriteID spriteid
; ///< First available SpriteID for loading realsprites.
100 /* Local state in the file */
101 uint file_index
; ///< File index of currently processed GRF file.
102 GRFFile
*grffile
; ///< Currently processed GRF file.
103 GRFConfig
*grfconfig
; ///< Config of the currently processed GRF file.
104 uint32 nfo_line
; ///< Currently processed pseudo sprite number in the GRF.
105 byte grf_container_ver
; ///< Container format of the current GRF file.
107 /* Kind of return values when processing certain actions */
108 int skip_sprites
; ///< Number of psuedo sprites to skip before processing the next one. (-1 to skip to end of file)
110 /* Currently referenceable spritegroups */
111 SpriteGroup
*spritegroups
[MAX_SPRITEGROUP
+ 1];
113 /** Clear temporary data before processing the next file in the current loading stage */
114 void ClearDataForNextFile()
117 this->skip_sprites
= 0;
119 for (uint i
= 0; i
< GSF_END
; i
++) {
120 this->spritesets
[i
].clear();
123 memset(this->spritegroups
, 0, sizeof(this->spritegroups
));
127 * Records new spritesets.
128 * @param feature GrfSpecFeature the set is defined for.
129 * @param first_sprite SpriteID of the first sprite in the set.
130 * @param first_set First spriteset to define.
131 * @param numsets Number of sets to define.
132 * @param numents Number of sprites per set to define.
134 void AddSpriteSets(byte feature
, SpriteID first_sprite
, uint first_set
, uint numsets
, uint numents
)
136 assert(feature
< GSF_END
);
137 for (uint i
= 0; i
< numsets
; i
++) {
138 SpriteSet
&set
= this->spritesets
[feature
][first_set
+ i
];
139 set
.sprite
= first_sprite
+ i
* numents
;
140 set
.num_sprites
= numents
;
145 * Check whether there are any valid spritesets for a feature.
146 * @param feature GrfSpecFeature to check.
147 * @return true if there are any valid sets.
148 * @note Spritesets with zero sprites are valid to allow callback-failures.
150 bool HasValidSpriteSets(byte feature
) const
152 assert(feature
< GSF_END
);
153 return !this->spritesets
[feature
].empty();
157 * Check whether a specific set is defined.
158 * @param feature GrfSpecFeature to check.
159 * @param set Set to check.
160 * @return true if the set is valid.
161 * @note Spritesets with zero sprites are valid to allow callback-failures.
163 bool IsValidSpriteSet(byte feature
, uint set
) const
165 assert(feature
< GSF_END
);
166 return this->spritesets
[feature
].find(set
) != this->spritesets
[feature
].end();
170 * Returns the first sprite of a spriteset.
171 * @param feature GrfSpecFeature to query.
172 * @param set Set to query.
173 * @return First sprite of the set.
175 SpriteID
GetSprite(byte feature
, uint set
) const
177 assert(IsValidSpriteSet(feature
, set
));
178 return this->spritesets
[feature
].find(set
)->second
.sprite
;
182 * Returns the number of sprites in a spriteset
183 * @param feature GrfSpecFeature to query.
184 * @param set Set to query.
185 * @return Number of sprites in the set.
187 uint
GetNumEnts(byte feature
, uint set
) const
189 assert(IsValidSpriteSet(feature
, set
));
190 return this->spritesets
[feature
].find(set
)->second
.num_sprites
;
194 static GrfProcessingState _cur
;
198 * Helper to check whether an image index is valid for a particular NewGRF vehicle.
199 * @param <T> The type of vehicle.
200 * @param image_index The image index to check.
201 * @return True iff the image index is valid, or 0xFD (use new graphics).
203 template <VehicleType T
>
204 static inline bool IsValidNewGRFImageIndex(uint8 image_index
)
206 return image_index
== 0xFD || IsValidImageIndex
<T
>(image_index
);
209 class OTTDByteReaderSignal
{ };
211 /** Class to read from a NewGRF file */
218 ByteReader(byte
*data
, byte
*end
) : data(data
), end(end
) { }
220 inline byte
ReadByte()
222 if (data
< end
) return *(data
)++;
223 throw OTTDByteReaderSignal();
228 uint16 val
= ReadByte();
229 return val
| (ReadByte() << 8);
232 uint16
ReadExtendedByte()
234 uint16 val
= ReadByte();
235 return val
== 0xFF ? ReadWord() : val
;
240 uint32 val
= ReadWord();
241 return val
| (ReadWord() << 16);
244 uint32
ReadVarSize(byte size
)
247 case 1: return ReadByte();
248 case 2: return ReadWord();
249 case 4: return ReadDWord();
256 const char *ReadString()
258 char *string
= reinterpret_cast<char *>(data
);
259 size_t string_length
= ttd_strnlen(string
, Remaining());
261 if (string_length
== Remaining()) {
262 /* String was not NUL terminated, so make sure it is now. */
263 string
[string_length
- 1] = '\0';
264 grfmsg(7, "String was not terminated with a zero byte.");
266 /* Increase the string length to include the NUL byte. */
274 inline size_t Remaining() const
279 inline bool HasData(size_t count
= 1) const
281 return data
+ count
<= end
;
289 inline void Skip(size_t len
)
292 /* It is valid to move the buffer to exactly the end of the data,
293 * as there may not be any more data read. */
294 if (data
> end
) throw OTTDByteReaderSignal();
298 typedef void (*SpecialSpriteHandler
)(ByteReader
*buf
);
300 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.
302 /** Temporary engine data used when loading only */
303 struct GRFTempEngineData
{
304 /** Summary state of refittability properties */
306 UNSET
= 0, ///< No properties assigned. Default refit masks shall be activated.
307 EMPTY
, ///< GRF defined vehicle as not-refittable. The vehicle shall only carry the default cargo.
308 NONEMPTY
, ///< GRF defined the vehicle as refittable. If the refitmask is empty after translation (cargotypes not available), disable the vehicle.
311 uint16 cargo_allowed
;
312 uint16 cargo_disallowed
;
313 RailTypeLabel railtypelabel
;
314 const GRFFile
*defaultcargo_grf
; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'.
315 Refittability refittability
; ///< Did the newgrf set any refittability property? If not, default refittability will be applied.
316 bool prop27_set
; ///< Did the NewGRF set property 27 (misc flags)?
317 uint8 rv_max_speed
; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8
318 uint32 ctt_include_mask
; ///< Cargo types always included in the refit mask.
319 uint32 ctt_exclude_mask
; ///< Cargo types always excluded from the refit mask.
322 * Update the summary refittability on setting a refittability property.
323 * @param non_empty true if the GRF sets the vehicle to be refittable.
325 void UpdateRefittability(bool non_empty
)
328 this->refittability
= NONEMPTY
;
329 } else if (this->refittability
== UNSET
) {
330 this->refittability
= EMPTY
;
335 static GRFTempEngineData
*_gted
; ///< Temporary engine data used during NewGRF loading
338 * Contains the GRF ID of the owner of a vehicle if it has been reserved.
339 * GRM for vehicles is only used if dynamic engine allocation is disabled,
340 * so 256 is the number of original engines. */
341 static uint32 _grm_engines
[256];
343 /** Contains the GRF ID of the owner of a cargo if it has been reserved */
344 static uint32 _grm_cargoes
[NUM_CARGO
* 2];
351 GRFLocation(uint32 grfid
, uint32 nfoline
) : grfid(grfid
), nfoline(nfoline
) { }
353 bool operator<(const GRFLocation
&other
) const
355 return this->grfid
< other
.grfid
|| (this->grfid
== other
.grfid
&& this->nfoline
< other
.nfoline
);
358 bool operator == (const GRFLocation
&other
) const
360 return this->grfid
== other
.grfid
&& this->nfoline
== other
.nfoline
;
364 static btree::btree_map
<GRFLocation
, SpriteID
> _grm_sprites
;
365 typedef btree::btree_map
<GRFLocation
, byte
*> GRFLineToSpriteOverride
;
366 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override
;
369 * DEBUG() function dedicated to newGRF debugging messages
370 * Function is essentially the same as DEBUG(grf, severity, ...) with the
371 * addition of file:line information when parsing grf files.
372 * NOTE: for the above reason(s) grfmsg() should ONLY be used for
373 * loading/parsing grf files, not for runtime debug messages as there
374 * is no file information available during that time.
375 * @param severity debugging severity level, see debug.h
376 * @param str message in printf() format
378 void CDECL
grfmsg(int severity
, const char *str
, ...)
384 vseprintf(buf
, lastof(buf
), str
, va
);
387 DEBUG(grf
, severity
, "[%s:%d] %s", _cur
.grfconfig
->filename
, _cur
.nfo_line
, buf
);
391 * Obtain a NewGRF file by its grfID
392 * @param grfid The grfID to obtain the file for
395 static GRFFile
*GetFileByGRFID(uint32 grfid
)
397 const GRFFile
* const *end
= _grf_files
.End();
398 for (GRFFile
* const *file
= _grf_files
.Begin(); file
!= end
; file
++) {
399 if ((*file
)->grfid
== grfid
) return *file
;
405 * Obtain a NewGRF file by its filename
406 * @param filename The filename to obtain the file for.
409 static GRFFile
*GetFileByFilename(const char *filename
)
411 const GRFFile
* const *end
= _grf_files
.End();
412 for (GRFFile
* const *file
= _grf_files
.Begin(); file
!= end
; file
++) {
413 if (strcmp((*file
)->filename
, filename
) == 0) return *file
;
418 /** Reset all NewGRFData that was used only while processing data */
419 static void ClearTemporaryNewGRFData(GRFFile
*gf
)
421 /* Clear the GOTO labels used for GRF processing */
422 for (GRFLabel
*l
= gf
->label
; l
!= NULL
;) {
423 GRFLabel
*l2
= l
->next
;
432 * @param message Error message or STR_NULL.
433 * @param config GRFConfig to disable, NULL for current.
434 * @return Error message of the GRF for further customisation.
436 static GRFError
*DisableGrf(StringID message
= STR_NULL
, GRFConfig
*config
= NULL
)
439 if (config
!= NULL
) {
440 file
= GetFileByGRFID(config
->ident
.grfid
);
442 config
= _cur
.grfconfig
;
446 config
->status
= GCS_DISABLED
;
447 if (file
!= NULL
) ClearTemporaryNewGRFData(file
);
448 if (config
== _cur
.grfconfig
) _cur
.skip_sprites
= -1;
450 if (message
!= STR_NULL
) {
451 delete config
->error
;
452 config
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, message
);
453 if (config
== _cur
.grfconfig
) config
->error
->param_value
[0] = _cur
.nfo_line
;
456 return config
->error
;
460 * Information for mapping static StringIDs.
462 struct StringIDMapping
{
463 uint32 grfid
; ///< Source NewGRF.
464 StringID source
; ///< Source StringID (GRF local).
465 StringID
*target
; ///< Destination for mapping result.
467 typedef SmallVector
<StringIDMapping
, 16> StringIDMappingVector
;
468 static StringIDMappingVector _string_to_grf_mapping
;
471 * Record a static StringID for getting translated later.
472 * @param source Source StringID (GRF local).
473 * @param target Destination for the mapping result.
475 static void AddStringForMapping(StringID source
, StringID
*target
)
477 *target
= STR_UNDEFINED
;
478 StringIDMapping
*item
= _string_to_grf_mapping
.Append();
479 item
->grfid
= _cur
.grffile
->grfid
;
480 item
->source
= source
;
481 item
->target
= target
;
485 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
486 * string IDs, but only for the ones we are aware off; the rest
487 * like likely unused and will show a warning.
488 * @param str the string ID to convert
489 * @return the converted string ID
491 static StringID
TTDPStringIDToOTTDStringIDMapping(StringID str
)
493 /* StringID table for TextIDs 0x4E->0x6D */
494 static const StringID units_volume
[] = {
495 STR_ITEMS
, STR_PASSENGERS
, STR_TONS
, STR_BAGS
,
496 STR_LITERS
, STR_ITEMS
, STR_CRATES
, STR_TONS
,
497 STR_TONS
, STR_TONS
, STR_TONS
, STR_BAGS
,
498 STR_TONS
, STR_TONS
, STR_TONS
, STR_BAGS
,
499 STR_TONS
, STR_TONS
, STR_BAGS
, STR_LITERS
,
500 STR_TONS
, STR_LITERS
, STR_TONS
, STR_ITEMS
,
501 STR_BAGS
, STR_LITERS
, STR_TONS
, STR_ITEMS
,
502 STR_TONS
, STR_ITEMS
, STR_LITERS
, STR_ITEMS
505 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
506 assert(!IsInsideMM(str
, 0xD000, 0xD7FF));
508 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
509 assert_compile(stringend - stringid == end - begin); \
510 if (str >= begin && str <= end) return str + (stringid - begin)
512 /* We have some changes in our cargo strings, resulting in some missing. */
513 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING
, STR_CARGO_PLURAL_FIZZY_DRINKS
);
514 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING
, STR_CARGO_SINGULAR_FIZZY_DRINK
);
515 if (str
>= 0x004E && str
<= 0x006D) return units_volume
[str
- 0x004E];
516 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING
, STR_QUANTITY_FIZZY_DRINKS
);
517 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING
, STR_ABBREV_FIZZY_DRINKS
);
518 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE
, STR_COLOUR_WHITE
);
520 /* Map building names according to our lang file changes. There are several
521 * ranges of house ids, all of which need to be remapped to allow newgrfs
522 * to use original house names. */
523 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1
, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1
);
524 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1
, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1
);
525 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1
, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1
);
527 /* Same thing for industries */
528 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE
, STR_INDUSTRY_NAME_SUGAR_MINE
);
529 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION
, STR_NEWS_INDUSTRY_PLANTED
);
530 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL
, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES
);
531 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL
, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM
);
532 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL
, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM
);
535 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY
;
536 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED
;
537 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED
;
539 #undef TEXTID_TO_STRINGID
541 if (str
== STR_NULL
) return STR_EMPTY
;
543 DEBUG(grf
, 0, "Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str
);
549 * Used when setting an object's property to map to the GRF's strings
550 * while taking in consideration the "drift" between TTDPatch string system and OpenTTD's one
551 * @param grfid Id of the grf file.
552 * @param str StringID that we want to have the equivalent in OoenTTD.
553 * @return The properly adjusted StringID.
555 StringID
MapGRFStringID(uint32 grfid
, StringID str
)
557 if (IsInsideMM(str
, 0xD800, 0xE000)) {
558 /* General text provided by NewGRF.
559 * In the specs this is called the 0xDCxx range (misc presistent texts),
560 * but we meanwhile extended the range to 0xD800-0xDFFF.
561 * Note: We are not involved in the "persistent" business, since we do not store
562 * any NewGRF strings in savegames. */
563 return GetGRFStringID(grfid
, str
);
564 } else if (IsInsideMM(str
, 0xD000, 0xD800)) {
565 /* Callback text provided by NewGRF.
566 * In the specs this is called the 0xD0xx range (misc graphics texts).
567 * These texts can be returned by various callbacks.
569 * Due to how TTDP implements the GRF-local- to global-textid translation
570 * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
571 * We do not care about that difference and just mask out the 0x400 bit.
574 return GetGRFStringID(grfid
, str
);
576 /* The NewGRF wants to include/reference an original TTD string.
577 * Try our best to find an equivalent one. */
578 return TTDPStringIDToOTTDStringIDMapping(str
);
582 static std::map
<uint32
, uint32
> _grf_id_overrides
;
585 * Set the override for a NewGRF
586 * @param source_grfid The grfID which wants to override another NewGRF.
587 * @param target_grfid The grfID which is being overridden.
589 static void SetNewGRFOverride(uint32 source_grfid
, uint32 target_grfid
)
591 _grf_id_overrides
[source_grfid
] = target_grfid
;
592 grfmsg(5, "SetNewGRFOverride: Added override of 0x%X to 0x%X", BSWAP32(source_grfid
), BSWAP32(target_grfid
));
596 * Returns the engine associated to a certain internal_id, resp. allocates it.
597 * @param file NewGRF that wants to change the engine.
598 * @param type Vehicle type.
599 * @param internal_id Engine ID inside the NewGRF.
600 * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04).
601 * @return The requested engine.
603 static Engine
*GetNewEngine(const GRFFile
*file
, VehicleType type
, uint16 internal_id
, bool static_access
= false)
605 /* Hack for add-on GRFs that need to modify another GRF's engines. This lets
606 * them use the same engine slots. */
607 uint32 scope_grfid
= INVALID_GRFID
; // If not using dynamic_engines, all newgrfs share their ID range
608 if (_settings_game
.vehicle
.dynamic_engines
) {
609 /* If dynamic_engies is enabled, there can be multiple independent ID ranges. */
610 scope_grfid
= file
->grfid
;
611 uint32 override
= _grf_id_overrides
[file
->grfid
];
613 scope_grfid
= override
;
614 const GRFFile
*grf_match
= GetFileByGRFID(override
);
615 if (grf_match
== NULL
) {
616 grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file
->grfid
), BSWAP32(override
));
618 grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file
->grfid
), BSWAP32(override
));
622 /* Check if the engine is registered in the override manager */
623 EngineID engine
= _engine_mngr
.GetID(type
, internal_id
, scope_grfid
);
624 if (engine
!= INVALID_ENGINE
) {
625 Engine
*e
= Engine::Get(engine
);
626 if (e
->grf_prop
.grffile
== NULL
) e
->grf_prop
.grffile
= file
;
631 /* Check if there is an unreserved slot */
632 EngineID engine
= _engine_mngr
.GetID(type
, internal_id
, INVALID_GRFID
);
633 if (engine
!= INVALID_ENGINE
) {
634 Engine
*e
= Engine::Get(engine
);
636 if (e
->grf_prop
.grffile
== NULL
) {
637 e
->grf_prop
.grffile
= file
;
638 grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e
->index
, BSWAP32(file
->grfid
), type
, internal_id
);
641 /* Reserve the engine slot */
642 if (!static_access
) {
643 EngineIDMapping
*eid
= _engine_mngr
.Get(engine
);
644 eid
->grfid
= scope_grfid
; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
650 if (static_access
) return NULL
;
652 if (!Engine::CanAllocateItem()) {
653 grfmsg(0, "Can't allocate any more engines");
657 size_t engine_pool_size
= Engine::GetPoolSize();
659 /* ... it's not, so create a new one based off an existing engine */
660 Engine
*e
= new Engine(type
, internal_id
);
661 e
->grf_prop
.grffile
= file
;
663 /* Reserve the engine slot */
664 assert(_engine_mngr
.Length() == e
->index
);
665 EngineIDMapping
*eid
= _engine_mngr
.Append();
667 eid
->grfid
= scope_grfid
; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation
668 eid
->internal_id
= internal_id
;
669 eid
->substitute_id
= min(internal_id
, _engine_counts
[type
]); // substitute_id == _engine_counts[subtype] means "no substitute"
671 if (engine_pool_size
!= Engine::GetPoolSize()) {
672 /* Resize temporary engine data ... */
673 _gted
= ReallocT(_gted
, Engine::GetPoolSize());
675 /* and blank the new block. */
676 size_t len
= (Engine::GetPoolSize() - engine_pool_size
) * sizeof(*_gted
);
677 memset(_gted
+ engine_pool_size
, 0, len
);
679 if (type
== VEH_TRAIN
) {
680 _gted
[e
->index
].railtypelabel
= GetRailTypeInfo(e
->u
.rail
.railtype
)->label
;
683 grfmsg(5, "Created new engine at index %d for GRFID %x, type %d, index %d", e
->index
, BSWAP32(file
->grfid
), type
, internal_id
);
689 * Return the ID of a new engine
690 * @param file The NewGRF file providing the engine.
691 * @param type The Vehicle type.
692 * @param internal_id NewGRF-internal ID of the engine.
693 * @return The new EngineID.
694 * @note depending on the dynamic_engine setting and a possible override
695 * property the grfID may be unique or overwriting or partially re-defining
696 * properties of an existing engine.
698 EngineID
GetNewEngineID(const GRFFile
*file
, VehicleType type
, uint16 internal_id
)
700 uint32 scope_grfid
= INVALID_GRFID
; // If not using dynamic_engines, all newgrfs share their ID range
701 if (_settings_game
.vehicle
.dynamic_engines
) {
702 scope_grfid
= file
->grfid
;
703 uint32 override
= _grf_id_overrides
[file
->grfid
];
704 if (override
!= 0) scope_grfid
= override
;
707 return _engine_mngr
.GetID(type
, internal_id
, scope_grfid
);
711 * Map the colour modifiers of TTDPatch to those that Open is using.
712 * @param grf_sprite Pointer to the structure been modified.
714 static void MapSpriteMappingRecolour(PalSpriteID
*grf_sprite
)
716 if (HasBit(grf_sprite
->pal
, 14)) {
717 ClrBit(grf_sprite
->pal
, 14);
718 SetBit(grf_sprite
->sprite
, SPRITE_MODIFIER_OPAQUE
);
721 if (HasBit(grf_sprite
->sprite
, 14)) {
722 ClrBit(grf_sprite
->sprite
, 14);
723 SetBit(grf_sprite
->sprite
, PALETTE_MODIFIER_TRANSPARENT
);
726 if (HasBit(grf_sprite
->sprite
, 15)) {
727 ClrBit(grf_sprite
->sprite
, 15);
728 SetBit(grf_sprite
->sprite
, PALETTE_MODIFIER_COLOUR
);
733 * Read a sprite and a palette from the GRF and convert them into a format
734 * suitable to OpenTTD.
735 * @param buf Input stream.
736 * @param read_flags Whether to read TileLayoutFlags.
737 * @param invert_action1_flag Set to true, if palette bit 15 means 'not from action 1'.
738 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
739 * @param feature GrfSpecFeature to use spritesets from.
740 * @param [out] grf_sprite Read sprite and palette.
741 * @param [out] max_sprite_offset Optionally returns the number of sprites in the spriteset of the sprite. (0 if no spritset)
742 * @param [out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset)
743 * @return Read TileLayoutFlags.
745 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
)
747 grf_sprite
->sprite
= buf
->ReadWord();
748 grf_sprite
->pal
= buf
->ReadWord();
749 TileLayoutFlags flags
= read_flags
? (TileLayoutFlags
)buf
->ReadWord() : TLF_NOTHING
;
751 MapSpriteMappingRecolour(grf_sprite
);
753 bool custom_sprite
= HasBit(grf_sprite
->pal
, 15) != invert_action1_flag
;
754 ClrBit(grf_sprite
->pal
, 15);
756 /* Use sprite from Action 1 */
757 uint index
= GB(grf_sprite
->sprite
, 0, 14);
758 if (use_cur_spritesets
&& (!_cur
.IsValidSpriteSet(feature
, index
) || _cur
.GetNumEnts(feature
, index
) == 0)) {
759 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index
);
760 grf_sprite
->sprite
= SPR_IMG_QUERY
;
761 grf_sprite
->pal
= PAL_NONE
;
763 SpriteID sprite
= use_cur_spritesets
? _cur
.GetSprite(feature
, index
) : index
;
764 if (max_sprite_offset
!= NULL
) *max_sprite_offset
= use_cur_spritesets
? _cur
.GetNumEnts(feature
, index
) : UINT16_MAX
;
765 SB(grf_sprite
->sprite
, 0, SPRITE_WIDTH
, sprite
);
766 SetBit(grf_sprite
->sprite
, SPRITE_MODIFIER_CUSTOM_SPRITE
);
768 } else if ((flags
& TLF_SPRITE_VAR10
) && !(flags
& TLF_SPRITE_REG_FLAGS
)) {
769 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
770 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
774 if (flags
& TLF_CUSTOM_PALETTE
) {
775 /* Use palette from Action 1 */
776 uint index
= GB(grf_sprite
->pal
, 0, 14);
777 if (use_cur_spritesets
&& (!_cur
.IsValidSpriteSet(feature
, index
) || _cur
.GetNumEnts(feature
, index
) == 0)) {
778 grfmsg(1, "ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index
);
779 grf_sprite
->pal
= PAL_NONE
;
781 SpriteID sprite
= use_cur_spritesets
? _cur
.GetSprite(feature
, index
) : index
;
782 if (max_palette_offset
!= NULL
) *max_palette_offset
= use_cur_spritesets
? _cur
.GetNumEnts(feature
, index
) : UINT16_MAX
;
783 SB(grf_sprite
->pal
, 0, SPRITE_WIDTH
, sprite
);
784 SetBit(grf_sprite
->pal
, SPRITE_MODIFIER_CUSTOM_SPRITE
);
786 } else if ((flags
& TLF_PALETTE_VAR10
) && !(flags
& TLF_PALETTE_REG_FLAGS
)) {
787 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
788 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
796 * Preprocess the TileLayoutFlags and read register modifiers from the GRF.
797 * @param buf Input stream.
798 * @param flags TileLayoutFlags to process.
799 * @param is_parent Whether the sprite is a parentsprite with a bounding box.
800 * @param dts Sprite layout to insert data into.
801 * @param index Sprite index to process; 0 for ground sprite.
803 static void ReadSpriteLayoutRegisters(ByteReader
*buf
, TileLayoutFlags flags
, bool is_parent
, NewGRFSpriteLayout
*dts
, uint index
)
805 if (!(flags
& TLF_DRAWING_FLAGS
)) return;
807 if (dts
->registers
== NULL
) dts
->AllocateRegisters();
808 TileLayoutRegisters
®s
= const_cast<TileLayoutRegisters
&>(dts
->registers
[index
]);
809 regs
.flags
= flags
& TLF_DRAWING_FLAGS
;
811 if (flags
& TLF_DODRAW
) regs
.dodraw
= buf
->ReadByte();
812 if (flags
& TLF_SPRITE
) regs
.sprite
= buf
->ReadByte();
813 if (flags
& TLF_PALETTE
) regs
.palette
= buf
->ReadByte();
816 if (flags
& TLF_BB_XY_OFFSET
) {
817 regs
.delta
.parent
[0] = buf
->ReadByte();
818 regs
.delta
.parent
[1] = buf
->ReadByte();
820 if (flags
& TLF_BB_Z_OFFSET
) regs
.delta
.parent
[2] = buf
->ReadByte();
822 if (flags
& TLF_CHILD_X_OFFSET
) regs
.delta
.child
[0] = buf
->ReadByte();
823 if (flags
& TLF_CHILD_Y_OFFSET
) regs
.delta
.child
[1] = buf
->ReadByte();
826 if (flags
& TLF_SPRITE_VAR10
) {
827 regs
.sprite_var10
= buf
->ReadByte();
828 if (regs
.sprite_var10
> TLR_MAX_VAR10
) {
829 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs
.sprite_var10
, TLR_MAX_VAR10
);
830 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
835 if (flags
& TLF_PALETTE_VAR10
) {
836 regs
.palette_var10
= buf
->ReadByte();
837 if (regs
.palette_var10
> TLR_MAX_VAR10
) {
838 grfmsg(1, "ReadSpriteLayoutRegisters: Spritelayout specifies var10 (%d) exceeding the maximal allowed value %d", regs
.palette_var10
, TLR_MAX_VAR10
);
839 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
846 * Read a spritelayout from the GRF.
848 * @param num_building_sprites Number of building sprites to read
849 * @param use_cur_spritesets Whether to use currently referenceable action 1 sets.
850 * @param feature GrfSpecFeature to use spritesets from.
851 * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains
852 * @param no_z_position Whether bounding boxes have no Z offset
853 * @param dts Layout container to output into
854 * @return True on error (GRF was disabled).
856 static bool ReadSpriteLayout(ByteReader
*buf
, uint num_building_sprites
, bool use_cur_spritesets
, byte feature
, bool allow_var10
, bool no_z_position
, NewGRFSpriteLayout
*dts
)
858 bool has_flags
= HasBit(num_building_sprites
, 6);
859 ClrBit(num_building_sprites
, 6);
860 TileLayoutFlags valid_flags
= TLF_KNOWN_FLAGS
;
861 if (!allow_var10
) valid_flags
&= ~TLF_VAR10_FLAGS
;
862 dts
->Allocate(num_building_sprites
); // allocate before reading groundsprite flags
864 uint16
*max_sprite_offset
= AllocaM(uint16
, num_building_sprites
+ 1);
865 uint16
*max_palette_offset
= AllocaM(uint16
, num_building_sprites
+ 1);
866 MemSetT(max_sprite_offset
, 0, num_building_sprites
+ 1);
867 MemSetT(max_palette_offset
, 0, num_building_sprites
+ 1);
870 TileLayoutFlags flags
= ReadSpriteLayoutSprite(buf
, has_flags
, false, use_cur_spritesets
, feature
, &dts
->ground
, max_sprite_offset
, max_palette_offset
);
871 if (_cur
.skip_sprites
< 0) return true;
873 if (flags
& ~(valid_flags
& ~TLF_NON_GROUND_FLAGS
)) {
874 grfmsg(1, "ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags
& ~(valid_flags
& ~TLF_NON_GROUND_FLAGS
));
875 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
879 ReadSpriteLayoutRegisters(buf
, flags
, false, dts
, 0);
880 if (_cur
.skip_sprites
< 0) return true;
882 for (uint i
= 0; i
< num_building_sprites
; i
++) {
883 DrawTileSeqStruct
*seq
= const_cast<DrawTileSeqStruct
*>(&dts
->seq
[i
]);
885 flags
= ReadSpriteLayoutSprite(buf
, has_flags
, false, use_cur_spritesets
, feature
, &seq
->image
, max_sprite_offset
+ i
+ 1, max_palette_offset
+ i
+ 1);
886 if (_cur
.skip_sprites
< 0) return true;
888 if (flags
& ~valid_flags
) {
889 grfmsg(1, "ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags
& ~valid_flags
);
890 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT
);
894 seq
->delta_x
= buf
->ReadByte();
895 seq
->delta_y
= buf
->ReadByte();
897 if (!no_z_position
) seq
->delta_z
= buf
->ReadByte();
899 if (seq
->IsParentSprite()) {
900 seq
->size_x
= buf
->ReadByte();
901 seq
->size_y
= buf
->ReadByte();
902 seq
->size_z
= buf
->ReadByte();
905 ReadSpriteLayoutRegisters(buf
, flags
, seq
->IsParentSprite(), dts
, i
+ 1);
906 if (_cur
.skip_sprites
< 0) return true;
909 /* Check if the number of sprites per spriteset is consistent */
910 bool is_consistent
= true;
911 dts
->consistent_max_offset
= 0;
912 for (uint i
= 0; i
< num_building_sprites
+ 1; i
++) {
913 if (max_sprite_offset
[i
] > 0) {
914 if (dts
->consistent_max_offset
== 0) {
915 dts
->consistent_max_offset
= max_sprite_offset
[i
];
916 } else if (dts
->consistent_max_offset
!= max_sprite_offset
[i
]) {
917 is_consistent
= false;
921 if (max_palette_offset
[i
] > 0) {
922 if (dts
->consistent_max_offset
== 0) {
923 dts
->consistent_max_offset
= max_palette_offset
[i
];
924 } else if (dts
->consistent_max_offset
!= max_palette_offset
[i
]) {
925 is_consistent
= false;
931 /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */
932 assert(use_cur_spritesets
|| (is_consistent
&& (dts
->consistent_max_offset
== 0 || dts
->consistent_max_offset
== UINT16_MAX
)));
934 if (!is_consistent
|| dts
->registers
!= NULL
) {
935 dts
->consistent_max_offset
= 0;
936 if (dts
->registers
== NULL
) dts
->AllocateRegisters();
938 for (uint i
= 0; i
< num_building_sprites
+ 1; i
++) {
939 TileLayoutRegisters
®s
= const_cast<TileLayoutRegisters
&>(dts
->registers
[i
]);
940 regs
.max_sprite_offset
= max_sprite_offset
[i
];
941 regs
.max_palette_offset
= max_palette_offset
[i
];
949 * Translate the refit mask.
951 static uint32
TranslateRefitMask(uint32 refit_mask
)
955 FOR_EACH_SET_BIT(bit
, refit_mask
) {
956 CargoID cargo
= GetCargoTranslation(bit
, _cur
.grffile
, true);
957 if (cargo
!= CT_INVALID
) SetBit(result
, cargo
);
963 * Converts TTD(P) Base Price pointers into the enum used by OTTD
964 * See http://wiki.ttdpatch.net/tiki-index.php?page=BaseCosts
965 * @param base_pointer TTD(P) Base Price Pointer
966 * @param error_location Function name for grf error messages
967 * @param[out] index If \a base_pointer is valid, \a index is assigned to the matching price; else it is left unchanged
969 static void ConvertTTDBasePrice(uint32 base_pointer
, const char *error_location
, Price
*index
)
971 /* Special value for 'none' */
972 if (base_pointer
== 0) {
973 *index
= INVALID_PRICE
;
977 static const uint32 start
= 0x4B34; ///< Position of first base price
978 static const uint32 size
= 6; ///< Size of each base price record
980 if (base_pointer
< start
|| (base_pointer
- start
) % size
!= 0 || (base_pointer
- start
) / size
>= PR_END
) {
981 grfmsg(1, "%s: Unsupported running cost base 0x%04X, ignoring", error_location
, base_pointer
);
985 *index
= (Price
)((base_pointer
- start
) / size
);
988 /** Possible return values for the FeatureChangeInfo functions */
989 enum ChangeInfoResult
{
990 CIR_SUCCESS
, ///< Variable was parsed and read
991 CIR_DISABLED
, ///< GRF was disabled due to error
992 CIR_UNHANDLED
, ///< Variable was parsed but unread
993 CIR_UNKNOWN
, ///< Variable is unknown
994 CIR_INVALID_ID
, ///< Attempt to modify an invalid ID
997 typedef ChangeInfoResult (*VCI_Handler
)(uint engine
, int numinfo
, int prop
, ByteReader
*buf
);
1000 * Define properties common to all vehicles
1001 * @param ei Engine info.
1002 * @param prop The property to change.
1003 * @param buf The property value.
1004 * @return ChangeInfoResult.
1006 static ChangeInfoResult
CommonVehicleChangeInfo(EngineInfo
*ei
, int prop
, ByteReader
*buf
)
1009 case 0x00: // Introduction date
1010 ei
->base_intro
= buf
->ReadWord() + DAYS_TILL_ORIGINAL_BASE_YEAR
;
1013 case 0x02: // Decay speed
1014 ei
->decay_speed
= buf
->ReadByte();
1017 case 0x03: // Vehicle life
1018 ei
->lifelength
= buf
->ReadByte();
1021 case 0x04: // Model life
1022 ei
->base_life
= buf
->ReadByte();
1025 case 0x06: // Climates available
1026 ei
->climates
= buf
->ReadByte();
1029 case PROP_VEHICLE_LOAD_AMOUNT
: // 0x07 Loading speed
1030 /* Amount of cargo loaded during a vehicle's "loading tick" */
1031 ei
->load_amount
= buf
->ReadByte();
1042 * Define properties for rail vehicles
1043 * @param engine :ocal ID of the first vehicle.
1044 * @param numinfo Number of subsequent IDs to change the property for.
1045 * @param prop The property to change.
1046 * @param buf The property value.
1047 * @return ChangeInfoResult.
1049 static ChangeInfoResult
RailVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1051 ChangeInfoResult ret
= CIR_SUCCESS
;
1053 for (int i
= 0; i
< numinfo
; i
++) {
1054 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_TRAIN
, engine
+ i
);
1055 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1057 EngineInfo
*ei
= &e
->info
;
1058 RailVehicleInfo
*rvi
= &e
->u
.rail
;
1061 case 0x05: { // Track type
1062 uint8 tracktype
= buf
->ReadByte();
1064 if (tracktype
< _cur
.grffile
->railtype_list
.Length()) {
1065 _gted
[e
->index
].railtypelabel
= _cur
.grffile
->railtype_list
[tracktype
];
1069 switch (tracktype
) {
1070 case 0: _gted
[e
->index
].railtypelabel
= rvi
->engclass
>= 2 ? RAILTYPE_ELECTRIC_LABEL
: RAILTYPE_RAIL_LABEL
; break;
1071 case 1: _gted
[e
->index
].railtypelabel
= RAILTYPE_MONO_LABEL
; break;
1072 case 2: _gted
[e
->index
].railtypelabel
= RAILTYPE_MAGLEV_LABEL
; break;
1074 grfmsg(1, "RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype
);
1080 case 0x08: // AI passenger service
1081 /* Tells the AI that this engine is designed for
1082 * passenger services and shouldn't be used for freight. */
1083 rvi
->ai_passenger_only
= buf
->ReadByte();
1086 case PROP_TRAIN_SPEED
: { // 0x09 Speed (1 unit is 1 km-ish/h)
1087 uint16 speed
= buf
->ReadWord();
1088 if (speed
== 0xFFFF) speed
= 0;
1090 rvi
->max_speed
= speed
;
1094 case PROP_TRAIN_POWER
: // 0x0B Power
1095 rvi
->power
= buf
->ReadWord();
1097 /* Set engine / wagon state based on power */
1098 if (rvi
->power
!= 0) {
1099 if (rvi
->railveh_type
== RAILVEH_WAGON
) {
1100 rvi
->railveh_type
= RAILVEH_SINGLEHEAD
;
1103 rvi
->railveh_type
= RAILVEH_WAGON
;
1107 case PROP_TRAIN_RUNNING_COST_FACTOR
: // 0x0D Running cost factor
1108 rvi
->running_cost
= buf
->ReadByte();
1111 case 0x0E: // Running cost base
1112 ConvertTTDBasePrice(buf
->ReadDWord(), "RailVehicleChangeInfo", &rvi
->running_cost_class
);
1115 case 0x12: { // Sprite ID
1116 uint8 spriteid
= buf
->ReadByte();
1117 uint8 orig_spriteid
= spriteid
;
1119 /* TTD sprite IDs point to a location in a 16bit array, but we use it
1120 * as an array index, so we need it to be half the original value. */
1121 if (spriteid
< 0xFD) spriteid
>>= 1;
1123 if (IsValidNewGRFImageIndex
<VEH_TRAIN
>(spriteid
)) {
1124 rvi
->image_index
= spriteid
;
1126 grfmsg(1, "RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1127 rvi
->image_index
= 0;
1132 case 0x13: { // Dual-headed
1133 uint8 dual
= buf
->ReadByte();
1136 rvi
->railveh_type
= RAILVEH_MULTIHEAD
;
1138 rvi
->railveh_type
= rvi
->power
== 0 ?
1139 RAILVEH_WAGON
: RAILVEH_SINGLEHEAD
;
1144 case PROP_TRAIN_CARGO_CAPACITY
: // 0x14 Cargo capacity
1145 rvi
->capacity
= buf
->ReadByte();
1148 case 0x15: { // Cargo type
1149 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1150 uint8 ctype
= buf
->ReadByte();
1152 if (ctype
== 0xFF) {
1153 /* 0xFF is specified as 'use first refittable' */
1154 ei
->cargo_type
= CT_INVALID
;
1155 } else if (_cur
.grffile
->grf_version
>= 8) {
1156 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1157 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1158 } else if (ctype
< NUM_CARGO
) {
1159 /* Use untranslated cargo. */
1160 ei
->cargo_type
= ctype
;
1162 ei
->cargo_type
= CT_INVALID
;
1163 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1168 case PROP_TRAIN_WEIGHT
: // 0x16 Weight
1169 SB(rvi
->weight
, 0, 8, buf
->ReadByte());
1172 case PROP_TRAIN_COST_FACTOR
: // 0x17 Cost factor
1173 rvi
->cost_factor
= buf
->ReadByte();
1176 case 0x18: // AI rank
1177 grfmsg(2, "RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1181 case 0x19: { // Engine traction type
1182 /* What do the individual numbers mean?
1183 * 0x00 .. 0x07: Steam
1184 * 0x08 .. 0x27: Diesel
1185 * 0x28 .. 0x31: Electric
1186 * 0x32 .. 0x37: Monorail
1187 * 0x38 .. 0x41: Maglev
1189 uint8 traction
= buf
->ReadByte();
1190 EngineClass engclass
;
1192 if (traction
<= 0x07) {
1193 engclass
= EC_STEAM
;
1194 } else if (traction
<= 0x27) {
1195 engclass
= EC_DIESEL
;
1196 } else if (traction
<= 0x31) {
1197 engclass
= EC_ELECTRIC
;
1198 } else if (traction
<= 0x37) {
1199 engclass
= EC_MONORAIL
;
1200 } else if (traction
<= 0x41) {
1201 engclass
= EC_MAGLEV
;
1206 if (_cur
.grffile
->railtype_list
.Length() == 0) {
1207 /* Use traction type to select between normal and electrified
1208 * rail only when no translation list is in place. */
1209 if (_gted
[e
->index
].railtypelabel
== RAILTYPE_RAIL_LABEL
&& engclass
>= EC_ELECTRIC
) _gted
[e
->index
].railtypelabel
= RAILTYPE_ELECTRIC_LABEL
;
1210 if (_gted
[e
->index
].railtypelabel
== RAILTYPE_ELECTRIC_LABEL
&& engclass
< EC_ELECTRIC
) _gted
[e
->index
].railtypelabel
= RAILTYPE_RAIL_LABEL
;
1213 rvi
->engclass
= engclass
;
1217 case 0x1A: // Alter purchase list sort order
1218 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1221 case 0x1B: // Powered wagons power bonus
1222 rvi
->pow_wag_power
= buf
->ReadWord();
1225 case 0x1C: // Refit cost
1226 ei
->refit_cost
= buf
->ReadByte();
1229 case 0x1D: { // Refit cargo
1230 uint32 mask
= buf
->ReadDWord();
1231 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1232 ei
->refit_mask
= TranslateRefitMask(mask
);
1233 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1237 case 0x1E: // Callback
1238 ei
->callback_mask
= buf
->ReadByte();
1241 case PROP_TRAIN_TRACTIVE_EFFORT
: // 0x1F Tractive effort coefficient
1242 rvi
->tractive_effort
= buf
->ReadByte();
1245 case 0x20: // Air drag
1246 rvi
->air_drag
= buf
->ReadByte();
1249 case PROP_TRAIN_SHORTEN_FACTOR
: // 0x21 Shorter vehicle
1250 rvi
->shorten_factor
= buf
->ReadByte();
1253 case 0x22: // Visual effect
1254 rvi
->visual_effect
= buf
->ReadByte();
1255 /* Avoid accidentally setting visual_effect to the default value
1256 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1257 if (rvi
->visual_effect
== VE_DEFAULT
) {
1258 assert(HasBit(rvi
->visual_effect
, VE_DISABLE_EFFECT
));
1259 SB(rvi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1263 case 0x23: // Powered wagons weight bonus
1264 rvi
->pow_wag_weight
= buf
->ReadByte();
1267 case 0x24: { // High byte of vehicle weight
1268 byte weight
= buf
->ReadByte();
1271 grfmsg(2, "RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight
<< 8);
1273 SB(rvi
->weight
, 8, 8, weight
);
1278 case PROP_TRAIN_USER_DATA
: // 0x25 User-defined bit mask to set when checking veh. var. 42
1279 rvi
->user_def_data
= buf
->ReadByte();
1282 case 0x26: // Retire vehicle early
1283 ei
->retire_early
= buf
->ReadByte();
1286 case 0x27: // Miscellaneous flags
1287 ei
->misc_flags
= buf
->ReadByte();
1288 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1289 _gted
[e
->index
].prop27_set
= true;
1292 case 0x28: // Cargo classes allowed
1293 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1294 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1295 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1298 case 0x29: // Cargo classes disallowed
1299 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1300 _gted
[e
->index
].UpdateRefittability(false);
1303 case 0x2A: // Long format introduction date (days since year 0)
1304 ei
->base_intro
= buf
->ReadDWord();
1307 case PROP_TRAIN_CARGO_AGE_PERIOD
: // 0x2B Cargo aging period
1308 ei
->cargo_age_period
= buf
->ReadWord();
1311 case 0x2C: // CTT refit include list
1312 case 0x2D: { // CTT refit exclude list
1313 uint8 count
= buf
->ReadByte();
1314 _gted
[e
->index
].UpdateRefittability(prop
== 0x2C && count
!= 0);
1315 if (prop
== 0x2C) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1316 uint32
&ctt
= prop
== 0x2C ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1319 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1320 if (ctype
== CT_INVALID
) continue;
1327 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1336 * Define properties for road vehicles
1337 * @param engine Local ID of the first vehicle.
1338 * @param numinfo Number of subsequent IDs to change the property for.
1339 * @param prop The property to change.
1340 * @param buf The property value.
1341 * @return ChangeInfoResult.
1343 static ChangeInfoResult
RoadVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1345 ChangeInfoResult ret
= CIR_SUCCESS
;
1347 for (int i
= 0; i
< numinfo
; i
++) {
1348 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_ROAD
, engine
+ i
);
1349 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1351 EngineInfo
*ei
= &e
->info
;
1352 RoadVehicleInfo
*rvi
= &e
->u
.road
;
1355 case 0x08: // Speed (1 unit is 0.5 kmh)
1356 rvi
->max_speed
= buf
->ReadByte();
1359 case PROP_ROADVEH_RUNNING_COST_FACTOR
: // 0x09 Running cost factor
1360 rvi
->running_cost
= buf
->ReadByte();
1363 case 0x0A: // Running cost base
1364 ConvertTTDBasePrice(buf
->ReadDWord(), "RoadVehicleChangeInfo", &rvi
->running_cost_class
);
1367 case 0x0E: { // Sprite ID
1368 uint8 spriteid
= buf
->ReadByte();
1369 uint8 orig_spriteid
= spriteid
;
1371 /* cars have different custom id in the GRF file */
1372 if (spriteid
== 0xFF) spriteid
= 0xFD;
1374 if (spriteid
< 0xFD) spriteid
>>= 1;
1376 if (IsValidNewGRFImageIndex
<VEH_ROAD
>(spriteid
)) {
1377 rvi
->image_index
= spriteid
;
1379 grfmsg(1, "RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1380 rvi
->image_index
= 0;
1385 case PROP_ROADVEH_CARGO_CAPACITY
: // 0x0F Cargo capacity
1386 rvi
->capacity
= buf
->ReadByte();
1389 case 0x10: { // Cargo type
1390 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1391 uint8 ctype
= buf
->ReadByte();
1393 if (ctype
== 0xFF) {
1394 /* 0xFF is specified as 'use first refittable' */
1395 ei
->cargo_type
= CT_INVALID
;
1396 } else if (_cur
.grffile
->grf_version
>= 8) {
1397 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1398 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1399 } else if (ctype
< NUM_CARGO
) {
1400 /* Use untranslated cargo. */
1401 ei
->cargo_type
= ctype
;
1403 ei
->cargo_type
= CT_INVALID
;
1404 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1409 case PROP_ROADVEH_COST_FACTOR
: // 0x11 Cost factor
1410 rvi
->cost_factor
= buf
->ReadByte();
1414 rvi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1417 case PROP_ROADVEH_POWER
: // Power in units of 10 HP.
1418 rvi
->power
= buf
->ReadByte();
1421 case PROP_ROADVEH_WEIGHT
: // Weight in units of 1/4 tons.
1422 rvi
->weight
= buf
->ReadByte();
1425 case PROP_ROADVEH_SPEED
: // Speed in mph/0.8
1426 _gted
[e
->index
].rv_max_speed
= buf
->ReadByte();
1429 case 0x16: { // Cargoes available for refitting
1430 uint32 mask
= buf
->ReadDWord();
1431 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1432 ei
->refit_mask
= TranslateRefitMask(mask
);
1433 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1437 case 0x17: // Callback mask
1438 ei
->callback_mask
= buf
->ReadByte();
1441 case PROP_ROADVEH_TRACTIVE_EFFORT
: // Tractive effort coefficient in 1/256.
1442 rvi
->tractive_effort
= buf
->ReadByte();
1445 case 0x19: // Air drag
1446 rvi
->air_drag
= buf
->ReadByte();
1449 case 0x1A: // Refit cost
1450 ei
->refit_cost
= buf
->ReadByte();
1453 case 0x1B: // Retire vehicle early
1454 ei
->retire_early
= buf
->ReadByte();
1457 case 0x1C: // Miscellaneous flags
1458 ei
->misc_flags
= buf
->ReadByte();
1459 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1462 case 0x1D: // Cargo classes allowed
1463 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1464 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1465 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1468 case 0x1E: // Cargo classes disallowed
1469 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1470 _gted
[e
->index
].UpdateRefittability(false);
1473 case 0x1F: // Long format introduction date (days since year 0)
1474 ei
->base_intro
= buf
->ReadDWord();
1477 case 0x20: // Alter purchase list sort order
1478 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1481 case 0x21: // Visual effect
1482 rvi
->visual_effect
= buf
->ReadByte();
1483 /* Avoid accidentally setting visual_effect to the default value
1484 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1485 if (rvi
->visual_effect
== VE_DEFAULT
) {
1486 assert(HasBit(rvi
->visual_effect
, VE_DISABLE_EFFECT
));
1487 SB(rvi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1491 case PROP_ROADVEH_CARGO_AGE_PERIOD
: // 0x22 Cargo aging period
1492 ei
->cargo_age_period
= buf
->ReadWord();
1495 case PROP_ROADVEH_SHORTEN_FACTOR
: // 0x23 Shorter vehicle
1496 rvi
->shorten_factor
= buf
->ReadByte();
1499 case 0x24: // CTT refit include list
1500 case 0x25: { // CTT refit exclude list
1501 uint8 count
= buf
->ReadByte();
1502 _gted
[e
->index
].UpdateRefittability(prop
== 0x24 && count
!= 0);
1503 if (prop
== 0x24) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1504 uint32
&ctt
= prop
== 0x24 ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1507 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1508 if (ctype
== CT_INVALID
) continue;
1515 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1524 * Define properties for ships
1525 * @param engine Local ID of the first vehicle.
1526 * @param numinfo Number of subsequent IDs to change the property for.
1527 * @param prop The property to change.
1528 * @param buf The property value.
1529 * @return ChangeInfoResult.
1531 static ChangeInfoResult
ShipVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1533 ChangeInfoResult ret
= CIR_SUCCESS
;
1535 for (int i
= 0; i
< numinfo
; i
++) {
1536 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_SHIP
, engine
+ i
);
1537 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1539 EngineInfo
*ei
= &e
->info
;
1540 ShipVehicleInfo
*svi
= &e
->u
.ship
;
1543 case 0x08: { // Sprite ID
1544 uint8 spriteid
= buf
->ReadByte();
1545 uint8 orig_spriteid
= spriteid
;
1547 /* ships have different custom id in the GRF file */
1548 if (spriteid
== 0xFF) spriteid
= 0xFD;
1550 if (spriteid
< 0xFD) spriteid
>>= 1;
1552 if (IsValidNewGRFImageIndex
<VEH_SHIP
>(spriteid
)) {
1553 svi
->image_index
= spriteid
;
1555 grfmsg(1, "ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1556 svi
->image_index
= 0;
1561 case 0x09: // Refittable
1562 svi
->old_refittable
= (buf
->ReadByte() != 0);
1565 case PROP_SHIP_COST_FACTOR
: // 0x0A Cost factor
1566 svi
->cost_factor
= buf
->ReadByte();
1569 case PROP_SHIP_SPEED
: // 0x0B Speed (1 unit is 0.5 km-ish/h)
1570 svi
->max_speed
= buf
->ReadByte();
1573 case 0x0C: { // Cargo type
1574 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1575 uint8 ctype
= buf
->ReadByte();
1577 if (ctype
== 0xFF) {
1578 /* 0xFF is specified as 'use first refittable' */
1579 ei
->cargo_type
= CT_INVALID
;
1580 } else if (_cur
.grffile
->grf_version
>= 8) {
1581 /* Use translated cargo. Might result in CT_INVALID (first refittable), if cargo is not defined. */
1582 ei
->cargo_type
= GetCargoTranslation(ctype
, _cur
.grffile
);
1583 } else if (ctype
< NUM_CARGO
) {
1584 /* Use untranslated cargo. */
1585 ei
->cargo_type
= ctype
;
1587 ei
->cargo_type
= CT_INVALID
;
1588 grfmsg(2, "RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype
);
1593 case PROP_SHIP_CARGO_CAPACITY
: // 0x0D Cargo capacity
1594 svi
->capacity
= buf
->ReadWord();
1597 case PROP_SHIP_RUNNING_COST_FACTOR
: // 0x0F Running cost factor
1598 svi
->running_cost
= buf
->ReadByte();
1602 svi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1605 case 0x11: { // Cargoes available for refitting
1606 uint32 mask
= buf
->ReadDWord();
1607 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1608 ei
->refit_mask
= TranslateRefitMask(mask
);
1609 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1613 case 0x12: // Callback mask
1614 ei
->callback_mask
= buf
->ReadByte();
1617 case 0x13: // Refit cost
1618 ei
->refit_cost
= buf
->ReadByte();
1621 case 0x14: // Ocean speed fraction
1622 svi
->ocean_speed_frac
= buf
->ReadByte();
1625 case 0x15: // Canal speed fraction
1626 svi
->canal_speed_frac
= buf
->ReadByte();
1629 case 0x16: // Retire vehicle early
1630 ei
->retire_early
= buf
->ReadByte();
1633 case 0x17: // Miscellaneous flags
1634 ei
->misc_flags
= buf
->ReadByte();
1635 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1638 case 0x18: // Cargo classes allowed
1639 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1640 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1641 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1644 case 0x19: // Cargo classes disallowed
1645 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1646 _gted
[e
->index
].UpdateRefittability(false);
1649 case 0x1A: // Long format introduction date (days since year 0)
1650 ei
->base_intro
= buf
->ReadDWord();
1653 case 0x1B: // Alter purchase list sort order
1654 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1657 case 0x1C: // Visual effect
1658 svi
->visual_effect
= buf
->ReadByte();
1659 /* Avoid accidentally setting visual_effect to the default value
1660 * Since bit 6 (disable effects) is set anyways, we can safely erase some bits. */
1661 if (svi
->visual_effect
== VE_DEFAULT
) {
1662 assert(HasBit(svi
->visual_effect
, VE_DISABLE_EFFECT
));
1663 SB(svi
->visual_effect
, VE_TYPE_START
, VE_TYPE_COUNT
, 0);
1667 case PROP_SHIP_CARGO_AGE_PERIOD
: // 0x1D Cargo aging period
1668 ei
->cargo_age_period
= buf
->ReadWord();
1671 case 0x1E: // CTT refit include list
1672 case 0x1F: { // CTT refit exclude list
1673 uint8 count
= buf
->ReadByte();
1674 _gted
[e
->index
].UpdateRefittability(prop
== 0x1E && count
!= 0);
1675 if (prop
== 0x1E) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1676 uint32
&ctt
= prop
== 0x1E ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1679 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1680 if (ctype
== CT_INVALID
) continue;
1687 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1696 * Define properties for aircraft
1697 * @param engine Local ID of the aircraft.
1698 * @param numinfo Number of subsequent IDs to change the property for.
1699 * @param prop The property to change.
1700 * @param buf The property value.
1701 * @return ChangeInfoResult.
1703 static ChangeInfoResult
AircraftVehicleChangeInfo(uint engine
, int numinfo
, int prop
, ByteReader
*buf
)
1705 ChangeInfoResult ret
= CIR_SUCCESS
;
1707 for (int i
= 0; i
< numinfo
; i
++) {
1708 Engine
*e
= GetNewEngine(_cur
.grffile
, VEH_AIRCRAFT
, engine
+ i
);
1709 if (e
== NULL
) return CIR_INVALID_ID
; // No engine could be allocated, so neither can any next vehicles
1711 EngineInfo
*ei
= &e
->info
;
1712 AircraftVehicleInfo
*avi
= &e
->u
.air
;
1715 case 0x08: { // Sprite ID
1716 uint8 spriteid
= buf
->ReadByte();
1717 uint8 orig_spriteid
= spriteid
;
1719 /* aircraft have different custom id in the GRF file */
1720 if (spriteid
== 0xFF) spriteid
= 0xFD;
1722 if (spriteid
< 0xFD) spriteid
>>= 1;
1724 if (IsValidNewGRFImageIndex
<VEH_AIRCRAFT
>(spriteid
)) {
1725 avi
->image_index
= spriteid
;
1727 grfmsg(1, "AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid
);
1728 avi
->image_index
= 0;
1733 case 0x09: // Helicopter
1734 if (buf
->ReadByte() == 0) {
1735 avi
->subtype
= AIR_HELI
;
1737 SB(avi
->subtype
, 0, 1, 1); // AIR_CTOL
1742 SB(avi
->subtype
, 1, 1, (buf
->ReadByte() != 0 ? 1 : 0)); // AIR_FAST
1745 case PROP_AIRCRAFT_COST_FACTOR
: // 0x0B Cost factor
1746 avi
->cost_factor
= buf
->ReadByte();
1749 case PROP_AIRCRAFT_SPEED
: // 0x0C Speed (1 unit is 8 mph, we translate to 1 unit is 1 km-ish/h)
1750 avi
->max_speed
= (buf
->ReadByte() * 128) / 10;
1753 case 0x0D: // Acceleration
1754 avi
->acceleration
= buf
->ReadByte();
1757 case PROP_AIRCRAFT_RUNNING_COST_FACTOR
: // 0x0E Running cost factor
1758 avi
->running_cost
= buf
->ReadByte();
1761 case PROP_AIRCRAFT_PASSENGER_CAPACITY
: // 0x0F Passenger capacity
1762 avi
->passenger_capacity
= buf
->ReadWord();
1765 case PROP_AIRCRAFT_MAIL_CAPACITY
: // 0x11 Mail capacity
1766 avi
->mail_capacity
= buf
->ReadByte();
1770 avi
->sfx
= GetNewGRFSoundID(_cur
.grffile
, buf
->ReadByte());
1773 case 0x13: { // Cargoes available for refitting
1774 uint32 mask
= buf
->ReadDWord();
1775 _gted
[e
->index
].UpdateRefittability(mask
!= 0);
1776 ei
->refit_mask
= TranslateRefitMask(mask
);
1777 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1781 case 0x14: // Callback mask
1782 ei
->callback_mask
= buf
->ReadByte();
1785 case 0x15: // Refit cost
1786 ei
->refit_cost
= buf
->ReadByte();
1789 case 0x16: // Retire vehicle early
1790 ei
->retire_early
= buf
->ReadByte();
1793 case 0x17: // Miscellaneous flags
1794 ei
->misc_flags
= buf
->ReadByte();
1795 _loaded_newgrf_features
.has_2CC
|= HasBit(ei
->misc_flags
, EF_USES_2CC
);
1798 case 0x18: // Cargo classes allowed
1799 _gted
[e
->index
].cargo_allowed
= buf
->ReadWord();
1800 _gted
[e
->index
].UpdateRefittability(_gted
[e
->index
].cargo_allowed
!= 0);
1801 _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1804 case 0x19: // Cargo classes disallowed
1805 _gted
[e
->index
].cargo_disallowed
= buf
->ReadWord();
1806 _gted
[e
->index
].UpdateRefittability(false);
1809 case 0x1A: // Long format introduction date (days since year 0)
1810 ei
->base_intro
= buf
->ReadDWord();
1813 case 0x1B: // Alter purchase list sort order
1814 AlterVehicleListOrder(e
->index
, buf
->ReadExtendedByte());
1817 case PROP_AIRCRAFT_CARGO_AGE_PERIOD
: // 0x1C Cargo aging period
1818 ei
->cargo_age_period
= buf
->ReadWord();
1821 case 0x1D: // CTT refit include list
1822 case 0x1E: { // CTT refit exclude list
1823 uint8 count
= buf
->ReadByte();
1824 _gted
[e
->index
].UpdateRefittability(prop
== 0x1D && count
!= 0);
1825 if (prop
== 0x1D) _gted
[e
->index
].defaultcargo_grf
= _cur
.grffile
;
1826 uint32
&ctt
= prop
== 0x1D ? _gted
[e
->index
].ctt_include_mask
: _gted
[e
->index
].ctt_exclude_mask
;
1829 CargoID ctype
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
1830 if (ctype
== CT_INVALID
) continue;
1836 case PROP_AIRCRAFT_RANGE
: // 0x1F Max aircraft range
1837 avi
->max_range
= buf
->ReadWord();
1841 ret
= CommonVehicleChangeInfo(ei
, prop
, buf
);
1850 * Define properties for stations
1851 * @param stdid StationID of the first station tile.
1852 * @param numinfo Number of subsequent station tiles to change the property for.
1853 * @param prop The property to change.
1854 * @param buf The property value.
1855 * @return ChangeInfoResult.
1857 static ChangeInfoResult
StationChangeInfo(uint stid
, int numinfo
, int prop
, ByteReader
*buf
)
1859 ChangeInfoResult ret
= CIR_SUCCESS
;
1861 if (stid
+ numinfo
> NUM_STATIONS_PER_GRF
) {
1862 grfmsg(1, "StationChangeInfo: Station %u is invalid, max %u, ignoring", stid
+ numinfo
, NUM_STATIONS_PER_GRF
);
1863 return CIR_INVALID_ID
;
1866 /* Allocate station specs if necessary */
1867 if (_cur
.grffile
->stations
== NULL
) _cur
.grffile
->stations
= CallocT
<StationSpec
*>(NUM_STATIONS_PER_GRF
);
1869 for (int i
= 0; i
< numinfo
; i
++) {
1870 StationSpec
*statspec
= _cur
.grffile
->stations
[stid
+ i
];
1872 /* Check that the station we are modifying is defined. */
1873 if (statspec
== NULL
&& prop
!= 0x08) {
1874 grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid
+ i
);
1875 return CIR_INVALID_ID
;
1879 case 0x08: { // Class ID
1880 StationSpec
**spec
= &_cur
.grffile
->stations
[stid
+ i
];
1882 /* Property 0x08 is special; it is where the station is allocated */
1883 if (*spec
== NULL
) *spec
= CallocT
<StationSpec
>(1);
1885 /* Swap classid because we read it in BE meaning WAYP or DFLT */
1886 uint32 classid
= buf
->ReadDWord();
1887 (*spec
)->cls_id
= StationClass::Allocate(BSWAP32(classid
));
1891 case 0x09: // Define sprite layout
1892 statspec
->tiles
= buf
->ReadExtendedByte();
1893 delete[] statspec
->renderdata
; // delete earlier loaded stuff
1894 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
1896 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
1897 NewGRFSpriteLayout
*dts
= &statspec
->renderdata
[t
];
1898 dts
->consistent_max_offset
= UINT16_MAX
; // Spritesets are unknown, so no limit.
1900 if (buf
->HasData(4) && *(uint32
*)buf
->Data() == 0) {
1902 extern const DrawTileSprites _station_display_datas_rail
[8];
1903 dts
->Clone(&_station_display_datas_rail
[t
% 8]);
1907 ReadSpriteLayoutSprite(buf
, false, false, false, GSF_STATIONS
, &dts
->ground
);
1908 /* On error, bail out immediately. Temporary GRF data was already freed */
1909 if (_cur
.skip_sprites
< 0) return CIR_DISABLED
;
1911 static SmallVector
<DrawTileSeqStruct
, 8> tmp_layout
;
1914 /* no relative bounding box support */
1915 DrawTileSeqStruct
*dtss
= tmp_layout
.Append();
1918 dtss
->delta_x
= buf
->ReadByte();
1919 if (dtss
->IsTerminator()) break;
1920 dtss
->delta_y
= buf
->ReadByte();
1921 dtss
->delta_z
= buf
->ReadByte();
1922 dtss
->size_x
= buf
->ReadByte();
1923 dtss
->size_y
= buf
->ReadByte();
1924 dtss
->size_z
= buf
->ReadByte();
1926 ReadSpriteLayoutSprite(buf
, false, true, false, GSF_STATIONS
, &dtss
->image
);
1927 /* On error, bail out immediately. Temporary GRF data was already freed */
1928 if (_cur
.skip_sprites
< 0) return CIR_DISABLED
;
1930 dts
->Clone(tmp_layout
.Begin());
1934 case 0x0A: { // Copy sprite layout
1935 byte srcid
= buf
->ReadByte();
1936 const StationSpec
*srcstatspec
= _cur
.grffile
->stations
[srcid
];
1938 if (srcstatspec
== NULL
) {
1939 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid
, stid
+ i
);
1943 delete[] statspec
->renderdata
; // delete earlier loaded stuff
1945 statspec
->tiles
= srcstatspec
->tiles
;
1946 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
1947 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
1948 statspec
->renderdata
[t
].Clone(&srcstatspec
->renderdata
[t
]);
1953 case 0x0B: // Callback mask
1954 statspec
->callback_mask
= buf
->ReadByte();
1957 case 0x0C: // Disallowed number of platforms
1958 statspec
->disallowed_platforms
= buf
->ReadByte();
1961 case 0x0D: // Disallowed platform lengths
1962 statspec
->disallowed_lengths
= buf
->ReadByte();
1965 case 0x0E: // Define custom layout
1966 statspec
->copied_layouts
= false;
1968 while (buf
->HasData()) {
1969 byte length
= buf
->ReadByte();
1970 byte number
= buf
->ReadByte();
1971 StationLayout layout
;
1974 if (length
== 0 || number
== 0) break;
1976 if (length
> statspec
->lengths
) {
1977 statspec
->platforms
= ReallocT(statspec
->platforms
, length
);
1978 memset(statspec
->platforms
+ statspec
->lengths
, 0, length
- statspec
->lengths
);
1980 statspec
->layouts
= ReallocT(statspec
->layouts
, length
);
1981 memset(statspec
->layouts
+ statspec
->lengths
, 0,
1982 (length
- statspec
->lengths
) * sizeof(*statspec
->layouts
));
1984 statspec
->lengths
= length
;
1986 l
= length
- 1; // index is zero-based
1988 if (number
> statspec
->platforms
[l
]) {
1989 statspec
->layouts
[l
] = ReallocT(statspec
->layouts
[l
], number
);
1990 /* We expect NULL being 0 here, but C99 guarantees that. */
1991 memset(statspec
->layouts
[l
] + statspec
->platforms
[l
], 0,
1992 (number
- statspec
->platforms
[l
]) * sizeof(**statspec
->layouts
));
1994 statspec
->platforms
[l
] = number
;
1998 layout
= MallocT
<byte
>(length
* number
);
2000 for (l
= 0; l
< length
; l
++) {
2001 for (p
= 0; p
< number
; p
++) {
2002 layout
[l
* number
+ p
] = buf
->ReadByte();
2012 free(statspec
->layouts
[l
][p
]);
2013 statspec
->layouts
[l
][p
] = layout
;
2017 case 0x0F: { // Copy custom layout
2018 byte srcid
= buf
->ReadByte();
2019 const StationSpec
*srcstatspec
= _cur
.grffile
->stations
[srcid
];
2021 if (srcstatspec
== NULL
) {
2022 grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid
, stid
+ i
);
2026 statspec
->lengths
= srcstatspec
->lengths
;
2027 statspec
->platforms
= srcstatspec
->platforms
;
2028 statspec
->layouts
= srcstatspec
->layouts
;
2029 statspec
->copied_layouts
= true;
2033 case 0x10: // Little/lots cargo threshold
2034 statspec
->cargo_threshold
= buf
->ReadWord();
2037 case 0x11: // Pylon placement
2038 statspec
->pylons
= buf
->ReadByte();
2041 case 0x12: // Cargo types for random triggers
2042 statspec
->cargo_triggers
= buf
->ReadDWord();
2043 if (_cur
.grffile
->grf_version
>= 7) {
2044 statspec
->cargo_triggers
= TranslateRefitMask(statspec
->cargo_triggers
);
2048 case 0x13: // General flags
2049 statspec
->flags
= buf
->ReadByte();
2052 case 0x14: // Overhead wire placement
2053 statspec
->wires
= buf
->ReadByte();
2056 case 0x15: // Blocked tiles
2057 statspec
->blocked
= buf
->ReadByte();
2060 case 0x16: // Animation info
2061 statspec
->animation
.frames
= buf
->ReadByte();
2062 statspec
->animation
.status
= buf
->ReadByte();
2065 case 0x17: // Animation speed
2066 statspec
->animation
.speed
= buf
->ReadByte();
2069 case 0x18: // Animation triggers
2070 statspec
->animation
.triggers
= buf
->ReadWord();
2073 case 0x1A: // Advanced sprite layout
2074 statspec
->tiles
= buf
->ReadExtendedByte();
2075 delete[] statspec
->renderdata
; // delete earlier loaded stuff
2076 statspec
->renderdata
= new NewGRFSpriteLayout
[statspec
->tiles
];
2078 for (uint t
= 0; t
< statspec
->tiles
; t
++) {
2079 NewGRFSpriteLayout
*dts
= &statspec
->renderdata
[t
];
2080 uint num_building_sprites
= buf
->ReadByte();
2081 /* On error, bail out immediately. Temporary GRF data was already freed */
2082 if (ReadSpriteLayout(buf
, num_building_sprites
, false, GSF_STATIONS
, true, false, dts
)) return CIR_DISABLED
;
2096 * Define properties for water features
2097 * @param id Type of the first water feature.
2098 * @param numinfo Number of subsequent water feature ids to change the property for.
2099 * @param prop The property to change.
2100 * @param buf The property value.
2101 * @return ChangeInfoResult.
2103 static ChangeInfoResult
CanalChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
2105 ChangeInfoResult ret
= CIR_SUCCESS
;
2107 if (id
+ numinfo
> CF_END
) {
2108 grfmsg(1, "CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring", id
+ numinfo
, CF_END
);
2109 return CIR_INVALID_ID
;
2112 for (int i
= 0; i
< numinfo
; i
++) {
2113 CanalProperties
*cp
= &_cur
.grffile
->canal_local_properties
[id
+ i
];
2117 cp
->callback_mask
= buf
->ReadByte();
2121 cp
->flags
= buf
->ReadByte();
2134 * Define properties for bridges
2135 * @param brid BridgeID of the bridge.
2136 * @param numinfo Number of subsequent bridgeIDs to change the property for.
2137 * @param prop The property to change.
2138 * @param buf The property value.
2139 * @return ChangeInfoResult.
2141 static ChangeInfoResult
BridgeChangeInfo(uint brid
, int numinfo
, int prop
, ByteReader
*buf
)
2143 ChangeInfoResult ret
= CIR_SUCCESS
;
2145 if (brid
+ numinfo
> MAX_BRIDGES
) {
2146 grfmsg(1, "BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid
+ numinfo
, MAX_BRIDGES
);
2147 return CIR_INVALID_ID
;
2150 for (int i
= 0; i
< numinfo
; i
++) {
2151 BridgeSpec
*bridge
= &_bridge
[brid
+ i
];
2154 case 0x08: { // Year of availability
2155 /* We treat '0' as always available */
2156 byte year
= buf
->ReadByte();
2157 bridge
->avail_year
= (year
> 0 ? ORIGINAL_BASE_YEAR
+ year
: 0);
2161 case 0x09: // Minimum length
2162 bridge
->min_length
= buf
->ReadByte();
2165 case 0x0A: // Maximum length
2166 bridge
->max_length
= buf
->ReadByte();
2167 if (bridge
->max_length
> 16) bridge
->max_length
= 0xFFFF;
2170 case 0x0B: // Cost factor
2171 bridge
->price
= buf
->ReadByte();
2174 case 0x0C: // Maximum speed
2175 bridge
->speed
= buf
->ReadWord();
2178 case 0x0D: { // Bridge sprite tables
2179 byte tableid
= buf
->ReadByte();
2180 byte numtables
= buf
->ReadByte();
2182 if (bridge
->sprite_table
== NULL
) {
2183 /* Allocate memory for sprite table pointers and zero out */
2184 bridge
->sprite_table
= CallocT
<PalSpriteID
*>(7);
2187 for (; numtables
-- != 0; tableid
++) {
2188 if (tableid
>= 7) { // skip invalid data
2189 grfmsg(1, "BridgeChangeInfo: Table %d >= 7, skipping", tableid
);
2190 for (byte sprite
= 0; sprite
< 32; sprite
++) buf
->ReadDWord();
2194 if (bridge
->sprite_table
[tableid
] == NULL
) {
2195 bridge
->sprite_table
[tableid
] = MallocT
<PalSpriteID
>(32);
2198 for (byte sprite
= 0; sprite
< 32; sprite
++) {
2199 SpriteID image
= buf
->ReadWord();
2200 PaletteID pal
= buf
->ReadWord();
2202 bridge
->sprite_table
[tableid
][sprite
].sprite
= image
;
2203 bridge
->sprite_table
[tableid
][sprite
].pal
= pal
;
2205 MapSpriteMappingRecolour(&bridge
->sprite_table
[tableid
][sprite
]);
2211 case 0x0E: // Flags; bit 0 - disable far pillars
2212 bridge
->flags
= buf
->ReadByte();
2215 case 0x0F: // Long format year of availability (year since year 0)
2216 bridge
->avail_year
= Clamp(buf
->ReadDWord(), MIN_YEAR
, MAX_YEAR
);
2219 case 0x10: { // purchase string
2220 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2221 if (newone
!= STR_UNDEFINED
) bridge
->material
= newone
;
2225 case 0x11: // description of bridge with rails or roads
2227 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2228 if (newone
!= STR_UNDEFINED
) bridge
->transport_name
[prop
- 0x11] = newone
;
2232 case 0x13: // 16 bits cost multiplier
2233 bridge
->price
= buf
->ReadWord();
2246 * Ignore a house property
2247 * @param prop Property to read.
2248 * @param buf Property value.
2249 * @return ChangeInfoResult.
2251 static ChangeInfoResult
IgnoreTownHouseProperty(int prop
, ByteReader
*buf
)
2253 ChangeInfoResult ret
= CIR_SUCCESS
;
2290 for (uint j
= 0; j
< 4; j
++) buf
->ReadByte();
2294 byte count
= buf
->ReadByte();
2295 for (byte j
= 0; j
< count
; j
++) buf
->ReadByte();
2307 * Define properties for houses
2308 * @param hid HouseID of the house.
2309 * @param numinfo Number of subsequent houseIDs to change the property for.
2310 * @param prop The property to change.
2311 * @param buf The property value.
2312 * @return ChangeInfoResult.
2314 static ChangeInfoResult
TownHouseChangeInfo(uint hid
, int numinfo
, int prop
, ByteReader
*buf
)
2316 ChangeInfoResult ret
= CIR_SUCCESS
;
2318 if (hid
+ numinfo
> NUM_HOUSES_PER_GRF
) {
2319 grfmsg(1, "TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid
+ numinfo
, NUM_HOUSES_PER_GRF
);
2320 return CIR_INVALID_ID
;
2323 /* Allocate house specs if they haven't been allocated already. */
2324 if (_cur
.grffile
->housespec
== NULL
) {
2325 _cur
.grffile
->housespec
= CallocT
<HouseSpec
*>(NUM_HOUSES_PER_GRF
);
2328 for (int i
= 0; i
< numinfo
; i
++) {
2329 HouseSpec
*housespec
= _cur
.grffile
->housespec
[hid
+ i
];
2331 if (prop
!= 0x08 && housespec
== NULL
) {
2332 /* If the house property 08 is not yet set, ignore this property */
2333 ChangeInfoResult cir
= IgnoreTownHouseProperty(prop
, buf
);
2334 if (cir
> ret
) ret
= cir
;
2339 case 0x08: { // Substitute building type, and definition of a new house
2340 HouseSpec
**house
= &_cur
.grffile
->housespec
[hid
+ i
];
2341 byte subs_id
= buf
->ReadByte();
2343 if (subs_id
== 0xFF) {
2344 /* Instead of defining a new house, a substitute house id
2345 * of 0xFF disables the old house with the current id. */
2346 HouseSpec::Get(hid
+ i
)->enabled
= false;
2348 } else if (subs_id
>= NEW_HOUSE_OFFSET
) {
2349 /* The substitute id must be one of the original houses. */
2350 grfmsg(2, "TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id
, hid
+ i
);
2354 /* Allocate space for this house. */
2355 if (*house
== NULL
) *house
= CallocT
<HouseSpec
>(1);
2359 MemCpyT(housespec
, HouseSpec::Get(subs_id
));
2361 housespec
->enabled
= true;
2362 housespec
->grf_prop
.local_id
= hid
+ i
;
2363 housespec
->grf_prop
.subst_id
= subs_id
;
2364 housespec
->grf_prop
.grffile
= _cur
.grffile
;
2365 housespec
->random_colour
[0] = 0x04; // those 4 random colours are the base colour
2366 housespec
->random_colour
[1] = 0x08; // for all new houses
2367 housespec
->random_colour
[2] = 0x0C; // they stand for red, blue, orange and green
2368 housespec
->random_colour
[3] = 0x06;
2370 /* Make sure that the third cargo type is valid in this
2371 * climate. This can cause problems when copying the properties
2372 * of a house that accepts food, where the new house is valid
2373 * in the temperate climate. */
2374 if (!CargoSpec::Get(housespec
->accepts_cargo
[2])->IsValid()) {
2375 housespec
->cargo_acceptance
[2] = 0;
2378 _loaded_newgrf_features
.has_newhouses
= true;
2382 case 0x09: // Building flags
2383 housespec
->building_flags
= (BuildingFlags
)buf
->ReadByte();
2386 case 0x0A: { // Availability years
2387 uint16 years
= buf
->ReadWord();
2388 housespec
->min_year
= GB(years
, 0, 8) > 150 ? MAX_YEAR
: ORIGINAL_BASE_YEAR
+ GB(years
, 0, 8);
2389 housespec
->max_year
= GB(years
, 8, 8) > 150 ? MAX_YEAR
: ORIGINAL_BASE_YEAR
+ GB(years
, 8, 8);
2393 case 0x0B: // Population
2394 housespec
->population
= buf
->ReadByte();
2397 case 0x0C: // Mail generation multiplier
2398 housespec
->mail_generation
= buf
->ReadByte();
2401 case 0x0D: // Passenger acceptance
2402 case 0x0E: // Mail acceptance
2403 housespec
->cargo_acceptance
[prop
- 0x0D] = buf
->ReadByte();
2406 case 0x0F: { // Goods/candy, food/fizzy drinks acceptance
2407 int8 goods
= buf
->ReadByte();
2409 /* If value of goods is negative, it means in fact food or, if in toyland, fizzy_drink acceptance.
2410 * Else, we have "standard" 3rd cargo type, goods or candy, for toyland once more */
2411 CargoID cid
= (goods
>= 0) ? ((_settings_game
.game_creation
.landscape
== LT_TOYLAND
) ? CT_CANDY
: CT_GOODS
) :
2412 ((_settings_game
.game_creation
.landscape
== LT_TOYLAND
) ? CT_FIZZY_DRINKS
: CT_FOOD
);
2414 /* Make sure the cargo type is valid in this climate. */
2415 if (!CargoSpec::Get(cid
)->IsValid()) goods
= 0;
2417 housespec
->accepts_cargo
[2] = cid
;
2418 housespec
->cargo_acceptance
[2] = abs(goods
); // but we do need positive value here
2422 case 0x10: // Local authority rating decrease on removal
2423 housespec
->remove_rating_decrease
= buf
->ReadWord();
2426 case 0x11: // Removal cost multiplier
2427 housespec
->removal_cost
= buf
->ReadByte();
2430 case 0x12: // Building name ID
2431 AddStringForMapping(buf
->ReadWord(), &housespec
->building_name
);
2434 case 0x13: // Building availability mask
2435 housespec
->building_availability
= (HouseZones
)buf
->ReadWord();
2438 case 0x14: // House callback mask
2439 housespec
->callback_mask
|= buf
->ReadByte();
2442 case 0x15: { // House override byte
2443 byte override
= buf
->ReadByte();
2445 /* The house being overridden must be an original house. */
2446 if (override
>= NEW_HOUSE_OFFSET
) {
2447 grfmsg(2, "TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.", override
, hid
+ i
);
2451 _house_mngr
.Add(hid
+ i
, _cur
.grffile
->grfid
, override
);
2455 case 0x16: // Periodic refresh multiplier
2456 housespec
->processing_time
= min(buf
->ReadByte(), 63);
2459 case 0x17: // Four random colours to use
2460 for (uint j
= 0; j
< 4; j
++) housespec
->random_colour
[j
] = buf
->ReadByte();
2463 case 0x18: // Relative probability of appearing
2464 housespec
->probability
= buf
->ReadByte();
2467 case 0x19: // Extra flags
2468 housespec
->extra_flags
= (HouseExtraFlags
)buf
->ReadByte();
2471 case 0x1A: // Animation frames
2472 housespec
->animation
.frames
= buf
->ReadByte();
2473 housespec
->animation
.status
= GB(housespec
->animation
.frames
, 7, 1);
2474 SB(housespec
->animation
.frames
, 7, 1, 0);
2477 case 0x1B: // Animation speed
2478 housespec
->animation
.speed
= Clamp(buf
->ReadByte(), 2, 16);
2481 case 0x1C: // Class of the building type
2482 housespec
->class_id
= AllocateHouseClassID(buf
->ReadByte(), _cur
.grffile
->grfid
);
2485 case 0x1D: // Callback mask part 2
2486 housespec
->callback_mask
|= (buf
->ReadByte() << 8);
2489 case 0x1E: { // Accepted cargo types
2490 uint32 cargotypes
= buf
->ReadDWord();
2492 /* Check if the cargo types should not be changed */
2493 if (cargotypes
== 0xFFFFFFFF) break;
2495 for (uint j
= 0; j
< 3; j
++) {
2496 /* Get the cargo number from the 'list' */
2497 uint8 cargo_part
= GB(cargotypes
, 8 * j
, 8);
2498 CargoID cargo
= GetCargoTranslation(cargo_part
, _cur
.grffile
);
2500 if (cargo
== CT_INVALID
) {
2501 /* Disable acceptance of invalid cargo type */
2502 housespec
->cargo_acceptance
[j
] = 0;
2504 housespec
->accepts_cargo
[j
] = cargo
;
2510 case 0x1F: // Minimum life span
2511 housespec
->minimum_life
= buf
->ReadByte();
2514 case 0x20: { // Cargo acceptance watch list
2515 byte count
= buf
->ReadByte();
2516 for (byte j
= 0; j
< count
; j
++) {
2517 CargoID cargo
= GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
2518 if (cargo
!= CT_INVALID
) SetBit(housespec
->watched_cargoes
, cargo
);
2523 case 0x21: // long introduction year
2524 housespec
->min_year
= buf
->ReadWord();
2527 case 0x22: // long maximum year
2528 housespec
->max_year
= buf
->ReadWord();
2541 * Get the language map associated with a given NewGRF and language.
2542 * @param grfid The NewGRF to get the map for.
2543 * @param language_id The (NewGRF) language ID to get the map for.
2544 * @return The LanguageMap, or NULL if it couldn't be found.
2546 /* static */ const LanguageMap
*LanguageMap::GetLanguageMap(uint32 grfid
, uint8 language_id
)
2548 /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */
2549 const GRFFile
*grffile
= GetFileByGRFID(grfid
);
2550 return (grffile
!= NULL
&& grffile
->language_map
!= NULL
&& language_id
< MAX_LANG
) ? &grffile
->language_map
[language_id
] : NULL
;
2554 * Load a cargo- or railtype-translation table.
2555 * @param gvid ID of the global variable. This is basically only checked for zerones.
2556 * @param numinfo Number of subsequent IDs to change the property for.
2557 * @param buf The property value.
2558 * @param [in,out] translation_table Storage location for the translation table.
2559 * @param name Name of the table for debug output.
2560 * @return ChangeInfoResult.
2562 template <typename T
>
2563 static ChangeInfoResult
LoadTranslationTable(uint gvid
, int numinfo
, ByteReader
*buf
, T
&translation_table
, const char *name
)
2566 grfmsg(1, "LoadTranslationTable: %s translation table must start at zero", name
);
2567 return CIR_INVALID_ID
;
2570 translation_table
.Clear();
2571 for (int i
= 0; i
< numinfo
; i
++) {
2572 uint32 item
= buf
->ReadDWord();
2573 *translation_table
.Append() = BSWAP32(item
);
2580 * Define properties for global variables
2581 * @param gvid ID of the global variable.
2582 * @param numinfo Number of subsequent IDs to change the property for.
2583 * @param prop The property to change.
2584 * @param buf The property value.
2585 * @return ChangeInfoResult.
2587 static ChangeInfoResult
GlobalVarChangeInfo(uint gvid
, int numinfo
, int prop
, ByteReader
*buf
)
2589 /* Properties which are handled as a whole */
2591 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2592 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->cargo_list
, "Cargo");
2594 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2595 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->railtype_list
, "Rail type");
2601 /* Properties which are handled per item */
2602 ChangeInfoResult ret
= CIR_SUCCESS
;
2603 for (int i
= 0; i
< numinfo
; i
++) {
2605 case 0x08: { // Cost base factor
2606 int factor
= buf
->ReadByte();
2607 uint price
= gvid
+ i
;
2609 if (price
< PR_END
) {
2610 _cur
.grffile
->price_base_multipliers
[price
] = min
<int>(factor
- 8, MAX_PRICE_MODIFIER
);
2612 grfmsg(1, "GlobalVarChangeInfo: Price %d out of range, ignoring", price
);
2617 case 0x0A: { // Currency display names
2618 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2619 StringID newone
= GetGRFStringID(_cur
.grffile
->grfid
, buf
->ReadWord());
2621 if ((newone
!= STR_UNDEFINED
) && (curidx
< CURRENCY_END
)) {
2622 _currency_specs
[curidx
].name
= newone
;
2627 case 0x0B: { // Currency multipliers
2628 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2629 uint32 rate
= buf
->ReadDWord();
2631 if (curidx
< CURRENCY_END
) {
2632 /* TTDPatch uses a multiple of 1000 for its conversion calculations,
2633 * which OTTD does not. For this reason, divide grf value by 1000,
2634 * to be compatible */
2635 _currency_specs
[curidx
].rate
= rate
/ 1000;
2637 grfmsg(1, "GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx
);
2642 case 0x0C: { // Currency options
2643 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2644 uint16 options
= buf
->ReadWord();
2646 if (curidx
< CURRENCY_END
) {
2647 _currency_specs
[curidx
].separator
[0] = GB(options
, 0, 8);
2648 _currency_specs
[curidx
].separator
[1] = '\0';
2649 /* By specifying only one bit, we prevent errors,
2650 * since newgrf specs said that only 0 and 1 can be set for symbol_pos */
2651 _currency_specs
[curidx
].symbol_pos
= GB(options
, 8, 1);
2653 grfmsg(1, "GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx
);
2658 case 0x0D: { // Currency prefix symbol
2659 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2660 uint32 tempfix
= buf
->ReadDWord();
2662 if (curidx
< CURRENCY_END
) {
2663 memcpy(_currency_specs
[curidx
].prefix
, &tempfix
, 4);
2664 _currency_specs
[curidx
].prefix
[4] = 0;
2666 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx
);
2671 case 0x0E: { // Currency suffix symbol
2672 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2673 uint32 tempfix
= buf
->ReadDWord();
2675 if (curidx
< CURRENCY_END
) {
2676 memcpy(&_currency_specs
[curidx
].suffix
, &tempfix
, 4);
2677 _currency_specs
[curidx
].suffix
[4] = 0;
2679 grfmsg(1, "GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx
);
2684 case 0x0F: { // Euro introduction dates
2685 uint curidx
= GetNewgrfCurrencyIdConverted(gvid
+ i
);
2686 Year year_euro
= buf
->ReadWord();
2688 if (curidx
< CURRENCY_END
) {
2689 _currency_specs
[curidx
].to_euro
= year_euro
;
2691 grfmsg(1, "GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx
);
2696 case 0x10: // Snow line height table
2697 if (numinfo
> 1 || IsSnowLineSet()) {
2698 grfmsg(1, "GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo
);
2699 } else if (buf
->Remaining() < SNOW_LINE_MONTHS
* SNOW_LINE_DAYS
) {
2700 grfmsg(1, "GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf
->Remaining());
2702 byte table
[SNOW_LINE_MONTHS
][SNOW_LINE_DAYS
];
2704 for (uint i
= 0; i
< SNOW_LINE_MONTHS
; i
++) {
2705 for (uint j
= 0; j
< SNOW_LINE_DAYS
; j
++) {
2706 table
[i
][j
] = buf
->ReadByte();
2707 if (_cur
.grffile
->grf_version
>= 8) {
2708 if (table
[i
][j
] != 0xFF) table
[i
][j
] = table
[i
][j
] * (1 + _settings_game
.construction
.max_heightlevel
) / 256;
2710 if (table
[i
][j
] >= 128) {
2714 table
[i
][j
] = table
[i
][j
] * (1 + _settings_game
.construction
.max_heightlevel
) / 128;
2723 case 0x11: // GRF match for engine allocation
2724 /* This is loaded during the reservation stage, so just skip it here. */
2725 /* Each entry is 8 bytes. */
2729 case 0x13: // Gender translation table
2730 case 0x14: // Case translation table
2731 case 0x15: { // Plural form translation
2732 uint curidx
= gvid
+ i
; // The current index, i.e. language.
2733 const LanguageMetadata
*lang
= curidx
< MAX_LANG
? GetLanguage(curidx
) : NULL
;
2735 grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx
);
2736 /* Skip over the data. */
2740 while (buf
->ReadByte() != 0) {
2747 if (_cur
.grffile
->language_map
== NULL
) _cur
.grffile
->language_map
= new LanguageMap
[MAX_LANG
];
2750 uint plural_form
= buf
->ReadByte();
2751 if (plural_form
>= LANGUAGE_MAX_PLURAL
) {
2752 grfmsg(1, "GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form
);
2754 _cur
.grffile
->language_map
[curidx
].plural_form
= plural_form
;
2759 byte newgrf_id
= buf
->ReadByte(); // The NewGRF (custom) identifier.
2760 while (newgrf_id
!= 0) {
2761 const char *name
= buf
->ReadString(); // The name for the OpenTTD identifier.
2763 /* We'll just ignore the UTF8 identifier character. This is (fairly)
2764 * safe as OpenTTD's strings gender/cases are usually in ASCII which
2765 * is just a subset of UTF8, or they need the bigger UTF8 characters
2766 * such as Cyrillic. Thus we will simply assume they're all UTF8. */
2768 size_t len
= Utf8Decode(&c
, name
);
2769 if (c
== NFO_UTF8_IDENTIFIER
) name
+= len
;
2771 LanguageMap::Mapping map
;
2772 map
.newgrf_id
= newgrf_id
;
2774 map
.openttd_id
= lang
->GetGenderIndex(name
);
2775 if (map
.openttd_id
>= MAX_NUM_GENDERS
) {
2776 grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name
);
2778 *_cur
.grffile
->language_map
[curidx
].gender_map
.Append() = map
;
2781 map
.openttd_id
= lang
->GetCaseIndex(name
);
2782 if (map
.openttd_id
>= MAX_NUM_CASES
) {
2783 grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name
);
2785 *_cur
.grffile
->language_map
[curidx
].case_map
.Append() = map
;
2788 newgrf_id
= buf
->ReadByte();
2802 static ChangeInfoResult
GlobalVarReserveInfo(uint gvid
, int numinfo
, int prop
, ByteReader
*buf
)
2804 /* Properties which are handled as a whole */
2806 case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos)
2807 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->cargo_list
, "Cargo");
2809 case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes)
2810 return LoadTranslationTable(gvid
, numinfo
, buf
, _cur
.grffile
->railtype_list
, "Rail type");
2816 /* Properties which are handled per item */
2817 ChangeInfoResult ret
= CIR_SUCCESS
;
2818 for (int i
= 0; i
< numinfo
; i
++) {
2820 case 0x08: // Cost base factor
2821 case 0x15: // Plural form translation
2825 case 0x0A: // Currency display names
2826 case 0x0C: // Currency options
2827 case 0x0F: // Euro introduction dates
2831 case 0x0B: // Currency multipliers
2832 case 0x0D: // Currency prefix symbol
2833 case 0x0E: // Currency suffix symbol
2837 case 0x10: // Snow line height table
2838 buf
->Skip(SNOW_LINE_MONTHS
* SNOW_LINE_DAYS
);
2841 case 0x11: { // GRF match for engine allocation
2842 uint32 s
= buf
->ReadDWord();
2843 uint32 t
= buf
->ReadDWord();
2844 SetNewGRFOverride(s
, t
);
2848 case 0x13: // Gender translation table
2849 case 0x14: // Case translation table
2850 while (buf
->ReadByte() != 0) {
2866 * Define properties for cargoes
2867 * @param cid Local ID of the cargo.
2868 * @param numinfo Number of subsequent IDs to change the property for.
2869 * @param prop The property to change.
2870 * @param buf The property value.
2871 * @return ChangeInfoResult.
2873 static ChangeInfoResult
CargoChangeInfo(uint cid
, int numinfo
, int prop
, ByteReader
*buf
)
2875 ChangeInfoResult ret
= CIR_SUCCESS
;
2877 if (cid
+ numinfo
> NUM_CARGO
) {
2878 grfmsg(2, "CargoChangeInfo: Cargo type %d out of range (max %d)", cid
+ numinfo
, NUM_CARGO
- 1);
2879 return CIR_INVALID_ID
;
2882 for (int i
= 0; i
< numinfo
; i
++) {
2883 CargoSpec
*cs
= CargoSpec::Get(cid
+ i
);
2886 case 0x08: // Bit number of cargo
2887 cs
->bitnum
= buf
->ReadByte();
2888 if (cs
->IsValid()) {
2889 cs
->grffile
= _cur
.grffile
;
2890 SetBit(_cargo_mask
, cid
+ i
);
2892 ClrBit(_cargo_mask
, cid
+ i
);
2896 case 0x09: // String ID for cargo type name
2897 AddStringForMapping(buf
->ReadWord(), &cs
->name
);
2900 case 0x0A: // String for 1 unit of cargo
2901 AddStringForMapping(buf
->ReadWord(), &cs
->name_single
);
2904 case 0x0B: // String for singular quantity of cargo (e.g. 1 tonne of coal)
2905 case 0x1B: // String for cargo units
2906 /* String for units of cargo. This is different in OpenTTD
2907 * (e.g. tonnes) to TTDPatch (e.g. {COMMA} tonne of coal).
2908 * Property 1B is used to set OpenTTD's behaviour. */
2909 AddStringForMapping(buf
->ReadWord(), &cs
->units_volume
);
2912 case 0x0C: // String for plural quantity of cargo (e.g. 10 tonnes of coal)
2913 case 0x1C: // String for any amount of cargo
2914 /* Strings for an amount of cargo. This is different in OpenTTD
2915 * (e.g. {WEIGHT} of coal) to TTDPatch (e.g. {COMMA} tonnes of coal).
2916 * Property 1C is used to set OpenTTD's behaviour. */
2917 AddStringForMapping(buf
->ReadWord(), &cs
->quantifier
);
2920 case 0x0D: // String for two letter cargo abbreviation
2921 AddStringForMapping(buf
->ReadWord(), &cs
->abbrev
);
2924 case 0x0E: // Sprite ID for cargo icon
2925 cs
->sprite
= buf
->ReadWord();
2928 case 0x0F: // Weight of one unit of cargo
2929 cs
->weight
= buf
->ReadByte();
2932 case 0x10: // Used for payment calculation
2933 cs
->transit_days
[0] = buf
->ReadByte();
2936 case 0x11: // Used for payment calculation
2937 cs
->transit_days
[1] = buf
->ReadByte();
2940 case 0x12: // Base cargo price
2941 cs
->initial_payment
= buf
->ReadDWord();
2944 case 0x13: // Colour for station rating bars
2945 cs
->rating_colour
= buf
->ReadByte();
2948 case 0x14: // Colour for cargo graph
2949 cs
->legend_colour
= buf
->ReadByte();
2952 case 0x15: // Freight status
2953 cs
->is_freight
= (buf
->ReadByte() != 0);
2956 case 0x16: // Cargo classes
2957 cs
->classes
= buf
->ReadWord();
2960 case 0x17: // Cargo label
2961 cs
->label
= buf
->ReadDWord();
2962 cs
->label
= BSWAP32(cs
->label
);
2965 case 0x18: { // Town growth substitute type
2966 uint8 substitute_type
= buf
->ReadByte();
2968 switch (substitute_type
) {
2969 case 0x00: cs
->town_effect
= TE_PASSENGERS
; break;
2970 case 0x02: cs
->town_effect
= TE_MAIL
; break;
2971 case 0x05: cs
->town_effect
= TE_GOODS
; break;
2972 case 0x09: cs
->town_effect
= TE_WATER
; break;
2973 case 0x0B: cs
->town_effect
= TE_FOOD
; break;
2975 grfmsg(1, "CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type
);
2977 case 0xFF: cs
->town_effect
= TE_NONE
; break;
2982 case 0x19: // Town growth coefficient
2983 cs
->multipliertowngrowth
= buf
->ReadWord();
2986 case 0x1A: // Bitmask of callbacks to use
2987 cs
->callback_mask
= buf
->ReadByte();
2990 case 0x1D: // Vehicle capacity muliplier
2991 cs
->multiplier
= max
<uint16
>(1u, buf
->ReadWord());
3005 * Define properties for sound effects
3006 * @param sid Local ID of the sound.
3007 * @param numinfo Number of subsequent IDs to change the property for.
3008 * @param prop The property to change.
3009 * @param buf The property value.
3010 * @return ChangeInfoResult.
3012 static ChangeInfoResult
SoundEffectChangeInfo(uint sid
, int numinfo
, int prop
, ByteReader
*buf
)
3014 ChangeInfoResult ret
= CIR_SUCCESS
;
3016 if (_cur
.grffile
->sound_offset
== 0) {
3017 grfmsg(1, "SoundEffectChangeInfo: No effects defined, skipping");
3018 return CIR_INVALID_ID
;
3021 if (sid
+ numinfo
- ORIGINAL_SAMPLE_COUNT
> _cur
.grffile
->num_sounds
) {
3022 grfmsg(1, "SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid
+ numinfo
, ORIGINAL_SAMPLE_COUNT
+ _cur
.grffile
->num_sounds
);
3023 return CIR_INVALID_ID
;
3026 for (int i
= 0; i
< numinfo
; i
++) {
3027 SoundEntry
*sound
= GetSound(sid
+ i
+ _cur
.grffile
->sound_offset
- ORIGINAL_SAMPLE_COUNT
);
3030 case 0x08: // Relative volume
3031 sound
->volume
= buf
->ReadByte();
3034 case 0x09: // Priority
3035 sound
->priority
= buf
->ReadByte();
3038 case 0x0A: { // Override old sound
3039 SoundID orig_sound
= buf
->ReadByte();
3041 if (orig_sound
>= ORIGINAL_SAMPLE_COUNT
) {
3042 grfmsg(1, "SoundEffectChangeInfo: Original sound %d not defined (max %d)", orig_sound
, ORIGINAL_SAMPLE_COUNT
);
3044 SoundEntry
*old_sound
= GetSound(orig_sound
);
3046 /* Literally copy the data of the new sound over the original */
3047 *old_sound
= *sound
;
3062 * Ignore an industry tile property
3063 * @param prop The property to ignore.
3064 * @param buf The property value.
3065 * @return ChangeInfoResult.
3067 static ChangeInfoResult
IgnoreIndustryTileProperty(int prop
, ByteReader
*buf
)
3069 ChangeInfoResult ret
= CIR_SUCCESS
;
3096 * Define properties for industry tiles
3097 * @param indtid Local ID of the industry tile.
3098 * @param numinfo Number of subsequent industry tile IDs to change the property for.
3099 * @param prop The property to change.
3100 * @param buf The property value.
3101 * @return ChangeInfoResult.
3103 static ChangeInfoResult
IndustrytilesChangeInfo(uint indtid
, int numinfo
, int prop
, ByteReader
*buf
)
3105 ChangeInfoResult ret
= CIR_SUCCESS
;
3107 if (indtid
+ numinfo
> NUM_INDUSTRYTILES_PER_GRF
) {
3108 grfmsg(1, "IndustryTilesChangeInfo: Too many industry tiles loaded (%u), max (%u). Ignoring.", indtid
+ numinfo
, NUM_INDUSTRYTILES_PER_GRF
);
3109 return CIR_INVALID_ID
;
3112 /* Allocate industry tile specs if they haven't been allocated already. */
3113 if (_cur
.grffile
->indtspec
== NULL
) {
3114 _cur
.grffile
->indtspec
= CallocT
<IndustryTileSpec
*>(NUM_INDUSTRYTILES_PER_GRF
);
3117 for (int i
= 0; i
< numinfo
; i
++) {
3118 IndustryTileSpec
*tsp
= _cur
.grffile
->indtspec
[indtid
+ i
];
3120 if (prop
!= 0x08 && tsp
== NULL
) {
3121 ChangeInfoResult cir
= IgnoreIndustryTileProperty(prop
, buf
);
3122 if (cir
> ret
) ret
= cir
;
3127 case 0x08: { // Substitute industry tile type
3128 IndustryTileSpec
**tilespec
= &_cur
.grffile
->indtspec
[indtid
+ i
];
3129 byte subs_id
= buf
->ReadByte();
3131 if (subs_id
>= NEW_INDUSTRYTILEOFFSET
) {
3132 /* The substitute id must be one of the original industry tile. */
3133 grfmsg(2, "IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id
, indtid
+ i
);
3137 /* Allocate space for this industry. */
3138 if (*tilespec
== NULL
) {
3139 *tilespec
= CallocT
<IndustryTileSpec
>(1);
3142 memcpy(tsp
, &_industry_tile_specs
[subs_id
], sizeof(_industry_tile_specs
[subs_id
]));
3143 tsp
->enabled
= true;
3145 /* A copied tile should not have the animation infos copied too.
3146 * The anim_state should be left untouched, though
3147 * It is up to the author to animate them himself */
3148 tsp
->anim_production
= INDUSTRYTILE_NOANIM
;
3149 tsp
->anim_next
= INDUSTRYTILE_NOANIM
;
3151 tsp
->grf_prop
.local_id
= indtid
+ i
;
3152 tsp
->grf_prop
.subst_id
= subs_id
;
3153 tsp
->grf_prop
.grffile
= _cur
.grffile
;
3154 _industile_mngr
.AddEntityID(indtid
+ i
, _cur
.grffile
->grfid
, subs_id
); // pre-reserve the tile slot
3159 case 0x09: { // Industry tile override
3160 byte ovrid
= buf
->ReadByte();
3162 /* The industry being overridden must be an original industry. */
3163 if (ovrid
>= NEW_INDUSTRYTILEOFFSET
) {
3164 grfmsg(2, "IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid
, indtid
+ i
);
3168 _industile_mngr
.Add(indtid
+ i
, _cur
.grffile
->grfid
, ovrid
);
3172 case 0x0A: // Tile acceptance
3175 uint16 acctp
= buf
->ReadWord();
3176 tsp
->accepts_cargo
[prop
- 0x0A] = GetCargoTranslation(GB(acctp
, 0, 8), _cur
.grffile
);
3177 tsp
->acceptance
[prop
- 0x0A] = GB(acctp
, 8, 8);
3181 case 0x0D: // Land shape flags
3182 tsp
->slopes_refused
= (Slope
)buf
->ReadByte();
3185 case 0x0E: // Callback mask
3186 tsp
->callback_mask
= buf
->ReadByte();
3189 case 0x0F: // Animation information
3190 tsp
->animation
.frames
= buf
->ReadByte();
3191 tsp
->animation
.status
= buf
->ReadByte();
3194 case 0x10: // Animation speed
3195 tsp
->animation
.speed
= buf
->ReadByte();
3198 case 0x11: // Triggers for callback 25
3199 tsp
->animation
.triggers
= buf
->ReadByte();
3202 case 0x12: // Special flags
3203 tsp
->special_flags
= (IndustryTileSpecialFlags
)buf
->ReadByte();
3216 * Ignore an industry property
3217 * @param prop The property to ignore.
3218 * @param buf The property value.
3219 * @return ChangeInfoResult.
3221 static ChangeInfoResult
IgnoreIndustryProperty(int prop
, ByteReader
*buf
)
3223 ChangeInfoResult ret
= CIR_SUCCESS
;
3261 byte num_table
= buf
->ReadByte();
3262 for (byte j
= 0; j
< num_table
; j
++) {
3263 for (uint k
= 0;; k
++) {
3264 byte x
= buf
->ReadByte();
3265 if (x
== 0xFE && k
== 0) {
3271 byte y
= buf
->ReadByte();
3272 if (x
== 0 && y
== 0x80) break;
3274 byte gfx
= buf
->ReadByte();
3275 if (gfx
== 0xFE) buf
->ReadWord();
3282 for (byte j
= 0; j
< 3; j
++) buf
->ReadByte();
3286 byte number_of_sounds
= buf
->ReadByte();
3287 for (uint8 j
= 0; j
< number_of_sounds
; j
++) {
3301 * Validate the industry layout; e.g. to prevent duplicate tiles.
3302 * @param layout The layout to check.
3303 * @param size The size of the layout.
3304 * @return True if the layout is deemed valid.
3306 static bool ValidateIndustryLayout(const IndustryTileTable
*layout
, int size
)
3308 for (int i
= 0; i
< size
- 1; i
++) {
3309 for (int j
= i
+ 1; j
< size
; j
++) {
3310 if (layout
[i
].ti
.x
== layout
[j
].ti
.x
&&
3311 layout
[i
].ti
.y
== layout
[j
].ti
.y
) {
3319 /** Clean the tile table of the IndustrySpec if it's needed. */
3320 static void CleanIndustryTileTable(IndustrySpec
*ind
)
3322 if (HasBit(ind
->cleanup_flag
, CLEAN_TILELAYOUT
) && ind
->table
!= NULL
) {
3323 for (int j
= 0; j
< ind
->num_table
; j
++) {
3324 /* remove the individual layouts */
3325 free(ind
->table
[j
]);
3327 /* remove the layouts pointers */
3334 * Define properties for industries
3335 * @param indid Local ID of the industry.
3336 * @param numinfo Number of subsequent industry IDs to change the property for.
3337 * @param prop The property to change.
3338 * @param buf The property value.
3339 * @return ChangeInfoResult.
3341 static ChangeInfoResult
IndustriesChangeInfo(uint indid
, int numinfo
, int prop
, ByteReader
*buf
)
3343 ChangeInfoResult ret
= CIR_SUCCESS
;
3345 if (indid
+ numinfo
> NUM_INDUSTRYTYPES_PER_GRF
) {
3346 grfmsg(1, "IndustriesChangeInfo: Too many industries loaded (%u), max (%u). Ignoring.", indid
+ numinfo
, NUM_INDUSTRYTYPES_PER_GRF
);
3347 return CIR_INVALID_ID
;
3350 /* Allocate industry specs if they haven't been allocated already. */
3351 if (_cur
.grffile
->industryspec
== NULL
) {
3352 _cur
.grffile
->industryspec
= CallocT
<IndustrySpec
*>(NUM_INDUSTRYTYPES_PER_GRF
);
3355 for (int i
= 0; i
< numinfo
; i
++) {
3356 IndustrySpec
*indsp
= _cur
.grffile
->industryspec
[indid
+ i
];
3358 if (prop
!= 0x08 && indsp
== NULL
) {
3359 ChangeInfoResult cir
= IgnoreIndustryProperty(prop
, buf
);
3360 if (cir
> ret
) ret
= cir
;
3365 case 0x08: { // Substitute industry type
3366 IndustrySpec
**indspec
= &_cur
.grffile
->industryspec
[indid
+ i
];
3367 byte subs_id
= buf
->ReadByte();
3369 if (subs_id
== 0xFF) {
3370 /* Instead of defining a new industry, a substitute industry id
3371 * of 0xFF disables the old industry with the current id. */
3372 _industry_specs
[indid
+ i
].enabled
= false;
3374 } else if (subs_id
>= NEW_INDUSTRYOFFSET
) {
3375 /* The substitute id must be one of the original industry. */
3376 grfmsg(2, "_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id
, indid
+ i
);
3380 /* Allocate space for this industry.
3381 * Only need to do it once. If ever it is called again, it should not
3383 if (*indspec
== NULL
) {
3384 *indspec
= CallocT
<IndustrySpec
>(1);
3387 memcpy(indsp
, &_origin_industry_specs
[subs_id
], sizeof(_industry_specs
[subs_id
]));
3388 indsp
->enabled
= true;
3389 indsp
->grf_prop
.local_id
= indid
+ i
;
3390 indsp
->grf_prop
.subst_id
= subs_id
;
3391 indsp
->grf_prop
.grffile
= _cur
.grffile
;
3392 /* If the grf industry needs to check its surounding upon creation, it should
3393 * rely on callbacks, not on the original placement functions */
3394 indsp
->check_proc
= CHECK_NOTHING
;
3399 case 0x09: { // Industry type override
3400 byte ovrid
= buf
->ReadByte();
3402 /* The industry being overridden must be an original industry. */
3403 if (ovrid
>= NEW_INDUSTRYOFFSET
) {
3404 grfmsg(2, "IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid
, indid
+ i
);
3407 indsp
->grf_prop
.override
= ovrid
;
3408 _industry_mngr
.Add(indid
+ i
, _cur
.grffile
->grfid
, ovrid
);
3412 case 0x0A: { // Set industry layout(s)
3413 byte new_num_layouts
= buf
->ReadByte(); // Number of layaouts
3414 /* We read the total size in bytes, but we can't rely on the
3415 * newgrf to provide a sane value. First assume the value is
3416 * sane but later on we make sure we enlarge the array if the
3417 * newgrf contains more data. Each tile uses either 3 or 5
3418 * bytes, so to play it safe we assume 3. */
3419 uint32 def_num_tiles
= buf
->ReadDWord() / 3 + 1;
3420 IndustryTileTable
**tile_table
= CallocT
<IndustryTileTable
*>(new_num_layouts
); // Table with tiles to compose an industry
3421 IndustryTileTable
*itt
= CallocT
<IndustryTileTable
>(def_num_tiles
); // Temporary array to read the tile layouts from the GRF
3423 const IndustryTileTable
*copy_from
;
3426 for (byte j
= 0; j
< new_num_layouts
; j
++) {
3427 for (uint k
= 0;; k
++) {
3428 if (k
>= def_num_tiles
) {
3429 grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid
);
3430 /* Size reported by newgrf was not big enough so enlarge the array. */
3432 itt
= ReallocT
<IndustryTileTable
>(itt
, def_num_tiles
);
3435 itt
[k
].ti
.x
= buf
->ReadByte(); // Offsets from northermost tile
3437 if (itt
[k
].ti
.x
== 0xFE && k
== 0) {
3438 /* This means we have to borrow the layout from an old industry */
3439 IndustryType type
= buf
->ReadByte(); // industry holding required layout
3440 byte laynbr
= buf
->ReadByte(); // layout number to borrow
3442 copy_from
= _origin_industry_specs
[type
].table
[laynbr
];
3443 for (size
= 1;; size
++) {
3444 if (copy_from
[size
- 1].ti
.x
== -0x80 && copy_from
[size
- 1].ti
.y
== 0) break;
3449 itt
[k
].ti
.y
= buf
->ReadByte(); // Or table definition finalisation
3451 if (itt
[k
].ti
.x
== 0 && itt
[k
].ti
.y
== 0x80) {
3452 /* Not the same terminator. The one we are using is rather
3453 x = -80, y = x . So, adjust it. */
3454 itt
[k
].ti
.x
= -0x80;
3463 itt
[k
].gfx
= buf
->ReadByte();
3465 if (itt
[k
].gfx
== 0xFE) {
3466 /* Use a new tile from this GRF */
3467 int local_tile_id
= buf
->ReadWord();
3469 /* Read the ID from the _industile_mngr. */
3470 int tempid
= _industile_mngr
.GetID(local_tile_id
, _cur
.grffile
->grfid
);
3472 if (tempid
== INVALID_INDUSTRYTILE
) {
3473 grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id
, indid
);
3475 /* Declared as been valid, can be used */
3476 itt
[k
].gfx
= tempid
;
3480 } else if (itt
[k
].gfx
== 0xFF) {
3481 itt
[k
].ti
.x
= (int8
)GB(itt
[k
].ti
.x
, 0, 8);
3482 itt
[k
].ti
.y
= (int8
)GB(itt
[k
].ti
.y
, 0, 8);
3484 /* When there were only 256x256 maps, TileIndex was a uint16 and
3485 * itt[k].ti was just a TileIndexDiff that was added to it.
3486 * As such negative "x" values were shifted into the "y" position.
3487 * x = -1, y = 1 -> x = 255, y = 0
3488 * Since GRF version 8 the position is interpreted as pair of independent int8.
3489 * For GRF version < 8 we need to emulate the old shifting behaviour.
3491 if (_cur
.grffile
->grf_version
< 8 && itt
[k
].ti
.x
< 0) itt
[k
].ti
.y
+= 1;
3495 if (!ValidateIndustryLayout(copy_from
, size
)) {
3496 /* The industry layout was not valid, so skip this one. */
3497 grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid
);
3501 tile_table
[j
] = CallocT
<IndustryTileTable
>(size
);
3502 memcpy(tile_table
[j
], copy_from
, sizeof(*copy_from
) * size
);
3506 for (int i
= 0; i
< new_num_layouts
; i
++) {
3507 free(tile_table
[i
]);
3514 /* Clean the tile table if it was already set by a previous prop A. */
3515 CleanIndustryTileTable(indsp
);
3516 /* Install final layout construction in the industry spec */
3517 indsp
->num_table
= new_num_layouts
;
3518 indsp
->table
= tile_table
;
3519 SetBit(indsp
->cleanup_flag
, CLEAN_TILELAYOUT
);
3524 case 0x0B: // Industry production flags
3525 indsp
->life_type
= (IndustryLifeType
)buf
->ReadByte();
3528 case 0x0C: // Industry closure message
3529 AddStringForMapping(buf
->ReadWord(), &indsp
->closure_text
);
3532 case 0x0D: // Production increase message
3533 AddStringForMapping(buf
->ReadWord(), &indsp
->production_up_text
);
3536 case 0x0E: // Production decrease message
3537 AddStringForMapping(buf
->ReadWord(), &indsp
->production_down_text
);
3540 case 0x0F: // Fund cost multiplier
3541 indsp
->cost_multiplier
= buf
->ReadByte();
3544 case 0x10: // Production cargo types
3545 for (byte j
= 0; j
< 2; j
++) {
3546 indsp
->produced_cargo
[j
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3550 case 0x11: // Acceptance cargo types
3551 for (byte j
= 0; j
< 3; j
++) {
3552 indsp
->accepts_cargo
[j
] = GetCargoTranslation(buf
->ReadByte(), _cur
.grffile
);
3554 buf
->ReadByte(); // Unnused, eat it up
3557 case 0x12: // Production multipliers
3559 indsp
->production_rate
[prop
- 0x12] = buf
->ReadByte();
3562 case 0x14: // Minimal amount of cargo distributed
3563 indsp
->minimal_cargo
= buf
->ReadByte();
3566 case 0x15: { // Random sound effects
3567 indsp
->number_of_sounds
= buf
->ReadByte();
3568 uint8
*sounds
= MallocT
<uint8
>(indsp
->number_of_sounds
);
3571 for (uint8 j
= 0; j
< indsp
->number_of_sounds
; j
++) {
3572 sounds
[j
] = buf
->ReadByte();
3579 if (HasBit(indsp
->cleanup_flag
, CLEAN_RANDOMSOUNDS
)) {
3580 free(indsp
->random_sounds
);
3582 indsp
->random_sounds
= sounds
;
3583 SetBit(indsp
->cleanup_flag
, CLEAN_RANDOMSOUNDS
);
3587 case 0x16: // Conflicting industry types
3588 for (byte j
= 0; j
< 3; j
++) indsp
->conflicting
[j
] = buf
->ReadByte();
3591 case 0x17: // Probability in random game
3592 indsp
->appear_creation
[_settings_game
.game_creation
.landscape
] = buf
->ReadByte();
3595 case 0x18: // Probability during gameplay
3596 indsp
->appear_ingame
[_settings_game
.game_creation
.landscape
] = buf
->ReadByte();
3599 case 0x19: // Map colour
3600 indsp
->map_colour
= buf
->ReadByte();
3603 case 0x1A: // Special industry flags to define special behavior
3604 indsp
->behaviour
= (IndustryBehaviour
)buf
->ReadDWord();
3607 case 0x1B: // New industry text ID
3608 AddStringForMapping(buf
->ReadWord(), &indsp
->new_industry_text
);
3611 case 0x1C: // Input cargo multipliers for the three input cargo types
3614 uint32 multiples
= buf
->ReadDWord();
3615 indsp
->input_cargo_multiplier
[prop
- 0x1C][0] = GB(multiples
, 0, 16);
3616 indsp
->input_cargo_multiplier
[prop
- 0x1C][1] = GB(multiples
, 16, 16);
3620 case 0x1F: // Industry name
3621 AddStringForMapping(buf
->ReadWord(), &indsp
->name
);
3624 case 0x20: // Prospecting success chance
3625 indsp
->prospecting_chance
= buf
->ReadDWord();
3628 case 0x21: // Callback mask
3629 case 0x22: { // Callback additional mask
3630 byte aflag
= buf
->ReadByte();
3631 SB(indsp
->callback_mask
, (prop
- 0x21) * 8, 8, aflag
);
3635 case 0x23: // removal cost multiplier
3636 indsp
->removal_cost_multiplier
= buf
->ReadDWord();
3639 case 0x24: { // name for nearby station
3640 uint16 str
= buf
->ReadWord();
3642 indsp
->station_name
= STR_NULL
;
3644 AddStringForMapping(str
, &indsp
->station_name
);
3659 * Create a copy of the tile table so it can be freed later
3661 * @param as The AirportSpec to copy the arrays of.
3663 static void DuplicateTileTable(AirportSpec
*as
)
3665 AirportTileTable
**table_list
= MallocT
<AirportTileTable
*>(as
->num_table
);
3666 for (int i
= 0; i
< as
->num_table
; i
++) {
3668 const AirportTileTable
*it
= as
->table
[0];
3671 } while ((++it
)->ti
.x
!= -0x80);
3672 table_list
[i
] = MallocT
<AirportTileTable
>(num_tiles
);
3673 MemCpyT(table_list
[i
], as
->table
[i
], num_tiles
);
3675 as
->table
= table_list
;
3676 HangarTileTable
*depot_table
= NULL
;
3677 if (as
->nof_depots
> 0) {
3678 depot_table
= MallocT
<HangarTileTable
>(as
->nof_depots
);
3679 MemCpyT(depot_table
, as
->depot_table
, as
->nof_depots
);
3681 as
->depot_table
= depot_table
;
3682 Direction
*rotation
= MallocT
<Direction
>(as
->num_table
);
3683 MemCpyT(rotation
, as
->rotation
, as
->num_table
);
3684 as
->rotation
= rotation
;
3688 * Define properties for airports
3689 * @param airport Local ID of the airport.
3690 * @param numinfo Number of subsequent airport IDs to change the property for.
3691 * @param prop The property to change.
3692 * @param buf The property value.
3693 * @return ChangeInfoResult.
3695 static ChangeInfoResult
AirportChangeInfo(uint airport
, int numinfo
, int prop
, ByteReader
*buf
)
3697 ChangeInfoResult ret
= CIR_SUCCESS
;
3699 if (airport
+ numinfo
> NUM_AIRPORTS_PER_GRF
) {
3700 grfmsg(1, "AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport
+ numinfo
, NUM_AIRPORTS_PER_GRF
);
3701 return CIR_INVALID_ID
;
3704 /* Allocate industry specs if they haven't been allocated already. */
3705 if (_cur
.grffile
->airportspec
== NULL
) {
3706 _cur
.grffile
->airportspec
= CallocT
<AirportSpec
*>(NUM_AIRPORTS_PER_GRF
);
3709 for (int i
= 0; i
< numinfo
; i
++) {
3710 AirportSpec
*as
= _cur
.grffile
->airportspec
[airport
+ i
];
3712 if (as
== NULL
&& prop
!= 0x08 && prop
!= 0x09) {
3713 grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport
+ i
);
3714 return CIR_INVALID_ID
;
3718 case 0x08: { // Modify original airport
3719 byte subs_id
= buf
->ReadByte();
3721 if (subs_id
== 0xFF) {
3722 /* Instead of defining a new airport, an airport id
3723 * of 0xFF disables the old airport with the current id. */
3724 AirportSpec::GetWithoutOverride(airport
+ i
)->enabled
= false;
3726 } else if (subs_id
>= NEW_AIRPORT_OFFSET
) {
3727 /* The substitute id must be one of the original airports. */
3728 grfmsg(2, "AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id
, airport
+ i
);
3732 AirportSpec
**spec
= &_cur
.grffile
->airportspec
[airport
+ i
];
3733 /* Allocate space for this airport.
3734 * Only need to do it once. If ever it is called again, it should not
3736 if (*spec
== NULL
) {
3737 *spec
= MallocT
<AirportSpec
>(1);
3740 memcpy(as
, AirportSpec::GetWithoutOverride(subs_id
), sizeof(*as
));
3742 as
->grf_prop
.local_id
= airport
+ i
;
3743 as
->grf_prop
.subst_id
= subs_id
;
3744 as
->grf_prop
.grffile
= _cur
.grffile
;
3745 /* override the default airport */
3746 _airport_mngr
.Add(airport
+ i
, _cur
.grffile
->grfid
, subs_id
);
3747 /* Create a copy of the original tiletable so it can be freed later. */
3748 DuplicateTileTable(as
);
3753 case 0x0A: { // Set airport layout
3754 as
->num_table
= buf
->ReadByte(); // Number of layaouts
3756 as
->rotation
= MallocT
<Direction
>(as
->num_table
);
3757 uint32 defsize
= buf
->ReadDWord(); // Total size of the definition
3758 AirportTileTable
**tile_table
= CallocT
<AirportTileTable
*>(as
->num_table
); // Table with tiles to compose the airport
3759 AirportTileTable
*att
= CallocT
<AirportTileTable
>(defsize
); // Temporary array to read the tile layouts from the GRF
3761 const AirportTileTable
*copy_from
;
3763 for (byte j
= 0; j
< as
->num_table
; j
++) {
3764 const_cast<Direction
&>(as
->rotation
[j
]) = (Direction
)buf
->ReadByte();
3765 for (int k
= 0;; k
++) {
3766 att
[k
].ti
.x
= buf
->ReadByte(); // Offsets from northermost tile
3767 att
[k
].ti
.y
= buf
->ReadByte();
3769 if (att
[k
].ti
.x
== 0 && att
[k
].ti
.y
== 0x80) {
3770 /* Not the same terminator. The one we are using is rather
3771 * x = -80, y = 0 . So, adjust it. */
3772 att
[k
].ti
.x
= -0x80;
3781 att
[k
].gfx
= buf
->ReadByte();
3783 if (att
[k
].gfx
== 0xFE) {
3784 /* Use a new tile from this GRF */
3785 int local_tile_id
= buf
->ReadWord();
3787 /* Read the ID from the _airporttile_mngr. */
3788 uint16 tempid
= _airporttile_mngr
.GetID(local_tile_id
, _cur
.grffile
->grfid
);
3790 if (tempid
== INVALID_AIRPORTTILE
) {
3791 grfmsg(2, "AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id
, airport
+ i
);
3793 /* Declared as been valid, can be used */
3794 att
[k
].gfx
= tempid
;
3798 } else if (att
[k
].gfx
== 0xFF) {
3799 att
[k
].ti
.x
= (int8
)GB(att
[k
].ti
.x
, 0, 8);
3800 att
[k
].ti
.y
= (int8
)GB(att
[k
].ti
.y
, 0, 8);
3803 if (as
->rotation
[j
] == DIR_E
|| as
->rotation
[j
] == DIR_W
) {
3804 as
->size_x
= max
<byte
>(as
->size_x
, att
[k
].ti
.y
+ 1);
3805 as
->size_y
= max
<byte
>(as
->size_y
, att
[k
].ti
.x
+ 1);
3807 as
->size_x
= max
<byte
>(as
->size_x
, att
[k
].ti
.x
+ 1);
3808 as
->size_y
= max
<byte
>(as
->size_y
, att
[k
].ti
.y
+ 1);
3811 tile_table
[j
] = CallocT
<AirportTileTable
>(size
);
3812 memcpy(tile_table
[j
], copy_from
, sizeof(*copy_from
) * size
);
3814 /* Install final layout construction in the airport spec */
3815 as
->table
= tile_table
;
3818 for (int i
= 0; i
< as
->num_table
; i
++) {
3819 free(tile_table
[i
]);
3829 as
->min_year
= buf
->ReadWord();
3830 as
->max_year
= buf
->ReadWord();
3831 if (as
->max_year
== 0xFFFF) as
->max_year
= MAX_YEAR
;
3835 as
->ttd_airport_type
= (TTDPAirportType
)buf
->ReadByte();
3839 as
->catchment
= Clamp(buf
->ReadByte(), 1, MAX_CATCHMENT
);
3843 as
->noise_level
= buf
->ReadByte();
3847 AddStringForMapping(buf
->ReadWord(), &as
->name
);
3850 case 0x11: // Maintenance cost factor
3851 as
->maintenance_cost
= buf
->ReadWord();
3854 case 0x12: { // Accept seaplanes
3855 byte is_seaplane
= buf
->ReadByte();
3856 if (is_seaplane
== 0x01){
3857 as
->cls_id
= APC_SEA
;
3872 * Ignore properties for objects
3873 * @param prop The property to ignore.
3874 * @param buf The property value.
3875 * @return ChangeInfoResult.
3877 static ChangeInfoResult
IgnoreObjectProperty(uint prop
, ByteReader
*buf
)
3879 ChangeInfoResult ret
= CIR_SUCCESS
;
3916 * Define properties for objects
3917 * @param id Local ID of the object.
3918 * @param numinfo Number of subsequent objectIDs to change the property for.
3919 * @param prop The property to change.
3920 * @param buf The property value.
3921 * @return ChangeInfoResult.
3923 static ChangeInfoResult
ObjectChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
3925 ChangeInfoResult ret
= CIR_SUCCESS
;
3927 if (id
+ numinfo
> NUM_OBJECTS_PER_GRF
) {
3928 grfmsg(1, "ObjectChangeInfo: Too many objects loaded (%u), max (%u). Ignoring.", id
+ numinfo
, NUM_OBJECTS_PER_GRF
);
3929 return CIR_INVALID_ID
;
3932 /* Allocate object specs if they haven't been allocated already. */
3933 if (_cur
.grffile
->objectspec
== NULL
) {
3934 _cur
.grffile
->objectspec
= CallocT
<ObjectSpec
*>(NUM_OBJECTS_PER_GRF
);
3937 for (int i
= 0; i
< numinfo
; i
++) {
3938 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[id
+ i
];
3940 if (prop
!= 0x08 && spec
== NULL
) {
3941 /* If the object property 08 is not yet set, ignore this property */
3942 ChangeInfoResult cir
= IgnoreObjectProperty(prop
, buf
);
3943 if (cir
> ret
) ret
= cir
;
3948 case 0x08: { // Class ID
3949 ObjectSpec
**ospec
= &_cur
.grffile
->objectspec
[id
+ i
];
3951 /* Allocate space for this object. */
3952 if (*ospec
== NULL
) {
3953 *ospec
= CallocT
<ObjectSpec
>(1);
3954 (*ospec
)->views
= 1; // Default for NewGRFs that don't set it.
3957 /* Swap classid because we read it in BE. */
3958 uint32 classid
= buf
->ReadDWord();
3959 (*ospec
)->cls_id
= ObjectClass::Allocate(BSWAP32(classid
));
3960 (*ospec
)->enabled
= true;
3964 case 0x09: { // Class name
3965 ObjectClass
*objclass
= ObjectClass::Get(spec
->cls_id
);
3966 AddStringForMapping(buf
->ReadWord(), &objclass
->name
);
3970 case 0x0A: // Object name
3971 AddStringForMapping(buf
->ReadWord(), &spec
->name
);
3974 case 0x0B: // Climate mask
3975 spec
->climate
= buf
->ReadByte();
3979 spec
->size
= buf
->ReadByte();
3982 case 0x0D: // Build cost multipler
3983 spec
->build_cost_multiplier
= buf
->ReadByte();
3984 spec
->clear_cost_multiplier
= spec
->build_cost_multiplier
;
3987 case 0x0E: // Introduction date
3988 spec
->introduction_date
= buf
->ReadDWord();
3991 case 0x0F: // End of life
3992 spec
->end_of_life_date
= buf
->ReadDWord();
3996 spec
->flags
= (ObjectFlags
)buf
->ReadWord();
3997 _loaded_newgrf_features
.has_2CC
|= (spec
->flags
& OBJECT_FLAG_2CC_COLOUR
) != 0;
4000 case 0x11: // Animation info
4001 spec
->animation
.frames
= buf
->ReadByte();
4002 spec
->animation
.status
= buf
->ReadByte();
4005 case 0x12: // Animation speed
4006 spec
->animation
.speed
= buf
->ReadByte();
4009 case 0x13: // Animation triggers
4010 spec
->animation
.triggers
= buf
->ReadWord();
4013 case 0x14: // Removal cost multiplier
4014 spec
->clear_cost_multiplier
= buf
->ReadByte();
4017 case 0x15: // Callback mask
4018 spec
->callback_mask
= buf
->ReadWord();
4021 case 0x16: // Building height
4022 spec
->height
= buf
->ReadByte();
4026 spec
->views
= buf
->ReadByte();
4027 if (spec
->views
!= 1 && spec
->views
!= 2 && spec
->views
!= 4) {
4028 grfmsg(2, "ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec
->views
, id
+ i
);
4033 case 0x18: // Amount placed on 256^2 map on map creation
4034 spec
->generate_amount
= buf
->ReadByte();
4047 * Define properties for railtypes
4048 * @param id ID of the railtype.
4049 * @param numinfo Number of subsequent IDs to change the property for.
4050 * @param prop The property to change.
4051 * @param buf The property value.
4052 * @return ChangeInfoResult.
4054 static ChangeInfoResult
RailTypeChangeInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4056 ChangeInfoResult ret
= CIR_SUCCESS
;
4058 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
4060 if (id
+ numinfo
> RAILTYPE_END
) {
4061 grfmsg(1, "RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring", id
+ numinfo
, RAILTYPE_END
);
4062 return CIR_INVALID_ID
;
4065 for (int i
= 0; i
< numinfo
; i
++) {
4066 RailType rt
= _cur
.grffile
->railtype_map
[id
+ i
];
4067 if (rt
== INVALID_RAILTYPE
) return CIR_INVALID_ID
;
4069 RailtypeInfo
*rti
= &_railtypes
[rt
];
4072 case 0x08: // Label of rail type
4073 /* Skipped here as this is loaded during reservation stage. */
4077 case 0x09: { // Toolbar caption of railtype (sets name as well for backwards compatibility for grf ver < 8)
4078 uint16 str
= buf
->ReadWord();
4079 AddStringForMapping(str
, &rti
->strings
.toolbar_caption
);
4080 if (_cur
.grffile
->grf_version
< 8) {
4081 AddStringForMapping(str
, &rti
->strings
.name
);
4086 case 0x0A: // Menu text of railtype
4087 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.menu_text
);
4090 case 0x0B: // Build window caption
4091 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.build_caption
);
4094 case 0x0C: // Autoreplace text
4095 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.replace_text
);
4098 case 0x0D: // New locomotive text
4099 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.new_loco
);
4102 case 0x0E: // Compatible railtype list
4103 case 0x0F: // Powered railtype list
4104 case 0x18: // Railtype list required for date introduction
4105 case 0x19: // Introduced railtype list
4107 /* Rail type compatibility bits are added to the existing bits
4108 * to allow multiple GRFs to modify compatibility with the
4109 * default rail types. */
4110 int n
= buf
->ReadByte();
4111 for (int j
= 0; j
!= n
; j
++) {
4112 RailTypeLabel label
= buf
->ReadDWord();
4113 RailType rt
= GetRailTypeByLabel(BSWAP32(label
), false);
4114 if (rt
!= INVALID_RAILTYPE
) {
4116 case 0x0F: SetBit(rti
->powered_railtypes
, rt
); FALLTHROUGH
; // Powered implies compatible.
4117 case 0x0E: SetBit(rti
->compatible_railtypes
, rt
); break;
4118 case 0x18: SetBit(rti
->introduction_required_railtypes
, rt
); break;
4119 case 0x19: SetBit(rti
->introduces_railtypes
, rt
); break;
4126 case 0x10: // Rail Type flags
4127 rti
->flags
= (RailTypeFlags
)buf
->ReadByte();
4130 case 0x11: // Curve speed advantage
4131 rti
->curve_speed
= buf
->ReadByte();
4134 case 0x12: // Station graphic
4135 rti
->fallback_railtype
= Clamp(buf
->ReadByte(), 0, 2);
4138 case 0x13: // Construction cost factor
4139 rti
->cost_multiplier
= buf
->ReadWord();
4142 case 0x14: // Speed limit
4143 rti
->max_speed
= buf
->ReadWord();
4146 case 0x15: // Acceleration model
4147 rti
->acceleration_type
= Clamp(buf
->ReadByte(), 0, 2);
4150 case 0x16: // Map colour
4151 rti
->map_colour
= buf
->ReadByte();
4154 case 0x17: // Introduction date
4155 rti
->introduction_date
= buf
->ReadDWord();
4158 case 0x1A: // Sort order
4159 rti
->sorting_order
= buf
->ReadByte();
4162 case 0x1B: // Name of railtype (overridden by prop 09 for grf ver < 8)
4163 AddStringForMapping(buf
->ReadWord(), &rti
->strings
.name
);
4166 case 0x1C: // Maintenance cost factor
4167 rti
->maintenance_multiplier
= buf
->ReadWord();
4170 case 0x1D: // Alternate rail type label list
4171 /* Skipped here as this is loaded during reservation stage. */
4172 for (int j
= buf
->ReadByte(); j
!= 0; j
--) buf
->ReadDWord();
4184 static ChangeInfoResult
RailTypeReserveInfo(uint id
, int numinfo
, int prop
, ByteReader
*buf
)
4186 ChangeInfoResult ret
= CIR_SUCCESS
;
4188 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
4190 if (id
+ numinfo
> RAILTYPE_END
) {
4191 grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id
+ numinfo
, RAILTYPE_END
);
4192 return CIR_INVALID_ID
;
4195 for (int i
= 0; i
< numinfo
; i
++) {
4197 case 0x08: // Label of rail type
4199 RailTypeLabel rtl
= buf
->ReadDWord();
4202 RailType rt
= GetRailTypeByLabel(rtl
, false);
4203 if (rt
== INVALID_RAILTYPE
) {
4204 /* Set up new rail type */
4205 rt
= AllocateRailType(rtl
);
4208 _cur
.grffile
->railtype_map
[id
+ i
] = rt
;
4212 case 0x09: // Toolbar caption of railtype
4213 case 0x0A: // Menu text
4214 case 0x0B: // Build window caption
4215 case 0x0C: // Autoreplace text
4216 case 0x0D: // New loco
4217 case 0x13: // Construction cost
4218 case 0x14: // Speed limit
4219 case 0x1B: // Name of railtype
4220 case 0x1C: // Maintenance cost factor
4224 case 0x1D: // Alternate rail type label list
4225 if (_cur
.grffile
->railtype_map
[id
+ i
] != INVALID_RAILTYPE
) {
4226 int n
= buf
->ReadByte();
4227 for (int j
= 0; j
!= n
; j
++) {
4228 *_railtypes
[_cur
.grffile
->railtype_map
[id
+ i
]].alternate_labels
.Append() = BSWAP32(buf
->ReadDWord());
4232 grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id
+ i
);
4235 case 0x0E: // Compatible railtype list
4236 case 0x0F: // Powered railtype list
4237 case 0x18: // Railtype list required for date introduction
4238 case 0x19: // Introduced railtype list
4239 for (int j
= buf
->ReadByte(); j
!= 0; j
--) buf
->ReadDWord();
4242 case 0x10: // Rail Type flags
4243 case 0x11: // Curve speed advantage
4244 case 0x12: // Station graphic
4245 case 0x15: // Acceleration model
4246 case 0x16: // Map colour
4247 case 0x1A: // Sort order
4251 case 0x17: // Introduction date
4264 static ChangeInfoResult
AirportTilesChangeInfo(uint airtid
, int numinfo
, int prop
, ByteReader
*buf
)
4266 ChangeInfoResult ret
= CIR_SUCCESS
;
4268 if (airtid
+ numinfo
> NUM_AIRPORTTILES_PER_GRF
) {
4269 grfmsg(1, "AirportTileChangeInfo: Too many airport tiles loaded (%u), max (%u). Ignoring.", airtid
+ numinfo
, NUM_AIRPORTTILES_PER_GRF
);
4270 return CIR_INVALID_ID
;
4273 /* Allocate airport tile specs if they haven't been allocated already. */
4274 if (_cur
.grffile
->airtspec
== NULL
) {
4275 _cur
.grffile
->airtspec
= CallocT
<AirportTileSpec
*>(NUM_AIRPORTTILES_PER_GRF
);
4278 for (int i
= 0; i
< numinfo
; i
++) {
4279 AirportTileSpec
*tsp
= _cur
.grffile
->airtspec
[airtid
+ i
];
4281 if (prop
!= 0x08 && tsp
== NULL
) {
4282 grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid
+ i
);
4283 return CIR_INVALID_ID
;
4287 case 0x08: { // Substitute airport tile type
4288 AirportTileSpec
**tilespec
= &_cur
.grffile
->airtspec
[airtid
+ i
];
4289 byte subs_id
= buf
->ReadByte();
4291 if (subs_id
>= NEW_AIRPORTTILE_OFFSET
) {
4292 /* The substitute id must be one of the original airport tiles. */
4293 grfmsg(2, "AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id
, airtid
+ i
);
4297 /* Allocate space for this airport tile. */
4298 if (*tilespec
== NULL
) {
4299 *tilespec
= CallocT
<AirportTileSpec
>(1);
4302 memcpy(tsp
, AirportTileSpec::Get(subs_id
), sizeof(AirportTileSpec
));
4303 tsp
->enabled
= true;
4305 tsp
->animation
.status
= ANIM_STATUS_NO_ANIMATION
;
4307 tsp
->grf_prop
.local_id
= airtid
+ i
;
4308 tsp
->grf_prop
.subst_id
= subs_id
;
4309 tsp
->grf_prop
.grffile
= _cur
.grffile
;
4310 _airporttile_mngr
.AddEntityID(airtid
+ i
, _cur
.grffile
->grfid
, subs_id
); // pre-reserve the tile slot
4315 case 0x09: { // Airport tile override
4316 byte override
= buf
->ReadByte();
4318 /* The airport tile being overridden must be an original airport tile. */
4319 if (override
>= NEW_AIRPORTTILE_OFFSET
) {
4320 grfmsg(2, "AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.", override
, airtid
+ i
);
4324 _airporttile_mngr
.Add(airtid
+ i
, _cur
.grffile
->grfid
, override
);
4328 case 0x0E: // Callback mask
4329 tsp
->callback_mask
= buf
->ReadByte();
4332 case 0x0F: // Animation information
4333 tsp
->animation
.frames
= buf
->ReadByte();
4334 tsp
->animation
.status
= buf
->ReadByte();
4337 case 0x10: // Animation speed
4338 tsp
->animation
.speed
= buf
->ReadByte();
4341 case 0x11: // Animation triggers
4342 tsp
->animation
.triggers
= buf
->ReadByte();
4354 static bool HandleChangeInfoResult(const char *caller
, ChangeInfoResult cir
, uint8 feature
, uint8 property
)
4357 default: NOT_REACHED();
4360 /* Error has already been printed; just stop parsing */
4367 grfmsg(1, "%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller
, property
, feature
);
4371 grfmsg(0, "%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller
, property
, feature
);
4374 case CIR_INVALID_ID
: {
4375 /* No debug message for an invalid ID, as it has already been output */
4376 GRFError
*error
= DisableGrf(cir
== CIR_INVALID_ID
? STR_NEWGRF_ERROR_INVALID_ID
: STR_NEWGRF_ERROR_UNKNOWN_PROPERTY
);
4377 if (cir
!= CIR_INVALID_ID
) error
->param_value
[1] = property
;
4384 static void FeatureChangeInfo(ByteReader
*buf
)
4386 /* <00> <feature> <num-props> <num-info> <id> (<property <new-info>)...
4389 * B num-props how many properties to change per vehicle/station
4390 * B num-info how many vehicles/stations to change
4391 * E id ID of first vehicle/station to change, if num-info is
4392 * greater than one, this one and the following
4393 * vehicles/stations will be changed
4394 * B property what property to change, depends on the feature
4395 * V new-info new bytes of info (variable size; depends on properties) */
4397 static const VCI_Handler handler
[] = {
4398 /* GSF_TRAINS */ RailVehicleChangeInfo
,
4399 /* GSF_ROADVEHICLES */ RoadVehicleChangeInfo
,
4400 /* GSF_SHIPS */ ShipVehicleChangeInfo
,
4401 /* GSF_AIRCRAFT */ AircraftVehicleChangeInfo
,
4402 /* GSF_STATIONS */ StationChangeInfo
,
4403 /* GSF_CANALS */ CanalChangeInfo
,
4404 /* GSF_BRIDGES */ BridgeChangeInfo
,
4405 /* GSF_HOUSES */ TownHouseChangeInfo
,
4406 /* GSF_GLOBALVAR */ GlobalVarChangeInfo
,
4407 /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo
,
4408 /* GSF_INDUSTRIES */ IndustriesChangeInfo
,
4409 /* GSF_CARGOES */ NULL
, // Cargo is handled during reservation
4410 /* GSF_SOUNDFX */ SoundEffectChangeInfo
,
4411 /* GSF_AIRPORTS */ AirportChangeInfo
,
4412 /* GSF_SIGNALS */ NULL
,
4413 /* GSF_OBJECTS */ ObjectChangeInfo
,
4414 /* GSF_RAILTYPES */ RailTypeChangeInfo
,
4415 /* GSF_AIRPORTTILES */ AirportTilesChangeInfo
,
4418 uint8 feature
= buf
->ReadByte();
4419 uint8 numprops
= buf
->ReadByte();
4420 uint numinfo
= buf
->ReadByte();
4421 uint engine
= buf
->ReadExtendedByte();
4423 grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4424 feature
, numprops
, engine
, numinfo
);
4426 if (feature
>= lengthof(handler
) || handler
[feature
] == NULL
) {
4427 if (feature
!= GSF_CARGOES
) grfmsg(1, "FeatureChangeInfo: Unsupported feature %d, skipping", feature
);
4431 /* Mark the feature as used by the grf */
4432 SetBit(_cur
.grffile
->grf_features
, feature
);
4434 while (numprops
-- && buf
->HasData()) {
4435 uint8 prop
= buf
->ReadByte();
4437 ChangeInfoResult cir
= handler
[feature
](engine
, numinfo
, prop
, buf
);
4438 if (HandleChangeInfoResult("FeatureChangeInfo", cir
, feature
, prop
)) return;
4442 /* Action 0x00 (GLS_SAFETYSCAN) */
4443 static void SafeChangeInfo(ByteReader
*buf
)
4445 uint8 feature
= buf
->ReadByte();
4446 uint8 numprops
= buf
->ReadByte();
4447 uint numinfo
= buf
->ReadByte();
4448 buf
->ReadExtendedByte(); // id
4450 if (feature
== GSF_BRIDGES
&& numprops
== 1) {
4451 uint8 prop
= buf
->ReadByte();
4452 /* Bridge property 0x0D is redefinition of sprite layout tables, which
4453 * is considered safe. */
4454 if (prop
== 0x0D) return;
4455 } else if (feature
== GSF_GLOBALVAR
&& numprops
== 1) {
4456 uint8 prop
= buf
->ReadByte();
4457 /* Engine ID Mappings are safe, if the source is static */
4459 bool is_safe
= true;
4460 for (uint i
= 0; i
< numinfo
; i
++) {
4461 uint32 s
= buf
->ReadDWord();
4462 buf
->ReadDWord(); // dest
4463 const GRFConfig
*grfconfig
= GetGRFConfig(s
);
4464 if (grfconfig
!= NULL
&& !HasBit(grfconfig
->flags
, GCF_STATIC
)) {
4469 if (is_safe
) return;
4473 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
4475 /* Skip remainder of GRF */
4476 _cur
.skip_sprites
= -1;
4479 /* Action 0x00 (GLS_RESERVE) */
4480 static void ReserveChangeInfo(ByteReader
*buf
)
4482 uint8 feature
= buf
->ReadByte();
4484 if (feature
!= GSF_CARGOES
&& feature
!= GSF_GLOBALVAR
&& feature
!= GSF_RAILTYPES
) return;
4486 uint8 numprops
= buf
->ReadByte();
4487 uint8 numinfo
= buf
->ReadByte();
4488 uint8 index
= buf
->ReadExtendedByte();
4490 while (numprops
-- && buf
->HasData()) {
4491 uint8 prop
= buf
->ReadByte();
4492 ChangeInfoResult cir
= CIR_SUCCESS
;
4495 default: NOT_REACHED();
4497 cir
= CargoChangeInfo(index
, numinfo
, prop
, buf
);
4501 cir
= GlobalVarReserveInfo(index
, numinfo
, prop
, buf
);
4505 cir
= RailTypeReserveInfo(index
, numinfo
, prop
, buf
);
4509 if (HandleChangeInfoResult("ReserveChangeInfo", cir
, feature
, prop
)) return;
4514 static void NewSpriteSet(ByteReader
*buf
)
4516 /* Basic format: <01> <feature> <num-sets> <num-ent>
4517 * Extended format: <01> <feature> 00 <first-set> <num-sets> <num-ent>
4519 * B feature feature to define sprites for
4520 * 0, 1, 2, 3: veh-type, 4: train stations
4521 * E first-set first sprite set to define
4522 * B num-sets number of sprite sets (extended byte in extended format)
4523 * E num-ent how many entries per sprite set
4524 * For vehicles, this is the number of different
4525 * vehicle directions in each sprite set
4526 * Set num-dirs=8, unless your sprites are symmetric.
4527 * In that case, use num-dirs=4.
4530 uint8 feature
= buf
->ReadByte();
4531 uint16 num_sets
= buf
->ReadByte();
4532 uint16 first_set
= 0;
4534 if (num_sets
== 0 && buf
->HasData(3)) {
4535 /* Extended Action1 format.
4536 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4537 first_set
= buf
->ReadExtendedByte();
4538 num_sets
= buf
->ReadExtendedByte();
4540 uint16 num_ents
= buf
->ReadExtendedByte();
4542 _cur
.AddSpriteSets(feature
, _cur
.spriteid
, first_set
, num_sets
, num_ents
);
4544 grfmsg(7, "New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4545 _cur
.spriteid
, feature
, num_sets
, num_ents
, num_sets
* num_ents
4548 for (int i
= 0; i
< num_sets
* num_ents
; i
++) {
4550 LoadNextSprite(_cur
.spriteid
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
4554 /* Action 0x01 (SKIP) */
4555 static void SkipAct1(ByteReader
*buf
)
4558 uint16 num_sets
= buf
->ReadByte();
4560 if (num_sets
== 0 && buf
->HasData(3)) {
4561 /* Extended Action1 format.
4562 * Some GRFs define zero sets of zero sprites, though there is actually no use in that. Ignore them. */
4563 buf
->ReadExtendedByte(); // first_set
4564 num_sets
= buf
->ReadExtendedByte();
4566 uint16 num_ents
= buf
->ReadExtendedByte();
4568 _cur
.skip_sprites
= num_sets
* num_ents
;
4570 grfmsg(3, "SkipAct1: Skipping %d sprites", _cur
.skip_sprites
);
4573 /* Helper function to either create a callback or link to a previously
4574 * defined spritegroup. */
4575 static const SpriteGroup
*GetGroupFromGroupID(byte setid
, byte type
, uint16 groupid
)
4577 if (HasBit(groupid
, 15)) {
4578 assert(CallbackResultSpriteGroup::CanAllocateItem());
4579 return new CallbackResultSpriteGroup(groupid
, _cur
.grffile
->grf_version
>= 8);
4582 if (groupid
> MAX_SPRITEGROUP
|| _cur
.spritegroups
[groupid
] == NULL
) {
4583 grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid
, type
, groupid
);
4587 return _cur
.spritegroups
[groupid
];
4591 * Helper function to either create a callback or a result sprite group.
4592 * @param feature GrfSpecFeature to define spritegroup for.
4593 * @param setid SetID of the currently being parsed Action2. (only for debug output)
4594 * @param type Type of the currently being parsed Action2. (only for debug output)
4595 * @param spriteid Raw value from the GRF for the new spritegroup; describes either the return value or the referenced spritegroup.
4596 * @return Created spritegroup.
4598 static const SpriteGroup
*CreateGroupFromGroupID(byte feature
, byte setid
, byte type
, uint16 spriteid
)
4600 if (HasBit(spriteid
, 15)) {
4601 assert(CallbackResultSpriteGroup::CanAllocateItem());
4602 return new CallbackResultSpriteGroup(spriteid
, _cur
.grffile
->grf_version
>= 8);
4605 if (!_cur
.IsValidSpriteSet(feature
, spriteid
)) {
4606 grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid
, type
, spriteid
);
4610 SpriteID spriteset_start
= _cur
.GetSprite(feature
, spriteid
);
4611 uint num_sprites
= _cur
.GetNumEnts(feature
, spriteid
);
4613 /* Ensure that the sprites are loeded */
4614 assert(spriteset_start
+ num_sprites
<= _cur
.spriteid
);
4616 assert(ResultSpriteGroup::CanAllocateItem());
4617 return new ResultSpriteGroup(spriteset_start
, num_sprites
);
4621 static void NewSpriteGroup(ByteReader
*buf
)
4623 /* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
4625 * B feature see action 1
4626 * B set-id ID of this particular definition
4627 * B type/num-entries
4628 * if 80 or greater, this is a randomized or variational
4629 * list definition, see below
4630 * otherwise it specifies a number of entries, the exact
4631 * meaning depends on the feature
4632 * V feature-specific-data (huge mess, don't even look it up --pasky) */
4633 SpriteGroup
*act_group
= NULL
;
4635 uint8 feature
= buf
->ReadByte();
4636 uint8 setid
= buf
->ReadByte();
4637 uint8 type
= buf
->ReadByte();
4639 /* Sprite Groups are created here but they are allocated from a pool, so
4640 * we do not need to delete anything if there is an exception from the
4644 /* Deterministic Sprite Group */
4645 case 0x81: // Self scope, byte
4646 case 0x82: // Parent scope, byte
4647 case 0x85: // Self scope, word
4648 case 0x86: // Parent scope, word
4649 case 0x89: // Self scope, dword
4650 case 0x8A: // Parent scope, dword
4655 assert(DeterministicSpriteGroup::CanAllocateItem());
4656 DeterministicSpriteGroup
*group
= new DeterministicSpriteGroup();
4658 group
->var_scope
= HasBit(type
, 1) ? VSG_SCOPE_PARENT
: VSG_SCOPE_SELF
;
4660 switch (GB(type
, 2, 2)) {
4661 default: NOT_REACHED();
4662 case 0: group
->size
= DSG_SIZE_BYTE
; varsize
= 1; break;
4663 case 1: group
->size
= DSG_SIZE_WORD
; varsize
= 2; break;
4664 case 2: group
->size
= DSG_SIZE_DWORD
; varsize
= 4; break;
4667 static SmallVector
<DeterministicSpriteGroupAdjust
, 16> adjusts
;
4670 /* Loop through the var adjusts. Unfortunately we don't know how many we have
4671 * from the outset, so we shall have to keep reallocing. */
4673 DeterministicSpriteGroupAdjust
*adjust
= adjusts
.Append();
4675 /* The first var adjust doesn't have an operation specified, so we set it to add. */
4676 adjust
->operation
= adjusts
.Length() == 1 ? DSGA_OP_ADD
: (DeterministicSpriteGroupAdjustOperation
)buf
->ReadByte();
4677 adjust
->variable
= buf
->ReadByte();
4678 if (adjust
->variable
== 0x7E) {
4679 /* Link subroutine group */
4680 adjust
->subroutine
= GetGroupFromGroupID(setid
, type
, buf
->ReadByte());
4682 adjust
->parameter
= IsInsideMM(adjust
->variable
, 0x60, 0x80) ? buf
->ReadByte() : 0;
4685 varadjust
= buf
->ReadByte();
4686 adjust
->shift_num
= GB(varadjust
, 0, 5);
4687 adjust
->type
= (DeterministicSpriteGroupAdjustType
)GB(varadjust
, 6, 2);
4688 adjust
->and_mask
= buf
->ReadVarSize(varsize
);
4690 if (adjust
->type
!= DSGA_TYPE_NONE
) {
4691 adjust
->add_val
= buf
->ReadVarSize(varsize
);
4692 adjust
->divmod_val
= buf
->ReadVarSize(varsize
);
4694 adjust
->add_val
= 0;
4695 adjust
->divmod_val
= 0;
4698 /* Continue reading var adjusts while bit 5 is set. */
4699 } while (HasBit(varadjust
, 5));
4701 group
->num_adjusts
= adjusts
.Length();
4702 group
->adjusts
= MallocT
<DeterministicSpriteGroupAdjust
>(group
->num_adjusts
);
4703 MemCpyT(group
->adjusts
, adjusts
.Begin(), group
->num_adjusts
);
4705 std::vector
<DeterministicSpriteGroupRange
> ranges
;
4706 ranges
.resize(buf
->ReadByte());
4707 for (uint i
= 0; i
< ranges
.size(); i
++) {
4708 ranges
[i
].group
= GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4709 ranges
[i
].low
= buf
->ReadVarSize(varsize
);
4710 ranges
[i
].high
= buf
->ReadVarSize(varsize
);
4713 group
->default_group
= GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4714 group
->error_group
= ranges
.size() > 0 ? ranges
[0].group
: group
->default_group
;
4715 /* nvar == 0 is a special case -- we turn our value into a callback result */
4716 group
->calculated_result
= ranges
.size() == 0;
4718 /* Sort ranges ascending. When ranges overlap, this may required clamping or splitting them */
4719 std::vector
<uint32
> bounds
;
4720 for (uint i
= 0; i
< ranges
.size(); i
++) {
4721 bounds
.push_back(ranges
[i
].low
);
4722 if (ranges
[i
].high
!= UINT32_MAX
) bounds
.push_back(ranges
[i
].high
+ 1);
4724 std::sort(bounds
.begin(), bounds
.end());
4725 bounds
.erase(std::unique(bounds
.begin(), bounds
.end()), bounds
.end());
4727 std::vector
<const SpriteGroup
*> target
;
4728 for (uint j
= 0; j
< bounds
.size(); ++j
) {
4729 uint32 v
= bounds
[j
];
4730 const SpriteGroup
*t
= group
->default_group
;
4731 for (uint i
= 0; i
< ranges
.size(); i
++) {
4732 if (ranges
[i
].low
<= v
&& v
<= ranges
[i
].high
) {
4733 t
= ranges
[i
].group
;
4737 target
.push_back(t
);
4739 assert(target
.size() == bounds
.size());
4741 std::vector
<DeterministicSpriteGroupRange
> optimised
;
4742 for (uint j
= 0; j
< bounds
.size(); ) {
4743 if (target
[j
] != group
->default_group
) {
4744 DeterministicSpriteGroupRange r
;
4745 r
.group
= target
[j
];
4747 while (j
< bounds
.size() && target
[j
] == r
.group
) {
4750 r
.high
= j
< bounds
.size() ? bounds
[j
] - 1 : UINT32_MAX
;
4751 optimised
.push_back(r
);
4757 group
->num_ranges
= (uint
)optimised
.size();
4758 if (group
->num_ranges
> 0) {
4759 group
->ranges
= MallocT
<DeterministicSpriteGroupRange
>(group
->num_ranges
);
4760 MemCpyT(group
->ranges
, &optimised
.front(), group
->num_ranges
);
4765 /* Randomized Sprite Group */
4766 case 0x80: // Self scope
4767 case 0x83: // Parent scope
4768 case 0x84: // Relative scope
4770 assert(RandomizedSpriteGroup::CanAllocateItem());
4771 RandomizedSpriteGroup
*group
= new RandomizedSpriteGroup();
4773 group
->var_scope
= HasBit(type
, 1) ? VSG_SCOPE_PARENT
: VSG_SCOPE_SELF
;
4775 if (HasBit(type
, 2)) {
4776 if (feature
<= GSF_AIRCRAFT
) group
->var_scope
= VSG_SCOPE_RELATIVE
;
4777 group
->count
= buf
->ReadByte();
4780 uint8 triggers
= buf
->ReadByte();
4781 group
->triggers
= GB(triggers
, 0, 7);
4782 group
->cmp_mode
= HasBit(triggers
, 7) ? RSG_CMP_ALL
: RSG_CMP_ANY
;
4783 group
->lowest_randbit
= buf
->ReadByte();
4784 group
->num_groups
= buf
->ReadByte();
4785 group
->groups
= CallocT
<const SpriteGroup
*>(group
->num_groups
);
4787 for (uint i
= 0; i
< group
->num_groups
; i
++) {
4788 group
->groups
[i
] = GetGroupFromGroupID(setid
, type
, buf
->ReadWord());
4794 /* Neither a variable or randomized sprite group... must be a real group */
4799 case GSF_ROADVEHICLES
:
4808 byte num_loaded
= type
;
4809 byte num_loading
= buf
->ReadByte();
4811 if (!_cur
.HasValidSpriteSets(feature
)) {
4812 grfmsg(0, "NewSpriteGroup: No sprite set to work on! Skipping");
4816 assert(RealSpriteGroup::CanAllocateItem());
4817 RealSpriteGroup
*group
= new RealSpriteGroup();
4820 group
->num_loaded
= num_loaded
;
4821 group
->num_loading
= num_loading
;
4822 if (num_loaded
> 0) group
->loaded
= CallocT
<const SpriteGroup
*>(num_loaded
);
4823 if (num_loading
> 0) group
->loading
= CallocT
<const SpriteGroup
*>(num_loading
);
4825 grfmsg(6, "NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4826 setid
, num_loaded
, num_loading
);
4828 for (uint i
= 0; i
< num_loaded
; i
++) {
4829 uint16 spriteid
= buf
->ReadWord();
4830 group
->loaded
[i
] = CreateGroupFromGroupID(feature
, setid
, type
, spriteid
);
4831 grfmsg(8, "NewSpriteGroup: + rg->loaded[%i] = subset %u", i
, spriteid
);
4834 for (uint i
= 0; i
< num_loading
; i
++) {
4835 uint16 spriteid
= buf
->ReadWord();
4836 group
->loading
[i
] = CreateGroupFromGroupID(feature
, setid
, type
, spriteid
);
4837 grfmsg(8, "NewSpriteGroup: + rg->loading[%i] = subset %u", i
, spriteid
);
4844 case GSF_AIRPORTTILES
:
4846 case GSF_INDUSTRYTILES
: {
4847 byte num_building_sprites
= max((uint8
)1, type
);
4849 assert(TileLayoutSpriteGroup::CanAllocateItem());
4850 TileLayoutSpriteGroup
*group
= new TileLayoutSpriteGroup();
4853 /* On error, bail out immediately. Temporary GRF data was already freed */
4854 if (ReadSpriteLayout(buf
, num_building_sprites
, true, feature
, false, type
== 0, &group
->dts
)) return;
4858 case GSF_INDUSTRIES
: {
4860 grfmsg(1, "NewSpriteGroup: Unsupported industry production version %d, skipping", type
);
4864 assert(IndustryProductionSpriteGroup::CanAllocateItem());
4865 IndustryProductionSpriteGroup
*group
= new IndustryProductionSpriteGroup();
4867 group
->version
= type
;
4869 for (uint i
= 0; i
< 3; i
++) {
4870 group
->subtract_input
[i
] = (int16
)buf
->ReadWord(); // signed
4872 for (uint i
= 0; i
< 2; i
++) {
4873 group
->add_output
[i
] = buf
->ReadWord(); // unsigned
4875 group
->again
= buf
->ReadByte();
4877 for (uint i
= 0; i
< 3; i
++) {
4878 group
->subtract_input
[i
] = buf
->ReadByte();
4880 for (uint i
= 0; i
< 2; i
++) {
4881 group
->add_output
[i
] = buf
->ReadByte();
4883 group
->again
= buf
->ReadByte();
4888 /* Loading of Tile Layout and Production Callback groups would happen here */
4889 default: grfmsg(1, "NewSpriteGroup: Unsupported feature %d, skipping", feature
);
4894 _cur
.spritegroups
[setid
] = act_group
;
4897 static CargoID
TranslateCargo(uint8 feature
, uint8 ctype
)
4899 if (feature
== GSF_OBJECTS
) {
4902 case 0xFF: return CT_PURCHASE_OBJECT
;
4904 grfmsg(1, "TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype
);
4908 /* Special cargo types for purchase list and stations */
4909 if (feature
== GSF_STATIONS
&& ctype
== 0xFE) return CT_DEFAULT_NA
;
4910 if (ctype
== 0xFF) return CT_PURCHASE
;
4912 if (_cur
.grffile
->cargo_list
.Length() == 0) {
4913 /* No cargo table, so use bitnum values */
4915 grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype
);
4919 const CargoSpec
*cs
;
4920 FOR_ALL_CARGOSPECS(cs
) {
4921 if (cs
->bitnum
== ctype
) {
4922 grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype
, cs
->Index());
4927 grfmsg(5, "TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype
);
4931 /* Check if the cargo type is out of bounds of the cargo translation table */
4932 if (ctype
>= _cur
.grffile
->cargo_list
.Length()) {
4933 grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype
, _cur
.grffile
->cargo_list
.Length() - 1);
4937 /* Look up the cargo label from the translation table */
4938 CargoLabel cl
= _cur
.grffile
->cargo_list
[ctype
];
4940 grfmsg(5, "TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype
);
4944 ctype
= GetCargoIDByLabel(cl
);
4945 if (ctype
== CT_INVALID
) {
4946 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));
4950 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
);
4955 static bool IsValidGroupID(uint16 groupid
, const char *function
)
4957 if (groupid
> MAX_SPRITEGROUP
|| _cur
.spritegroups
[groupid
] == NULL
) {
4958 grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function
, groupid
);
4965 static void VehicleMapSpriteGroup(ByteReader
*buf
, byte feature
, uint8 idcount
)
4967 static EngineID
*last_engines
;
4968 static uint last_engines_count
;
4969 bool wagover
= false;
4971 /* Test for 'wagon override' flag */
4972 if (HasBit(idcount
, 7)) {
4974 /* Strip off the flag */
4975 idcount
= GB(idcount
, 0, 7);
4977 if (last_engines_count
== 0) {
4978 grfmsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4982 grfmsg(6, "VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4983 last_engines_count
, idcount
);
4985 if (last_engines_count
!= idcount
) {
4986 last_engines
= ReallocT(last_engines
, idcount
);
4987 last_engines_count
= idcount
;
4991 EngineID
*engines
= AllocaM(EngineID
, idcount
);
4992 for (uint i
= 0; i
< idcount
; i
++) {
4993 Engine
*e
= GetNewEngine(_cur
.grffile
, (VehicleType
)feature
, buf
->ReadExtendedByte());
4995 /* No engine could be allocated?!? Deal with it. Okay,
4996 * this might look bad. Also make sure this NewGRF
4997 * gets disabled, as a half loaded one is bad. */
4998 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID
, 0, 0);
5002 engines
[i
] = e
->index
;
5003 if (!wagover
) last_engines
[i
] = engines
[i
];
5006 uint8 cidcount
= buf
->ReadByte();
5007 for (uint c
= 0; c
< cidcount
; c
++) {
5008 uint8 ctype
= buf
->ReadByte();
5009 uint16 groupid
= buf
->ReadWord();
5010 if (!IsValidGroupID(groupid
, "VehicleMapSpriteGroup")) continue;
5012 grfmsg(8, "VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c
, ctype
, groupid
);
5014 ctype
= TranslateCargo(feature
, ctype
);
5015 if (ctype
== CT_INVALID
) continue;
5017 for (uint i
= 0; i
< idcount
; i
++) {
5018 EngineID engine
= engines
[i
];
5020 grfmsg(7, "VehicleMapSpriteGroup: [%d] Engine %d...", i
, engine
);
5023 SetWagonOverrideSprites(engine
, ctype
, _cur
.spritegroups
[groupid
], last_engines
, last_engines_count
);
5025 SetCustomEngineSprites(engine
, ctype
, _cur
.spritegroups
[groupid
]);
5030 uint16 groupid
= buf
->ReadWord();
5031 if (!IsValidGroupID(groupid
, "VehicleMapSpriteGroup")) return;
5033 grfmsg(8, "-- Default group id 0x%04X", groupid
);
5035 for (uint i
= 0; i
< idcount
; i
++) {
5036 EngineID engine
= engines
[i
];
5039 SetWagonOverrideSprites(engine
, CT_DEFAULT
, _cur
.spritegroups
[groupid
], last_engines
, last_engines_count
);
5041 SetCustomEngineSprites(engine
, CT_DEFAULT
, _cur
.spritegroups
[groupid
]);
5042 SetEngineGRF(engine
, _cur
.grffile
);
5048 static void CanalMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5050 CanalFeature
*cfs
= AllocaM(CanalFeature
, idcount
);
5051 for (uint i
= 0; i
< idcount
; i
++) {
5052 cfs
[i
] = (CanalFeature
)buf
->ReadByte();
5055 uint8 cidcount
= buf
->ReadByte();
5056 buf
->Skip(cidcount
* 3);
5058 uint16 groupid
= buf
->ReadWord();
5059 if (!IsValidGroupID(groupid
, "CanalMapSpriteGroup")) return;
5061 for (uint i
= 0; i
< idcount
; i
++) {
5062 CanalFeature cf
= cfs
[i
];
5065 grfmsg(1, "CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf
);
5069 _water_feature
[cf
].grffile
= _cur
.grffile
;
5070 _water_feature
[cf
].group
= _cur
.spritegroups
[groupid
];
5075 static void StationMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5077 uint8
*stations
= AllocaM(uint8
, idcount
);
5078 for (uint i
= 0; i
< idcount
; i
++) {
5079 stations
[i
] = buf
->ReadByte();
5082 uint8 cidcount
= buf
->ReadByte();
5083 for (uint c
= 0; c
< cidcount
; c
++) {
5084 uint8 ctype
= buf
->ReadByte();
5085 uint16 groupid
= buf
->ReadWord();
5086 if (!IsValidGroupID(groupid
, "StationMapSpriteGroup")) continue;
5088 ctype
= TranslateCargo(GSF_STATIONS
, ctype
);
5089 if (ctype
== CT_INVALID
) continue;
5091 for (uint i
= 0; i
< idcount
; i
++) {
5092 StationSpec
*statspec
= _cur
.grffile
->stations
== NULL
? NULL
: _cur
.grffile
->stations
[stations
[i
]];
5094 if (statspec
== NULL
) {
5095 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations
[i
]);
5099 statspec
->grf_prop
.spritegroup
[ctype
] = _cur
.spritegroups
[groupid
];
5103 uint16 groupid
= buf
->ReadWord();
5104 if (!IsValidGroupID(groupid
, "StationMapSpriteGroup")) return;
5106 for (uint i
= 0; i
< idcount
; i
++) {
5107 StationSpec
*statspec
= _cur
.grffile
->stations
== NULL
? NULL
: _cur
.grffile
->stations
[stations
[i
]];
5109 if (statspec
== NULL
) {
5110 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations
[i
]);
5114 if (statspec
->grf_prop
.grffile
!= NULL
) {
5115 grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations
[i
]);
5119 statspec
->grf_prop
.spritegroup
[CT_DEFAULT
] = _cur
.spritegroups
[groupid
];
5120 statspec
->grf_prop
.grffile
= _cur
.grffile
;
5121 statspec
->grf_prop
.local_id
= stations
[i
];
5122 StationClass::Assign(statspec
);
5127 static void TownHouseMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5129 uint8
*houses
= AllocaM(uint8
, idcount
);
5130 for (uint i
= 0; i
< idcount
; i
++) {
5131 houses
[i
] = buf
->ReadByte();
5134 /* Skip the cargo type section, we only care about the default group */
5135 uint8 cidcount
= buf
->ReadByte();
5136 buf
->Skip(cidcount
* 3);
5138 uint16 groupid
= buf
->ReadWord();
5139 if (!IsValidGroupID(groupid
, "TownHouseMapSpriteGroup")) return;
5141 if (_cur
.grffile
->housespec
== NULL
) {
5142 grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping");
5146 for (uint i
= 0; i
< idcount
; i
++) {
5147 HouseSpec
*hs
= _cur
.grffile
->housespec
[houses
[i
]];
5150 grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses
[i
]);
5154 hs
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5158 static void IndustryMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5160 uint8
*industries
= AllocaM(uint8
, idcount
);
5161 for (uint i
= 0; i
< idcount
; i
++) {
5162 industries
[i
] = buf
->ReadByte();
5165 /* Skip the cargo type section, we only care about the default group */
5166 uint8 cidcount
= buf
->ReadByte();
5167 buf
->Skip(cidcount
* 3);
5169 uint16 groupid
= buf
->ReadWord();
5170 if (!IsValidGroupID(groupid
, "IndustryMapSpriteGroup")) return;
5172 if (_cur
.grffile
->industryspec
== NULL
) {
5173 grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping");
5177 for (uint i
= 0; i
< idcount
; i
++) {
5178 IndustrySpec
*indsp
= _cur
.grffile
->industryspec
[industries
[i
]];
5180 if (indsp
== NULL
) {
5181 grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries
[i
]);
5185 indsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5189 static void IndustrytileMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5191 uint8
*indtiles
= AllocaM(uint8
, idcount
);
5192 for (uint i
= 0; i
< idcount
; i
++) {
5193 indtiles
[i
] = buf
->ReadByte();
5196 /* Skip the cargo type section, we only care about the default group */
5197 uint8 cidcount
= buf
->ReadByte();
5198 buf
->Skip(cidcount
* 3);
5200 uint16 groupid
= buf
->ReadWord();
5201 if (!IsValidGroupID(groupid
, "IndustrytileMapSpriteGroup")) return;
5203 if (_cur
.grffile
->indtspec
== NULL
) {
5204 grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5208 for (uint i
= 0; i
< idcount
; i
++) {
5209 IndustryTileSpec
*indtsp
= _cur
.grffile
->indtspec
[indtiles
[i
]];
5211 if (indtsp
== NULL
) {
5212 grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles
[i
]);
5216 indtsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5220 static void CargoMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5222 CargoID
*cargoes
= AllocaM(CargoID
, idcount
);
5223 for (uint i
= 0; i
< idcount
; i
++) {
5224 cargoes
[i
] = buf
->ReadByte();
5227 /* Skip the cargo type section, we only care about the default group */
5228 uint8 cidcount
= buf
->ReadByte();
5229 buf
->Skip(cidcount
* 3);
5231 uint16 groupid
= buf
->ReadWord();
5232 if (!IsValidGroupID(groupid
, "CargoMapSpriteGroup")) return;
5234 for (uint i
= 0; i
< idcount
; i
++) {
5235 CargoID cid
= cargoes
[i
];
5237 if (cid
>= NUM_CARGO
) {
5238 grfmsg(1, "CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid
);
5242 CargoSpec
*cs
= CargoSpec::Get(cid
);
5243 cs
->grffile
= _cur
.grffile
;
5244 cs
->group
= _cur
.spritegroups
[groupid
];
5248 static void ObjectMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5250 if (_cur
.grffile
->objectspec
== NULL
) {
5251 grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping");
5255 uint8
*objects
= AllocaM(uint8
, idcount
);
5256 for (uint i
= 0; i
< idcount
; i
++) {
5257 objects
[i
] = buf
->ReadByte();
5260 uint8 cidcount
= buf
->ReadByte();
5261 for (uint c
= 0; c
< cidcount
; c
++) {
5262 uint8 ctype
= buf
->ReadByte();
5263 uint16 groupid
= buf
->ReadWord();
5264 if (!IsValidGroupID(groupid
, "ObjectMapSpriteGroup")) continue;
5266 ctype
= TranslateCargo(GSF_OBJECTS
, ctype
);
5267 if (ctype
== CT_INVALID
) continue;
5269 for (uint i
= 0; i
< idcount
; i
++) {
5270 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[objects
[i
]];
5273 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects
[i
]);
5277 spec
->grf_prop
.spritegroup
[ctype
] = _cur
.spritegroups
[groupid
];
5281 uint16 groupid
= buf
->ReadWord();
5282 if (!IsValidGroupID(groupid
, "ObjectMapSpriteGroup")) return;
5284 for (uint i
= 0; i
< idcount
; i
++) {
5285 ObjectSpec
*spec
= _cur
.grffile
->objectspec
[objects
[i
]];
5288 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects
[i
]);
5292 if (spec
->grf_prop
.grffile
!= NULL
) {
5293 grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects
[i
]);
5297 spec
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5298 spec
->grf_prop
.grffile
= _cur
.grffile
;
5299 spec
->grf_prop
.local_id
= objects
[i
];
5303 static void RailTypeMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5305 uint8
*railtypes
= AllocaM(uint8
, idcount
);
5306 for (uint i
= 0; i
< idcount
; i
++) {
5307 railtypes
[i
] = _cur
.grffile
->railtype_map
[buf
->ReadByte()];
5310 uint8 cidcount
= buf
->ReadByte();
5311 for (uint c
= 0; c
< cidcount
; c
++) {
5312 uint8 ctype
= buf
->ReadByte();
5313 uint16 groupid
= buf
->ReadWord();
5314 if (!IsValidGroupID(groupid
, "RailTypeMapSpriteGroup")) continue;
5316 if (ctype
>= RTSG_END
) continue;
5318 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
5319 for (uint i
= 0; i
< idcount
; i
++) {
5320 if (railtypes
[i
] != INVALID_RAILTYPE
) {
5321 RailtypeInfo
*rti
= &_railtypes
[railtypes
[i
]];
5323 rti
->grffile
[ctype
] = _cur
.grffile
;
5324 rti
->group
[ctype
] = _cur
.spritegroups
[groupid
];
5329 /* Railtypes do not use the default group. */
5333 static void AirportMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5335 uint8
*airports
= AllocaM(uint8
, idcount
);
5336 for (uint i
= 0; i
< idcount
; i
++) {
5337 airports
[i
] = buf
->ReadByte();
5340 /* Skip the cargo type section, we only care about the default group */
5341 uint8 cidcount
= buf
->ReadByte();
5342 buf
->Skip(cidcount
* 3);
5344 uint16 groupid
= buf
->ReadWord();
5345 if (!IsValidGroupID(groupid
, "AirportMapSpriteGroup")) return;
5347 if (_cur
.grffile
->airportspec
== NULL
) {
5348 grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping");
5352 for (uint i
= 0; i
< idcount
; i
++) {
5353 AirportSpec
*as
= _cur
.grffile
->airportspec
[airports
[i
]];
5356 grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports
[i
]);
5360 as
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5364 static void AirportTileMapSpriteGroup(ByteReader
*buf
, uint8 idcount
)
5366 uint8
*airptiles
= AllocaM(uint8
, idcount
);
5367 for (uint i
= 0; i
< idcount
; i
++) {
5368 airptiles
[i
] = buf
->ReadByte();
5371 /* Skip the cargo type section, we only care about the default group */
5372 uint8 cidcount
= buf
->ReadByte();
5373 buf
->Skip(cidcount
* 3);
5375 uint16 groupid
= buf
->ReadWord();
5376 if (!IsValidGroupID(groupid
, "AirportTileMapSpriteGroup")) return;
5378 if (_cur
.grffile
->airtspec
== NULL
) {
5379 grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5383 for (uint i
= 0; i
< idcount
; i
++) {
5384 AirportTileSpec
*airtsp
= _cur
.grffile
->airtspec
[airptiles
[i
]];
5386 if (airtsp
== NULL
) {
5387 grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles
[i
]);
5391 airtsp
->grf_prop
.spritegroup
[0] = _cur
.spritegroups
[groupid
];
5397 static void FeatureMapSpriteGroup(ByteReader
*buf
)
5399 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
5400 * id-list := [<id>] [id-list]
5401 * cargo-list := <cargo-type> <cid> [cargo-list]
5403 * B feature see action 0
5404 * B n-id bits 0-6: how many IDs this definition applies to
5405 * bit 7: if set, this is a wagon override definition (see below)
5406 * B ids the IDs for which this definition applies
5407 * B num-cid number of cargo IDs (sprite group IDs) in this definition
5408 * can be zero, in that case the def-cid is used always
5409 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
5410 * W cid cargo ID (sprite group ID) for this type of cargo
5411 * W def-cid default cargo ID (sprite group ID) */
5413 uint8 feature
= buf
->ReadByte();
5414 uint8 idcount
= buf
->ReadByte();
5416 /* If idcount is zero, this is a feature callback */
5418 /* Skip number of cargo ids? */
5420 uint16 groupid
= buf
->ReadWord();
5421 if (!IsValidGroupID(groupid
, "FeatureMapSpriteGroup")) return;
5423 grfmsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature
);
5425 AddGenericCallback(feature
, _cur
.grffile
, _cur
.spritegroups
[groupid
]);
5429 /* Mark the feature as used by the grf (generic callbacks do not count) */
5430 SetBit(_cur
.grffile
->grf_features
, feature
);
5432 grfmsg(6, "FeatureMapSpriteGroup: Feature %d, %d ids", feature
, idcount
);
5436 case GSF_ROADVEHICLES
:
5439 VehicleMapSpriteGroup(buf
, feature
, idcount
);
5443 CanalMapSpriteGroup(buf
, idcount
);
5447 StationMapSpriteGroup(buf
, idcount
);
5451 TownHouseMapSpriteGroup(buf
, idcount
);
5454 case GSF_INDUSTRIES
:
5455 IndustryMapSpriteGroup(buf
, idcount
);
5458 case GSF_INDUSTRYTILES
:
5459 IndustrytileMapSpriteGroup(buf
, idcount
);
5463 CargoMapSpriteGroup(buf
, idcount
);
5467 AirportMapSpriteGroup(buf
, idcount
);
5471 ObjectMapSpriteGroup(buf
, idcount
);
5475 RailTypeMapSpriteGroup(buf
, idcount
);
5478 case GSF_AIRPORTTILES
:
5479 AirportTileMapSpriteGroup(buf
, idcount
);
5483 grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature
);
5489 static void FeatureNewName(ByteReader
*buf
)
5491 /* <04> <veh-type> <language-id> <num-veh> <offset> <data...>
5493 * B veh-type see action 0 (as 00..07, + 0A
5494 * But IF veh-type = 48, then generic text
5495 * B language-id If bit 6 is set, This is the extended language scheme,
5496 * with up to 64 language.
5497 * Otherwise, it is a mapping where set bits have meaning
5498 * 0 = american, 1 = english, 2 = german, 3 = french, 4 = spanish
5499 * Bit 7 set means this is a generic text, not a vehicle one (or else)
5500 * B num-veh number of vehicles which are getting a new name
5501 * B/W offset number of the first vehicle that gets a new name
5502 * Byte : ID of vehicle to change
5503 * Word : ID of string to change/add
5504 * S data new texts, each of them zero-terminated, after
5505 * which the next name begins. */
5507 bool new_scheme
= _cur
.grffile
->grf_version
>= 7;
5509 uint8 feature
= buf
->ReadByte();
5510 uint8 lang
= buf
->ReadByte();
5511 uint8 num
= buf
->ReadByte();
5512 bool generic
= HasBit(lang
, 7);
5515 id
= buf
->ReadWord();
5516 } else if (feature
<= GSF_AIRCRAFT
) {
5517 id
= buf
->ReadExtendedByte();
5519 id
= buf
->ReadByte();
5524 uint16 endid
= id
+ num
;
5526 grfmsg(6, "FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5527 id
, endid
, feature
, lang
);
5529 for (; id
< endid
&& buf
->HasData(); id
++) {
5530 const char *name
= buf
->ReadString();
5531 grfmsg(8, "FeatureNewName: 0x%04X <- %s", id
, name
);
5535 case GSF_ROADVEHICLES
:
5539 Engine
*e
= GetNewEngine(_cur
.grffile
, (VehicleType
)feature
, id
, HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
));
5540 if (e
== NULL
) break;
5541 StringID string
= AddGRFString(_cur
.grffile
->grfid
, e
->index
, lang
, new_scheme
, false, name
, e
->info
.string_id
);
5542 e
->info
.string_id
= string
;
5544 AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, true, name
, STR_UNDEFINED
);
5549 if (IsInsideMM(id
, 0xD000, 0xD400) || IsInsideMM(id
, 0xD800, 0xE000)) {
5550 AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, true, name
, STR_UNDEFINED
);
5554 switch (GB(id
, 8, 8)) {
5555 case 0xC4: // Station class name
5556 if (_cur
.grffile
->stations
== NULL
|| _cur
.grffile
->stations
[GB(id
, 0, 8)] == NULL
) {
5557 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id
, 0, 8));
5559 StationClassID cls_id
= _cur
.grffile
->stations
[GB(id
, 0, 8)]->cls_id
;
5560 StationClass::Get(cls_id
)->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5564 case 0xC5: // Station name
5565 if (_cur
.grffile
->stations
== NULL
|| _cur
.grffile
->stations
[GB(id
, 0, 8)] == NULL
) {
5566 grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id
, 0, 8));
5568 _cur
.grffile
->stations
[GB(id
, 0, 8)]->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5572 case 0xC7: // Airporttile name
5573 if (_cur
.grffile
->airtspec
== NULL
|| _cur
.grffile
->airtspec
[GB(id
, 0, 8)] == NULL
) {
5574 grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id
, 0, 8));
5576 _cur
.grffile
->airtspec
[GB(id
, 0, 8)]->name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5580 case 0xC9: // House name
5581 if (_cur
.grffile
->housespec
== NULL
|| _cur
.grffile
->housespec
[GB(id
, 0, 8)] == NULL
) {
5582 grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id
, 0, 8));
5584 _cur
.grffile
->housespec
[GB(id
, 0, 8)]->building_name
= AddGRFString(_cur
.grffile
->grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
5589 grfmsg(7, "FeatureNewName: Unsupported ID (0x%04X)", id
);
5598 * Sanitize incoming sprite offsets for Action 5 graphics replacements.
5599 * @param num The number of sprites to load.
5600 * @param offset Offset from the base.
5601 * @param max_sprites The maximum number of sprites that can be loaded in this action 5.
5602 * @param name Used for error warnings.
5603 * @return The number of sprites that is going to be skipped.
5605 static uint16
SanitizeSpriteOffset(uint16
& num
, uint16 offset
, int max_sprites
, const char *name
)
5608 if (offset
>= max_sprites
) {
5609 grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name
, max_sprites
);
5610 uint orig_num
= num
;
5615 if (offset
+ num
> max_sprites
) {
5616 grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name
);
5617 uint orig_num
= num
;
5618 num
= max(max_sprites
- offset
, 0);
5619 return orig_num
- num
;
5626 /** The type of action 5 type. */
5627 enum Action5BlockType
{
5628 A5BLOCK_FIXED
, ///< Only allow replacing a whole block of sprites. (TTDP compatible)
5629 A5BLOCK_ALLOW_OFFSET
, ///< Allow replacing any subset by specifiing an offset.
5630 A5BLOCK_INVALID
, ///< unknown/not-implemented type
5632 /** Information about a single action 5 type. */
5633 struct Action5Type
{
5634 Action5BlockType block_type
; ///< How is this Action5 type processed?
5635 SpriteID sprite_base
; ///< Load the sprites starting from this sprite.
5636 uint16 min_sprites
; ///< If the Action5 contains less sprites, the whole block will be ignored.
5637 uint16 max_sprites
; ///< If the Action5 contains more sprites, only the first max_sprites sprites will be used.
5638 const char *name
; ///< Name for error messages.
5641 /** The information about action 5 types. */
5642 static const Action5Type _action5_types
[] = {
5643 /* Note: min_sprites should not be changed. Therefore these constants are directly here and not in sprites.h */
5644 /* 0x00 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x00" },
5645 /* 0x01 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x01" },
5646 /* 0x02 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x02" },
5647 /* 0x03 */ { A5BLOCK_INVALID
, 0, 0, 0, "Type 0x03" },
5648 /* 0x04 */ { A5BLOCK_ALLOW_OFFSET
, SPR_SIGNALS_BASE
, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT
, "Signal graphics" },
5649 /* 0x05 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ELRAIL_BASE
, 1, ELRAIL_SPRITE_COUNT
, "Rail catenary graphics" },
5650 /* 0x06 */ { A5BLOCK_ALLOW_OFFSET
, SPR_SLOPES_BASE
, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT
, "Foundation graphics" },
5651 /* 0x07 */ { A5BLOCK_INVALID
, 0, 75, 0, "TTDP GUI graphics" }, // Not used by OTTD.
5652 /* 0x08 */ { A5BLOCK_ALLOW_OFFSET
, SPR_CANALS_BASE
, 1, CANALS_SPRITE_COUNT
, "Canal graphics" },
5653 /* 0x09 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ONEWAY_BASE
, 1, ONEWAY_SPRITE_COUNT
, "One way road graphics" },
5654 /* 0x0A */ { A5BLOCK_ALLOW_OFFSET
, SPR_2CCMAP_BASE
, 1, TWOCCMAP_SPRITE_COUNT
, "2CC colour maps" },
5655 /* 0x0B */ { A5BLOCK_ALLOW_OFFSET
, SPR_TRAMWAY_BASE
, 1, TRAMWAY_SPRITE_COUNT
, "Tramway graphics" },
5656 /* 0x0C */ { A5BLOCK_INVALID
, 0, 133, 0, "Snowy temperate tree" }, // Not yet used by OTTD.
5657 /* 0x0D */ { A5BLOCK_FIXED
, SPR_SHORE_BASE
, 16, SPR_SHORE_SPRITE_COUNT
, "Shore graphics" },
5658 /* 0x0E */ { A5BLOCK_INVALID
, 0, 0, 0, "New Signals graphics" }, // Not yet used by OTTD.
5659 /* 0x0F */ { A5BLOCK_ALLOW_OFFSET
, SPR_TRACKS_FOR_SLOPES_BASE
, 1, TRACKS_FOR_SLOPES_SPRITE_COUNT
, "Sloped rail track" },
5660 /* 0x10 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AIRPORTX_BASE
, 1, AIRPORTX_SPRITE_COUNT
, "Airport graphics" },
5661 /* 0x11 */ { A5BLOCK_ALLOW_OFFSET
, SPR_ROADSTOP_BASE
, 1, ROADSTOP_SPRITE_COUNT
, "Road stop graphics" },
5662 /* 0x12 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AQUEDUCT_BASE
, 1, AQUEDUCT_SPRITE_COUNT
, "Aqueduct graphics" },
5663 /* 0x13 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AUTORAIL_BASE
, 1, AUTORAIL_SPRITE_COUNT
, "Autorail graphics" },
5664 /* 0x14 */ { A5BLOCK_ALLOW_OFFSET
, SPR_FLAGS_BASE
, 1, FLAGS_SPRITE_COUNT
, "Flag graphics" },
5665 /* 0x15 */ { A5BLOCK_ALLOW_OFFSET
, SPR_OPENTTD_BASE
, 1, OPENTTD_SPRITE_COUNT
, "OpenTTD GUI graphics" },
5666 /* 0x16 */ { A5BLOCK_ALLOW_OFFSET
, SPR_AIRPORT_PREVIEW_BASE
, 1, SPR_AIRPORT_PREVIEW_COUNT
, "Airport preview graphics" },
5667 /* 0x17 */ { A5BLOCK_ALLOW_OFFSET
, SPR_RAILTYPE_TUNNEL_BASE
, 1, RAILTYPE_TUNNEL_BASE_COUNT
, "Railtype tunnel base" },
5668 /* 0x18 */ { A5BLOCK_ALLOW_OFFSET
, SPR_PALETTE_BASE
, 1, PALETTE_SPRITE_COUNT
, "Palette" },
5672 static void GraphicsNew(ByteReader
*buf
)
5674 /* <05> <graphics-type> <num-sprites> <other data...>
5676 * B graphics-type What set of graphics the sprites define.
5677 * E num-sprites How many sprites are in this set?
5678 * V other data Graphics type specific data. Currently unused. */
5681 uint8 type
= buf
->ReadByte();
5682 uint16 num
= buf
->ReadExtendedByte();
5683 uint16 offset
= HasBit(type
, 7) ? buf
->ReadExtendedByte() : 0;
5684 ClrBit(type
, 7); // Clear the high bit as that only indicates whether there is an offset.
5686 if ((type
== 0x0D) && (num
== 10) && HasBit(_cur
.grfconfig
->flags
, GCF_SYSTEM
)) {
5687 /* Special not-TTDP-compatible case used in openttd.grf
5688 * Missing shore sprites and initialisation of SPR_SHORE_BASE */
5689 grfmsg(2, "GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5690 LoadNextSprite(SPR_SHORE_BASE
+ 0, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_S
5691 LoadNextSprite(SPR_SHORE_BASE
+ 5, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_W
5692 LoadNextSprite(SPR_SHORE_BASE
+ 7, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_WSE
5693 LoadNextSprite(SPR_SHORE_BASE
+ 10, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_N
5694 LoadNextSprite(SPR_SHORE_BASE
+ 11, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_NWS
5695 LoadNextSprite(SPR_SHORE_BASE
+ 13, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_ENW
5696 LoadNextSprite(SPR_SHORE_BASE
+ 14, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_SEN
5697 LoadNextSprite(SPR_SHORE_BASE
+ 15, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_STEEP_E
5698 LoadNextSprite(SPR_SHORE_BASE
+ 16, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_EW
5699 LoadNextSprite(SPR_SHORE_BASE
+ 17, _cur
.file_index
, _cur
.nfo_line
++, _cur
.grf_container_ver
); // SLOPE_NS
5700 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_NONE
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ONLY_NEW
;
5704 /* Supported type? */
5705 if ((type
>= lengthof(_action5_types
)) || (_action5_types
[type
].block_type
== A5BLOCK_INVALID
)) {
5706 grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type
, num
);
5707 _cur
.skip_sprites
= num
;
5711 const Action5Type
*action5_type
= &_action5_types
[type
];
5713 /* Contrary to TTDP we allow always to specify too few sprites as we allow always an offset,
5714 * except for the long version of the shore type:
5715 * Ignore offset if not allowed */
5716 if ((action5_type
->block_type
!= A5BLOCK_ALLOW_OFFSET
) && (offset
!= 0)) {
5717 grfmsg(1, "GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type
->name
, type
);
5721 /* Ignore action5 if too few sprites are specified. (for TTDP compatibility)
5722 * This does not make sense, if <offset> is allowed */
5723 if ((action5_type
->block_type
== A5BLOCK_FIXED
) && (num
< action5_type
->min_sprites
)) {
5724 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
);
5725 _cur
.skip_sprites
= num
;
5729 /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */
5730 uint16 skip_num
= SanitizeSpriteOffset(num
, offset
, action5_type
->max_sprites
, action5_type
->name
);
5731 SpriteID replace
= action5_type
->sprite_base
+ offset
;
5733 /* Load <num> sprites starting from <replace>, then skip <skip_num> sprites. */
5734 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
);
5736 for (; num
> 0; num
--) {
5738 LoadNextSprite(replace
== 0 ? _cur
.spriteid
++ : replace
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
5741 if (type
== 0x0D) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_5
;
5743 _cur
.skip_sprites
= skip_num
;
5746 /* Action 0x05 (SKIP) */
5747 static void SkipAct5(ByteReader
*buf
)
5749 /* Ignore type byte */
5752 /* Skip the sprites of this action */
5753 _cur
.skip_sprites
= buf
->ReadExtendedByte();
5755 grfmsg(3, "SkipAct5: Skipping %d sprites", _cur
.skip_sprites
);
5759 * Reads a variable common to VarAction2 and Action7/9/D.
5761 * Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
5762 * If a variable is not accessible from all four actions, it is handled in the action specific functions.
5764 * @param param variable number (as for VarAction2, for Action7/9/D you have to subtract 0x80 first).
5765 * @param value returns the value of the variable.
5766 * @param grffile NewGRF querying the variable
5767 * @return true iff the variable is known and the value is returned in 'value'.
5769 bool GetGlobalVariable(byte param
, uint32
*value
, const GRFFile
*grffile
)
5772 case 0x00: // current date
5773 *value
= max(_date
- DAYS_TILL_ORIGINAL_BASE_YEAR
, 0);
5776 case 0x01: // current year
5777 *value
= Clamp(_cur_year
, ORIGINAL_BASE_YEAR
, ORIGINAL_MAX_YEAR
) - ORIGINAL_BASE_YEAR
;
5780 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)
5781 Date start_of_year
= ConvertYMDToDate(_cur_date_ymd
.year
, 0, 1);
5782 *value
= _cur_date_ymd
.month
| (_cur_date_ymd
.day
- 1) << 8 | (IsLeapYear(_cur_date_ymd
.year
) ? 1 << 15 : 0) | (_date
- start_of_year
) << 16;
5786 case 0x03: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
5787 *value
= _settings_game
.game_creation
.landscape
;
5790 case 0x06: // road traffic side, bit 4 clear=left, set=right
5791 *value
= _settings_game
.vehicle
.road_side
<< 4;
5794 case 0x09: // date fraction
5795 *value
= _date_fract
* 885;
5798 case 0x0A: // animation counter
5799 *value
= _tick_counter
;
5802 case 0x0B: { // TTDPatch version
5805 uint revision
= 1; // special case: 2.0.1 is 2.0.10
5807 *value
= (major
<< 24) | (minor
<< 20) | (revision
<< 16) | build
;
5811 case 0x0D: // TTD Version, 00=DOS, 01=Windows
5812 *value
= _cur
.grfconfig
->palette
& GRFP_USE_MASK
;
5815 case 0x0E: // Y-offset for train sprites
5816 *value
= _cur
.grffile
->traininfo_vehicle_pitch
;
5819 case 0x0F: // Rail track type cost factors
5821 SB(*value
, 0, 8, GetRailTypeInfo(RAILTYPE_RAIL
)->cost_multiplier
); // normal rail
5822 if (_settings_game
.vehicle
.disable_elrails
) {
5823 /* skip elrail multiplier - disabled */
5824 SB(*value
, 8, 8, GetRailTypeInfo(RAILTYPE_MONO
)->cost_multiplier
); // monorail
5826 SB(*value
, 8, 8, GetRailTypeInfo(RAILTYPE_ELECTRIC
)->cost_multiplier
); // electified railway
5827 /* Skip monorail multiplier - no space in result */
5829 SB(*value
, 16, 8, GetRailTypeInfo(RAILTYPE_MAGLEV
)->cost_multiplier
); // maglev
5832 case 0x11: // current rail tool type
5833 *value
= 0; // constant fake value to avoid desync
5836 case 0x12: // Game mode
5837 *value
= _game_mode
;
5840 /* case 0x13: // Tile refresh offset to left not implemented */
5841 /* case 0x14: // Tile refresh offset to right not implemented */
5842 /* case 0x15: // Tile refresh offset upwards not implemented */
5843 /* case 0x16: // Tile refresh offset downwards not implemented */
5844 /* case 0x17: // temperate snow line not implemented */
5846 case 0x1A: // Always -1
5850 case 0x1B: // Display options
5851 *value
= 0x3F; // constant fake value to avoid desync
5854 case 0x1D: // TTD Platform, 00=TTDPatch, 01=OpenTTD
5858 case 0x1E: // Miscellaneous GRF features
5859 *value
= _misc_grf_features
;
5861 /* Add the local flags */
5862 assert(!HasBit(*value
, GMB_TRAIN_WIDTH_32_PIXELS
));
5863 if (_cur
.grffile
->traininfo_vehicle_width
== VEHICLEINFO_FULL_VEHICLE_WIDTH
) SetBit(*value
, GMB_TRAIN_WIDTH_32_PIXELS
);
5866 /* case 0x1F: // locale dependent settings not implemented to avoid desync */
5868 case 0x20: { // snow line height
5869 byte snowline
= GetSnowLine();
5870 if (_settings_game
.game_creation
.landscape
== LT_ARCTIC
&& snowline
<= _settings_game
.construction
.max_heightlevel
) {
5871 *value
= Clamp(snowline
* (grffile
->grf_version
>= 8 ? 1 : TILE_HEIGHT
), 0, 0xFE);
5879 case 0x21: // OpenTTD version
5880 *value
= _openttd_newgrf_version
;
5883 case 0x22: // difficulty level
5887 case 0x23: // long format date
5891 case 0x24: // long format year
5895 default: return false;
5899 static uint32
GetParamVal(byte param
, uint32
*cond_val
)
5901 /* First handle variable common with VarAction2 */
5903 if (GetGlobalVariable(param
- 0x80, &value
, _cur
.grffile
)) return value
;
5905 /* Non-common variable */
5907 case 0x84: { // GRF loading stage
5910 if (_cur
.stage
> GLS_INIT
) SetBit(res
, 0);
5911 if (_cur
.stage
== GLS_RESERVE
) SetBit(res
, 8);
5912 if (_cur
.stage
== GLS_ACTIVATION
) SetBit(res
, 9);
5916 case 0x85: // TTDPatch flags, only for bit tests
5917 if (cond_val
== NULL
) {
5918 /* Supported in Action 0x07 and 0x09, not 0x0D */
5921 uint32 param_val
= _ttdpatch_flags
[*cond_val
/ 0x20];
5926 case 0x88: // GRF ID check
5929 /* case 0x99: Global ID offset not implemented */
5933 if (param
< 0x80) return _cur
.grffile
->GetParam(param
);
5935 /* In-game variable. */
5936 grfmsg(1, "Unsupported in-game variable 0x%02X", param
);
5942 static void CfgApply(ByteReader
*buf
)
5944 /* <06> <param-num> <param-size> <offset> ... <FF>
5946 * B param-num Number of parameter to substitute (First = "zero")
5947 * Ignored if that parameter was not specified in newgrf.cfg
5948 * B param-size How many bytes to replace. If larger than 4, the
5949 * bytes of the following parameter are used. In that
5950 * case, nothing is applied unless *all* parameters
5952 * B offset Offset into data from beginning of next sprite
5953 * to place where parameter is to be stored. */
5955 /* Preload the next sprite */
5956 size_t pos
= FioGetPos();
5957 uint32 num
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
5958 uint8 type
= FioReadByte();
5959 byte
*preload_sprite
= NULL
;
5961 /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */
5963 preload_sprite
= MallocT
<byte
>(num
);
5964 FioReadBlock(preload_sprite
, num
);
5967 /* Reset the file position to the start of the next sprite */
5968 FioSeekTo(pos
, SEEK_SET
);
5971 grfmsg(2, "CfgApply: Ignoring (next sprite is real, unsupported)");
5972 free(preload_sprite
);
5976 GRFLocation
location(_cur
.grfconfig
->ident
.grfid
, _cur
.nfo_line
+ 1);
5977 GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.find(location
);
5978 if (it
!= _grf_line_to_action6_sprite_override
.end()) {
5979 free(preload_sprite
);
5980 preload_sprite
= it
->second
;
5982 _grf_line_to_action6_sprite_override
[location
] = preload_sprite
;
5985 /* Now perform the Action 0x06 on our data. */
5994 /* Read the parameter to apply. 0xFF indicates no more data to change. */
5995 param_num
= buf
->ReadByte();
5996 if (param_num
== 0xFF) break;
5998 /* Get the size of the parameter to use. If the size covers multiple
5999 * double words, sequential parameter values are used. */
6000 param_size
= buf
->ReadByte();
6002 /* Bit 7 of param_size indicates we should add to the original value
6003 * instead of replacing it. */
6004 add_value
= HasBit(param_size
, 7);
6005 param_size
= GB(param_size
, 0, 7);
6007 /* Where to apply the data to within the pseudo sprite data. */
6008 offset
= buf
->ReadExtendedByte();
6010 /* If the parameter is a GRF parameter (not an internal variable) check
6011 * if it (and all further sequential parameters) has been defined. */
6012 if (param_num
< 0x80 && (param_num
+ (param_size
- 1) / 4) >= _cur
.grffile
->param_end
) {
6013 grfmsg(2, "CfgApply: Ignoring (param %d not set)", (param_num
+ (param_size
- 1) / 4));
6017 grfmsg(8, "CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size
, param_num
, offset
);
6020 for (i
= 0; i
< param_size
&& offset
+ i
< num
; i
++) {
6021 uint32 value
= GetParamVal(param_num
+ i
/ 4, NULL
);
6022 /* Reset carry flag for each iteration of the variable (only really
6023 * matters if param_size is greater than 4) */
6024 if (i
% 4 == 0) carry
= false;
6027 uint new_value
= preload_sprite
[offset
+ i
] + GB(value
, (i
% 4) * 8, 8) + (carry
? 1 : 0);
6028 preload_sprite
[offset
+ i
] = GB(new_value
, 0, 8);
6029 /* Check if the addition overflowed */
6030 carry
= new_value
>= 256;
6032 preload_sprite
[offset
+ i
] = GB(value
, (i
% 4) * 8, 8);
6039 * Disable a static NewGRF when it is influencing another (non-static)
6040 * NewGRF as this could cause desyncs.
6042 * We could just tell the NewGRF querying that the file doesn't exist,
6043 * but that might give unwanted results. Disabling the NewGRF gives the
6044 * best result as no NewGRF author can complain about that.
6045 * @param c The NewGRF to disable.
6047 static void DisableStaticNewGRFInfluencingNonStaticNewGRFs(GRFConfig
*c
)
6049 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC
, c
);
6050 error
->data
= stredup(_cur
.grfconfig
->GetName());
6055 static void SkipIf(ByteReader
*buf
)
6057 /* <07/09> <param-num> <param-size> <condition-type> <value> <num-sprites>
6064 /* TODO: More params. More condition types. */
6065 uint32 cond_val
= 0;
6069 uint8 param
= buf
->ReadByte();
6070 uint8 paramsize
= buf
->ReadByte();
6071 uint8 condtype
= buf
->ReadByte();
6074 /* Always 1 for bit tests, the given value should be ignored. */
6078 switch (paramsize
) {
6079 case 8: cond_val
= buf
->ReadDWord(); mask
= buf
->ReadDWord(); break;
6080 case 4: cond_val
= buf
->ReadDWord(); mask
= 0xFFFFFFFF; break;
6081 case 2: cond_val
= buf
->ReadWord(); mask
= 0x0000FFFF; break;
6082 case 1: cond_val
= buf
->ReadByte(); mask
= 0x000000FF; break;
6086 if (param
< 0x80 && _cur
.grffile
->param_end
<= param
) {
6087 grfmsg(7, "SkipIf: Param %d undefined, skipping test", param
);
6091 uint32 param_val
= GetParamVal(param
, &cond_val
);
6093 grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype
, param_val
, cond_val
);
6096 * Parameter (variable in specs) 0x88 can only have GRF ID checking
6097 * conditions, except conditions 0x0B, 0x0C (cargo availability) and
6098 * 0x0D, 0x0E (Rail type availability) as those ignore the parameter.
6099 * So, when the condition type is one of those, the specific variable
6100 * 0x88 code is skipped, so the "general" code for the cargo
6101 * availability conditions kicks in.
6103 if (param
== 0x88 && (condtype
< 0x0B || condtype
> 0x0E)) {
6106 GRFConfig
*c
= GetGRFConfig(cond_val
, mask
);
6108 if (c
!= NULL
&& HasBit(c
->flags
, GCF_STATIC
) && !HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
) && _networking
) {
6109 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c
);
6113 if (condtype
!= 10 && c
== NULL
) {
6114 grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val
));
6119 /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
6120 case 0x06: // Is GRFID active?
6121 result
= c
->status
== GCS_ACTIVATED
;
6124 case 0x07: // Is GRFID non-active?
6125 result
= c
->status
!= GCS_ACTIVATED
;
6128 case 0x08: // GRFID is not but will be active?
6129 result
= c
->status
== GCS_INITIALISED
;
6132 case 0x09: // GRFID is or will be active?
6133 result
= c
->status
== GCS_ACTIVATED
|| c
->status
== GCS_INITIALISED
;
6136 case 0x0A: // GRFID is not nor will be active
6137 /* This is the only condtype that doesn't get ignored if the GRFID is not found */
6138 result
= c
== NULL
|| c
->status
== GCS_DISABLED
|| c
->status
== GCS_NOT_FOUND
;
6141 default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype
); return;
6144 /* Parameter or variable tests */
6146 case 0x00: result
= !!(param_val
& (1 << cond_val
));
6148 case 0x01: result
= !(param_val
& (1 << cond_val
));
6150 case 0x02: result
= (param_val
& mask
) == cond_val
;
6152 case 0x03: result
= (param_val
& mask
) != cond_val
;
6154 case 0x04: result
= (param_val
& mask
) < cond_val
;
6156 case 0x05: result
= (param_val
& mask
) > cond_val
;
6158 case 0x0B: result
= GetCargoIDByLabel(BSWAP32(cond_val
)) == CT_INVALID
;
6160 case 0x0C: result
= GetCargoIDByLabel(BSWAP32(cond_val
)) != CT_INVALID
;
6162 case 0x0D: result
= GetRailTypeByLabel(BSWAP32(cond_val
)) == INVALID_RAILTYPE
;
6164 case 0x0E: result
= GetRailTypeByLabel(BSWAP32(cond_val
)) != INVALID_RAILTYPE
;
6167 default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype
); return;
6172 grfmsg(2, "SkipIf: Not skipping sprites, test was false");
6176 uint8 numsprites
= buf
->ReadByte();
6178 /* numsprites can be a GOTO label if it has been defined in the GRF
6179 * file. The jump will always be the first matching label that follows
6180 * the current nfo_line. If no matching label is found, the first matching
6181 * label in the file is used. */
6182 GRFLabel
*choice
= NULL
;
6183 for (GRFLabel
*label
= _cur
.grffile
->label
; label
!= NULL
; label
= label
->next
) {
6184 if (label
->label
!= numsprites
) continue;
6186 /* Remember a goto before the current line */
6187 if (choice
== NULL
) choice
= label
;
6188 /* If we find a label here, this is definitely good */
6189 if (label
->nfo_line
> _cur
.nfo_line
) {
6195 if (choice
!= NULL
) {
6196 grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice
->label
, choice
->nfo_line
);
6197 FioSeekTo(choice
->pos
, SEEK_SET
);
6198 _cur
.nfo_line
= choice
->nfo_line
;
6202 grfmsg(2, "SkipIf: Skipping %d sprites, test was true", numsprites
);
6203 _cur
.skip_sprites
= numsprites
;
6204 if (_cur
.skip_sprites
== 0) {
6205 /* Zero means there are no sprites to skip, so
6206 * we use -1 to indicate that all further
6207 * sprites should be skipped. */
6208 _cur
.skip_sprites
= -1;
6210 /* If an action 8 hasn't been encountered yet, disable the grf. */
6211 if (_cur
.grfconfig
->status
!= (_cur
.stage
< GLS_RESERVE
? GCS_INITIALISED
: GCS_ACTIVATED
)) {
6218 /* Action 0x08 (GLS_FILESCAN) */
6219 static void ScanInfo(ByteReader
*buf
)
6221 uint8 grf_version
= buf
->ReadByte();
6222 uint32 grfid
= buf
->ReadDWord();
6223 const char *name
= buf
->ReadString();
6225 _cur
.grfconfig
->ident
.grfid
= grfid
;
6227 if (grf_version
< 2 || grf_version
> 8) {
6228 SetBit(_cur
.grfconfig
->flags
, GCF_INVALID
);
6229 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
);
6232 /* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
6233 if (GB(grfid
, 0, 8) == 0xFF) SetBit(_cur
.grfconfig
->flags
, GCF_SYSTEM
);
6235 AddGRFTextToList(&_cur
.grfconfig
->name
->text
, 0x7F, grfid
, false, name
);
6237 if (buf
->HasData()) {
6238 const char *info
= buf
->ReadString();
6239 AddGRFTextToList(&_cur
.grfconfig
->info
->text
, 0x7F, grfid
, true, info
);
6242 /* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
6243 _cur
.skip_sprites
= -1;
6247 static void GRFInfo(ByteReader
*buf
)
6249 /* <08> <version> <grf-id> <name> <info>
6251 * B version newgrf version, currently 06
6252 * 4*B grf-id globally unique ID of this .grf file
6253 * S name name of this .grf set
6254 * S info string describing the set, and e.g. author and copyright */
6256 uint8 version
= buf
->ReadByte();
6257 uint32 grfid
= buf
->ReadDWord();
6258 const char *name
= buf
->ReadString();
6260 if (_cur
.stage
< GLS_RESERVE
&& _cur
.grfconfig
->status
!= GCS_UNKNOWN
) {
6261 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8
);
6265 if (_cur
.grffile
->grfid
!= grfid
) {
6266 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
));
6267 _cur
.grffile
->grfid
= grfid
;
6270 _cur
.grffile
->grf_version
= version
;
6271 _cur
.grfconfig
->status
= _cur
.stage
< GLS_RESERVE
? GCS_INITIALISED
: GCS_ACTIVATED
;
6273 /* Do swap the GRFID for displaying purposes since people expect that */
6274 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
);
6278 static void SpriteReplace(ByteReader
*buf
)
6280 /* <0A> <num-sets> <set1> [<set2> ...]
6281 * <set>: <num-sprites> <first-sprite>
6283 * B num-sets How many sets of sprites to replace.
6285 * B num-sprites How many sprites are in this set
6286 * W first-sprite First sprite number to replace */
6288 uint8 num_sets
= buf
->ReadByte();
6290 for (uint i
= 0; i
< num_sets
; i
++) {
6291 uint8 num_sprites
= buf
->ReadByte();
6292 uint16 first_sprite
= buf
->ReadWord();
6294 grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6295 i
, num_sprites
, first_sprite
6298 for (uint j
= 0; j
< num_sprites
; j
++) {
6299 int load_index
= first_sprite
+ j
;
6301 LoadNextSprite(load_index
, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
); // XXX
6303 /* Shore sprites now located at different addresses.
6304 * So detect when the old ones get replaced. */
6305 if (IsInsideMM(load_index
, SPR_ORIGINALSHORE_START
, SPR_ORIGINALSHORE_END
+ 1)) {
6306 if (_loaded_newgrf_features
.shore
!= SHORE_REPLACE_ACTION_5
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_A
;
6312 /* Action 0x0A (SKIP) */
6313 static void SkipActA(ByteReader
*buf
)
6315 uint8 num_sets
= buf
->ReadByte();
6317 for (uint i
= 0; i
< num_sets
; i
++) {
6318 /* Skip the sprites this replaces */
6319 _cur
.skip_sprites
+= buf
->ReadByte();
6320 /* But ignore where they go */
6324 grfmsg(3, "SkipActA: Skipping %d sprites", _cur
.skip_sprites
);
6328 static void GRFLoadError(ByteReader
*buf
)
6330 /* <0B> <severity> <language-id> <message-id> [<message...> 00] [<data...>] 00 [<parnum>]
6332 * B severity 00: notice, contine loading grf file
6333 * 01: warning, continue loading grf file
6334 * 02: error, but continue loading grf file, and attempt
6335 * loading grf again when loading or starting next game
6336 * 03: error, abort loading and prevent loading again in
6337 * the future (only when restarting the patch)
6338 * B language-id see action 4, use 1F for built-in error messages
6339 * B message-id message to show, see below
6340 * S message for custom messages (message-id FF), text of the message
6341 * not present for built-in messages.
6342 * V data additional data for built-in (or custom) messages
6343 * B parnum parameter numbers to be shown in the message (maximum of 2) */
6345 static const StringID msgstr
[] = {
6346 STR_NEWGRF_ERROR_VERSION_NUMBER
,
6347 STR_NEWGRF_ERROR_DOS_OR_WINDOWS
,
6348 STR_NEWGRF_ERROR_UNSET_SWITCH
,
6349 STR_NEWGRF_ERROR_INVALID_PARAMETER
,
6350 STR_NEWGRF_ERROR_LOAD_BEFORE
,
6351 STR_NEWGRF_ERROR_LOAD_AFTER
,
6352 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER
,
6355 static const StringID sevstr
[] = {
6356 STR_NEWGRF_ERROR_MSG_INFO
,
6357 STR_NEWGRF_ERROR_MSG_WARNING
,
6358 STR_NEWGRF_ERROR_MSG_ERROR
,
6359 STR_NEWGRF_ERROR_MSG_FATAL
6362 byte severity
= buf
->ReadByte();
6363 byte lang
= buf
->ReadByte();
6364 byte message_id
= buf
->ReadByte();
6366 /* Skip the error if it isn't valid for the current language. */
6367 if (!CheckGrfLangID(lang
, _cur
.grffile
->grf_version
)) return;
6369 /* Skip the error until the activation stage unless bit 7 of the severity
6371 if (!HasBit(severity
, 7) && _cur
.stage
== GLS_INIT
) {
6372 grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur
.stage
);
6375 ClrBit(severity
, 7);
6377 if (severity
>= lengthof(sevstr
)) {
6378 grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity
);
6380 } else if (severity
== 3) {
6381 /* This is a fatal error, so make sure the GRF is deactivated and no
6382 * more of it gets loaded. */
6385 /* Make sure we show fatal errors, instead of silly infos from before */
6386 delete _cur
.grfconfig
->error
;
6387 _cur
.grfconfig
->error
= NULL
;
6390 if (message_id
>= lengthof(msgstr
) && message_id
!= 0xFF) {
6391 grfmsg(7, "GRFLoadError: Invalid message id.");
6395 if (buf
->Remaining() <= 1) {
6396 grfmsg(7, "GRFLoadError: No message data supplied.");
6400 /* For now we can only show one message per newgrf file. */
6401 if (_cur
.grfconfig
->error
!= NULL
) return;
6403 GRFError
*error
= new GRFError(sevstr
[severity
]);
6405 if (message_id
== 0xFF) {
6406 /* This is a custom error message. */
6407 if (buf
->HasData()) {
6408 const char *message
= buf
->ReadString();
6410 error
->custom_message
= TranslateTTDPatchCodes(_cur
.grffile
->grfid
, lang
, true, message
, NULL
, SCC_RAW_STRING_POINTER
);
6412 grfmsg(7, "GRFLoadError: No custom message supplied.");
6413 error
->custom_message
= stredup("");
6416 error
->message
= msgstr
[message_id
];
6419 if (buf
->HasData()) {
6420 const char *data
= buf
->ReadString();
6422 error
->data
= TranslateTTDPatchCodes(_cur
.grffile
->grfid
, lang
, true, data
);
6424 grfmsg(7, "GRFLoadError: No message data supplied.");
6425 error
->data
= stredup("");
6428 /* Only two parameter numbers can be used in the string. */
6429 for (uint i
= 0; i
< lengthof(error
->param_value
) && buf
->HasData(); i
++) {
6430 uint param_number
= buf
->ReadByte();
6431 error
->param_value
[i
] = _cur
.grffile
->GetParam(param_number
);
6434 _cur
.grfconfig
->error
= error
;
6438 static void GRFComment(ByteReader
*buf
)
6440 /* <0C> [<ignored...>]
6442 * V ignored Anything following the 0C is ignored */
6444 if (!buf
->HasData()) return;
6446 const char *text
= buf
->ReadString();
6447 grfmsg(2, "GRFComment: %s", text
);
6450 /* Action 0x0D (GLS_SAFETYSCAN) */
6451 static void SafeParamSet(ByteReader
*buf
)
6453 uint8 target
= buf
->ReadByte();
6455 /* Writing GRF parameters and some bits of 'misc GRF features' are safe. */
6456 if (target
< 0x80 || target
== 0x9E) return;
6458 /* GRM could be unsafe, but as here it can only happen after other GRFs
6459 * are loaded, it should be okay. If the GRF tried to use the slots it
6460 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
6461 * sprites is considered safe. */
6463 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
6465 /* Skip remainder of GRF */
6466 _cur
.skip_sprites
= -1;
6470 static uint32
GetPatchVariable(uint8 param
)
6473 /* start year - 1920 */
6474 case 0x0B: return max(_settings_game
.game_creation
.starting_year
, ORIGINAL_BASE_YEAR
) - ORIGINAL_BASE_YEAR
;
6476 /* freight trains weight factor */
6477 case 0x0E: return _settings_game
.vehicle
.freight_trains
;
6479 /* empty wagon speed increase */
6480 case 0x0F: return 0;
6482 /* plane speed factor; our patch option is reversed from TTDPatch's,
6483 * the following is good for 1x, 2x and 4x (most common?) and...
6484 * well not really for 3x. */
6486 switch (_settings_game
.vehicle
.plane_speed
) {
6495 /* 2CC colourmap base sprite */
6496 case 0x11: return SPR_2CCMAP_BASE
;
6498 /* map size: format = -MABXYSS
6499 * M : the type of map
6500 * bit 0 : set : squared map. Bit 1 is now not relevant
6501 * clear : rectangle map. Bit 1 will indicate the bigger edge of the map
6502 * bit 1 : set : Y is the bigger edge. Bit 0 is clear
6503 * clear : X is the bigger edge.
6504 * A : minimum edge(log2) of the map
6505 * B : maximum edge(log2) of the map
6506 * XY : edges(log2) of each side of the map.
6507 * SS : combination of both X and Y, thus giving the size(log2) of the map
6511 byte log_X
= MapLogX() - 6; // substraction is required to make the minimal size (64) zero based
6512 byte log_Y
= MapLogY() - 6;
6513 byte max_edge
= max(log_X
, log_Y
);
6515 if (log_X
== log_Y
) { // we have a squared map, since both edges are identical
6516 SetBit(map_bits
, 0);
6518 if (max_edge
== log_Y
) SetBit(map_bits
, 1); // edge Y been the biggest, mark it
6521 return (map_bits
<< 24) | (min(log_X
, log_Y
) << 20) | (max_edge
<< 16) |
6522 (log_X
<< 12) | (log_Y
<< 8) | (log_X
+ log_Y
);
6525 /* The maximum height of the map. */
6527 return _settings_game
.construction
.max_heightlevel
;
6529 /* Extra foundations base sprite */
6531 return SPR_SLOPES_BASE
;
6533 /* Shore base sprite */
6535 return SPR_SHORE_BASE
;
6538 grfmsg(2, "ParamSet: Unknown Patch variable 0x%02X.", param
);
6544 static uint32
PerformGRM(uint32
*grm
, uint16 num_ids
, uint16 count
, uint8 op
, uint8 target
, const char *type
)
6550 /* Return GRFID of set that reserved ID */
6551 return grm
[_cur
.grffile
->GetParam(target
)];
6554 /* With an operation of 2 or 3, we want to reserve a specific block of IDs */
6555 if (op
== 2 || op
== 3) start
= _cur
.grffile
->GetParam(target
);
6557 for (uint i
= start
; i
< num_ids
; i
++) {
6561 if (op
== 2 || op
== 3) break;
6566 if (size
== count
) break;
6569 if (size
== count
) {
6570 /* Got the slot... */
6571 if (op
== 0 || op
== 3) {
6572 grfmsg(2, "ParamSet: GRM: Reserving %d %s at %d", count
, type
, start
);
6573 for (uint i
= 0; i
< count
; i
++) grm
[start
+ i
] = _cur
.grffile
->grfid
;
6578 /* Unable to allocate */
6579 if (op
!= 4 && op
!= 5) {
6580 /* Deactivate GRF */
6581 grfmsg(0, "ParamSet: GRM: Unable to allocate %d %s, deactivating", count
, type
);
6582 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED
);
6586 grfmsg(1, "ParamSet: GRM: Unable to allocate %d %s", count
, type
);
6591 /** Action 0x0D: Set parameter */
6592 static void ParamSet(ByteReader
*buf
)
6594 /* <0D> <target> <operation> <source1> <source2> [<data>]
6596 * B target parameter number where result is stored
6597 * B operation operation to perform, see below
6598 * B source1 first source operand
6599 * B source2 second source operand
6600 * D data data to use in the calculation, not necessary
6601 * if both source1 and source2 refer to actual parameters
6604 * 00 Set parameter equal to source1
6605 * 01 Addition, source1 + source2
6606 * 02 Subtraction, source1 - source2
6607 * 03 Unsigned multiplication, source1 * source2 (both unsigned)
6608 * 04 Signed multiplication, source1 * source2 (both signed)
6609 * 05 Unsigned bit shift, source1 by source2 (source2 taken to be a
6610 * signed quantity; left shift if positive and right shift if
6611 * negative, source1 is unsigned)
6612 * 06 Signed bit shift, source1 by source2
6613 * (source2 like in 05, and source1 as well)
6616 uint8 target
= buf
->ReadByte();
6617 uint8 oper
= buf
->ReadByte();
6618 uint32 src1
= buf
->ReadByte();
6619 uint32 src2
= buf
->ReadByte();
6622 if (buf
->Remaining() >= 4) data
= buf
->ReadDWord();
6624 /* You can add 80 to the operation to make it apply only if the target
6625 * is not defined yet. In this respect, a parameter is taken to be
6626 * defined if any of the following applies:
6627 * - it has been set to any value in the newgrf(w).cfg parameter list
6628 * - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
6629 * an earlier action D */
6630 if (HasBit(oper
, 7)) {
6631 if (target
< 0x80 && target
< _cur
.grffile
->param_end
) {
6632 grfmsg(7, "ParamSet: Param %u already defined, skipping", target
);
6636 oper
= GB(oper
, 0, 7);
6640 if (GB(data
, 0, 8) == 0xFF) {
6641 if (data
== 0x0000FFFF) {
6642 /* Patch variables */
6643 src1
= GetPatchVariable(src1
);
6645 /* GRF Resource Management */
6647 uint8 feature
= GB(data
, 8, 8);
6648 uint16 count
= GB(data
, 16, 16);
6650 if (_cur
.stage
== GLS_RESERVE
) {
6651 if (feature
== 0x08) {
6652 /* General sprites */
6654 /* Check if the allocated sprites will fit below the original sprite limit */
6655 if (_cur
.spriteid
+ count
>= 16384) {
6656 grfmsg(0, "ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count
);
6657 DisableGrf(STR_NEWGRF_ERROR_GRM_FAILED
);
6661 /* Reserve space at the current sprite ID */
6662 grfmsg(4, "ParamSet: GRM: Allocated %d sprites at %d", count
, _cur
.spriteid
);
6663 _grm_sprites
[GRFLocation(_cur
.grffile
->grfid
, _cur
.nfo_line
)] = _cur
.spriteid
;
6664 _cur
.spriteid
+= count
;
6667 /* Ignore GRM result during reservation */
6669 } else if (_cur
.stage
== GLS_ACTIVATION
) {
6671 case 0x00: // Trains
6672 case 0x01: // Road Vehicles
6674 case 0x03: // Aircraft
6675 if (!_settings_game
.vehicle
.dynamic_engines
) {
6676 src1
= PerformGRM(&_grm_engines
[_engine_offsets
[feature
]], _engine_counts
[feature
], count
, op
, target
, "vehicles");
6677 if (_cur
.skip_sprites
== -1) return;
6679 /* GRM does not apply for dynamic engine allocation. */
6683 src1
= _cur
.grffile
->GetParam(target
);
6693 case 0x08: // General sprites
6696 /* Return space reserved during reservation stage */
6697 src1
= _grm_sprites
[GRFLocation(_cur
.grffile
->grfid
, _cur
.nfo_line
)];
6698 grfmsg(4, "ParamSet: GRM: Using pre-allocated sprites at %d", src1
);
6702 src1
= _cur
.spriteid
;
6706 grfmsg(1, "ParamSet: GRM: Unsupported operation %d for general sprites", op
);
6712 /* There are two ranges: one for cargo IDs and one for cargo bitmasks */
6713 src1
= PerformGRM(_grm_cargoes
, NUM_CARGO
* 2, count
, op
, target
, "cargoes");
6714 if (_cur
.skip_sprites
== -1) return;
6717 default: grfmsg(1, "ParamSet: GRM: Unsupported feature 0x%X", feature
); return;
6720 /* Ignore GRM during initialization */
6725 /* Read another GRF File's parameter */
6726 const GRFFile
*file
= GetFileByGRFID(data
);
6727 GRFConfig
*c
= GetGRFConfig(data
);
6728 if (c
!= NULL
&& HasBit(c
->flags
, GCF_STATIC
) && !HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
) && _networking
) {
6729 /* Disable the read GRF if it is a static NewGRF. */
6730 DisableStaticNewGRFInfluencingNonStaticNewGRFs(c
);
6732 } else if (file
== NULL
|| c
== NULL
|| c
->status
== GCS_DISABLED
) {
6734 } else if (src1
== 0xFE) {
6737 src1
= file
->GetParam(src1
);
6741 /* The source1 and source2 operands refer to the grf parameter number
6742 * like in action 6 and 7. In addition, they can refer to the special
6743 * variables available in action 7, or they can be FF to use the value
6744 * of <data>. If referring to parameters that are undefined, a value
6745 * of 0 is used instead. */
6746 src1
= (src1
== 0xFF) ? data
: GetParamVal(src1
, NULL
);
6747 src2
= (src2
== 0xFF) ? data
: GetParamVal(src2
, NULL
);
6750 /* TODO: You can access the parameters of another GRF file by using
6751 * source2=FE, source1=the other GRF's parameter number and data=GRF
6752 * ID. This is only valid with operation 00 (set). If the GRF ID
6753 * cannot be found, a value of 0 is used for the parameter value
6775 res
= (int32
)src1
* (int32
)src2
;
6779 if ((int32
)src2
< 0) {
6780 res
= src1
>> -(int32
)src2
;
6782 res
= src1
<< (src2
& 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6787 if ((int32
)src2
< 0) {
6788 res
= (int32
)src1
>> -(int32
)src2
;
6790 res
= (int32
)src1
<< (src2
& 0x1F); // Same behaviour as in EvalAdjustT, mask 'value' to 5 bits, which should behave the same on all architectures.
6794 case 0x07: // Bitwise AND
6798 case 0x08: // Bitwise OR
6802 case 0x09: // Unsigned division
6810 case 0x0A: // Signed divison
6814 res
= (int32
)src1
/ (int32
)src2
;
6818 case 0x0B: // Unsigned modulo
6826 case 0x0C: // Signed modulo
6830 res
= (int32
)src1
% (int32
)src2
;
6834 default: grfmsg(0, "ParamSet: Unknown operation %d, skipping", oper
); return;
6838 case 0x8E: // Y-Offset for train sprites
6839 _cur
.grffile
->traininfo_vehicle_pitch
= res
;
6842 case 0x8F: { // Rail track type cost factors
6843 extern RailtypeInfo _railtypes
[RAILTYPE_END
];
6844 _railtypes
[RAILTYPE_RAIL
].cost_multiplier
= GB(res
, 0, 8);
6845 if (_settings_game
.vehicle
.disable_elrails
) {
6846 _railtypes
[RAILTYPE_ELECTRIC
].cost_multiplier
= GB(res
, 0, 8);
6847 _railtypes
[RAILTYPE_MONO
].cost_multiplier
= GB(res
, 8, 8);
6849 _railtypes
[RAILTYPE_ELECTRIC
].cost_multiplier
= GB(res
, 8, 8);
6850 _railtypes
[RAILTYPE_MONO
].cost_multiplier
= GB(res
, 16, 8);
6852 _railtypes
[RAILTYPE_MAGLEV
].cost_multiplier
= GB(res
, 16, 8);
6856 /* @todo implement */
6857 case 0x93: // Tile refresh offset to left
6858 case 0x94: // Tile refresh offset to right
6859 case 0x95: // Tile refresh offset upwards
6860 case 0x96: // Tile refresh offset downwards
6861 case 0x97: // Snow line height
6862 case 0x99: // Global ID offset
6863 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target
);
6866 case 0x9E: // Miscellaneous GRF features
6867 /* Set train list engine width */
6868 _cur
.grffile
->traininfo_vehicle_width
= HasBit(res
, GMB_TRAIN_WIDTH_32_PIXELS
) ? VEHICLEINFO_FULL_VEHICLE_WIDTH
: TRAININFO_DEFAULT_VEHICLE_WIDTH
;
6869 /* Remove the local flags from the global flags */
6870 ClrBit(res
, GMB_TRAIN_WIDTH_32_PIXELS
);
6872 /* Only copy safe bits for static grfs */
6873 if (HasBit(_cur
.grfconfig
->flags
, GCF_STATIC
)) {
6874 uint32 safe_bits
= 0;
6875 SetBit(safe_bits
, GMB_SECOND_ROCKY_TILE_SET
);
6877 _misc_grf_features
= (_misc_grf_features
& ~safe_bits
) | (res
& safe_bits
);
6879 _misc_grf_features
= res
;
6883 case 0x9F: // locale-dependent settings
6884 grfmsg(7, "ParamSet: Skipping unimplemented target 0x%02X", target
);
6888 if (target
< 0x80) {
6889 _cur
.grffile
->param
[target
] = res
;
6890 /* param is zeroed by default */
6891 if (target
+ 1U > _cur
.grffile
->param_end
) _cur
.grffile
->param_end
= target
+ 1;
6893 grfmsg(7, "ParamSet: Skipping unknown target 0x%02X", target
);
6899 /* Action 0x0E (GLS_SAFETYSCAN) */
6900 static void SafeGRFInhibit(ByteReader
*buf
)
6902 /* <0E> <num> <grfids...>
6904 * B num Number of GRFIDs that follow
6905 * D grfids GRFIDs of the files to deactivate */
6907 uint8 num
= buf
->ReadByte();
6909 for (uint i
= 0; i
< num
; i
++) {
6910 uint32 grfid
= buf
->ReadDWord();
6912 /* GRF is unsafe it if tries to deactivate other GRFs */
6913 if (grfid
!= _cur
.grfconfig
->ident
.grfid
) {
6914 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
6916 /* Skip remainder of GRF */
6917 _cur
.skip_sprites
= -1;
6925 static void GRFInhibit(ByteReader
*buf
)
6927 /* <0E> <num> <grfids...>
6929 * B num Number of GRFIDs that follow
6930 * D grfids GRFIDs of the files to deactivate */
6932 uint8 num
= buf
->ReadByte();
6934 for (uint i
= 0; i
< num
; i
++) {
6935 uint32 grfid
= buf
->ReadDWord();
6936 GRFConfig
*file
= GetGRFConfig(grfid
);
6938 /* Unset activation flag */
6939 if (file
!= NULL
&& file
!= _cur
.grfconfig
) {
6940 grfmsg(2, "GRFInhibit: Deactivating file '%s'", file
->filename
);
6941 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED
, file
);
6942 error
->data
= stredup(_cur
.grfconfig
->GetName());
6947 /** Action 0x0F - Define Town names */
6948 static void FeatureTownName(ByteReader
*buf
)
6950 /* <0F> <id> <style-name> <num-parts> <parts>
6952 * B id ID of this definition in bottom 7 bits (final definition if bit 7 set)
6953 * V style-name Name of the style (only for final definition)
6954 * B num-parts Number of parts in this definition
6955 * V parts The parts */
6957 uint32 grfid
= _cur
.grffile
->grfid
;
6959 GRFTownName
*townname
= AddGRFTownName(grfid
);
6961 byte id
= buf
->ReadByte();
6962 grfmsg(6, "FeatureTownName: definition 0x%02X", id
& 0x7F);
6964 if (HasBit(id
, 7)) {
6965 /* Final definition */
6967 bool new_scheme
= _cur
.grffile
->grf_version
>= 7;
6969 byte lang
= buf
->ReadByte();
6971 byte nb_gen
= townname
->nb_gen
;
6975 const char *name
= buf
->ReadString();
6977 char *lang_name
= TranslateTTDPatchCodes(grfid
, lang
, false, name
);
6978 grfmsg(6, "FeatureTownName: lang 0x%X -> '%s'", lang
, lang_name
);
6981 townname
->name
[nb_gen
] = AddGRFString(grfid
, id
, lang
, new_scheme
, false, name
, STR_UNDEFINED
);
6983 lang
= buf
->ReadByte();
6984 } while (lang
!= 0);
6985 townname
->id
[nb_gen
] = id
;
6989 byte nb
= buf
->ReadByte();
6990 grfmsg(6, "FeatureTownName: %u parts", nb
);
6992 townname
->nbparts
[id
] = nb
;
6993 townname
->partlist
[id
] = CallocT
<NamePartList
>(nb
);
6995 for (int i
= 0; i
< nb
; i
++) {
6996 byte nbtext
= buf
->ReadByte();
6997 townname
->partlist
[id
][i
].bitstart
= buf
->ReadByte();
6998 townname
->partlist
[id
][i
].bitcount
= buf
->ReadByte();
6999 townname
->partlist
[id
][i
].maxprob
= 0;
7000 townname
->partlist
[id
][i
].partcount
= nbtext
;
7001 townname
->partlist
[id
][i
].parts
= CallocT
<NamePart
>(nbtext
);
7002 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
);
7004 for (int j
= 0; j
< nbtext
; j
++) {
7005 byte prob
= buf
->ReadByte();
7007 if (HasBit(prob
, 7)) {
7008 byte ref_id
= buf
->ReadByte();
7010 if (townname
->nbparts
[ref_id
] == 0) {
7011 grfmsg(0, "FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id
);
7012 DelGRFTownName(grfid
);
7013 DisableGrf(STR_NEWGRF_ERROR_INVALID_ID
);
7017 grfmsg(6, "FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i
, j
, ref_id
, prob
& 0x7F);
7018 townname
->partlist
[id
][i
].parts
[j
].data
.id
= ref_id
;
7020 const char *text
= buf
->ReadString();
7021 townname
->partlist
[id
][i
].parts
[j
].data
.text
= TranslateTTDPatchCodes(grfid
, 0, false, text
);
7022 grfmsg(6, "FeatureTownName: part %d, text %d, '%s' (with probability %d)", i
, j
, townname
->partlist
[id
][i
].parts
[j
].data
.text
, prob
);
7024 townname
->partlist
[id
][i
].parts
[j
].prob
= prob
;
7025 townname
->partlist
[id
][i
].maxprob
+= GB(prob
, 0, 7);
7027 grfmsg(6, "FeatureTownName: part %d, total probability %d", i
, townname
->partlist
[id
][i
].maxprob
);
7031 /** Action 0x10 - Define goto label */
7032 static void DefineGotoLabel(ByteReader
*buf
)
7034 /* <10> <label> [<comment>]
7036 * B label The label to define
7037 * V comment Optional comment - ignored */
7039 byte nfo_label
= buf
->ReadByte();
7041 GRFLabel
*label
= MallocT
<GRFLabel
>(1);
7042 label
->label
= nfo_label
;
7043 label
->nfo_line
= _cur
.nfo_line
;
7044 label
->pos
= FioGetPos();
7047 /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */
7048 if (_cur
.grffile
->label
== NULL
) {
7049 _cur
.grffile
->label
= label
;
7051 /* Attach the label to the end of the list */
7053 for (l
= _cur
.grffile
->label
; l
->next
!= NULL
; l
= l
->next
) {}
7057 grfmsg(2, "DefineGotoLabel: GOTO target with label 0x%02X", label
->label
);
7061 * Process a sound import from another GRF file.
7062 * @param sound Destination for sound.
7064 static void ImportGRFSound(SoundEntry
*sound
)
7066 const GRFFile
*file
;
7067 uint32 grfid
= FioReadDword();
7068 SoundID sound_id
= FioReadWord();
7070 file
= GetFileByGRFID(grfid
);
7071 if (file
== NULL
|| file
->sound_offset
== 0) {
7072 grfmsg(1, "ImportGRFSound: Source file not available");
7076 if (sound_id
>= file
->num_sounds
) {
7077 grfmsg(1, "ImportGRFSound: Sound effect %d is invalid", sound_id
);
7081 grfmsg(2, "ImportGRFSound: Copying sound %d (%d) from file %X", sound_id
, file
->sound_offset
+ sound_id
, grfid
);
7083 *sound
= *GetSound(file
->sound_offset
+ sound_id
);
7085 /* Reset volume and priority, which TTDPatch doesn't copy */
7086 sound
->volume
= 128;
7087 sound
->priority
= 0;
7091 * Load a sound from a file.
7092 * @param offs File offset to read sound from.
7093 * @param sound Destination for sound.
7095 static void LoadGRFSound(size_t offs
, SoundEntry
*sound
)
7097 /* Set default volume and priority */
7098 sound
->volume
= 0x80;
7099 sound
->priority
= 0;
7101 if (offs
!= SIZE_MAX
) {
7102 /* Sound is present in the NewGRF. */
7103 sound
->file_slot
= _cur
.file_index
;
7104 sound
->file_offset
= offs
;
7105 sound
->grf_container_ver
= _cur
.grf_container_ver
;
7110 static void GRFSound(ByteReader
*buf
)
7114 * W num Number of sound files that follow */
7116 uint16 num
= buf
->ReadWord();
7117 if (num
== 0) return;
7120 if (_cur
.grffile
->sound_offset
== 0) {
7121 _cur
.grffile
->sound_offset
= GetNumSounds();
7122 _cur
.grffile
->num_sounds
= num
;
7123 sound
= AllocateSound(num
);
7125 sound
= GetSound(_cur
.grffile
->sound_offset
);
7128 for (int i
= 0; i
< num
; i
++) {
7131 /* Check whether the index is in range. This might happen if multiple action 11 are present.
7132 * While this is invalid, we do not check for this. But we should prevent it from causing bigger trouble */
7133 bool invalid
= i
>= _cur
.grffile
->num_sounds
;
7135 size_t offs
= FioGetPos();
7137 uint32 len
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
7138 byte type
= FioReadByte();
7140 if (_cur
.grf_container_ver
>= 2 && type
== 0xFD) {
7141 /* Reference to sprite section. */
7143 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7145 } else if (len
!= 4) {
7146 grfmsg(1, "GRFSound: Invalid sprite section import");
7149 uint32 id
= FioReadDword();
7150 if (_cur
.stage
== GLS_INIT
) LoadGRFSound(GetGRFSpriteOffset(id
), sound
+ i
);
7156 grfmsg(1, "GRFSound: Unexpected RealSprite found, skipping");
7158 SkipSpriteData(type
, len
- 8);
7163 grfmsg(1, "GRFSound: Sound index out of range (multiple Action 11?)");
7167 byte action
= FioReadByte();
7170 /* Allocate sound only in init stage. */
7171 if (_cur
.stage
== GLS_INIT
) {
7172 if (_cur
.grf_container_ver
>= 2) {
7173 grfmsg(1, "GRFSound: Inline sounds are not supported for container version >= 2");
7175 LoadGRFSound(offs
, sound
+ i
);
7178 FioSkipBytes(len
- 1); // already read <action>
7182 if (_cur
.stage
== GLS_ACTIVATION
) {
7183 /* XXX 'Action 0xFE' isn't really specified. It is only mentioned for
7184 * importing sounds, so this is probably all wrong... */
7185 if (FioReadByte() != 0) grfmsg(1, "GRFSound: Import type mismatch");
7186 ImportGRFSound(sound
+ i
);
7188 FioSkipBytes(len
- 1); // already read <action>
7193 grfmsg(1, "GRFSound: Unexpected Action %x found, skipping", action
);
7194 FioSkipBytes(len
- 1); // already read <action>
7200 /* Action 0x11 (SKIP) */
7201 static void SkipAct11(ByteReader
*buf
)
7205 * W num Number of sound files that follow */
7207 _cur
.skip_sprites
= buf
->ReadWord();
7209 grfmsg(3, "SkipAct11: Skipping %d sprites", _cur
.skip_sprites
);
7213 static void LoadFontGlyph(ByteReader
*buf
)
7215 /* <12> <num_def> <font_size> <num_char> <base_char>
7217 * B num_def Number of definitions
7218 * B font_size Size of font (0 = normal, 1 = small, 2 = large, 3 = mono)
7219 * B num_char Number of consecutive glyphs
7220 * W base_char First character index */
7222 uint8 num_def
= buf
->ReadByte();
7224 for (uint i
= 0; i
< num_def
; i
++) {
7225 FontSize size
= (FontSize
)buf
->ReadByte();
7226 uint8 num_char
= buf
->ReadByte();
7227 uint16 base_char
= buf
->ReadWord();
7229 if (size
>= FS_END
) {
7230 grfmsg(1, "LoadFontGlyph: Size %u is not supported, ignoring", size
);
7233 grfmsg(7, "LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char
, base_char
, size
);
7235 for (uint c
= 0; c
< num_char
; c
++) {
7236 if (size
< FS_END
) SetUnicodeGlyph(size
, base_char
+ c
, _cur
.spriteid
);
7238 LoadNextSprite(_cur
.spriteid
++, _cur
.file_index
, _cur
.nfo_line
, _cur
.grf_container_ver
);
7243 /** Action 0x12 (SKIP) */
7244 static void SkipAct12(ByteReader
*buf
)
7246 /* <12> <num_def> <font_size> <num_char> <base_char>
7248 * B num_def Number of definitions
7249 * B font_size Size of font (0 = normal, 1 = small, 2 = large)
7250 * B num_char Number of consecutive glyphs
7251 * W base_char First character index */
7253 uint8 num_def
= buf
->ReadByte();
7255 for (uint i
= 0; i
< num_def
; i
++) {
7256 /* Ignore 'size' byte */
7259 /* Sum up number of characters */
7260 _cur
.skip_sprites
+= buf
->ReadByte();
7262 /* Ignore 'base_char' word */
7266 grfmsg(3, "SkipAct12: Skipping %d sprites", _cur
.skip_sprites
);
7270 static void TranslateGRFStrings(ByteReader
*buf
)
7272 /* <13> <grfid> <num-ent> <offset> <text...>
7274 * 4*B grfid The GRFID of the file whose texts are to be translated
7275 * B num-ent Number of strings
7276 * W offset First text ID
7277 * S text... Zero-terminated strings */
7279 uint32 grfid
= buf
->ReadDWord();
7280 const GRFConfig
*c
= GetGRFConfig(grfid
);
7281 if (c
== NULL
|| (c
->status
!= GCS_INITIALISED
&& c
->status
!= GCS_ACTIVATED
)) {
7282 grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid
));
7286 if (c
->status
== GCS_INITIALISED
) {
7287 /* If the file is not active but will be activated later, give an error
7288 * and disable this file. */
7289 GRFError
*error
= DisableGrf(STR_NEWGRF_ERROR_LOAD_AFTER
);
7292 GetString(tmp
, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE
, lastof(tmp
));
7293 error
->data
= stredup(tmp
);
7298 /* Since no language id is supplied for with version 7 and lower NewGRFs, this string has
7299 * to be added as a generic string, thus the language id of 0x7F. For this to work
7300 * new_scheme has to be true as well, which will also be implicitly the case for version 8
7301 * and higher. A language id of 0x7F will be overridden by a non-generic id, so this will
7302 * not change anything if a string has been provided specifically for this language. */
7303 byte language
= _cur
.grffile
->grf_version
>= 8 ? buf
->ReadByte() : 0x7F;
7304 byte num_strings
= buf
->ReadByte();
7305 uint16 first_id
= buf
->ReadWord();
7307 if (!((first_id
>= 0xD000 && first_id
+ num_strings
<= 0xD400) || (first_id
>= 0xD800 && first_id
+ num_strings
<= 0xE000))) {
7308 grfmsg(7, "TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id
, num_strings
);
7312 for (uint i
= 0; i
< num_strings
&& buf
->HasData(); i
++) {
7313 const char *string
= buf
->ReadString();
7315 if (StrEmpty(string
)) {
7316 grfmsg(7, "TranslateGRFString: Ignoring empty string.");
7320 AddGRFString(grfid
, first_id
+ i
, language
, true, true, string
, STR_UNDEFINED
);
7324 /** Callback function for 'INFO'->'NAME' to add a translation to the newgrf name. */
7325 static bool ChangeGRFName(byte langid
, const char *str
)
7327 AddGRFTextToList(&_cur
.grfconfig
->name
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7331 /** Callback function for 'INFO'->'DESC' to add a translation to the newgrf description. */
7332 static bool ChangeGRFDescription(byte langid
, const char *str
)
7334 AddGRFTextToList(&_cur
.grfconfig
->info
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, true, str
);
7338 /** Callback function for 'INFO'->'URL_' to set the newgrf url. */
7339 static bool ChangeGRFURL(byte langid
, const char *str
)
7341 AddGRFTextToList(&_cur
.grfconfig
->url
->text
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7345 /** Callback function for 'INFO'->'NPAR' to set the number of valid parameters. */
7346 static bool ChangeGRFNumUsedParams(size_t len
, ByteReader
*buf
)
7349 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len
);
7352 _cur
.grfconfig
->num_valid_params
= min(buf
->ReadByte(), lengthof(_cur
.grfconfig
->param
));
7357 /** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
7358 static bool ChangeGRFPalette(size_t len
, ByteReader
*buf
)
7361 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len
);
7364 char data
= buf
->ReadByte();
7365 GRFPalette pal
= GRFP_GRF_UNSET
;
7368 case 'A': pal
= GRFP_GRF_ANY
; break;
7369 case 'W': pal
= GRFP_GRF_WINDOWS
; break;
7370 case 'D': pal
= GRFP_GRF_DOS
; break;
7372 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data
);
7375 if (pal
!= GRFP_GRF_UNSET
) {
7376 _cur
.grfconfig
->palette
&= ~GRFP_GRF_MASK
;
7377 _cur
.grfconfig
->palette
|= pal
;
7383 /** Callback function for 'INFO'->'BLTR' to set the blitter info. */
7384 static bool ChangeGRFBlitter(size_t len
, ByteReader
*buf
)
7387 grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len
);
7390 char data
= buf
->ReadByte();
7391 GRFPalette pal
= GRFP_BLT_UNSET
;
7393 case '8': pal
= GRFP_BLT_UNSET
; break;
7394 case '3': pal
= GRFP_BLT_32BPP
; break;
7396 grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data
);
7399 _cur
.grfconfig
->palette
&= ~GRFP_BLT_MASK
;
7400 _cur
.grfconfig
->palette
|= pal
;
7405 /** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
7406 static bool ChangeGRFVersion(size_t len
, ByteReader
*buf
)
7409 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len
);
7412 /* Set min_loadable_version as well (default to minimal compatibility) */
7413 _cur
.grfconfig
->version
= _cur
.grfconfig
->min_loadable_version
= buf
->ReadDWord();
7418 /** Callback function for 'INFO'->'MINV' to the minimum compatible version of the NewGRF. */
7419 static bool ChangeGRFMinVersion(size_t len
, ByteReader
*buf
)
7422 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len
);
7425 _cur
.grfconfig
->min_loadable_version
= buf
->ReadDWord();
7426 if (_cur
.grfconfig
->version
== 0) {
7427 grfmsg(2, "StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7428 _cur
.grfconfig
->min_loadable_version
= 0;
7430 if (_cur
.grfconfig
->version
< _cur
.grfconfig
->min_loadable_version
) {
7431 grfmsg(2, "StaticGRFInfo: 'MINV' defined as %d, limiting it to 'VRSN'", _cur
.grfconfig
->min_loadable_version
);
7432 _cur
.grfconfig
->min_loadable_version
= _cur
.grfconfig
->version
;
7438 static GRFParameterInfo
*_cur_parameter
; ///< The parameter which info is currently changed by the newgrf.
7440 /** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
7441 static bool ChangeGRFParamName(byte langid
, const char *str
)
7443 AddGRFTextToList(&_cur_parameter
->name
, langid
, _cur
.grfconfig
->ident
.grfid
, false, str
);
7447 /** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
7448 static bool ChangeGRFParamDescription(byte langid
, const char *str
)
7450 AddGRFTextToList(&_cur_parameter
->desc
, langid
, _cur
.grfconfig
->ident
.grfid
, true, str
);
7454 /** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
7455 static bool ChangeGRFParamType(size_t len
, ByteReader
*buf
)
7458 grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len
);
7461 GRFParameterType type
= (GRFParameterType
)buf
->ReadByte();
7462 if (type
< PTYPE_END
) {
7463 _cur_parameter
->type
= type
;
7465 grfmsg(3, "StaticGRFInfo: unknown parameter type %d, ignoring this field", type
);
7471 /** Callback function for 'INFO'->'PARAM'->param_num->'LIMI' to set the min/max value of a parameter. */
7472 static bool ChangeGRFParamLimits(size_t len
, ByteReader
*buf
)
7474 if (_cur_parameter
->type
!= PTYPE_UINT_ENUM
) {
7475 grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7477 } else if (len
!= 8) {
7478 grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len
);
7481 _cur_parameter
->min_value
= buf
->ReadDWord();
7482 _cur_parameter
->max_value
= buf
->ReadDWord();
7487 /** Callback function for 'INFO'->'PARAM'->param_num->'MASK' to set the parameter and bits to use. */
7488 static bool ChangeGRFParamMask(size_t len
, ByteReader
*buf
)
7490 if (len
< 1 || len
> 3) {
7491 grfmsg(2, "StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len
);
7494 byte param_nr
= buf
->ReadByte();
7495 if (param_nr
>= lengthof(_cur
.grfconfig
->param
)) {
7496 grfmsg(2, "StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr
);
7499 _cur_parameter
->param_nr
= param_nr
;
7500 if (len
>= 2) _cur_parameter
->first_bit
= min(buf
->ReadByte(), 31);
7501 if (len
>= 3) _cur_parameter
->num_bit
= min(buf
->ReadByte(), 32 - _cur_parameter
->first_bit
);
7508 /** Callback function for 'INFO'->'PARAM'->param_num->'DFLT' to set the default value. */
7509 static bool ChangeGRFParamDefault(size_t len
, ByteReader
*buf
)
7512 grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len
);
7515 _cur_parameter
->def_value
= buf
->ReadDWord();
7517 _cur
.grfconfig
->has_param_defaults
= true;
7521 typedef bool (*DataHandler
)(size_t, ByteReader
*); ///< Type of callback function for binary nodes
7522 typedef bool (*TextHandler
)(byte
, const char *str
); ///< Type of callback function for text nodes
7523 typedef bool (*BranchHandler
)(ByteReader
*); ///< Type of callback function for branch nodes
7526 * Data structure to store the allowed id/type combinations for action 14. The
7527 * data can be represented as a tree with 3 types of nodes:
7528 * 1. Branch nodes (identified by 'C' for choice).
7529 * 2. Binary leaf nodes (identified by 'B').
7530 * 3. Text leaf nodes (identified by 'T').
7532 struct AllowedSubtags
{
7533 /** Create empty subtags object used to identify the end of a list. */
7540 * Create a binary leaf node.
7541 * @param id The id for this node.
7542 * @param handler The callback function to call.
7544 AllowedSubtags(uint32 id
, DataHandler handler
) :
7548 this->handler
.data
= handler
;
7552 * Create a text leaf node.
7553 * @param id The id for this node.
7554 * @param handler The callback function to call.
7556 AllowedSubtags(uint32 id
, TextHandler handler
) :
7560 this->handler
.text
= handler
;
7564 * Create a branch node with a callback handler
7565 * @param id The id for this node.
7566 * @param handler The callback function to call.
7568 AllowedSubtags(uint32 id
, BranchHandler handler
) :
7572 this->handler
.call_handler
= true;
7573 this->handler
.u
.branch
= handler
;
7577 * Create a branch node with a list of sub-nodes.
7578 * @param id The id for this node.
7579 * @param subtags Array with all valid subtags.
7581 AllowedSubtags(uint32 id
, AllowedSubtags
*subtags
) :
7585 this->handler
.call_handler
= false;
7586 this->handler
.u
.subtags
= subtags
;
7589 uint32 id
; ///< The identifier for this node
7590 byte type
; ///< The type of the node, must be one of 'C', 'B' or 'T'.
7592 DataHandler data
; ///< Callback function for a binary node, only valid if type == 'B'.
7593 TextHandler text
; ///< Callback function for a text node, only valid if type == 'T'.
7596 BranchHandler branch
; ///< Callback function for a branch node, only valid if type == 'C' && call_handler.
7597 AllowedSubtags
*subtags
; ///< Pointer to a list of subtags, only valid if type == 'C' && !call_handler.
7599 bool call_handler
; ///< True if there is a callback function for this node, false if there is a list of subnodes.
7604 static bool SkipUnknownInfo(ByteReader
*buf
, byte type
);
7605 static bool HandleNodes(ByteReader
*buf
, AllowedSubtags
*tags
);
7608 * Callback function for 'INFO'->'PARA'->param_num->'VALU' to set the names
7609 * of some parameter values (type uint/enum) or the names of some bits
7610 * (type bitmask). In both cases the format is the same:
7611 * Each subnode should be a text node with the value/bit number as id.
7613 static bool ChangeGRFParamValueNames(ByteReader
*buf
)
7615 byte type
= buf
->ReadByte();
7617 uint32 id
= buf
->ReadDWord();
7618 if (type
!= 'T' || id
> _cur_parameter
->max_value
) {
7619 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7620 if (!SkipUnknownInfo(buf
, type
)) return false;
7621 type
= buf
->ReadByte();
7625 byte langid
= buf
->ReadByte();
7626 const char *name_string
= buf
->ReadString();
7628 SmallPair
<uint32
, GRFText
*> *val_name
= _cur_parameter
->value_names
.Find(id
);
7629 if (val_name
!= _cur_parameter
->value_names
.End()) {
7630 AddGRFTextToList(&val_name
->second
, langid
, _cur
.grfconfig
->ident
.grfid
, false, name_string
);
7632 GRFText
*list
= NULL
;
7633 AddGRFTextToList(&list
, langid
, _cur
.grfconfig
->ident
.grfid
, false, name_string
);
7634 _cur_parameter
->value_names
.Insert(id
, list
);
7637 type
= buf
->ReadByte();
7642 /** Action14 parameter tags */
7643 AllowedSubtags _tags_parameters
[] = {
7644 AllowedSubtags('NAME', ChangeGRFParamName
),
7645 AllowedSubtags('DESC', ChangeGRFParamDescription
),
7646 AllowedSubtags('TYPE', ChangeGRFParamType
),
7647 AllowedSubtags('LIMI', ChangeGRFParamLimits
),
7648 AllowedSubtags('MASK', ChangeGRFParamMask
),
7649 AllowedSubtags('VALU', ChangeGRFParamValueNames
),
7650 AllowedSubtags('DFLT', ChangeGRFParamDefault
),
7655 * Callback function for 'INFO'->'PARA' to set extra information about the
7656 * parameters. Each subnode of 'INFO'->'PARA' should be a branch node with
7657 * the parameter number as id. The first parameter has id 0. The maximum
7658 * parameter that can be changed is set by 'INFO'->'NPAR' which defaults to 80.
7660 static bool HandleParameterInfo(ByteReader
*buf
)
7662 byte type
= buf
->ReadByte();
7664 uint32 id
= buf
->ReadDWord();
7665 if (type
!= 'C' || id
>= _cur
.grfconfig
->num_valid_params
) {
7666 grfmsg(2, "StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7667 if (!SkipUnknownInfo(buf
, type
)) return false;
7668 type
= buf
->ReadByte();
7672 if (id
>= _cur
.grfconfig
->param_info
.Length()) {
7673 uint num_to_add
= id
- _cur
.grfconfig
->param_info
.Length() + 1;
7674 GRFParameterInfo
**newdata
= _cur
.grfconfig
->param_info
.Append(num_to_add
);
7675 MemSetT
<GRFParameterInfo
*>(newdata
, 0, num_to_add
);
7677 if (_cur
.grfconfig
->param_info
[id
] == NULL
) {
7678 _cur
.grfconfig
->param_info
[id
] = new GRFParameterInfo(id
);
7680 _cur_parameter
= _cur
.grfconfig
->param_info
[id
];
7681 /* Read all parameter-data and process each node. */
7682 if (!HandleNodes(buf
, _tags_parameters
)) return false;
7683 type
= buf
->ReadByte();
7688 /** Action14 tags for the INFO node */
7689 AllowedSubtags _tags_info
[] = {
7690 AllowedSubtags('NAME', ChangeGRFName
),
7691 AllowedSubtags('DESC', ChangeGRFDescription
),
7692 AllowedSubtags('URL_', ChangeGRFURL
),
7693 AllowedSubtags('NPAR', ChangeGRFNumUsedParams
),
7694 AllowedSubtags('PALS', ChangeGRFPalette
),
7695 AllowedSubtags('BLTR', ChangeGRFBlitter
),
7696 AllowedSubtags('VRSN', ChangeGRFVersion
),
7697 AllowedSubtags('MINV', ChangeGRFMinVersion
),
7698 AllowedSubtags('PARA', HandleParameterInfo
),
7702 /** Action14 root tags */
7703 AllowedSubtags _tags_root
[] = {
7704 AllowedSubtags('INFO', _tags_info
),
7710 * Try to skip the current node and all subnodes (if it's a branch node).
7711 * @param buf Buffer.
7712 * @param type The node type to skip.
7713 * @return True if we could skip the node, false if an error occurred.
7715 static bool SkipUnknownInfo(ByteReader
*buf
, byte type
)
7717 /* type and id are already read */
7720 byte new_type
= buf
->ReadByte();
7721 while (new_type
!= 0) {
7722 buf
->ReadDWord(); // skip the id
7723 if (!SkipUnknownInfo(buf
, new_type
)) return false;
7724 new_type
= buf
->ReadByte();
7730 buf
->ReadByte(); // lang
7731 buf
->ReadString(); // actual text
7735 uint16 size
= buf
->ReadWord();
7748 * Handle the nodes of an Action14
7749 * @param type Type of node.
7751 * @param buf Buffer.
7752 * @param subtags Allowed subtags.
7753 * @return Whether all tags could be handled.
7755 static bool HandleNode(byte type
, uint32 id
, ByteReader
*buf
, AllowedSubtags subtags
[])
7758 AllowedSubtags
*tag
;
7759 while ((tag
= &subtags
[i
++])->type
!= 0) {
7760 if (tag
->id
!= BSWAP32(id
) || tag
->type
!= type
) continue;
7762 default: NOT_REACHED();
7765 byte langid
= buf
->ReadByte();
7766 return tag
->handler
.text(langid
, buf
->ReadString());
7770 size_t len
= buf
->ReadWord();
7771 if (buf
->Remaining() < len
) return false;
7772 return tag
->handler
.data(len
, buf
);
7776 if (tag
->handler
.call_handler
) {
7777 return tag
->handler
.u
.branch(buf
);
7779 return HandleNodes(buf
, tag
->handler
.u
.subtags
);
7783 grfmsg(2, "StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type
, id
);
7784 return SkipUnknownInfo(buf
, type
);
7788 * Handle the contents of a 'C' choice of an Action14
7789 * @param buf Buffer.
7790 * @param subtags List of subtags.
7791 * @return Whether the nodes could all be handled.
7793 static bool HandleNodes(ByteReader
*buf
, AllowedSubtags subtags
[])
7795 byte type
= buf
->ReadByte();
7797 uint32 id
= buf
->ReadDWord();
7798 if (!HandleNode(type
, id
, buf
, subtags
)) return false;
7799 type
= buf
->ReadByte();
7805 * Handle Action 0x14
7806 * @param buf Buffer.
7808 static void StaticGRFInfo(ByteReader
*buf
)
7810 /* <14> <type> <id> <text/data...> */
7811 HandleNodes(buf
, _tags_root
);
7815 * Set the current NewGRF as unsafe for static use
7816 * @param buf Unused.
7817 * @note Used during safety scan on unsafe actions.
7819 static void GRFUnsafe(ByteReader
*buf
)
7821 SetBit(_cur
.grfconfig
->flags
, GCF_UNSAFE
);
7823 /* Skip remainder of GRF */
7824 _cur
.skip_sprites
= -1;
7828 /** Initialize the TTDPatch flags */
7829 static void InitializeGRFSpecial()
7831 _ttdpatch_flags
[0] = ((_settings_game
.station
.never_expire_airports
? 1 : 0) << 0x0C) // keepsmallairport
7832 | (1 << 0x0D) // newairports
7833 | (1 << 0x0E) // largestations
7834 | ((_settings_game
.construction
.max_bridge_length
> 16 ? 1 : 0) << 0x0F) // longbridges
7835 | (0 << 0x10) // loadtime
7836 | (1 << 0x12) // presignals
7837 | (1 << 0x13) // extpresignals
7838 | ((_settings_game
.vehicle
.never_expire_vehicles
? 1 : 0) << 0x16) // enginespersist
7839 | (1 << 0x1B) // multihead
7840 | (1 << 0x1D) // lowmemory
7841 | (1 << 0x1E); // generalfixes
7843 _ttdpatch_flags
[1] = ((_settings_game
.economy
.station_noise_level
? 1 : 0) << 0x07) // moreairports - based on units of noise
7844 | (1 << 0x08) // mammothtrains
7845 | (1 << 0x09) // trainrefit
7846 | (0 << 0x0B) // subsidiaries
7847 | ((_settings_game
.order
.gradual_loading
? 1 : 0) << 0x0C) // gradualloading
7848 | (1 << 0x12) // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
7849 | (1 << 0x13) // unifiedmaglevmode - set bit 1 mode
7850 | (1 << 0x14) // bridgespeedlimits
7851 | (1 << 0x16) // eternalgame
7852 | (1 << 0x17) // newtrains
7853 | (1 << 0x18) // newrvs
7854 | (1 << 0x19) // newships
7855 | (1 << 0x1A) // newplanes
7856 | ((_settings_game
.construction
.train_signal_side
== 1 ? 1 : 0) << 0x1B) // signalsontrafficside
7857 | ((_settings_game
.vehicle
.disable_elrails
? 0 : 1) << 0x1C); // electrifiedrailway
7859 _ttdpatch_flags
[2] = (1 << 0x01) // loadallgraphics - obsolote
7860 | (1 << 0x03) // semaphores
7861 | (1 << 0x0A) // newobjects
7862 | (0 << 0x0B) // enhancedgui
7863 | (0 << 0x0C) // newagerating
7864 | ((_settings_game
.construction
.build_on_slopes
? 1 : 0) << 0x0D) // buildonslopes
7865 | (1 << 0x0E) // fullloadany
7866 | (1 << 0x0F) // planespeed
7867 | (0 << 0x10) // moreindustriesperclimate - obsolete
7868 | (0 << 0x11) // moretoylandfeatures
7869 | (1 << 0x12) // newstations
7870 | (1 << 0x13) // tracktypecostdiff
7871 | (1 << 0x14) // manualconvert
7872 | ((_settings_game
.construction
.build_on_slopes
? 1 : 0) << 0x15) // buildoncoasts
7873 | (1 << 0x16) // canals
7874 | (1 << 0x17) // newstartyear
7875 | ((_settings_game
.vehicle
.freight_trains
> 1 ? 1 : 0) << 0x18) // freighttrains
7876 | (1 << 0x19) // newhouses
7877 | (1 << 0x1A) // newbridges
7878 | (1 << 0x1B) // newtownnames
7879 | (1 << 0x1C) // moreanimation
7880 | ((_settings_game
.vehicle
.wagon_speed_limits
? 1 : 0) << 0x1D) // wagonspeedlimits
7881 | (1 << 0x1E) // newshistory
7882 | (0 << 0x1F); // custombridgeheads
7884 _ttdpatch_flags
[3] = (0 << 0x00) // newcargodistribution
7885 | (1 << 0x01) // windowsnap
7886 | ((_settings_game
.economy
.allow_town_roads
|| _generating_world
? 0 : 1) << 0x02) // townbuildnoroad
7887 | (1 << 0x03) // pathbasedsignalling
7888 | (0 << 0x04) // aichoosechance
7889 | (1 << 0x05) // resolutionwidth
7890 | (1 << 0x06) // resolutionheight
7891 | (1 << 0x07) // newindustries
7892 | ((_settings_game
.order
.improved_load
? 1 : 0) << 0x08) // fifoloading
7893 | (0 << 0x09) // townroadbranchprob
7894 | (0 << 0x0A) // tempsnowline
7895 | (1 << 0x0B) // newcargo
7896 | (1 << 0x0C) // enhancemultiplayer
7897 | (1 << 0x0D) // onewayroads
7898 | (1 << 0x0E) // irregularstations
7899 | (1 << 0x0F) // statistics
7900 | (1 << 0x10) // newsounds
7901 | (1 << 0x11) // autoreplace
7902 | (1 << 0x12) // autoslope
7903 | (0 << 0x13) // followvehicle
7904 | (1 << 0x14) // trams
7905 | (0 << 0x15) // enhancetunnels
7906 | (1 << 0x16) // shortrvs
7907 | (1 << 0x17) // articulatedrvs
7908 | ((_settings_game
.vehicle
.dynamic_engines
? 1 : 0) << 0x18) // dynamic engines
7909 | (1 << 0x1E) // variablerunningcosts
7910 | (1 << 0x1F); // any switch is on
7913 /** Reset and clear all NewGRF stations */
7914 static void ResetCustomStations()
7916 const GRFFile
* const *end
= _grf_files
.End();
7917 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7918 StationSpec
**&stations
= (*file
)->stations
;
7919 if (stations
== NULL
) continue;
7920 for (uint i
= 0; i
< NUM_STATIONS_PER_GRF
; i
++) {
7921 if (stations
[i
] == NULL
) continue;
7922 StationSpec
*statspec
= stations
[i
];
7924 delete[] statspec
->renderdata
;
7926 /* Release platforms and layouts */
7927 if (!statspec
->copied_layouts
) {
7928 for (uint l
= 0; l
< statspec
->lengths
; l
++) {
7929 for (uint p
= 0; p
< statspec
->platforms
[l
]; p
++) {
7930 free(statspec
->layouts
[l
][p
]);
7932 free(statspec
->layouts
[l
]);
7934 free(statspec
->layouts
);
7935 free(statspec
->platforms
);
7938 /* Release this station */
7942 /* Free and reset the station data */
7948 /** Reset and clear all NewGRF houses */
7949 static void ResetCustomHouses()
7951 const GRFFile
* const *end
= _grf_files
.End();
7952 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7953 HouseSpec
**&housespec
= (*file
)->housespec
;
7954 if (housespec
== NULL
) continue;
7955 for (uint i
= 0; i
< NUM_HOUSES_PER_GRF
; i
++) {
7964 /** Reset and clear all NewGRF airports */
7965 static void ResetCustomAirports()
7967 const GRFFile
* const *end
= _grf_files
.End();
7968 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
7969 AirportSpec
**aslist
= (*file
)->airportspec
;
7970 if (aslist
!= NULL
) {
7971 for (uint i
= 0; i
< NUM_AIRPORTS_PER_GRF
; i
++) {
7972 AirportSpec
*as
= aslist
[i
];
7975 /* We need to remove the tiles layouts */
7976 for (int j
= 0; j
< as
->num_table
; j
++) {
7977 /* remove the individual layouts */
7981 free(as
->depot_table
);
7988 (*file
)->airportspec
= NULL
;
7991 AirportTileSpec
**&airporttilespec
= (*file
)->airtspec
;
7992 if (airporttilespec
!= NULL
) {
7993 for (uint i
= 0; i
< NUM_AIRPORTTILES_PER_GRF
; i
++) {
7994 free(airporttilespec
[i
]);
7996 free(airporttilespec
);
7997 airporttilespec
= NULL
;
8002 /** Reset and clear all NewGRF industries */
8003 static void ResetCustomIndustries()
8005 const GRFFile
* const *end
= _grf_files
.End();
8006 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8007 IndustrySpec
**&industryspec
= (*file
)->industryspec
;
8008 IndustryTileSpec
**&indtspec
= (*file
)->indtspec
;
8010 /* We are verifiying both tiles and industries specs loaded from the grf file
8011 * First, let's deal with industryspec */
8012 if (industryspec
!= NULL
) {
8013 for (uint i
= 0; i
< NUM_INDUSTRYTYPES_PER_GRF
; i
++) {
8014 IndustrySpec
*ind
= industryspec
[i
];
8015 if (ind
== NULL
) continue;
8017 /* We need to remove the sounds array */
8018 if (HasBit(ind
->cleanup_flag
, CLEAN_RANDOMSOUNDS
)) {
8019 free(ind
->random_sounds
);
8022 /* We need to remove the tiles layouts */
8023 CleanIndustryTileTable(ind
);
8029 industryspec
= NULL
;
8032 if (indtspec
== NULL
) continue;
8033 for (uint i
= 0; i
< NUM_INDUSTRYTILES_PER_GRF
; i
++) {
8042 /** Reset and clear all NewObjects */
8043 static void ResetCustomObjects()
8045 const GRFFile
* const *end
= _grf_files
.End();
8046 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8047 ObjectSpec
**&objectspec
= (*file
)->objectspec
;
8048 if (objectspec
== NULL
) continue;
8049 for (uint i
= 0; i
< NUM_OBJECTS_PER_GRF
; i
++) {
8050 free(objectspec
[i
]);
8058 /** Reset and clear all NewGRFs */
8059 static void ResetNewGRF()
8061 const GRFFile
* const *end
= _grf_files
.End();
8062 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8067 _cur
.grffile
= NULL
;
8070 /** Clear all NewGRF errors */
8071 static void ResetNewGRFErrors()
8073 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
8074 if (!HasBit(c
->flags
, GCF_COPY
) && c
->error
!= NULL
) {
8082 * Reset all NewGRF loaded data
8085 void ResetNewGRFData()
8088 CleanUpGRFTownNames();
8090 /* Copy/reset original engine info data */
8093 /* Copy/reset original bridge info data */
8096 /* Reset rail type information */
8099 /* Allocate temporary refit/cargo class data */
8100 _gted
= CallocT
<GRFTempEngineData
>(Engine::GetPoolSize());
8102 /* Fill rail type label temporary data for default trains */
8104 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_TRAIN
) {
8105 _gted
[e
->index
].railtypelabel
= GetRailTypeInfo(e
->u
.rail
.railtype
)->label
;
8108 /* Reset GRM reservations */
8109 memset(&_grm_engines
, 0, sizeof(_grm_engines
));
8110 memset(&_grm_cargoes
, 0, sizeof(_grm_cargoes
));
8112 /* Reset generic feature callback lists */
8113 ResetGenericCallbacks();
8115 /* Reset price base data */
8116 ResetPriceBaseMultipliers();
8118 /* Reset the curencies array */
8121 /* Reset the house array */
8122 ResetCustomHouses();
8125 /* Reset the industries structures*/
8126 ResetCustomIndustries();
8129 /* Reset the objects. */
8130 ObjectClass::Reset();
8131 ResetCustomObjects();
8134 /* Reset station classes */
8135 StationClass::Reset();
8136 ResetCustomStations();
8138 /* Reset airport-related structures */
8139 AirportClass::Reset();
8140 ResetCustomAirports();
8141 AirportSpec::ResetAirports();
8142 AirportTileSpec::ResetAirportTiles();
8144 /* Reset canal sprite groups and flags */
8145 memset(_water_feature
, 0, sizeof(_water_feature
));
8147 /* Reset the snowline table. */
8150 /* Reset NewGRF files */
8153 /* Reset NewGRF errors. */
8154 ResetNewGRFErrors();
8156 /* Set up the default cargo types */
8157 SetupCargoForClimate(_settings_game
.game_creation
.landscape
);
8159 /* Reset misc GRF features and train list display variables */
8160 _misc_grf_features
= 0;
8162 _loaded_newgrf_features
.has_2CC
= false;
8163 _loaded_newgrf_features
.used_liveries
= 1 << LS_DEFAULT
;
8164 _loaded_newgrf_features
.has_newhouses
= false;
8165 _loaded_newgrf_features
.has_newindustries
= false;
8166 _loaded_newgrf_features
.shore
= SHORE_REPLACE_NONE
;
8168 /* Clear all GRF overrides */
8169 _grf_id_overrides
.clear();
8171 InitializeSoundPool();
8172 _spritegroup_pool
.CleanPool();
8176 * Reset NewGRF data which is stored persistently in savegames.
8178 void ResetPersistentNewGRFData()
8180 /* Reset override managers */
8181 _engine_mngr
.ResetToDefaultMapping();
8182 _house_mngr
.ResetMapping();
8183 _industry_mngr
.ResetMapping();
8184 _industile_mngr
.ResetMapping();
8185 _airport_mngr
.ResetMapping();
8186 _airporttile_mngr
.ResetMapping();
8190 * Construct the Cargo Mapping
8191 * @note This is the reverse of a cargo translation table
8193 static void BuildCargoTranslationMap()
8195 memset(_cur
.grffile
->cargo_map
, 0xFF, sizeof(_cur
.grffile
->cargo_map
));
8197 for (CargoID c
= 0; c
< NUM_CARGO
; c
++) {
8198 const CargoSpec
*cs
= CargoSpec::Get(c
);
8199 if (!cs
->IsValid()) continue;
8201 if (_cur
.grffile
->cargo_list
.Length() == 0) {
8202 /* Default translation table, so just a straight mapping to bitnum */
8203 _cur
.grffile
->cargo_map
[c
] = cs
->bitnum
;
8205 /* Check the translation table for this cargo's label */
8206 int index
= _cur
.grffile
->cargo_list
.FindIndex(cs
->label
);
8207 if (index
>= 0) _cur
.grffile
->cargo_map
[c
] = index
;
8213 * Prepare loading a NewGRF file with its config
8214 * @param config The NewGRF configuration struct with name, id, parameters and alike.
8216 static void InitNewGRFFile(const GRFConfig
*config
)
8218 GRFFile
*newfile
= GetFileByFilename(config
->filename
);
8219 if (newfile
!= NULL
) {
8220 /* We already loaded it once. */
8221 _cur
.grffile
= newfile
;
8225 newfile
= new GRFFile(config
);
8226 *_grf_files
.Append() = _cur
.grffile
= newfile
;
8230 * Constructor for GRFFile
8231 * @param config GRFConfig to copy name, grfid and parameters from.
8233 GRFFile::GRFFile(const GRFConfig
*config
)
8235 this->filename
= stredup(config
->filename
);
8236 this->grfid
= config
->ident
.grfid
;
8238 /* Initialise local settings to defaults */
8239 this->traininfo_vehicle_pitch
= 0;
8240 this->traininfo_vehicle_width
= TRAININFO_DEFAULT_VEHICLE_WIDTH
;
8242 /* Mark price_base_multipliers as 'not set' */
8243 for (Price i
= PR_BEGIN
; i
< PR_END
; i
++) {
8244 this->price_base_multipliers
[i
] = INVALID_PRICE_MODIFIER
;
8247 /* Initialise rail type map with default rail types */
8248 memset(this->railtype_map
, INVALID_RAILTYPE
, sizeof(this->railtype_map
));
8249 this->railtype_map
[0] = RAILTYPE_RAIL
;
8250 this->railtype_map
[1] = RAILTYPE_ELECTRIC
;
8251 this->railtype_map
[2] = RAILTYPE_MONO
;
8252 this->railtype_map
[3] = RAILTYPE_MAGLEV
;
8254 /* Copy the initial parameter list
8255 * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */
8256 assert_compile(lengthof(this->param
) == lengthof(config
->param
) && lengthof(this->param
) == 0x80);
8258 assert(config
->num_params
<= lengthof(config
->param
));
8259 this->param_end
= config
->num_params
;
8260 if (this->param_end
> 0) {
8261 MemCpyT(this->param
, config
->param
, this->param_end
);
8267 free(this->filename
);
8268 delete[] this->language_map
;
8273 * List of what cargo labels are refittable for the given the vehicle-type.
8274 * Only currently active labels are applied.
8276 static const CargoLabel _default_refitmasks_rail
[] = {
8277 'PASS', 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD',
8278 'IORE', 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE',
8279 'WATR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8283 static const CargoLabel _default_refitmasks_road
[] = {
8286 static const CargoLabel _default_refitmasks_ships
[] = {
8287 'COAL', 'MAIL', 'LVST', 'GOOD', 'GRAI', 'WHEA', 'MAIZ', 'WOOD', 'IORE',
8288 'STEL', 'VALU', 'GOLD', 'DIAM', 'PAPR', 'FOOD', 'FRUT', 'CORE', 'WATR',
8289 'RUBR', 'SUGR', 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL',
8293 static const CargoLabel _default_refitmasks_aircraft
[] = {
8294 'PASS', 'MAIL', 'GOOD', 'VALU', 'GOLD', 'DIAM', 'FOOD', 'FRUT', 'SUGR',
8295 'TOYS', 'BATT', 'SWET', 'TOFF', 'COLA', 'CTCD', 'BUBL', 'PLST', 'FZDR',
8298 static const CargoLabel
* const _default_refitmasks
[] = {
8299 _default_refitmasks_rail
,
8300 _default_refitmasks_road
,
8301 _default_refitmasks_ships
,
8302 _default_refitmasks_aircraft
,
8307 * Precalculate refit masks from cargo classes for all vehicles.
8309 static void CalculateRefitMasks()
8313 FOR_ALL_ENGINES(e
) {
8314 EngineID engine
= e
->index
;
8315 EngineInfo
*ei
= &e
->info
;
8316 bool only_defaultcargo
; ///< Set if the vehicle shall carry only the default cargo
8318 /* Did the newgrf specify any refitting? If not, use defaults. */
8319 if (_gted
[engine
].refittability
!= GRFTempEngineData::UNSET
) {
8321 uint32 not_mask
= 0;
8322 uint32 xor_mask
= ei
->refit_mask
;
8324 /* If the original masks set by the grf are zero, the vehicle shall only carry the default cargo.
8325 * Note: After applying the translations, the vehicle may end up carrying no defined cargo. It becomes unavailable in that case. */
8326 only_defaultcargo
= _gted
[engine
].refittability
== GRFTempEngineData::EMPTY
;
8328 if (_gted
[engine
].cargo_allowed
!= 0) {
8329 /* Build up the list of cargo types from the set cargo classes. */
8330 const CargoSpec
*cs
;
8331 FOR_ALL_CARGOSPECS(cs
) {
8332 if (_gted
[engine
].cargo_allowed
& cs
->classes
) SetBit(mask
, cs
->Index());
8333 if (_gted
[engine
].cargo_disallowed
& cs
->classes
) SetBit(not_mask
, cs
->Index());
8337 ei
->refit_mask
= ((mask
& ~not_mask
) ^ xor_mask
) & _cargo_mask
;
8339 /* Apply explicit refit includes/excludes. */
8340 ei
->refit_mask
|= _gted
[engine
].ctt_include_mask
;
8341 ei
->refit_mask
&= ~_gted
[engine
].ctt_exclude_mask
;
8343 uint32 xor_mask
= 0;
8345 /* Don't apply default refit mask to wagons nor engines with no capacity */
8346 if (e
->type
!= VEH_TRAIN
|| (e
->u
.rail
.capacity
!= 0 && e
->u
.rail
.railveh_type
!= RAILVEH_WAGON
)) {
8347 const CargoLabel
*cl
= _default_refitmasks
[e
->type
];
8348 for (uint i
= 0;; i
++) {
8349 if (cl
[i
] == 0) break;
8351 CargoID cargo
= GetCargoIDByLabel(cl
[i
]);
8352 if (cargo
== CT_INVALID
) continue;
8354 SetBit(xor_mask
, cargo
);
8358 ei
->refit_mask
= xor_mask
& _cargo_mask
;
8360 /* If the mask is zero, the vehicle shall only carry the default cargo */
8361 only_defaultcargo
= (ei
->refit_mask
== 0);
8364 /* Clear invalid cargoslots (from default vehicles or pre-NewCargo GRFs) */
8365 if (ei
->cargo_type
!= CT_INVALID
&& !HasBit(_cargo_mask
, ei
->cargo_type
)) ei
->cargo_type
= CT_INVALID
;
8367 /* Ensure that the vehicle is either not refittable, or that the default cargo is one of the refittable cargoes.
8368 * Note: Vehicles refittable to no cargo are handle differently to vehicle refittable to a single cargo. The latter might have subtypes. */
8369 if (!only_defaultcargo
&& (e
->type
!= VEH_SHIP
|| e
->u
.ship
.old_refittable
) && ei
->cargo_type
!= CT_INVALID
&& !HasBit(ei
->refit_mask
, ei
->cargo_type
)) {
8370 ei
->cargo_type
= CT_INVALID
;
8373 /* Check if this engine's cargo type is valid. If not, set to the first refittable
8374 * cargo type. Finally disable the vehicle, if there is still no cargo. */
8375 if (ei
->cargo_type
== CT_INVALID
&& ei
->refit_mask
!= 0) {
8376 /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */
8377 const uint8
*cargo_map_for_first_refittable
= NULL
;
8379 const GRFFile
*file
= _gted
[engine
].defaultcargo_grf
;
8380 if (file
== NULL
) file
= e
->GetGRF();
8381 if (file
!= NULL
&& file
->grf_version
>= 8 && file
->cargo_list
.Length() != 0) {
8382 cargo_map_for_first_refittable
= file
->cargo_map
;
8386 if (cargo_map_for_first_refittable
!= NULL
) {
8387 /* Use first refittable cargo from cargo translation table */
8388 byte best_local_slot
= 0xFF;
8390 FOR_EACH_SET_CARGO_ID(cargo_type
, ei
->refit_mask
) {
8391 byte local_slot
= cargo_map_for_first_refittable
[cargo_type
];
8392 if (local_slot
< best_local_slot
) {
8393 best_local_slot
= local_slot
;
8394 ei
->cargo_type
= cargo_type
;
8399 if (ei
->cargo_type
== CT_INVALID
) {
8400 /* Use first refittable cargo slot */
8401 ei
->cargo_type
= (CargoID
)FindFirstBit(ei
->refit_mask
);
8404 if (ei
->cargo_type
== CT_INVALID
) ei
->climates
= 0;
8406 /* Clear refit_mask for not refittable ships */
8407 if (e
->type
== VEH_SHIP
&& !e
->u
.ship
.old_refittable
) {
8413 /** Set to use the correct action0 properties for each canal feature */
8414 static void FinaliseCanals()
8416 for (uint i
= 0; i
< CF_END
; i
++) {
8417 if (_water_feature
[i
].grffile
!= NULL
) {
8418 _water_feature
[i
].callback_mask
= _water_feature
[i
].grffile
->canal_local_properties
[i
].callback_mask
;
8419 _water_feature
[i
].flags
= _water_feature
[i
].grffile
->canal_local_properties
[i
].flags
;
8424 /** Check for invalid engines */
8425 static void FinaliseEngineArray()
8429 FOR_ALL_ENGINES(e
) {
8430 if (e
->GetGRF() == NULL
) {
8431 const EngineIDMapping
&eid
= _engine_mngr
[e
->index
];
8432 if (eid
.grfid
!= INVALID_GRFID
|| eid
.internal_id
!= eid
.substitute_id
) {
8433 e
->info
.string_id
= STR_NEWGRF_INVALID_ENGINE
;
8437 /* When the train does not set property 27 (misc flags), but it
8438 * is overridden by a NewGRF graphically we want to disable the
8439 * flipping possibility. */
8440 if (e
->type
== VEH_TRAIN
&& !_gted
[e
->index
].prop27_set
&& e
->GetGRF() != NULL
&& is_custom_sprite(e
->u
.rail
.image_index
)) {
8441 ClrBit(e
->info
.misc_flags
, EF_RAIL_FLIPS
);
8444 /* Skip wagons, there livery is defined via the engine */
8445 if (e
->type
!= VEH_TRAIN
|| e
->u
.rail
.railveh_type
!= RAILVEH_WAGON
) {
8446 LiveryScheme ls
= GetEngineLiveryScheme(e
->index
, INVALID_ENGINE
, NULL
);
8447 SetBit(_loaded_newgrf_features
.used_liveries
, ls
);
8448 /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */
8450 if (e
->type
== VEH_TRAIN
) {
8451 SetBit(_loaded_newgrf_features
.used_liveries
, LS_FREIGHT_WAGON
);
8458 SetBit(_loaded_newgrf_features
.used_liveries
, LS_PASSENGER_WAGON_STEAM
+ ls
- LS_STEAM
);
8463 SetBit(_loaded_newgrf_features
.used_liveries
, LS_PASSENGER_WAGON_DIESEL
+ ls
- LS_DMU
);
8466 default: NOT_REACHED();
8473 /** Check for invalid cargoes */
8474 static void FinaliseCargoArray()
8476 for (CargoID c
= 0; c
< NUM_CARGO
; c
++) {
8477 CargoSpec
*cs
= CargoSpec::Get(c
);
8478 if (!cs
->IsValid()) {
8479 cs
->name
= cs
->name_single
= cs
->units_volume
= STR_NEWGRF_INVALID_CARGO
;
8480 cs
->quantifier
= STR_NEWGRF_INVALID_CARGO_QUANTITY
;
8481 cs
->abbrev
= STR_NEWGRF_INVALID_CARGO_ABBREV
;
8487 * Check if a given housespec is valid and disable it if it's not.
8488 * The housespecs that follow it are used to check the validity of
8490 * @param hs The housespec to check.
8491 * @param next1 The housespec that follows \c hs.
8492 * @param next2 The housespec that follows \c next1.
8493 * @param next3 The housespec that follows \c next2.
8494 * @param filename The filename of the newgrf this house was defined in.
8495 * @return Whether the given housespec is valid.
8497 static bool IsHouseSpecValid(HouseSpec
*hs
, const HouseSpec
*next1
, const HouseSpec
*next2
, const HouseSpec
*next3
, const char *filename
)
8499 if (((hs
->building_flags
& BUILDING_HAS_2_TILES
) != 0 &&
8500 (next1
== NULL
|| !next1
->enabled
|| (next1
->building_flags
& BUILDING_HAS_1_TILE
) != 0)) ||
8501 ((hs
->building_flags
& BUILDING_HAS_4_TILES
) != 0 &&
8502 (next2
== NULL
|| !next2
->enabled
|| (next2
->building_flags
& BUILDING_HAS_1_TILE
) != 0 ||
8503 next3
== NULL
|| !next3
->enabled
|| (next3
->building_flags
& BUILDING_HAS_1_TILE
) != 0))) {
8504 hs
->enabled
= false;
8505 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
);
8509 /* Some places sum population by only counting north tiles. Other places use all tiles causing desyncs.
8510 * As the newgrf specs define population to be zero for non-north tiles, we just disable the offending house.
8511 * If you want to allow non-zero populations somewhen, make sure to sum the population of all tiles in all places. */
8512 if (((hs
->building_flags
& BUILDING_HAS_2_TILES
) != 0 && next1
->population
!= 0) ||
8513 ((hs
->building_flags
& BUILDING_HAS_4_TILES
) != 0 && (next2
->population
!= 0 || next3
->population
!= 0))) {
8514 hs
->enabled
= false;
8515 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
);
8519 /* Substitute type is also used for override, and having an override with a different size causes crashes.
8520 * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/
8521 if (filename
!= NULL
&& (hs
->building_flags
& BUILDING_HAS_1_TILE
) != (HouseSpec::Get(hs
->grf_prop
.subst_id
)->building_flags
& BUILDING_HAS_1_TILE
)) {
8522 hs
->enabled
= false;
8523 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
);
8527 /* Make sure that additional parts of multitile houses are not available. */
8528 if ((hs
->building_flags
& BUILDING_HAS_1_TILE
) == 0 && (hs
->building_availability
& HZ_ZONALL
) != 0 && (hs
->building_availability
& HZ_CLIMALL
) != 0) {
8529 hs
->enabled
= false;
8530 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
);
8538 * Make sure there is at least one house available in the year 0 for the given
8539 * climate / housezone combination.
8540 * @param bitmask The climate and housezone to check for. Exactly one climate
8541 * bit and one housezone bit should be set.
8543 static void EnsureEarlyHouse(HouseZones bitmask
)
8545 std::map
<int32
, Year
> min_year
;
8547 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8548 HouseSpec
*hs
= HouseSpec::Get(i
);
8549 if (hs
== NULL
|| !hs
->enabled
) continue;
8550 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
8552 int32 grfid
= (hs
->grf_prop
.grffile
!= nullptr) ? hs
->grf_prop
.grffile
->grfid
: -1;
8553 min_year
[grfid
] = MAX_YEAR
;
8556 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8557 HouseSpec
*hs
= HouseSpec::Get(i
);
8558 if (hs
== NULL
|| !hs
->enabled
) continue;
8559 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
8561 int32 grfid
= (hs
->grf_prop
.grffile
!= nullptr) ? hs
->grf_prop
.grffile
->grfid
: -1;
8562 if (hs
->min_year
< min_year
[grfid
]) min_year
[grfid
] = hs
->min_year
;
8565 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8566 HouseSpec
*hs
= HouseSpec::Get(i
);
8567 if (hs
== NULL
|| !hs
->enabled
) continue;
8568 if ((hs
->building_availability
& bitmask
) != bitmask
) continue;
8570 int32 grfid
= (hs
->grf_prop
.grffile
!= nullptr) ? hs
->grf_prop
.grffile
->grfid
: -1;
8571 if (hs
->min_year
== min_year
[grfid
]) hs
->min_year
= 0;
8576 * Add all new houses to the house array. House properties can be set at any
8577 * time in the GRF file, so we can only add a house spec to the house array
8578 * after the file has finished loading. We also need to check the dates, due to
8579 * the TTDPatch behaviour described below that we need to emulate.
8581 static void FinaliseHouseArray()
8583 /* If there are no houses with start dates before 1930, then all houses
8584 * with start dates of 1930 have them reset to 0. This is in order to be
8585 * compatible with TTDPatch, where if no houses have start dates before
8586 * 1930 and the date is before 1930, the game pretends that this is 1930.
8587 * If there have been any houses defined with start dates before 1930 then
8588 * the dates are left alone.
8589 * On the other hand, why 1930? Just 'fix' the houses with the lowest
8590 * minimum introduction date to 0.
8592 const GRFFile
* const *end
= _grf_files
.End();
8593 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8594 HouseSpec
**&housespec
= (*file
)->housespec
;
8595 if (housespec
== NULL
) continue;
8597 for (int i
= 0; i
< NUM_HOUSES_PER_GRF
; i
++) {
8598 HouseSpec
*hs
= housespec
[i
];
8600 if (hs
== NULL
) continue;
8602 const HouseSpec
*next1
= (i
+ 1 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 1] : NULL
);
8603 const HouseSpec
*next2
= (i
+ 2 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 2] : NULL
);
8604 const HouseSpec
*next3
= (i
+ 3 < NUM_HOUSES_PER_GRF
? housespec
[i
+ 3] : NULL
);
8606 if (!IsHouseSpecValid(hs
, next1
, next2
, next3
, (*file
)->filename
)) continue;
8608 _house_mngr
.SetEntitySpec(hs
);
8612 for (int i
= 0; i
< NUM_HOUSES
; i
++) {
8613 HouseSpec
*hs
= HouseSpec::Get(i
);
8614 const HouseSpec
*next1
= (i
+ 1 < NUM_HOUSES
? HouseSpec::Get(i
+ 1) : NULL
);
8615 const HouseSpec
*next2
= (i
+ 2 < NUM_HOUSES
? HouseSpec::Get(i
+ 2) : NULL
);
8616 const HouseSpec
*next3
= (i
+ 3 < NUM_HOUSES
? HouseSpec::Get(i
+ 3) : NULL
);
8618 /* We need to check all houses again to we are sure that multitile houses
8619 * did get consecutive IDs and none of the parts are missing. */
8620 if (!IsHouseSpecValid(hs
, next1
, next2
, next3
, NULL
)) {
8621 /* GetHouseNorthPart checks 3 houses that are directly before
8622 * it in the house pool. If any of those houses have multi-tile
8623 * flags set it assumes it's part of a multitile house. Since
8624 * we can have invalid houses in the pool marked as disabled, we
8625 * don't want to have them influencing valid tiles. As such set
8626 * building_flags to zero here to make sure any house following
8627 * this one in the pool is properly handled as 1x1 house. */
8628 hs
->building_flags
= TILE_NO_FLAG
;
8632 HouseZones climate_mask
= (HouseZones
)(1 << (_settings_game
.game_creation
.landscape
+ 12));
8633 EnsureEarlyHouse(HZ_ZON1
| climate_mask
);
8634 EnsureEarlyHouse(HZ_ZON2
| climate_mask
);
8635 EnsureEarlyHouse(HZ_ZON3
| climate_mask
);
8636 EnsureEarlyHouse(HZ_ZON4
| climate_mask
);
8637 EnsureEarlyHouse(HZ_ZON5
| climate_mask
);
8639 if (_settings_game
.game_creation
.landscape
== LT_ARCTIC
) {
8640 EnsureEarlyHouse(HZ_ZON1
| HZ_SUBARTC_ABOVE
);
8641 EnsureEarlyHouse(HZ_ZON2
| HZ_SUBARTC_ABOVE
);
8642 EnsureEarlyHouse(HZ_ZON3
| HZ_SUBARTC_ABOVE
);
8643 EnsureEarlyHouse(HZ_ZON4
| HZ_SUBARTC_ABOVE
);
8644 EnsureEarlyHouse(HZ_ZON5
| HZ_SUBARTC_ABOVE
);
8649 * Add all new industries to the industry array. Industry properties can be set at any
8650 * time in the GRF file, so we can only add a industry spec to the industry array
8651 * after the file has finished loading.
8653 static void FinaliseIndustriesArray()
8655 const GRFFile
* const *end
= _grf_files
.End();
8656 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8657 IndustrySpec
**&industryspec
= (*file
)->industryspec
;
8658 IndustryTileSpec
**&indtspec
= (*file
)->indtspec
;
8659 if (industryspec
!= NULL
) {
8660 for (int i
= 0; i
< NUM_INDUSTRYTYPES_PER_GRF
; i
++) {
8661 IndustrySpec
*indsp
= industryspec
[i
];
8663 if (indsp
!= NULL
&& indsp
->enabled
) {
8665 /* process the conversion of text at the end, so to be sure everything will be fine
8666 * and available. Check if it does not return undefind marker, which is a very good sign of a
8667 * substitute industry who has not changed the string been examined, thus using it as such */
8668 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->name
);
8669 if (strid
!= STR_UNDEFINED
) indsp
->name
= strid
;
8671 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->closure_text
);
8672 if (strid
!= STR_UNDEFINED
) indsp
->closure_text
= strid
;
8674 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->production_up_text
);
8675 if (strid
!= STR_UNDEFINED
) indsp
->production_up_text
= strid
;
8677 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->production_down_text
);
8678 if (strid
!= STR_UNDEFINED
) indsp
->production_down_text
= strid
;
8680 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->new_industry_text
);
8681 if (strid
!= STR_UNDEFINED
) indsp
->new_industry_text
= strid
;
8683 if (indsp
->station_name
!= STR_NULL
) {
8684 /* STR_NULL (0) can be set by grf. It has a meaning regarding assignation of the
8685 * station's name. Don't want to lose the value, therefore, do not process. */
8686 strid
= GetGRFStringID(indsp
->grf_prop
.grffile
->grfid
, indsp
->station_name
);
8687 if (strid
!= STR_UNDEFINED
) indsp
->station_name
= strid
;
8690 _industry_mngr
.SetEntitySpec(indsp
);
8691 _loaded_newgrf_features
.has_newindustries
= true;
8696 if (indtspec
!= NULL
) {
8697 for (int i
= 0; i
< NUM_INDUSTRYTILES_PER_GRF
; i
++) {
8698 IndustryTileSpec
*indtsp
= indtspec
[i
];
8699 if (indtsp
!= NULL
) {
8700 _industile_mngr
.SetEntitySpec(indtsp
);
8706 for (uint j
= 0; j
< NUM_INDUSTRYTYPES
; j
++) {
8707 IndustrySpec
*indsp
= &_industry_specs
[j
];
8708 if (indsp
->enabled
&& indsp
->grf_prop
.grffile
!= NULL
) {
8709 for (uint i
= 0; i
< 3; i
++) {
8710 indsp
->conflicting
[i
] = MapNewGRFIndustryType(indsp
->conflicting
[i
], indsp
->grf_prop
.grffile
->grfid
);
8713 if (!indsp
->enabled
) {
8714 indsp
->name
= STR_NEWGRF_INVALID_INDUSTRYTYPE
;
8720 * Add all new objects to the object array. Object properties can be set at any
8721 * time in the GRF file, so we can only add an object spec to the object array
8722 * after the file has finished loading.
8724 static void FinaliseObjectsArray()
8726 const GRFFile
* const *end
= _grf_files
.End();
8727 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8728 ObjectSpec
**&objectspec
= (*file
)->objectspec
;
8729 if (objectspec
!= NULL
) {
8730 for (int i
= 0; i
< NUM_OBJECTS_PER_GRF
; i
++) {
8731 if (objectspec
[i
] != NULL
&& objectspec
[i
]->grf_prop
.grffile
!= NULL
&& objectspec
[i
]->enabled
) {
8732 _object_mngr
.SetEntitySpec(objectspec
[i
]);
8740 * Add all new airports to the airport array. Airport properties can be set at any
8741 * time in the GRF file, so we can only add a airport spec to the airport array
8742 * after the file has finished loading.
8744 static void FinaliseAirportsArray()
8746 const GRFFile
* const *end
= _grf_files
.End();
8747 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
8748 AirportSpec
**&airportspec
= (*file
)->airportspec
;
8749 if (airportspec
!= NULL
) {
8750 for (int i
= 0; i
< NUM_AIRPORTS_PER_GRF
; i
++) {
8751 if (airportspec
[i
] != NULL
&& airportspec
[i
]->enabled
) {
8752 _airport_mngr
.SetEntitySpec(airportspec
[i
]);
8757 AirportTileSpec
**&airporttilespec
= (*file
)->airtspec
;
8758 if (airporttilespec
!= NULL
) {
8759 for (uint i
= 0; i
< NUM_AIRPORTTILES_PER_GRF
; i
++) {
8760 if (airporttilespec
[i
] != NULL
&& airporttilespec
[i
]->enabled
) {
8761 _airporttile_mngr
.SetEntitySpec(airporttilespec
[i
]);
8768 /* Here we perform initial decoding of some special sprites (as are they
8769 * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
8770 * partial implementation yet).
8771 * XXX: We consider GRF files trusted. It would be trivial to exploit OTTD by
8772 * a crafted invalid GRF file. We should tell that to the user somehow, or
8773 * better make this more robust in the future. */
8774 static void DecodeSpecialSprite(byte
*buf
, uint num
, GrfLoadingStage stage
)
8776 /* XXX: There is a difference between staged loading in TTDPatch and
8777 * here. In TTDPatch, for some reason actions 1 and 2 are carried out
8778 * during stage 1, whilst action 3 is carried out during stage 2 (to
8779 * "resolve" cargo IDs... wtf). This is a little problem, because cargo
8780 * IDs are valid only within a given set (action 1) block, and may be
8781 * overwritten after action 3 associates them. But overwriting happens
8782 * in an earlier stage than associating, so... We just process actions
8783 * 1 and 2 in stage 2 now, let's hope that won't get us into problems.
8785 * We need a pre-stage to set up GOTO labels of Action 0x10 because the grf
8786 * is not in memory and scanning the file every time would be too expensive.
8787 * In other stages we skip action 0x10 since it's already dealt with. */
8788 static const SpecialSpriteHandler handlers
[][GLS_END
] = {
8789 /* 0x00 */ { NULL
, SafeChangeInfo
, NULL
, NULL
, ReserveChangeInfo
, FeatureChangeInfo
, },
8790 /* 0x01 */ { SkipAct1
, SkipAct1
, SkipAct1
, SkipAct1
, SkipAct1
, NewSpriteSet
, },
8791 /* 0x02 */ { NULL
, NULL
, NULL
, NULL
, NULL
, NewSpriteGroup
, },
8792 /* 0x03 */ { NULL
, GRFUnsafe
, NULL
, NULL
, NULL
, FeatureMapSpriteGroup
, },
8793 /* 0x04 */ { NULL
, NULL
, NULL
, NULL
, NULL
, FeatureNewName
, },
8794 /* 0x05 */ { SkipAct5
, SkipAct5
, SkipAct5
, SkipAct5
, SkipAct5
, GraphicsNew
, },
8795 /* 0x06 */ { NULL
, NULL
, NULL
, CfgApply
, CfgApply
, CfgApply
, },
8796 /* 0x07 */ { NULL
, NULL
, NULL
, NULL
, SkipIf
, SkipIf
, },
8797 /* 0x08 */ { ScanInfo
, NULL
, NULL
, GRFInfo
, GRFInfo
, GRFInfo
, },
8798 /* 0x09 */ { NULL
, NULL
, NULL
, SkipIf
, SkipIf
, SkipIf
, },
8799 /* 0x0A */ { SkipActA
, SkipActA
, SkipActA
, SkipActA
, SkipActA
, SpriteReplace
, },
8800 /* 0x0B */ { NULL
, NULL
, NULL
, GRFLoadError
, GRFLoadError
, GRFLoadError
, },
8801 /* 0x0C */ { NULL
, NULL
, NULL
, GRFComment
, NULL
, GRFComment
, },
8802 /* 0x0D */ { NULL
, SafeParamSet
, NULL
, ParamSet
, ParamSet
, ParamSet
, },
8803 /* 0x0E */ { NULL
, SafeGRFInhibit
, NULL
, GRFInhibit
, GRFInhibit
, GRFInhibit
, },
8804 /* 0x0F */ { NULL
, GRFUnsafe
, NULL
, FeatureTownName
, NULL
, NULL
, },
8805 /* 0x10 */ { NULL
, NULL
, DefineGotoLabel
, NULL
, NULL
, NULL
, },
8806 /* 0x11 */ { SkipAct11
,GRFUnsafe
, SkipAct11
, GRFSound
, SkipAct11
, GRFSound
, },
8807 /* 0x12 */ { SkipAct12
, SkipAct12
, SkipAct12
, SkipAct12
, SkipAct12
, LoadFontGlyph
, },
8808 /* 0x13 */ { NULL
, NULL
, NULL
, NULL
, NULL
, TranslateGRFStrings
, },
8809 /* 0x14 */ { StaticGRFInfo
, NULL
, NULL
, NULL
, NULL
, NULL
, },
8812 GRFLocation
location(_cur
.grfconfig
->ident
.grfid
, _cur
.nfo_line
);
8814 GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.find(location
);
8815 if (it
== _grf_line_to_action6_sprite_override
.end()) {
8816 /* No preloaded sprite to work with; read the
8817 * pseudo sprite content. */
8818 FioReadBlock(buf
, num
);
8820 /* Use the preloaded sprite data. */
8822 grfmsg(7, "DecodeSpecialSprite: Using preloaded pseudo sprite data");
8824 /* Skip the real (original) content of this action. */
8825 FioSeekTo(num
, SEEK_CUR
);
8828 ByteReader
br(buf
, buf
+ num
);
8829 ByteReader
*bufp
= &br
;
8832 byte action
= bufp
->ReadByte();
8834 if (action
== 0xFF) {
8835 grfmsg(2, "DecodeSpecialSprite: Unexpected data block, skipping");
8836 } else if (action
== 0xFE) {
8837 grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping");
8838 } else if (action
>= lengthof(handlers
)) {
8839 grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action
);
8840 } else if (handlers
[action
][stage
] == NULL
) {
8841 grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action
, stage
);
8843 grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action
, stage
);
8844 handlers
[action
][stage
](bufp
);
8847 grfmsg(1, "DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8848 DisableGrf(STR_NEWGRF_ERROR_READ_BOUNDS
);
8853 /** Signature of a container version 2 GRF. */
8854 extern const byte _grf_cont_v2_sig
[8] = {'G', 'R', 'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8857 * Get the container version of the currently opened GRF file.
8858 * @return Container version of the GRF file or 0 if the file is corrupt/no GRF file.
8860 byte
GetGRFContainerVersion()
8862 size_t pos
= FioGetPos();
8864 if (FioReadWord() == 0) {
8865 /* Check for GRF container version 2, which is identified by the bytes
8866 * '47 52 46 82 0D 0A 1A 0A' at the start of the file. */
8867 for (uint i
= 0; i
< lengthof(_grf_cont_v2_sig
); i
++) {
8868 if (FioReadByte() != _grf_cont_v2_sig
[i
]) return 0; // Invalid format
8874 /* Container version 1 has no header, rewind to start. */
8875 FioSeekTo(pos
, SEEK_SET
);
8880 * Load a particular NewGRF.
8881 * @param config The configuration of the to be loaded NewGRF.
8882 * @param file_index The Fio index of the first NewGRF to load.
8883 * @param stage The loading stage of the NewGRF.
8884 * @param subdir The sub directory to find the NewGRF in.
8886 void LoadNewGRFFile(GRFConfig
*config
, uint file_index
, GrfLoadingStage stage
, Subdirectory subdir
)
8888 const char *filename
= config
->filename
;
8890 /* A .grf file is activated only if it was active when the game was
8891 * started. If a game is loaded, only its active .grfs will be
8892 * reactivated, unless "loadallgraphics on" is used. A .grf file is
8893 * considered active if its action 8 has been processed, i.e. its
8894 * action 8 hasn't been skipped using an action 7.
8896 * During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
8897 * carried out. All others are ignored, because they only need to be
8898 * processed once at initialization. */
8899 if (stage
!= GLS_FILESCAN
&& stage
!= GLS_SAFETYSCAN
&& stage
!= GLS_LABELSCAN
) {
8900 _cur
.grffile
= GetFileByFilename(filename
);
8901 if (_cur
.grffile
== NULL
) usererror("File '%s' lost in cache.\n", filename
);
8902 if (stage
== GLS_RESERVE
&& config
->status
!= GCS_INITIALISED
) return;
8903 if (stage
== GLS_ACTIVATION
&& !HasBit(config
->flags
, GCF_RESERVED
)) return;
8906 if (file_index
>= MAX_FILE_SLOTS
) {
8907 DEBUG(grf
, 0, "'%s' is not loaded as the maximum number of file slots has been reached", filename
);
8908 config
->status
= GCS_DISABLED
;
8909 config
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED
);
8913 FioOpenFile(file_index
, filename
, subdir
);
8914 _cur
.file_index
= file_index
; // XXX
8915 _palette_remap_grf
[_cur
.file_index
] = (config
->palette
& GRFP_USE_MASK
);
8917 _cur
.grfconfig
= config
;
8919 DEBUG(grf
, 2, "LoadNewGRFFile: Reading NewGRF-file '%s'", filename
);
8921 _cur
.grf_container_ver
= GetGRFContainerVersion();
8922 if (_cur
.grf_container_ver
== 0) {
8923 DEBUG(grf
, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8927 if (stage
== GLS_INIT
|| stage
== GLS_ACTIVATION
) {
8928 /* We need the sprite offsets in the init stage for NewGRF sounds
8929 * and in the activation stage for real sprites. */
8930 ReadGRFSpriteOffsets(_cur
.grf_container_ver
);
8932 /* Skip sprite section offset if present. */
8933 if (_cur
.grf_container_ver
>= 2) FioReadDword();
8936 if (_cur
.grf_container_ver
>= 2) {
8937 /* Read compression value. */
8938 byte compression
= FioReadByte();
8939 if (compression
!= 0) {
8940 DEBUG(grf
, 7, "LoadNewGRFFile: Unsupported compression format");
8945 /* Skip the first sprite; we don't care about how many sprites this
8946 * does contain; newest TTDPatches and George's longvehicles don't
8947 * neither, apparently. */
8948 uint32 num
= _cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord();
8949 if (num
== 4 && FioReadByte() == 0xFF) {
8952 DEBUG(grf
, 7, "LoadNewGRFFile: Custom .grf has invalid format");
8956 _cur
.ClearDataForNextFile();
8958 ReusableBuffer
<byte
> buf
;
8960 while ((num
= (_cur
.grf_container_ver
>= 2 ? FioReadDword() : FioReadWord())) != 0) {
8961 byte type
= FioReadByte();
8965 if (_cur
.skip_sprites
== 0) {
8966 DecodeSpecialSprite(buf
.Allocate(num
), num
, stage
);
8968 /* Stop all processing if we are to skip the remaining sprites */
8969 if (_cur
.skip_sprites
== -1) break;
8976 if (_cur
.skip_sprites
== 0) {
8977 grfmsg(0, "LoadNewGRFFile: Unexpected sprite, disabling");
8978 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE
);
8982 if (_cur
.grf_container_ver
>= 2 && type
== 0xFD) {
8983 /* Reference to data section. Container version >= 2 only. */
8987 SkipSpriteData(type
, num
- 8);
8991 if (_cur
.skip_sprites
> 0) _cur
.skip_sprites
--;
8996 * Relocates the old shore sprites at new positions.
8998 * 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)
8999 * 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)
9000 * 3. If a newgrf replaces shore sprites by Action5 any shore replacement by ActionA has no effect. (SHORE_REPLACE_ACTION_5)
9002 static void ActivateOldShore()
9004 /* Use default graphics, if no shore sprites were loaded.
9005 * Should not happen, as the base set's extra grf should include some. */
9006 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_NONE
) _loaded_newgrf_features
.shore
= SHORE_REPLACE_ACTION_A
;
9008 if (_loaded_newgrf_features
.shore
!= SHORE_REPLACE_ACTION_5
) {
9009 DupSprite(SPR_ORIGINALSHORE_START
+ 1, SPR_SHORE_BASE
+ 1); // SLOPE_W
9010 DupSprite(SPR_ORIGINALSHORE_START
+ 2, SPR_SHORE_BASE
+ 2); // SLOPE_S
9011 DupSprite(SPR_ORIGINALSHORE_START
+ 6, SPR_SHORE_BASE
+ 3); // SLOPE_SW
9012 DupSprite(SPR_ORIGINALSHORE_START
+ 0, SPR_SHORE_BASE
+ 4); // SLOPE_E
9013 DupSprite(SPR_ORIGINALSHORE_START
+ 4, SPR_SHORE_BASE
+ 6); // SLOPE_SE
9014 DupSprite(SPR_ORIGINALSHORE_START
+ 3, SPR_SHORE_BASE
+ 8); // SLOPE_N
9015 DupSprite(SPR_ORIGINALSHORE_START
+ 7, SPR_SHORE_BASE
+ 9); // SLOPE_NW
9016 DupSprite(SPR_ORIGINALSHORE_START
+ 5, SPR_SHORE_BASE
+ 12); // SLOPE_NE
9019 if (_loaded_newgrf_features
.shore
== SHORE_REPLACE_ACTION_A
) {
9020 DupSprite(SPR_FLAT_GRASS_TILE
+ 16, SPR_SHORE_BASE
+ 0); // SLOPE_STEEP_S
9021 DupSprite(SPR_FLAT_GRASS_TILE
+ 17, SPR_SHORE_BASE
+ 5); // SLOPE_STEEP_W
9022 DupSprite(SPR_FLAT_GRASS_TILE
+ 7, SPR_SHORE_BASE
+ 7); // SLOPE_WSE
9023 DupSprite(SPR_FLAT_GRASS_TILE
+ 15, SPR_SHORE_BASE
+ 10); // SLOPE_STEEP_N
9024 DupSprite(SPR_FLAT_GRASS_TILE
+ 11, SPR_SHORE_BASE
+ 11); // SLOPE_NWS
9025 DupSprite(SPR_FLAT_GRASS_TILE
+ 13, SPR_SHORE_BASE
+ 13); // SLOPE_ENW
9026 DupSprite(SPR_FLAT_GRASS_TILE
+ 14, SPR_SHORE_BASE
+ 14); // SLOPE_SEN
9027 DupSprite(SPR_FLAT_GRASS_TILE
+ 18, SPR_SHORE_BASE
+ 15); // SLOPE_STEEP_E
9029 /* XXX - SLOPE_EW, SLOPE_NS are currently not used.
9030 * If they would be used somewhen, then these grass tiles will most like not look as needed */
9031 DupSprite(SPR_FLAT_GRASS_TILE
+ 5, SPR_SHORE_BASE
+ 16); // SLOPE_EW
9032 DupSprite(SPR_FLAT_GRASS_TILE
+ 10, SPR_SHORE_BASE
+ 17); // SLOPE_NS
9037 * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them
9039 static void FinalisePriceBaseMultipliers()
9041 extern const PriceBaseSpec _price_base_specs
[];
9042 /** Features, to which '_grf_id_overrides' applies. Currently vehicle features only. */
9043 static const uint32 override_features
= (1 << GSF_TRAINS
) | (1 << GSF_ROADVEHICLES
) | (1 << GSF_SHIPS
) | (1 << GSF_AIRCRAFT
);
9045 /* Evaluate grf overrides */
9046 int num_grfs
= _grf_files
.Length();
9047 int *grf_overrides
= AllocaM(int, num_grfs
);
9048 for (int i
= 0; i
< num_grfs
; i
++) {
9049 grf_overrides
[i
] = -1;
9051 GRFFile
*source
= _grf_files
[i
];
9052 uint32 override
= _grf_id_overrides
[source
->grfid
];
9053 if (override
== 0) continue;
9055 GRFFile
*dest
= GetFileByGRFID(override
);
9056 if (dest
== NULL
) continue;
9058 grf_overrides
[i
] = _grf_files
.FindIndex(dest
);
9059 assert(grf_overrides
[i
] >= 0);
9062 /* Override features and price base multipliers of earlier loaded grfs */
9063 for (int i
= 0; i
< num_grfs
; i
++) {
9064 if (grf_overrides
[i
] < 0 || grf_overrides
[i
] >= i
) continue;
9065 GRFFile
*source
= _grf_files
[i
];
9066 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9068 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9069 source
->grf_features
|= features
;
9070 dest
->grf_features
|= features
;
9072 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9073 /* No price defined -> nothing to do */
9074 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
) || source
->price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) continue;
9075 DEBUG(grf
, 3, "'%s' overrides price base multiplier %d of '%s'", source
->filename
, p
, dest
->filename
);
9076 dest
->price_base_multipliers
[p
] = source
->price_base_multipliers
[p
];
9080 /* Propagate features and price base multipliers of afterwards loaded grfs, if none is present yet */
9081 for (int i
= num_grfs
- 1; i
>= 0; i
--) {
9082 if (grf_overrides
[i
] < 0 || grf_overrides
[i
] <= i
) continue;
9083 GRFFile
*source
= _grf_files
[i
];
9084 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9086 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9087 source
->grf_features
|= features
;
9088 dest
->grf_features
|= features
;
9090 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9091 /* Already a price defined -> nothing to do */
9092 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
) || dest
->price_base_multipliers
[p
] != INVALID_PRICE_MODIFIER
) continue;
9093 DEBUG(grf
, 3, "Price base multiplier %d from '%s' propagated to '%s'", p
, source
->filename
, dest
->filename
);
9094 dest
->price_base_multipliers
[p
] = source
->price_base_multipliers
[p
];
9098 /* The 'master grf' now have the correct multipliers. Assign them to the 'addon grfs' to make everything consistent. */
9099 for (int i
= 0; i
< num_grfs
; i
++) {
9100 if (grf_overrides
[i
] < 0) continue;
9101 GRFFile
*source
= _grf_files
[i
];
9102 GRFFile
*dest
= _grf_files
[grf_overrides
[i
]];
9104 uint32 features
= (source
->grf_features
| dest
->grf_features
) & override_features
;
9105 source
->grf_features
|= features
;
9106 dest
->grf_features
|= features
;
9108 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9109 if (!HasBit(features
, _price_base_specs
[p
].grf_feature
)) continue;
9110 if (source
->price_base_multipliers
[p
] != dest
->price_base_multipliers
[p
]) {
9111 DEBUG(grf
, 3, "Price base multiplier %d from '%s' propagated to '%s'", p
, dest
->filename
, source
->filename
);
9113 source
->price_base_multipliers
[p
] = dest
->price_base_multipliers
[p
];
9117 /* Apply fallback prices for grf version < 8 */
9118 const GRFFile
* const *end
= _grf_files
.End();
9119 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
9120 if ((*file
)->grf_version
>= 8) continue;
9121 PriceMultipliers
&price_base_multipliers
= (*file
)->price_base_multipliers
;
9122 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9123 Price fallback_price
= _price_base_specs
[p
].fallback_price
;
9124 if (fallback_price
!= INVALID_PRICE
&& price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) {
9125 /* No price multiplier has been set.
9126 * So copy the multiplier from the fallback price, maybe a multiplier was set there. */
9127 price_base_multipliers
[p
] = price_base_multipliers
[fallback_price
];
9132 /* Decide local/global scope of price base multipliers */
9133 for (GRFFile
**file
= _grf_files
.Begin(); file
!= end
; file
++) {
9134 PriceMultipliers
&price_base_multipliers
= (*file
)->price_base_multipliers
;
9135 for (Price p
= PR_BEGIN
; p
< PR_END
; p
++) {
9136 if (price_base_multipliers
[p
] == INVALID_PRICE_MODIFIER
) {
9137 /* No multiplier was set; set it to a neutral value */
9138 price_base_multipliers
[p
] = 0;
9140 if (!HasBit((*file
)->grf_features
, _price_base_specs
[p
].grf_feature
)) {
9141 /* The grf does not define any objects of the feature,
9142 * so it must be a difficulty setting. Apply it globally */
9143 DEBUG(grf
, 3, "'%s' sets global price base multiplier %d", (*file
)->filename
, p
);
9144 SetPriceBaseMultiplier(p
, price_base_multipliers
[p
]);
9145 price_base_multipliers
[p
] = 0;
9147 DEBUG(grf
, 3, "'%s' sets local price base multiplier %d", (*file
)->filename
, p
);
9154 extern void InitGRFTownGeneratorNames();
9156 /** Finish loading NewGRFs and execute needed post-processing */
9157 static void AfterLoadGRFs()
9159 for (StringIDMapping
*it
= _string_to_grf_mapping
.Begin(); it
!= _string_to_grf_mapping
.End(); it
++) {
9160 *it
->target
= MapGRFStringID(it
->grfid
, it
->source
);
9162 _string_to_grf_mapping
.Clear();
9164 /* Free the action 6 override sprites. */
9165 for (GRFLineToSpriteOverride::iterator it
= _grf_line_to_action6_sprite_override
.begin(); it
!= _grf_line_to_action6_sprite_override
.end(); it
++) {
9168 _grf_line_to_action6_sprite_override
.clear();
9170 /* Polish cargoes */
9171 FinaliseCargoArray();
9173 /* Pre-calculate all refit masks after loading GRF files. */
9174 CalculateRefitMasks();
9176 /* Polish engines */
9177 FinaliseEngineArray();
9179 /* Set the actually used Canal properties */
9182 /* Add all new houses to the house array. */
9183 FinaliseHouseArray();
9185 /* Add all new industries to the industry array. */
9186 FinaliseIndustriesArray();
9188 /* Add all new objects to the object array. */
9189 FinaliseObjectsArray();
9191 InitializeSortedCargoSpecs();
9193 /* Sort the list of industry types. */
9194 SortIndustryTypes();
9196 /* Create dynamic list of industry legends for smallmap_gui.cpp */
9197 BuildIndustriesLegend();
9199 /* Build the routemap legend, based on the available cargos */
9200 BuildLinkStatsLegend();
9202 /* Add all new airports to the airports array. */
9203 FinaliseAirportsArray();
9206 /* Update the townname generators list */
9207 InitGRFTownGeneratorNames();
9209 /* Run all queued vehicle list order changes */
9210 CommitVehicleListOrderChanges();
9212 /* Load old shore sprites in new position, if they were replaced by ActionA */
9215 /* Set up custom rail types */
9219 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_ROAD
) {
9220 if (_gted
[e
->index
].rv_max_speed
!= 0) {
9221 /* Set RV maximum speed from the mph/0.8 unit value */
9222 e
->u
.road
.max_speed
= _gted
[e
->index
].rv_max_speed
* 4;
9226 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_TRAIN
) {
9227 RailType railtype
= GetRailTypeByLabel(_gted
[e
->index
].railtypelabel
);
9228 if (railtype
== INVALID_RAILTYPE
) {
9229 /* Rail type is not available, so disable this engine */
9230 e
->info
.climates
= 0;
9232 e
->u
.rail
.railtype
= railtype
;
9236 SetYearEngineAgingStops();
9238 FinalisePriceBaseMultipliers();
9240 /* Deallocate temporary loading data */
9242 _grm_sprites
.clear();
9246 * Load all the NewGRFs.
9247 * @param load_index The offset for the first sprite to add.
9248 * @param file_index The Fio index of the first NewGRF to load.
9249 * @param num_baseset Number of NewGRFs at the front of the list to look up in the baseset dir instead of the newgrf dir.
9251 void LoadNewGRF(uint load_index
, uint file_index
, uint num_baseset
)
9253 /* In case of networking we need to "sync" the start values
9254 * so all NewGRFs are loaded equally. For this we use the
9255 * start date of the game and we set the counters, etc. to
9256 * 0 so they're the same too. */
9258 Year year
= _cur_year
;
9259 DateFract date_fract
= _date_fract
;
9260 uint16 tick_counter
= _tick_counter
;
9261 byte display_opt
= _display_opt
;
9264 _cur_year
= _settings_game
.game_creation
.starting_year
;
9265 _date
= ConvertYMDToDate(_cur_year
, 0, 1);
9271 InitializeGRFSpecial();
9276 * Reset the status of all files, so we can 'retry' to load them.
9277 * This is needed when one for example rearranges the NewGRFs in-game
9278 * and a previously disabled NewGRF becomes useable. If it would not
9279 * be reset, the NewGRF would remain disabled even though it should
9280 * have been enabled.
9282 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9283 if (c
->status
!= GCS_NOT_FOUND
) c
->status
= GCS_UNKNOWN
;
9286 _cur
.spriteid
= load_index
;
9288 /* Load newgrf sprites
9289 * in each loading stage, (try to) open each file specified in the config
9290 * and load information from it. */
9291 for (GrfLoadingStage stage
= GLS_LABELSCAN
; stage
<= GLS_ACTIVATION
; stage
++) {
9292 /* Set activated grfs back to will-be-activated between reservation- and activation-stage.
9293 * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */
9294 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9295 if (c
->status
== GCS_ACTIVATED
) c
->status
= GCS_INITIALISED
;
9298 if (stage
== GLS_RESERVE
) {
9299 static const uint32 overrides
[][2] = {
9300 { 0x44442202, 0x44440111 }, // UKRS addons modifies UKRS
9301 { 0x6D620402, 0x6D620401 }, // DBSetXL ECS extension modifies DBSetXL
9302 { 0x4D656f20, 0x4D656F17 }, // LV4cut modifies LV4
9304 for (size_t i
= 0; i
< lengthof(overrides
); i
++) {
9305 SetNewGRFOverride(BSWAP32(overrides
[i
][0]), BSWAP32(overrides
[i
][1]));
9309 uint slot
= file_index
;
9310 uint num_non_static
= 0;
9313 for (GRFConfig
*c
= _grfconfig
; c
!= NULL
; c
= c
->next
) {
9314 if (c
->status
== GCS_DISABLED
|| c
->status
== GCS_NOT_FOUND
) continue;
9315 if (stage
> GLS_INIT
&& HasBit(c
->flags
, GCF_INIT_ONLY
)) continue;
9317 Subdirectory subdir
= slot
< file_index
+ num_baseset
? BASESET_DIR
: NEWGRF_DIR
;
9318 if (!FioCheckFileExists(c
->filename
, subdir
)) {
9319 DEBUG(grf
, 0, "NewGRF file is missing '%s'; disabling", c
->filename
);
9320 c
->status
= GCS_NOT_FOUND
;
9324 if (stage
== GLS_LABELSCAN
) InitNewGRFFile(c
);
9326 if (!HasBit(c
->flags
, GCF_STATIC
) && !HasBit(c
->flags
, GCF_SYSTEM
)) {
9327 if (slot
== MAX_FILE_SLOTS
) {
9328 DEBUG(grf
, 0, "'%s' is not loaded as the maximum number of non-static GRFs has been reached", c
->filename
);
9329 c
->status
= GCS_DISABLED
;
9330 c
->error
= new GRFError(STR_NEWGRF_ERROR_MSG_FATAL
, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED
);
9335 LoadNewGRFFile(c
, slot
++, stage
, subdir
);
9336 if (stage
== GLS_RESERVE
) {
9337 SetBit(c
->flags
, GCF_RESERVED
);
9338 } else if (stage
== GLS_ACTIVATION
) {
9339 ClrBit(c
->flags
, GCF_RESERVED
);
9340 assert(GetFileByGRFID(c
->ident
.grfid
) == _cur
.grffile
);
9341 ClearTemporaryNewGRFData(_cur
.grffile
);
9342 BuildCargoTranslationMap();
9343 DEBUG(sprite
, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur
.spriteid
);
9344 } else if (stage
== GLS_INIT
&& HasBit(c
->flags
, GCF_INIT_ONLY
)) {
9345 /* We're not going to activate this, so free whatever data we allocated */
9346 ClearTemporaryNewGRFData(_cur
.grffile
);
9351 /* Pseudo sprite processing is finished; free temporary stuff */
9352 _cur
.ClearDataForNextFile();
9354 /* Call any functions that should be run after GRFs have been loaded. */
9357 /* Now revert back to the original situation */
9360 _date_fract
= date_fract
;
9361 _tick_counter
= tick_counter
;
9362 _display_opt
= display_opt
;
9366 * Returns amount of user selected NewGRFs files.
9368 uint
CountSelectedGRFs(GRFConfig
*grfconf
)
9372 /* Find last entry in the list */
9373 for (const GRFConfig
*list
= grfconf
; list
!= NULL
; list
= list
->next
) {
9374 if (!HasBit(list
->flags
, GCF_STATIC
) && !HasBit(list
->flags
, GCF_SYSTEM
)) i
++;