OpenTTD Source 20260712-master-gcf48f866eb
newgrf_commons.h
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#ifndef NEWGRF_COMMONS_H
11#define NEWGRF_COMMONS_H
12
13#include "newgrf_type.h"
14#include "sprite.h"
15#include "command_type.h"
16#include "direction_type.h"
17#include "company_type.h"
18#include "cargo_type.h"
19#include "core/bitmath_func.hpp"
20
22enum class TileContext : uint8_t {
26};
27
66
67
73inline uint GetConstructionStageOffset(uint construction_stage, uint num_sprites)
74{
75 assert(num_sprites > 0);
76 if (num_sprites > 4) num_sprites = 4;
77 switch (construction_stage) {
78 case 0: return 0;
79 case 1: return num_sprites > 2 ? 1 : 0;
80 case 2: return num_sprites > 2 ? num_sprites - 2 : 0;
81 case 3: return num_sprites - 1;
82 default: NOT_REACHED();
83 }
84}
85
91 uint8_t dodraw;
92 uint8_t sprite;
93 uint8_t palette;
96 union {
97 uint8_t parent[3];
98 uint8_t child[2];
99 } delta;
100 uint8_t sprite_var10;
102};
103
104static const uint TLR_MAX_VAR10 = 7;
105
111struct NewGRFSpriteLayout : DrawTileSprites {
112 std::vector<DrawTileSeqStruct> seq{};
113 std::vector<TileLayoutRegisters> registers{};
114
120
121 void Allocate(uint num_sprites);
122 void AllocateRegisters();
123
130 {
131 return !this->registers.empty();
132 }
133
134 std::span<const DrawTileSeqStruct> GetSequence() const override { return {this->seq.begin(), this->seq.end()}; }
135};
136
140class SpriteLayoutProcessor {
141 const NewGRFSpriteLayout *raw_layout = nullptr;
142 std::vector<DrawTileSeqStruct> result_seq;
143 uint32_t var10_values = 0;
144 bool separate_ground = false;
145public:
146 SpriteLayoutProcessor() = default;
147
152 SpriteLayoutProcessor(const NewGRFSpriteLayout &raw_layout) : raw_layout(&raw_layout) {}
153
154 SpriteLayoutProcessor(const NewGRFSpriteLayout &raw_layout, uint32_t orig_offset, uint32_t newgrf_ground_offset, uint32_t newgrf_offset, uint constr_stage, bool separate_ground);
155
161 SetBitIterator<uint8_t, uint32_t> Var10Values() const { return this->var10_values; }
162
163 void ProcessRegisters(const struct ResolverObject &object, uint8_t resolved_var10, uint32_t resolved_sprite);
164
170 {
171 assert(this->raw_layout != nullptr);
172 if (this->result_seq.empty()) {
173 /* Simple layout without preprocessing. */
174 return {this->raw_layout->ground, this->raw_layout->seq};
175 } else {
176 /* Dynamic layout with preprocessing. */
177 return {this->result_seq[0].image, {++this->result_seq.begin(), this->result_seq.end()}};
178 }
179 }
180};
181
199
201protected:
202 std::vector<uint16_t> entity_overrides;
203 std::vector<GrfID> grfid_overrides;
204
205 uint16_t max_offset;
206 uint16_t max_entities;
207
208 uint16_t invalid_id;
214 virtual bool CheckValidNewID([[maybe_unused]] uint16_t testid) { return true; }
215
216public:
217 std::vector<EntityIDMapping> mappings;
218
219 OverrideManagerBase(uint16_t offset, uint16_t maximum, uint16_t invalid);
221 virtual ~OverrideManagerBase() = default;
222
223 void ResetOverride();
224 void ResetMapping();
225
226 void Add(uint16_t local_id, GrfID grfid, uint entity_type);
227 virtual uint16_t AddEntityID(uint16_t grf_local_id, GrfID grfid, uint16_t substitute_id);
228
229 GrfID GetGRFID(uint16_t entity_id) const;
230 uint16_t GetSubstituteID(uint16_t entity_id) const;
231 virtual uint16_t GetID(uint16_t grf_local_id, GrfID grfid) const;
232
233 inline uint16_t GetMaxMapping() const { return this->max_entities; }
234 inline uint16_t GetMaxOffset() const { return this->max_offset; }
235};
236
237
238struct HouseSpec;
239class HouseOverrideManager : public OverrideManagerBase {
240public:
241 HouseOverrideManager(uint16_t offset, uint16_t maximum, uint16_t invalid) :
242 OverrideManagerBase(offset, maximum, invalid) {}
243
244 void SetEntitySpec(HouseSpec &&hs);
245};
246
247
248struct IndustrySpec;
249class IndustryOverrideManager : public OverrideManagerBase {
250public:
251 IndustryOverrideManager(uint16_t offset, uint16_t maximum, uint16_t invalid) :
252 OverrideManagerBase(offset, maximum, invalid) {}
253
254 uint16_t AddEntityID(uint16_t grf_local_id, GrfID grfid, uint16_t substitute_id) override;
255 uint16_t GetID(uint16_t grf_local_id, GrfID grfid) const override;
256
257 void SetEntitySpec(IndustrySpec &&inds);
258};
259
260
261struct IndustryTileSpec;
262class IndustryTileOverrideManager : public OverrideManagerBase {
263protected:
264 bool CheckValidNewID(uint16_t testid) override { return testid != 0xFF; }
265public:
266 IndustryTileOverrideManager(uint16_t offset, uint16_t maximum, uint16_t invalid) :
267 OverrideManagerBase(offset, maximum, invalid) {}
268
269 void SetEntitySpec(IndustryTileSpec &&indts);
270};
271
272struct AirportSpec;
273class AirportOverrideManager : public OverrideManagerBase {
274public:
275 AirportOverrideManager(uint16_t offset, uint16_t maximum, uint16_t invalid) :
276 OverrideManagerBase(offset, maximum, invalid) {}
277
278 void SetEntitySpec(AirportSpec &&inds);
279};
280
281struct AirportTileSpec;
282class AirportTileOverrideManager : public OverrideManagerBase {
283protected:
284 bool CheckValidNewID(uint16_t testid) override { return testid != 0xFF; }
285public:
286 AirportTileOverrideManager(uint16_t offset, uint16_t maximum, uint16_t invalid) :
287 OverrideManagerBase(offset, maximum, invalid) {}
288
289 void SetEntitySpec(AirportTileSpec &&ats);
290};
291
292struct ObjectSpec;
293class ObjectOverrideManager : public OverrideManagerBase {
294protected:
295 bool CheckValidNewID(uint16_t testid) override { return testid != 0xFF; }
296public:
297 ObjectOverrideManager(uint16_t offset, uint16_t maximum, uint16_t invalid) :
298 OverrideManagerBase(offset, maximum, invalid) {}
299
300 void SetEntitySpec(ObjectSpec &&spec);
301};
302
303extern HouseOverrideManager _house_mngr;
304extern IndustryOverrideManager _industry_mngr;
305extern IndustryTileOverrideManager _industile_mngr;
306extern AirportOverrideManager _airport_mngr;
307extern AirportTileOverrideManager _airporttile_mngr;
308extern ObjectOverrideManager _object_mngr;
309
311TileIndex GetNearbyTile(uint8_t parameter, TileIndex tile, bool signed_offsets = true, Axis axis = Axis::Invalid);
312uint32_t GetNearbyTileInformation(TileIndex tile, bool grf_version8);
313uint32_t GetCompanyInfo(CompanyID owner, const struct Livery *l = nullptr);
314CommandCost GetErrorMessageFromLocationCallbackResult(uint16_t cb_res, std::span<const int32_t> textstack, const GRFFile *grffile, StringID default_error);
315
316void ErrorUnknownCallbackResult(GrfID grfid, uint16_t cbid, uint16_t cb_res);
317bool ConvertBooleanCallback(const struct GRFFile *grffile, uint16_t cbid, uint16_t cb_res);
318bool Convert8bitBooleanCallback(const struct GRFFile *grffile, uint16_t cbid, uint16_t cb_res);
319
324 uint16_t local_id = 0;
326 const struct GRFFile *grffile = nullptr;
327
328 void SetGRFFile(const struct GRFFile *grffile);
329
334 inline bool HasGrfFile() const { return this->grffile != nullptr; }
335};
336
342template <class Tkey, size_t Tcount>
344 std::array<const struct SpriteGroup *, Tcount> spritegroups{};
345
351 const struct SpriteGroup *GetSpriteGroup(Tkey index) const { return this->spritegroups[static_cast<size_t>(index)]; }
352
358 const struct SpriteGroup *GetFirstSpriteGroupOf(std::initializer_list<Tkey> indices) const
359 {
360 for (auto key : indices) {
361 auto *result = GetSpriteGroup(key);
362 if (result != nullptr) return result;
363 }
364 return nullptr;
365 }
366
372 void SetSpriteGroup(Tkey index, const struct SpriteGroup *spritegroup) { this->spritegroups[static_cast<size_t>(index)] = spritegroup; }
373};
374
383
387struct StandardGRFFileProps : FixedGRFFileProps<StandardSpriteGroup, static_cast<size_t>(StandardSpriteGroup::End)> {
389
394 bool HasSpriteGroups() const
395 {
397 }
398
404 const struct SpriteGroup *GetSpriteGroup(bool entity_exists) const
405 {
406 auto *res = entity_exists ? nullptr : GetSpriteGroup(StandardSpriteGroup::Purchase);
408 }
409};
410
415template <class Tkey>
417 using ValueType = std::pair<Tkey, const struct SpriteGroup *>;
418 std::vector<ValueType> spritegroups;
419
425 const SpriteGroup *GetSpriteGroup(Tkey index) const
426 {
427 auto it = std::ranges::lower_bound(this->spritegroups, index, std::less{}, &ValueType::first);
428 if (it == std::end(this->spritegroups) || it->first != index) return nullptr;
429 return it->second;
430 }
431
437 const struct SpriteGroup *GetFirstSpriteGroupOf(std::initializer_list<Tkey> indices) const
438 {
439 for (auto key : indices) {
440 auto *result = GetSpriteGroup(key);
441 if (result != nullptr) return result;
442 }
443 return nullptr;
444 }
445
451 void SetSpriteGroup(Tkey index, const SpriteGroup *spritegroup)
452 {
453 auto it = std::ranges::lower_bound(this->spritegroups, index, std::less{}, &ValueType::first);
454 if (it == std::end(this->spritegroups) || it->first != index) {
455 this->spritegroups.emplace(it, index, spritegroup);
456 } else {
457 it->second = spritegroup;
458 }
459 }
460};
461
466 static constexpr CargoType SG_DEFAULT{NUM_CARGO};
467 static constexpr CargoType SG_PURCHASE{NUM_CARGO + 1};
468 static constexpr CargoType SG_DEFAULT_NA{NUM_CARGO + 2};
469};
470
484
486template <typename T>
488 T label = {};
489 uint8_t subtype = 0;
490};
491
492#endif /* NEWGRF_COMMONS_H */
Functions related to bit mathematics.
Types related to cargoes...
static constexpr CargoType NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:75
CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:22
bool CheckValidNewID(uint16_t testid) override
Checks whether the given ID is valid in the context of this override manager.
Common return value for all commands.
void SetEntitySpec(HouseSpec &&hs)
Install the specs into the HouseSpecs array It will find itself the proper slot on which it will go.
uint16_t GetID(uint16_t grf_local_id, GrfID grfid) const override
Return the ID (if ever available) of a previously inserted entity.
uint16_t AddEntityID(uint16_t grf_local_id, GrfID grfid, uint16_t substitute_id) override
Method to find an entity ID and to mark it as reserved for the Industry to be included.
void SetEntitySpec(IndustrySpec &&inds)
Method to install the new industry data in its proper slot The slot assignment is internal of this me...
bool CheckValidNewID(uint16_t testid) override
Checks whether the given ID is valid in the context of this override manager.
bool CheckValidNewID(uint16_t testid) override
Checks whether the given ID is valid in the context of this override manager.
void SetEntitySpec(ObjectSpec &&spec)
Method to install the new object data in its proper slot The slot assignment is internal of this meth...
virtual uint16_t GetID(uint16_t grf_local_id, GrfID grfid) const
Return the ID (if ever available) of a previously inserted entity.
virtual ~OverrideManagerBase()=default
Ensure the destructor of the sub classes are called as well.
void ResetMapping()
Resets the mapping, which is used while initializing game.
uint16_t max_entities
what is the amount of entities, old and new summed
uint16_t invalid_id
ID used to detected invalid entities.
GrfID GetGRFID(uint16_t entity_id) const
Gives the GRFID of the file the entity belongs to.
OverrideManagerBase(uint16_t offset, uint16_t maximum, uint16_t invalid)
Constructor of generic class.
std::vector< EntityIDMapping > mappings
mapping of ids from grf files. Public out of convenience
virtual bool CheckValidNewID(uint16_t testid)
Checks whether the given ID is valid in the context of this override manager.
void Add(uint16_t local_id, GrfID grfid, uint entity_type)
Since the entity IDs defined by the GRF file does not necessarily correlate to those used by the game...
void ResetOverride()
Resets the override, which is used while initializing game.
uint16_t GetSubstituteID(uint16_t entity_id) const
Gives the substitute of the entity, as specified by the grf file.
uint16_t max_offset
what is the length of the original entity's array of specs
virtual uint16_t AddEntityID(uint16_t grf_local_id, GrfID grfid, uint16_t substitute_id)
Reserves a place in the mapping array for an entity to be installed.
Add dynamic register values to a sprite layout.
DrawTileSpriteSpan GetLayout() const
Returns the result spritelayout after preprocessing.
void ProcessRegisters(const struct ResolverObject &object, uint8_t resolved_var10, uint32_t resolved_sprite)
Evaluates the register modifiers and integrates them into the preprocessed sprite layout.
SpriteLayoutProcessor(const NewGRFSpriteLayout &raw_layout)
Constructor for spritelayout, which do not need preprocessing.
SetBitIterator< uint8_t, uint32_t > Var10Values() const
Get values for variable 10 to resolve sprites for.
Types related to commands.
Types related to companies.
Different types to 'show' directions.
Axis
Enumeration for the two axis X and Y.
@ Invalid
Flag for an invalid Axis.
#define T
Climate temperate.
Definition engines.h:91
#define DECLARE_ENUM_AS_BIT_SET(enum_type)
Operators to allow to work with enum as with type safe bit set in C++.
bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
uint32_t GetCompanyInfo(CompanyID owner, const Livery *l)
Returns company information like in vehicle var 43 or station var 43.
bool ConvertBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
TileContext
Context for tile accesses.
@ UpperHalftile
Querying information about the upper part of a tile with halftile foundation.
@ Normal
Nothing special.
@ OnBridge
Querying information about stuff on the bridge (via some bridgehead).
StandardSpriteGroup
Standard sprite groups.
@ Purchase
Used before an entity exists.
@ Default
Default type used when no more-specific group matches.
TileIndex GetNearbyTile(uint8_t parameter, TileIndex tile, bool signed_offsets=true, Axis axis=Axis::Invalid)
Get the tile at the given offset.
TileLayoutFlags
Flags to enable register usage in sprite layouts.
@ TLF_BB_Z_OFFSET
Add signed offset to bounding box Z positions from register TileLayoutRegisters::delta....
@ TLF_CUSTOM_PALETTE
Palette is from Action 1 (moved to SPRITE_MODIFIER_CUSTOM_SPRITE in palette during loading).
@ TLF_SPRITE
Add signed offset to sprite from register TileLayoutRegisters::sprite.
@ TLF_CHILD_X_OFFSET
Add signed offset to child sprite X positions from register TileLayoutRegisters::delta....
@ TLF_DRAWING_FLAGS
Flags which are still required after loading the GRF.
@ TLF_DODRAW
Only draw sprite if value of register TileLayoutRegisters::dodraw is non-zero.
@ TLF_PALETTE_REG_FLAGS
Flags which require resolving the action-1-2-3 chain for the palette, even if it is no action-1 palet...
@ TLF_NON_GROUND_FLAGS
Flags which do not work for the (first) ground sprite.
@ TLF_BB_XY_OFFSET
Add signed offset to bounding box X and Y positions from register TileLayoutRegisters::delta....
@ TLF_SPRITE_REG_FLAGS
Flags which require resolving the action-1-2-3 chain for the sprite, even if it is no action-1 sprite...
@ TLF_PALETTE_VAR10
Resolve palette with a specific value in variable 10.
@ TLF_SPRITE_VAR10
Resolve sprite with a specific value in variable 10.
@ TLF_KNOWN_FLAGS
Known flags. Any unknown set flag will disable the GRF.
@ TLF_VAR10_FLAGS
Flags which refer to using multiple action-1-2-3 chains.
@ TLF_PALETTE
Add signed offset to palette from register TileLayoutRegisters::palette.
@ TLF_CHILD_Y_OFFSET
Add signed offset to child sprite Y positions from register TileLayoutRegisters::delta....
static const uint TLR_MAX_VAR10
Maximum value for var 10.
uint32_t GetTerrainType(TileIndex tile, TileContext context=TileContext::Normal)
Function used by houses (and soon industries) to get information on type of "terrain" the tile it is ...
CommandCost GetErrorMessageFromLocationCallbackResult(uint16_t cb_res, std::span< const int32_t > textstack, const GRFFile *grffile, StringID default_error)
Get the error message from a shape/location/slope check callback result.
uint32_t GetNearbyTileInformation(TileIndex tile, bool grf_version8)
Common part of station var 0x67, house var 0x62, indtile var 0x60, industry var 0x62.
uint GetConstructionStageOffset(uint construction_stage, uint num_sprites)
Determines which sprite to use from a spriteset for a specific construction stage.
void ErrorUnknownCallbackResult(GrfID grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
Commonly used types for the NewGRF implementation.
uint32_t GrfID
The unique identifier of a NewGRF.
Definition newgrf_type.h:15
Base for drawing complex sprites.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Defines the data structure for an airport.
Defines the data structure of each individual tile of an airport.
Sprite groups indexed by CargoType.
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.
Ground palette sprite of a tile, together with its sprite layout.
Definition sprite.h:76
PalSpriteID ground
Palette and sprite for the ground.
Definition sprite.h:56
Maps an entity id stored on the map to a GRF file.
uint16_t substitute_id
The (original) entity ID to use if this GRF is not available.
uint16_t entity_id
The entity ID within the GRF file.
GrfID grfid
The GRF ID of the file the entity belongs to.
Fixed-length list of sprite groups for an entity.
const struct SpriteGroup * GetSpriteGroup(Tkey index) const
Get the SpriteGroup at the specified index.
void SetSpriteGroup(Tkey index, const struct SpriteGroup *spritegroup)
Set the SpriteGroup at the specified index.
std::array< const struct SpriteGroup *, Tcount > spritegroups
pointers to the different sprite groups of the entity
const struct SpriteGroup * GetFirstSpriteGroupOf(std::initializer_list< Tkey > indices) const
Get the first existing SpriteGroup from a list of options.
Base data related to the handling of grf files.
GrfID grfid
grfid that introduced this entity.
const struct GRFFile * grffile
grf file that introduced this entity
uint16_t local_id
id defined by the grf file for this entity
void SetGRFFile(const struct GRFFile *grffile)
Set the NewGRF file, and its grfid, associated with grf props.
bool HasGrfFile() const
Test if this entity was introduced by NewGRF.
Dynamic data of a loaded NewGRF.
Definition newgrf.h:124
Defines the data structure for constructing industry.
Defines the data structure of each individual tile of an industry.
Container for a label for rail or road type conversion.
uint8_t subtype
Subtype of type (road or tram).
T label
Label of rail or road type.
Information about a particular livery.
Definition livery.h:82
NewGRF supplied spritelayout.
void Allocate(uint num_sprites)
Allocate a spritelayout for num_sprites building sprites.
uint consistent_max_offset
Number of sprites in all referenced spritesets.
bool NeedsPreprocessing() const
Tests whether this spritelayout needs preprocessing by SpriteLayoutProcessor, or whether it can be us...
void AllocateRegisters()
Allocate memory for register modifiers.
std::span< const DrawTileSeqStruct > GetSequence() const override
The child sprites to draw.
An object that isn't use for transport, industries or houses.
Interface for SpriteGroup-s to access the gamestate.
Iterable ensemble of each set bit in a value.
Common wrapper for all the different sprite group types.
Container for standard sprite groups.
const struct SpriteGroup * GetSpriteGroup(bool entity_exists) const
Get the standard sprite group.
bool HasSpriteGroups() const
Check whether the entity has sprite groups.
uint16_t override_id
The id of the entity been replaced by.
uint16_t subst_id
The id of the entity to replace.
constexpr SubstituteGRFFileProps(uint16_t subst_id=0)
Set all default data constructor for the props.
Additional modifiers for items in sprite layouts.
uint8_t parent[3]
Registers for signed offsets for the bounding box position of parent sprites.
TileLayoutFlags flags
Flags defining which members are valid and to be used.
uint8_t dodraw
Register deciding whether the sprite shall be drawn at all. Non-zero means drawing.
uint16_t max_sprite_offset
Maximum offset to add to the sprite. (limited by size of the spriteset).
uint8_t palette
Register specifying a signed offset for the palette.
uint8_t sprite_var10
Value for variable 10 when resolving the sprite.
uint16_t max_palette_offset
Maximum offset to add to the palette. (limited by size of the spriteset).
uint8_t palette_var10
Value for variable 10 when resolving the palette.
uint8_t child[2]
Registers for signed offsets for the position of child sprites.
uint8_t sprite
Register specifying a signed offset for the sprite.
Variable-length list of sprite groups for an entity.
std::vector< ValueType > spritegroups
pointers to the different sprite groups of the entity
const struct SpriteGroup * GetFirstSpriteGroupOf(std::initializer_list< Tkey > indices) const
Get the first existing SpriteGroup from a list of options.
const SpriteGroup * GetSpriteGroup(Tkey index) const
Get the SpriteGroup at the specified index.
void SetSpriteGroup(Tkey index, const SpriteGroup *spritegroup)
Set the SpriteGroup at the specified index.
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92