OpenTTD Source 20260311-master-g511d3794ce
newgrf_act3.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#include "../stdafx.h"
11
12#include "../debug.h"
13#include "../house.h"
14#include "../newgrf_engine.h"
15#include "../newgrf_badge.h"
17#include "../newgrf_cargo.h"
18#include "../newgrf_house.h"
19#include "../newgrf_station.h"
20#include "../industrytype.h"
21#include "../newgrf_canal.h"
23#include "../newgrf_airport.h"
24#include "../newgrf_object.h"
25#include "../error.h"
26#include "../vehicle_base.h"
27#include "../road.h"
28#include "../newgrf_roadstop.h"
29#include "newgrf_bytereader.h"
31#include "newgrf_internal.h"
32
33#include "../safeguards.h"
34
35
36static CargoType TranslateCargo(GrfSpecFeature feature, uint8_t ctype)
37{
38 /* Special cargo types for purchase list and stations */
39 if ((feature == GSF_STATIONS || feature == GSF_ROADSTOPS) && ctype == 0xFE) return CargoGRFFileProps::SG_DEFAULT_NA;
40 if (ctype == 0xFF) return CargoGRFFileProps::SG_PURCHASE;
41
42 auto cargo_list = GetCargoTranslationTable(*_cur_gps.grffile);
43
44 /* Check if the cargo type is out of bounds of the cargo translation table */
45 if (ctype >= cargo_list.size()) {
46 GrfMsg(1, "TranslateCargo: Cargo type {} out of range (max {}), skipping.", ctype, (unsigned int)_cur_gps.grffile->cargo_list.size() - 1);
47 return INVALID_CARGO;
48 }
49
50 /* Look up the cargo label from the translation table */
51 CargoLabel cl = cargo_list[ctype];
52 if (cl == CT_INVALID) {
53 GrfMsg(5, "TranslateCargo: Cargo type {} not available in this climate, skipping.", ctype);
54 return INVALID_CARGO;
55 }
56
57 CargoType cargo_type = GetCargoTypeByLabel(cl);
58 if (!IsValidCargoType(cargo_type)) {
59 GrfMsg(5, "TranslateCargo: Cargo '{:c}{:c}{:c}{:c}' unsupported, skipping.", GB(cl.base(), 24, 8), GB(cl.base(), 16, 8), GB(cl.base(), 8, 8), GB(cl.base(), 0, 8));
60 return INVALID_CARGO;
61 }
62
63 GrfMsg(6, "TranslateCargo: Cargo '{:c}{:c}{:c}{:c}' mapped to cargo type {}.", GB(cl.base(), 24, 8), GB(cl.base(), 16, 8), GB(cl.base(), 8, 8), GB(cl.base(), 0, 8), cargo_type);
64 return cargo_type;
65}
66
67
68static bool IsValidGroupID(uint16_t groupid, std::string_view function)
69{
70 if (groupid > MAX_SPRITEGROUP || _cur_gps.spritegroups[groupid] == nullptr) {
71 GrfMsg(1, "{}: Spritegroup 0x{:04X} out of range or empty, skipping.", function, groupid);
72 return false;
73 }
74
75 return true;
76}
77
78static void VehicleMapSpriteGroup(ByteReader &buf, GrfSpecFeature feature, uint8_t idcount)
79{
80 static std::vector<EngineID> last_engines; // Engine IDs are remembered in case the next action is a wagon override.
81 bool wagover = false;
82
83 /* Test for 'wagon override' flag */
84 if (HasBit(idcount, 7)) {
85 wagover = true;
86 /* Strip off the flag */
87 idcount = GB(idcount, 0, 7);
88
89 if (last_engines.empty()) {
90 GrfMsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
91 return;
92 }
93
94 GrfMsg(6, "VehicleMapSpriteGroup: WagonOverride: {} engines, {} wagons", last_engines.size(), idcount);
95 } else {
96 last_engines.resize(idcount);
97 }
98
99 std::vector<EngineID> engines;
100 engines.reserve(idcount);
101 for (uint i = 0; i < idcount; i++) {
102 Engine *e = GetNewEngine(_cur_gps.grffile, (VehicleType)feature, buf.ReadExtendedByte());
103 if (e == nullptr) {
104 /* No engine could be allocated?!? Deal with it. Okay,
105 * this might look bad. Also make sure this NewGRF
106 * gets disabled, as a half loaded one is bad. */
107 HandleChangeInfoResult("VehicleMapSpriteGroup", CIR_INVALID_ID, feature, 0);
108 return;
109 }
110
111 engines.push_back(e->index);
112 if (!wagover) last_engines[i] = engines[i];
113 }
114
115 uint8_t cidcount = buf.ReadByte();
116 for (uint c = 0; c < cidcount; c++) {
117 uint8_t ctype = buf.ReadByte();
118 uint16_t groupid = buf.ReadWord();
119 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
120
121 GrfMsg(8, "VehicleMapSpriteGroup: * [{}] Cargo type 0x{:X}, group id 0x{:02X}", c, ctype, groupid);
122
123 CargoType cargo_type = TranslateCargo(feature, ctype);
124 if (!IsValidCargoType(cargo_type)) continue;
125
126 for (uint i = 0; i < idcount; i++) {
127 EngineID engine = engines[i];
128
129 GrfMsg(7, "VehicleMapSpriteGroup: [{}] Engine {}...", i, engine);
130
131 if (wagover) {
132 SetWagonOverrideSprites(engine, cargo_type, _cur_gps.spritegroups[groupid], last_engines);
133 } else {
134 SetCustomEngineSprites(engine, cargo_type, _cur_gps.spritegroups[groupid]);
135 }
136 }
137 }
138
139 uint16_t groupid = buf.ReadWord();
140 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
141
142 GrfMsg(8, "-- Default group id 0x{:04X}", groupid);
143
144 for (uint i = 0; i < idcount; i++) {
145 EngineID engine = engines[i];
146
147 if (wagover) {
148 SetWagonOverrideSprites(engine, CargoGRFFileProps::SG_DEFAULT, _cur_gps.spritegroups[groupid], last_engines);
149 } else {
150 SetCustomEngineSprites(engine, CargoGRFFileProps::SG_DEFAULT, _cur_gps.spritegroups[groupid]);
151 SetEngineGRF(engine, _cur_gps.grffile);
152 }
153 }
154}
155
159 virtual ~MapSpriteGroupHandler() = default;
160
167 virtual void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) = 0;
168
174 virtual void MapDefault(uint16_t local_id, const SpriteGroup *group) = 0;
175};
176
183template <typename T> static auto *GetSpec(GRFFile *grffile, uint16_t local_id);
184
186template <typename T>
188 void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
189 {
190 if (cid != 0xFF) {
191 GrfMsg(1, "MapSpriteGroup: Invalid cargo bitnum {}, skipping.", cid);
192 } else if (T *spec = GetSpec<T>(_cur_gps.grffile, local_id); spec == nullptr) {
193 GrfMsg(1, "MapSpriteGroup: {} undefined, skipping.", local_id);
194 } else {
195 spec->grf_prop.SetSpriteGroup(StandardSpriteGroup::Purchase, group);
196 }
197 }
198
199 void MapDefault(uint16_t local_id, const SpriteGroup *group) override
200 {
201 if (T *spec = GetSpec<T>(_cur_gps.grffile, local_id); spec == nullptr) {
202 GrfMsg(1, "MapSpriteGroup: {} undefined, skipping.", local_id);
203 } else {
204 spec->grf_prop.SetSpriteGroup(StandardSpriteGroup::Default, group);
205 spec->grf_prop.SetGRFFile(_cur_gps.grffile);
206 spec->grf_prop.local_id = local_id;
207 }
208 }
209};
210
212template <typename T, typename Tclass>
214 void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
215 {
216 CargoType cargo_type = TranslateCargo(GSF_STATIONS, cid);
217 if (!IsValidCargoType(cargo_type)) return;
218
219 if (T *spec = GetSpec<T>(_cur_gps.grffile, local_id); spec == nullptr) {
220 GrfMsg(1, "MapSpriteGroup: {} undefined, skipping", local_id);
221 } else {
222 spec->grf_prop.SetSpriteGroup(cargo_type, group);
223 }
224 }
225
226 void MapDefault(uint16_t local_id, const SpriteGroup *group) override
227 {
228 if (T *spec = GetSpec<T>(_cur_gps.grffile, local_id); spec == nullptr) {
229 GrfMsg(1, "MapSpriteGroup: {} undefined, skipping", local_id);
230 } else if (spec->grf_prop.HasGrfFile()) {
231 GrfMsg(1, "MapSpriteGroup: {} mapped multiple times, skipping", local_id);
232 } else {
233 spec->grf_prop.SetSpriteGroup(CargoGRFFileProps::SG_DEFAULT, group);
234 spec->grf_prop.SetGRFFile(_cur_gps.grffile);
235 spec->grf_prop.local_id = local_id;
236 Tclass::Assign(spec);
237 }
238 }
239};
240
242 void MapSpecific(uint16_t, uint8_t, const SpriteGroup *) override {}
243
244 void MapDefault(uint16_t local_id, const SpriteGroup *group) override
245 {
246 if (local_id >= CF_END) {
247 GrfMsg(1, "CanalMapSpriteGroup: Canal subset {} out of range, skipping", local_id);
248 } else {
249 _water_feature[local_id].grffile = _cur_gps.grffile;
250 _water_feature[local_id].group = group;
251 }
252 }
253};
254
255template <> auto *GetSpec<StationSpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->stations.size() ? grffile->stations[local_id].get() : nullptr; }
257
258template <> auto *GetSpec<HouseSpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->housespec.size() ? grffile->housespec[local_id].get() : nullptr; }
260
261template <> auto *GetSpec<IndustrySpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->industryspec.size() ? grffile->industryspec[local_id].get() : nullptr; }
263
264template <> auto *GetSpec<IndustryTileSpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->indtspec.size() ? grffile->indtspec[local_id].get() : nullptr; }
266
268 void MapSpecific(uint16_t, uint8_t, const SpriteGroup *) override {}
269
270 void MapDefault(uint16_t local_id, const SpriteGroup *group) override
271 {
272 if (local_id >= NUM_CARGO) {
273 GrfMsg(1, "CargoMapSpriteGroup: Cargo type {} out of range, skipping", local_id);
274 } else {
275 CargoSpec *cs = CargoSpec::Get(local_id);
276 cs->grffile = _cur_gps.grffile;
277 cs->group = group;
278 }
279 }
280};
281
282template <> auto *GetSpec<ObjectSpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->objectspec.size() ? grffile->objectspec[local_id].get() : nullptr; }
284
286 void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
287 {
288 if (cid >= RTSG_END) return;
289
290 const auto &type_map = _cur_gps.grffile->railtype_map;
291 RailType railtype = local_id < std::size(type_map) ? type_map[local_id] : INVALID_RAILTYPE;
292 if (railtype == INVALID_RAILTYPE) return;
293
294 extern RailTypeInfo _railtypes[RAILTYPE_END];
295 RailTypeInfo &rti = _railtypes[railtype];
296 rti.grffile[cid] = _cur_gps.grffile;
297 rti.group[cid] = group;
298 }
299
300 void MapDefault(uint16_t, const SpriteGroup *) override {}
301};
302
303template <RoadTramType TRoadTramType>
305 void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
306 {
307 if (cid >= ROTSG_END) return;
308
309 const auto &type_map = (TRoadTramType == RTT_TRAM) ? _cur_gps.grffile->tramtype_map : _cur_gps.grffile->roadtype_map;
310 RoadType roadtype = local_id < std::size(type_map) ? type_map[local_id] : INVALID_ROADTYPE;
311 if (roadtype == INVALID_ROADTYPE) return;
312
313 extern RoadTypeInfo _roadtypes[ROADTYPE_END];
314 RoadTypeInfo &rti = _roadtypes[roadtype];
315 rti.grffile[cid] = _cur_gps.grffile;
316 rti.group[cid] = group;
317 }
318
319 void MapDefault(uint16_t, const SpriteGroup *) override {}
320};
321
322template <> auto *GetSpec<AirportSpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->airportspec.size() ? grffile->airportspec[local_id].get() : nullptr; }
324
325template <> auto *GetSpec<AirportTileSpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->airtspec.size() ? grffile->airtspec[local_id].get() : nullptr; }
327
328template <> auto *GetSpec<RoadStopSpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->roadstops.size() ? grffile->roadstops[local_id].get() : nullptr; }
329struct RoadStopMapSpriteGroupHandler : CargoTypeMapSpriteGroupHandler<RoadStopSpec, RoadStopClass> {};
330
332 void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
333 {
334 if (cid >= GSF_END) return;
335
336 auto found = _cur_gps.grffile->badge_map.find(local_id);
337 if (found == std::end(_cur_gps.grffile->badge_map)) {
338 GrfMsg(1, "BadgeMapSpriteGroup: Badge {} undefined, skipping", local_id);
339 } else {
340 auto &badge = *GetBadge(found->second);
341 badge.grf_prop.SetSpriteGroup(static_cast<GrfSpecFeature>(cid), group);
342 }
343 }
344
345 void MapDefault(uint16_t local_id, const SpriteGroup *group) override
346 {
347 auto found = _cur_gps.grffile->badge_map.find(local_id);
348 if (found == std::end(_cur_gps.grffile->badge_map)) {
349 GrfMsg(1, "BadgeMapSpriteGroup: Badge {} undefined, skipping", local_id);
350 } else {
351 auto &badge = *GetBadge(found->second);
352 badge.grf_prop.SetSpriteGroup(GSF_DEFAULT, group);
353 badge.grf_prop.SetGRFFile(_cur_gps.grffile);
354 badge.grf_prop.local_id = local_id;
355 }
356 }
357};
358
359static void MapSpriteGroup(ByteReader &buf, uint8_t idcount, MapSpriteGroupHandler &&handler)
360{
361 /* Read IDs to map into memory. */
362 std::array<uint16_t, 256> local_ids_buffer;
363 for (uint i = 0; i != idcount; ++i) {
364 local_ids_buffer[i] = buf.ReadExtendedByte();
365 }
366 std::span<const uint16_t> local_ids{local_ids_buffer.begin(), idcount};
367
368 /* Handle specific mappings. */
369 uint8_t cidcount = buf.ReadByte();
370 for (uint c = 0; c != cidcount; ++c) {
371 uint8_t cid = buf.ReadByte();
372 uint16_t groupid = buf.ReadWord();
373 if (!IsValidGroupID(groupid, "MapSpriteGroup")) continue;
374 for (uint16_t local_id : local_ids) {
375 handler.MapSpecific(local_id, cid, _cur_gps.spritegroups[groupid]);
376 }
377 }
378
379 /* Handle default mapping. */
380 uint16_t groupid = buf.ReadWord();
381 if (!IsValidGroupID(groupid, "MapSpriteGroup")) return;
382 for (uint16_t local_id : local_ids) {
383 handler.MapDefault(local_id, _cur_gps.spritegroups[groupid]);
384 }
385}
386
387/* Action 0x03 */
388static void FeatureMapSpriteGroup(ByteReader &buf)
389{
390 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
391 * id-list := [<id>] [id-list]
392 * cargo-list := <cargo-type> <cid> [cargo-list]
393 *
394 * B feature see action 0
395 * B n-id bits 0-6: how many IDs this definition applies to
396 * bit 7: if set, this is a wagon override definition (see below)
397 * E ids the IDs for which this definition applies
398 * B num-cid number of cargo IDs (sprite group IDs) in this definition
399 * can be zero, in that case the def-cid is used always
400 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
401 * W cid cargo ID (sprite group ID) for this type of cargo
402 * W def-cid default cargo ID (sprite group ID) */
403
404 GrfSpecFeature feature{buf.ReadByte()};
405 uint8_t idcount = buf.ReadByte();
406
407 if (feature >= GSF_END) {
408 GrfMsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x{:02X}, skipping", feature);
409 return;
410 }
411
412 /* If idcount is zero, this is a feature callback */
413 if (idcount == 0) {
414 /* Skip number of cargo ids? */
415 buf.ReadByte();
416 uint16_t groupid = buf.ReadWord();
417 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
418
419 GrfMsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature 0x{:02X}", feature);
420
421 AddGenericCallback(feature, _cur_gps.grffile, _cur_gps.spritegroups[groupid]);
422 return;
423 }
424
425 /* Mark the feature as used by the grf (generic callbacks do not count) */
426 _cur_gps.grffile->grf_features.Set(feature);
427
428 GrfMsg(6, "FeatureMapSpriteGroup: Feature 0x{:02X}, {} ids", feature, idcount);
429
430 switch (feature) {
431 case GSF_TRAINS:
432 case GSF_ROADVEHICLES:
433 case GSF_SHIPS:
434 case GSF_AIRCRAFT: VehicleMapSpriteGroup(buf, feature, idcount); return;
435 case GSF_CANALS: MapSpriteGroup(buf, idcount, CanalMapSpriteGroupHandler{}); return;
436 case GSF_STATIONS: MapSpriteGroup(buf, idcount, StationMapSpriteGroupHandler{}); return;
437 case GSF_HOUSES: MapSpriteGroup(buf, idcount, TownHouseMapSpriteGroupHandler{}); return;
438 case GSF_INDUSTRIES: MapSpriteGroup(buf, idcount, IndustryMapSpriteGroupHandler{}); return;
439 case GSF_INDUSTRYTILES: MapSpriteGroup(buf, idcount, IndustryTileMapSpriteGroupHandler{}); return;
440 case GSF_CARGOES: MapSpriteGroup(buf, idcount, CargoMapSpriteGroupHandler{}); return;
441 case GSF_AIRPORTS: MapSpriteGroup(buf, idcount, AirportMapSpriteGroupHandler{}); return;
442 case GSF_OBJECTS: MapSpriteGroup(buf, idcount, ObjectMapSpriteGroupHandler{}); return;
443 case GSF_RAILTYPES: MapSpriteGroup(buf, idcount, RailTypeMapSpriteGroupHandler{}); return;
444 case GSF_ROADTYPES: MapSpriteGroup(buf, idcount, RoadTypeMapSpriteGroupHandler<RTT_ROAD>{}); return;
445 case GSF_TRAMTYPES: MapSpriteGroup(buf, idcount, RoadTypeMapSpriteGroupHandler<RTT_TRAM>{}); return;
446 case GSF_AIRPORTTILES: MapSpriteGroup(buf, idcount, AirportTileMapSpriteGroupHandler{}); return;
447 case GSF_ROADSTOPS: MapSpriteGroup(buf, idcount, RoadStopMapSpriteGroupHandler{}); return;
448 case GSF_BADGES: MapSpriteGroup(buf, idcount, BadgeMapSpriteGroupHandler{}); return;
449
450 default:
451 GrfMsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x{:02X}, skipping", feature);
452 return;
453 }
454}
455
467template <> void GrfActionHandler<0x03>::Activation(ByteReader &buf) { FeatureMapSpriteGroup(buf); }
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
static constexpr CargoLabel CT_INVALID
Invalid cargo type.
Definition cargo_type.h:70
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:21
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:108
StrongType::Typedef< uint32_t, struct CargoLabelTag, StrongType::Compare > CargoLabel
Globally unique label of a cargo type.
Definition cargo_type.h:16
static const CargoType NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:73
Class to read from a NewGRF file.
uint16_t ReadWord()
Read a single Word (16 bits).
uint16_t ReadExtendedByte()
Read a single Extended Byte (8 or 16 bits).
uint8_t ReadByte()
Read a single byte (8 bits).
This struct contains all the info that is needed to draw and construct tracks.
Definition rail.h:115
const SpriteGroup * group[RTSG_END]
Sprite groups for resolving sprites.
Definition rail.h:270
const GRFFile * grffile[RTSG_END]
NewGRF providing the Action3 for the railtype.
Definition rail.h:265
const SpriteGroup * group[ROTSG_END]
Sprite groups for resolving sprites.
Definition road.h:166
const GRFFile * grffile[ROTSG_END]
NewGRF providing the Action3 for the roadtype.
Definition road.h:161
Functions related to debugging.
PoolID< uint16_t, struct EngineIDTag, 64000, 0xFFFF > EngineID
Unique identification number of an engine.
Definition engine_type.h:26
#define T
Climate temperate.
Definition engines.h:91
Functions related to errors.
Definition of HouseSpec and accessors.
Industry type specs.
std::span< const CargoLabel > GetCargoTranslationTable(const GRFFile &grffile)
Get the cargo translation table to use for the given GRF file.
Definition newgrf.cpp:527
void GRFUnsafe(ByteReader &)
Set the current NewGRF as unsafe for static use.
Definition newgrf.cpp:379
Engine * GetNewEngine(const GRFFile *file, VehicleType type, uint16_t internal_id, bool static_access)
Returns the engine associated to a certain internal_id, resp.
Definition newgrf.cpp:218
GrfSpecFeature
Definition newgrf.h:71
@ GSF_DEFAULT
Unspecified feature, default badge.
Definition newgrf.h:96
static auto * GetSpec(GRFFile *grffile, uint16_t local_id)
Specializable function to retrieve a NewGRF spec of a particular type.
NewGRF handling of airports.
NewGRF handling of airport tiles.
Badge * GetBadge(BadgeID index)
Get a badge if it exists.
Functions related to NewGRF badges.
Types related to NewGRF badges.
NewGRF buffer reader definition.
std::array< WaterFeature, CF_END > _water_feature
Table of canal 'feature' sprite groups.
Handling of NewGRF canals.
Cargo support for NewGRFs.
@ Purchase
Used before an entity exists.
@ Default
Default type used when no more-specific group matches.
void SetEngineGRF(EngineID engine, const GRFFile *file)
Tie a GRFFile entry to an engine, to allow us to retrieve GRF parameters etc during a game.
Functions for NewGRF engines.
void AddGenericCallback(GrfSpecFeature feature, const GRFFile *file, const SpriteGroup *group)
Add a generic feature callback sprite group to the appropriate feature list.
Functions related to NewGRF houses.
NewGRF internal processing state.
@ CIR_INVALID_ID
Attempt to modify an invalid ID.
static constexpr uint MAX_SPRITEGROUP
Maximum GRF-local ID for a spritegroup.
NewGRF internal processing state for vehicles.
Functions related to NewGRF objects.
NewGRF definitions and structures for road stops.
Header file for NewGRF stations.
RailType
Enumeration for all possible railtypes.
Definition rail_type.h:25
@ RAILTYPE_END
Used for iterations.
Definition rail_type.h:31
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition rail_type.h:32
Road specific functions.
@ RTT_TRAM
Tram road type.
Definition road_type.h:39
RoadType
The different roadtypes we support.
Definition road_type.h:23
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
@ ROADTYPE_END
Used for iterations.
Definition road_type.h:27
A number of safeguards to prevent using unsafe methods.
Definition of base types and functions in a cross-platform compatible way.
void MapDefault(uint16_t local_id, const SpriteGroup *group) override
Map default/fallback SpriteGroup to a specification.
void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
Map a SpriteGroup to specific 'cargo type' of a specification.
void MapSpecific(uint16_t, uint8_t, const SpriteGroup *) override
Map a SpriteGroup to specific 'cargo type' of a specification.
void MapDefault(uint16_t local_id, const SpriteGroup *group) override
Map default/fallback SpriteGroup to a specification.
static constexpr CargoType SG_PURCHASE
Used in purchase lists before an item exists.
static constexpr CargoType SG_DEFAULT
Default type used when no more-specific cargo matches.
static constexpr CargoType SG_DEFAULT_NA
Used only by stations and roads when no more-specific cargo matches.
void MapDefault(uint16_t local_id, const SpriteGroup *group) override
Map default/fallback SpriteGroup to a specification.
void MapSpecific(uint16_t, uint8_t, const SpriteGroup *) override
Map a SpriteGroup to specific 'cargo type' of a specification.
Specification of a cargo type.
Definition cargotype.h:74
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo type.
Definition cargotype.h:138
const struct GRFFile * grffile
NewGRF where group belongs to.
Definition cargotype.h:99
Common handler for mapping sprite groups for features which support cargo-type specific sprites.
void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
Map a SpriteGroup to specific 'cargo type' of a specification.
void MapDefault(uint16_t local_id, const SpriteGroup *group) override
Map default/fallback SpriteGroup to a specification.
Dynamic data of a loaded NewGRF.
Definition newgrf.h:117
static void FileScan(ByteReader &buf)
Implementation of the GrfLoadingStage::FileScan stage of this action.
static void SafetyScan(ByteReader &buf)
Implementation of the GrfLoadingStage::SafetyScan stage of this action.
static void Reserve(ByteReader &buf)
Implementation of the GrfLoadingStage::Reserve stage of this action.
static void Activation(ByteReader &buf)
Implementation of the GrfLoadingStage::Activation stage of this action.
static void Init(ByteReader &buf)
Implementation of the GrfLoadingStage::Init stage of this action.
static void LabelScan(ByteReader &buf)
Implementation of the GrfLoadingStage::LabelScan stage of this action.
Handler interface for mapping sprite groups to their respective feature specific specifications.
virtual void MapDefault(uint16_t local_id, const SpriteGroup *group)=0
Map default/fallback SpriteGroup to a specification.
virtual void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group)=0
Map a SpriteGroup to specific 'cargo type' of a specification.
virtual ~MapSpriteGroupHandler()=default
Ensure the destructor of the sub classes are called as well.
Common handler for mapping sprite groups for features which only support "Purchase" and "Default" spr...
void MapDefault(uint16_t local_id, const SpriteGroup *group) override
Map default/fallback SpriteGroup to a specification.
void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
Map a SpriteGroup to specific 'cargo type' of a specification.
void MapDefault(uint16_t, const SpriteGroup *) override
Map default/fallback SpriteGroup to a specification.
void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
Map a SpriteGroup to specific 'cargo type' of a specification.
void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
Map a SpriteGroup to specific 'cargo type' of a specification.
void MapDefault(uint16_t, const SpriteGroup *) override
Map default/fallback SpriteGroup to a specification.
Common wrapper for all the different sprite group types.
Base class for all vehicles.
VehicleType
Available vehicle types.