OpenTTD Source 20260421-master-gc2fbc6fdeb
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.h"
15#include "../newgrf_engine.h"
16#include "../newgrf_badge.h"
18#include "../newgrf_cargo.h"
19#include "../newgrf_house.h"
20#include "../newgrf_station.h"
21#include "../industrytype.h"
22#include "../newgrf_canal.h"
24#include "../newgrf_airport.h"
25#include "../newgrf_object.h"
26#include "../error.h"
27#include "../vehicle_base.h"
28#include "../road.h"
29#include "../newgrf_roadstop.h"
30#include "newgrf_bytereader.h"
32#include "newgrf_internal.h"
33
34#include "../safeguards.h"
35
36
37static CargoType TranslateCargo(GrfSpecFeature feature, uint8_t ctype)
38{
39 /* Special cargo types for purchase list and stations */
40 if ((feature == GrfSpecFeature::Stations || feature == GrfSpecFeature::RoadStops) && ctype == 0xFE) return CargoGRFFileProps::SG_DEFAULT_NA;
41 if (ctype == 0xFF) return CargoGRFFileProps::SG_PURCHASE;
42
43 auto cargo_list = GetCargoTranslationTable(*_cur_gps.grffile);
44
45 /* Check if the cargo type is out of bounds of the cargo translation table */
46 if (ctype >= cargo_list.size()) {
47 GrfMsg(1, "TranslateCargo: Cargo type {} out of range (max {}), skipping.", ctype, (unsigned int)_cur_gps.grffile->cargo_list.size() - 1);
48 return INVALID_CARGO;
49 }
50
51 /* Look up the cargo label from the translation table */
52 CargoLabel cl = cargo_list[ctype];
53 if (cl == CT_INVALID) {
54 GrfMsg(5, "TranslateCargo: Cargo type {} not available in this climate, skipping.", ctype);
55 return INVALID_CARGO;
56 }
57
58 CargoType cargo_type = GetCargoTypeByLabel(cl);
59 if (!IsValidCargoType(cargo_type)) {
60 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));
61 return INVALID_CARGO;
62 }
63
64 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);
65 return cargo_type;
66}
67
68
69static bool IsValidGroupID(uint16_t groupid, std::string_view function)
70{
71 if (groupid > MAX_SPRITEGROUP || _cur_gps.spritegroups[groupid] == nullptr) {
72 GrfMsg(1, "{}: Spritegroup 0x{:04X} out of range or empty, skipping.", function, groupid);
73 return false;
74 }
75
76 return true;
77}
78
79static void VehicleMapSpriteGroup(ByteReader &buf, GrfSpecFeature feature, uint8_t idcount)
80{
81 static std::vector<EngineID> last_engines; // Engine IDs are remembered in case the next action is a wagon override.
82 bool wagover = false;
83
84 /* Test for 'wagon override' flag */
85 if (HasBit(idcount, 7)) {
86 wagover = true;
87 /* Strip off the flag */
88 idcount = GB(idcount, 0, 7);
89
90 if (last_engines.empty()) {
91 GrfMsg(0, "VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
92 return;
93 }
94
95 GrfMsg(6, "VehicleMapSpriteGroup: WagonOverride: {} engines, {} wagons", last_engines.size(), idcount);
96 } else {
97 last_engines.resize(idcount);
98 }
99
100 std::vector<EngineID> engines;
101 engines.reserve(idcount);
102 for (uint i = 0; i < idcount; i++) {
103 Engine *e = GetNewEngine(_cur_gps.grffile, GetVehicleType(feature), buf.ReadExtendedByte());
104 if (e == nullptr) {
105 /* No engine could be allocated?!? Deal with it. Okay,
106 * this might look bad. Also make sure this NewGRF
107 * gets disabled, as a half loaded one is bad. */
108 HandleChangeInfoResult("VehicleMapSpriteGroup", ChangeInfoResult::InvalidId, feature, 0);
109 return;
110 }
111
112 engines.push_back(e->index);
113 if (!wagover) last_engines[i] = engines[i];
114 }
115
116 uint8_t cidcount = buf.ReadByte();
117 for (uint c = 0; c < cidcount; c++) {
118 uint8_t ctype = buf.ReadByte();
119 uint16_t groupid = buf.ReadWord();
120 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) continue;
121
122 GrfMsg(8, "VehicleMapSpriteGroup: * [{}] Cargo type 0x{:X}, group id 0x{:02X}", c, ctype, groupid);
123
124 CargoType cargo_type = TranslateCargo(feature, ctype);
125 if (!IsValidCargoType(cargo_type)) continue;
126
127 for (uint i = 0; i < idcount; i++) {
128 EngineID engine = engines[i];
129
130 GrfMsg(7, "VehicleMapSpriteGroup: [{}] Engine {}...", i, engine);
131
132 if (wagover) {
133 SetWagonOverrideSprites(engine, cargo_type, _cur_gps.spritegroups[groupid], last_engines);
134 } else {
135 SetCustomEngineSprites(engine, cargo_type, _cur_gps.spritegroups[groupid]);
136 }
137 }
138 }
139
140 uint16_t groupid = buf.ReadWord();
141 if (!IsValidGroupID(groupid, "VehicleMapSpriteGroup")) return;
142
143 GrfMsg(8, "-- Default group id 0x{:04X}", groupid);
144
145 for (uint i = 0; i < idcount; i++) {
146 EngineID engine = engines[i];
147
148 if (wagover) {
149 SetWagonOverrideSprites(engine, CargoGRFFileProps::SG_DEFAULT, _cur_gps.spritegroups[groupid], last_engines);
150 } else {
151 SetCustomEngineSprites(engine, CargoGRFFileProps::SG_DEFAULT, _cur_gps.spritegroups[groupid]);
152 SetEngineGRF(engine, _cur_gps.grffile);
153 }
154 }
155}
156
160 virtual ~MapSpriteGroupHandler() = default;
161
168 virtual void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) = 0;
169
175 virtual void MapDefault(uint16_t local_id, const SpriteGroup *group) = 0;
176};
177
184template <typename T> static auto *GetSpec(GRFFile *grffile, uint16_t local_id);
185
187template <typename T>
189 void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
190 {
191 if (cid != 0xFF) {
192 GrfMsg(1, "MapSpriteGroup: Invalid cargo bitnum {}, skipping.", cid);
193 } else if (T *spec = GetSpec<T>(_cur_gps.grffile, local_id); spec == nullptr) {
194 GrfMsg(1, "MapSpriteGroup: {} undefined, skipping.", local_id);
195 } else {
196 spec->grf_prop.SetSpriteGroup(StandardSpriteGroup::Purchase, group);
197 }
198 }
199
200 void MapDefault(uint16_t local_id, const SpriteGroup *group) override
201 {
202 if (T *spec = GetSpec<T>(_cur_gps.grffile, local_id); spec == nullptr) {
203 GrfMsg(1, "MapSpriteGroup: {} undefined, skipping.", local_id);
204 } else {
205 spec->grf_prop.SetSpriteGroup(StandardSpriteGroup::Default, group);
206 spec->grf_prop.SetGRFFile(_cur_gps.grffile);
207 spec->grf_prop.local_id = local_id;
208 }
209 }
210};
211
213template <typename T, typename Tclass>
215 void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
216 {
217 CargoType cargo_type = TranslateCargo(GrfSpecFeature::Stations, cid);
218 if (!IsValidCargoType(cargo_type)) return;
219
220 if (T *spec = GetSpec<T>(_cur_gps.grffile, local_id); spec == nullptr) {
221 GrfMsg(1, "MapSpriteGroup: {} undefined, skipping", local_id);
222 } else {
223 spec->grf_prop.SetSpriteGroup(cargo_type, group);
224 }
225 }
226
227 void MapDefault(uint16_t local_id, const SpriteGroup *group) override
228 {
229 if (T *spec = GetSpec<T>(_cur_gps.grffile, local_id); spec == nullptr) {
230 GrfMsg(1, "MapSpriteGroup: {} undefined, skipping", local_id);
231 } else if (spec->grf_prop.HasGrfFile()) {
232 GrfMsg(1, "MapSpriteGroup: {} mapped multiple times, skipping", local_id);
233 } else {
234 spec->grf_prop.SetSpriteGroup(CargoGRFFileProps::SG_DEFAULT, group);
235 spec->grf_prop.SetGRFFile(_cur_gps.grffile);
236 spec->grf_prop.local_id = local_id;
237 Tclass::Assign(spec);
238 }
239 }
240};
241
243 void MapSpecific(uint16_t, uint8_t, const SpriteGroup *) override {}
244
245 void MapDefault(uint16_t local_id, const SpriteGroup *group) override
246 {
247 if (local_id >= CF_END) {
248 GrfMsg(1, "CanalMapSpriteGroup: Canal subset {} out of range, skipping", local_id);
249 } else {
250 _water_feature[local_id].grffile = _cur_gps.grffile;
251 _water_feature[local_id].group = group;
252 }
253 }
254};
255
256template <> auto *GetSpec<StationSpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->stations.size() ? grffile->stations[local_id].get() : nullptr; }
258
259template <> auto *GetSpec<HouseSpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->housespec.size() ? grffile->housespec[local_id].get() : nullptr; }
261
262template <> auto *GetSpec<IndustrySpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->industryspec.size() ? grffile->industryspec[local_id].get() : nullptr; }
264
265template <> auto *GetSpec<IndustryTileSpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->indtspec.size() ? grffile->indtspec[local_id].get() : nullptr; }
267
269 void MapSpecific(uint16_t, uint8_t, const SpriteGroup *) override {}
270
271 void MapDefault(uint16_t local_id, const SpriteGroup *group) override
272 {
273 if (local_id >= NUM_CARGO) {
274 GrfMsg(1, "CargoMapSpriteGroup: Cargo type {} out of range, skipping", local_id);
275 } else {
276 CargoSpec *cs = CargoSpec::Get(local_id);
277 cs->grffile = _cur_gps.grffile;
278 cs->group = group;
279 }
280 }
281};
282
283template <> auto *GetSpec<ObjectSpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->objectspec.size() ? grffile->objectspec[local_id].get() : nullptr; }
285
287 void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
288 {
289 RailSpriteType rst{cid};
290 if (rst >= RailSpriteType::End) return;
291
292 const auto &type_map = _cur_gps.grffile->railtype_map;
293 RailType railtype = local_id < std::size(type_map) ? type_map[local_id] : INVALID_RAILTYPE;
294 if (railtype == INVALID_RAILTYPE) return;
295
296 extern RailTypeInfo _railtypes[RAILTYPE_END];
297 RailTypeInfo &rti = _railtypes[railtype];
298 rti.grffile[rst] = _cur_gps.grffile;
299 rti.group[rst] = group;
300 }
301
302 void MapDefault(uint16_t, const SpriteGroup *) override {}
303};
304
305template <RoadTramType TRoadTramType>
307 void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
308 {
309 RoadSpriteType rst{cid};
310 if (rst >= RoadSpriteType::End) return;
311
312 const auto &type_map = (TRoadTramType == RoadTramType::Tram) ? _cur_gps.grffile->tramtype_map : _cur_gps.grffile->roadtype_map;
313 RoadType roadtype = local_id < std::size(type_map) ? type_map[local_id] : INVALID_ROADTYPE;
314 if (roadtype == INVALID_ROADTYPE) return;
315
316 extern RoadTypeInfo _roadtypes[ROADTYPE_END];
317 RoadTypeInfo &rti = _roadtypes[roadtype];
318 rti.grffile[rst] = _cur_gps.grffile;
319 rti.group[rst] = group;
320 }
321
322 void MapDefault(uint16_t, const SpriteGroup *) override {}
323};
324
325template <> auto *GetSpec<AirportSpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->airportspec.size() ? grffile->airportspec[local_id].get() : nullptr; }
327
328template <> auto *GetSpec<AirportTileSpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->airtspec.size() ? grffile->airtspec[local_id].get() : nullptr; }
330
331template <> auto *GetSpec<RoadStopSpec>(GRFFile *grffile, uint16_t local_id) { return local_id < grffile->roadstops.size() ? grffile->roadstops[local_id].get() : nullptr; }
332struct RoadStopMapSpriteGroupHandler : CargoTypeMapSpriteGroupHandler<RoadStopSpec, RoadStopClass> {};
333
335 void MapSpecific(uint16_t local_id, uint8_t cid, const SpriteGroup *group) override
336 {
337 if (cid >= to_underlying(GrfSpecFeature::End)) return;
338
339 auto found = _cur_gps.grffile->badge_map.find(local_id);
340 if (found == std::end(_cur_gps.grffile->badge_map)) {
341 GrfMsg(1, "BadgeMapSpriteGroup: Badge {} undefined, skipping", local_id);
342 } else {
343 auto &badge = *GetBadge(found->second);
344 badge.grf_prop.SetSpriteGroup(static_cast<GrfSpecFeature>(cid), group);
345 }
346 }
347
348 void MapDefault(uint16_t local_id, const SpriteGroup *group) override
349 {
350 auto found = _cur_gps.grffile->badge_map.find(local_id);
351 if (found == std::end(_cur_gps.grffile->badge_map)) {
352 GrfMsg(1, "BadgeMapSpriteGroup: Badge {} undefined, skipping", local_id);
353 } else {
354 auto &badge = *GetBadge(found->second);
355 badge.grf_prop.SetSpriteGroup(GrfSpecFeature::Default, group);
356 badge.grf_prop.SetGRFFile(_cur_gps.grffile);
357 badge.grf_prop.local_id = local_id;
358 }
359 }
360};
361
362static void MapSpriteGroup(ByteReader &buf, uint8_t idcount, MapSpriteGroupHandler &&handler)
363{
364 /* Read IDs to map into memory. */
365 std::array<uint16_t, 256> local_ids_buffer;
366 for (uint i = 0; i != idcount; ++i) {
367 local_ids_buffer[i] = buf.ReadExtendedByte();
368 }
369 std::span<const uint16_t> local_ids{local_ids_buffer.begin(), idcount};
370
371 /* Handle specific mappings. */
372 uint8_t cidcount = buf.ReadByte();
373 for (uint c = 0; c != cidcount; ++c) {
374 uint8_t cid = buf.ReadByte();
375 uint16_t groupid = buf.ReadWord();
376 if (!IsValidGroupID(groupid, "MapSpriteGroup")) continue;
377 for (uint16_t local_id : local_ids) {
378 handler.MapSpecific(local_id, cid, _cur_gps.spritegroups[groupid]);
379 }
380 }
381
382 /* Handle default mapping. */
383 uint16_t groupid = buf.ReadWord();
384 if (!IsValidGroupID(groupid, "MapSpriteGroup")) return;
385 for (uint16_t local_id : local_ids) {
386 handler.MapDefault(local_id, _cur_gps.spritegroups[groupid]);
387 }
388}
389
390/* Action 0x03 */
391static void FeatureMapSpriteGroup(ByteReader &buf)
392{
393 /* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
394 * id-list := [<id>] [id-list]
395 * cargo-list := <cargo-type> <cid> [cargo-list]
396 *
397 * B feature see action 0
398 * B n-id bits 0-6: how many IDs this definition applies to
399 * bit 7: if set, this is a wagon override definition (see below)
400 * E ids the IDs for which this definition applies
401 * B num-cid number of cargo IDs (sprite group IDs) in this definition
402 * can be zero, in that case the def-cid is used always
403 * B cargo-type type of this cargo type (e.g. mail=2, wood=7, see below)
404 * W cid cargo ID (sprite group ID) for this type of cargo
405 * W def-cid default cargo ID (sprite group ID) */
406
407 GrfSpecFeature feature{buf.ReadByte()};
408 uint8_t idcount = buf.ReadByte();
409
410 if (feature >= GrfSpecFeature::End) {
411 GrfMsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x{:02X}, skipping", feature);
412 return;
413 }
414
415 /* If idcount is zero, this is a feature callback */
416 if (idcount == 0) {
417 /* Skip number of cargo ids? */
418 buf.ReadByte();
419 uint16_t groupid = buf.ReadWord();
420 if (!IsValidGroupID(groupid, "FeatureMapSpriteGroup")) return;
421
422 GrfMsg(6, "FeatureMapSpriteGroup: Adding generic feature callback for feature 0x{:02X}", feature);
423
424 AddGenericCallback(feature, _cur_gps.grffile, _cur_gps.spritegroups[groupid]);
425 return;
426 }
427
428 /* Mark the feature as used by the grf (generic callbacks do not count) */
429 _cur_gps.grffile->grf_features.Set(feature);
430
431 GrfMsg(6, "FeatureMapSpriteGroup: Feature 0x{:02X}, {} ids", feature, idcount);
432
433 switch (feature) {
437 case GrfSpecFeature::Aircraft: VehicleMapSpriteGroup(buf, feature, idcount); return;
438 case GrfSpecFeature::Canals: MapSpriteGroup(buf, idcount, CanalMapSpriteGroupHandler{}); return;
439 case GrfSpecFeature::Stations: MapSpriteGroup(buf, idcount, StationMapSpriteGroupHandler{}); return;
440 case GrfSpecFeature::Houses: MapSpriteGroup(buf, idcount, TownHouseMapSpriteGroupHandler{}); return;
441 case GrfSpecFeature::Industries: MapSpriteGroup(buf, idcount, IndustryMapSpriteGroupHandler{}); return;
442 case GrfSpecFeature::IndustryTiles: MapSpriteGroup(buf, idcount, IndustryTileMapSpriteGroupHandler{}); return;
443 case GrfSpecFeature::Cargoes: MapSpriteGroup(buf, idcount, CargoMapSpriteGroupHandler{}); return;
444 case GrfSpecFeature::Airports: MapSpriteGroup(buf, idcount, AirportMapSpriteGroupHandler{}); return;
445 case GrfSpecFeature::Objects: MapSpriteGroup(buf, idcount, ObjectMapSpriteGroupHandler{}); return;
446 case GrfSpecFeature::RailTypes: MapSpriteGroup(buf, idcount, RailTypeMapSpriteGroupHandler{}); return;
447 case GrfSpecFeature::RoadTypes: MapSpriteGroup(buf, idcount, RoadTypeMapSpriteGroupHandler<RoadTramType::Road>{}); return;
448 case GrfSpecFeature::TramTypes: MapSpriteGroup(buf, idcount, RoadTypeMapSpriteGroupHandler<RoadTramType::Tram>{}); return;
449 case GrfSpecFeature::AirportTiles: MapSpriteGroup(buf, idcount, AirportTileMapSpriteGroupHandler{}); return;
450 case GrfSpecFeature::RoadStops: MapSpriteGroup(buf, idcount, RoadStopMapSpriteGroupHandler{}); return;
451 case GrfSpecFeature::Badges: MapSpriteGroup(buf, idcount, BadgeMapSpriteGroupHandler{}); return;
452
453 default:
454 GrfMsg(1, "FeatureMapSpriteGroup: Unsupported feature 0x{:02X}, skipping", feature);
455 return;
456 }
457}
458
470template <> 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
EnumClassIndexContainer< std::array< const GRFFile *, to_underlying(RailSpriteType::End)>, RailSpriteType > grffile
NewGRF providing the Action3 for the railtype.
Definition rail.h:265
EnumClassIndexContainer< std::array< const SpriteGroup *, to_underlying(RailSpriteType::End)>, RailSpriteType > group
Sprite groups for resolving sprites.
Definition rail.h:270
EnumClassIndexContainer< std::array< const SpriteGroup *, to_underlying(RoadSpriteType::End)>, RoadSpriteType > group
Sprite groups for resolving sprites.
Definition road.h:166
EnumClassIndexContainer< std::array< const GRFFile *, to_underlying(RoadSpriteType::End)>, RoadSpriteType > grffile
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
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:21
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
VehicleType GetVehicleType(GrfSpecFeature feature)
Get the VehicleType associated with a GrfSpecFeature.
Definition newgrf.cpp:1920
Base for the NewGRF implementation.
GrfSpecFeature
Definition newgrf.h:72
@ RoadStops
Road stops feature.
Definition newgrf.h:93
@ RailTypes
Rail types feature.
Definition newgrf.h:89
@ Trains
Trains feature.
Definition newgrf.h:73
@ Cargoes
Cargoes feature.
Definition newgrf.h:84
@ RoadVehicles
Road vehicles feature.
Definition newgrf.h:74
@ TramTypes
Tram types feature.
Definition newgrf.h:92
@ RoadTypes
Road types feature.
Definition newgrf.h:91
@ Ships
Ships feature.
Definition newgrf.h:75
@ Houses
Houses feature.
Definition newgrf.h:80
@ Default
Unspecified feature, default badge.
Definition newgrf.h:97
@ End
End marker.
Definition newgrf.h:95
@ Stations
Stations feature.
Definition newgrf.h:77
@ Airports
Airports feature.
Definition newgrf.h:86
@ Aircraft
Aircraft feature.
Definition newgrf.h:76
@ IndustryTiles
Industry tiles feature.
Definition newgrf.h:82
@ Objects
Objects feature.
Definition newgrf.h:88
@ AirportTiles
Airport tiles feature.
Definition newgrf.h:90
@ Canals
Canals feature.
Definition newgrf.h:78
@ Industries
Industries feature.
Definition newgrf.h:83
@ Badges
Badges feature.
Definition newgrf.h:94
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.
@ InvalidId
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.
RailSpriteType
Sprite types for a railtype.
Definition rail.h:40
@ End
End marker.
Definition rail.h:54
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.
RoadSpriteType
Sprite types for a roadtype.
Definition road.h:36
@ End
End marker.
Definition road.h:49
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
@ Tram
Tram type.
Definition road_type.h:39
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:75
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo type.
Definition cargotype.h:139
const struct GRFFile * grffile
NewGRF where group belongs to.
Definition cargotype.h:100
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:118
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.