35 GrfMsg(1,
"StationChangeInfo: Station {} is invalid, max {}, ignoring", last,
NUM_STATIONS_PER_GRF);
40 if (_cur_gps.grffile->stations.size() < last) _cur_gps.grffile->stations.resize(last);
42 for (uint
id = first;
id < last; ++id) {
43 auto &statspec = _cur_gps.grffile->stations[id];
46 if (statspec ==
nullptr && prop != 0x08) {
47 GrfMsg(2,
"StationChangeInfo: Attempt to modify undefined station {}, ignoring",
id);
54 if (statspec ==
nullptr) {
55 statspec = std::make_unique<StationSpec>();
66 statspec->renderdata.clear();
67 statspec->renderdata.reserve(tiles);
69 for (uint t = 0; t < tiles; t++) {
73 if (buf.HasData(4) && buf.
PeekDWord() == 0) {
78 dts->seq.insert(dts->seq.end(), dtss.GetSequence().begin(), dtss.GetSequence().end());
86 std::vector<DrawTileSeqStruct> tmp_layout;
89 if (delta_x == 0x80)
break;
104 dts->seq = std::move(tmp_layout);
108 if (statspec->renderdata.size() & 1) {
109 GrfMsg(1,
"StationChangeInfo: Station {} defines an odd number of sprite layouts, dropping the last item",
id);
110 statspec->renderdata.pop_back();
117 const StationSpec *srcstatspec = srcid >= _cur_gps.grffile->stations.size() ? nullptr : _cur_gps.grffile->stations[srcid].get();
119 if (srcstatspec ==
nullptr) {
120 GrfMsg(1,
"StationChangeInfo: Station {} is not defined, cannot copy sprite layout to {}.", srcid,
id);
125 statspec->renderdata.reserve(srcstatspec->
renderdata.size());
127 for (
const auto &it : srcstatspec->
renderdata) {
128 statspec->renderdata.emplace_back(it);
134 statspec->callback_mask =
static_cast<StationCallbackMasks
>(buf.
ReadByte());
138 statspec->disallowed_platforms = buf.
ReadByte();
142 statspec->disallowed_lengths = buf.
ReadByte();
146 while (buf.HasData()) {
150 if (length == 0 || number == 0)
break;
152 const uint8_t *buf_layout = buf.ReadBytes(length * number);
156 layout.assign(buf_layout, buf_layout + length * number);
159 for (
auto &tile : layout) {
160 if ((tile & ~1U) != tile) {
161 GrfMsg(1,
"StationChangeInfo: Invalid tile {} in layout {}x{}", tile, length, number);
170 const StationSpec *srcstatspec = srcid >= _cur_gps.grffile->stations.size() ? nullptr : _cur_gps.grffile->stations[srcid].get();
172 if (srcstatspec ==
nullptr) {
173 GrfMsg(1,
"StationChangeInfo: Station {} is not defined, cannot copy tile layout to {}.", srcid,
id);
182 statspec->cargo_threshold = buf.
ReadWord();
187 if (statspec->tileflags.size() < 8) statspec->tileflags.resize(8);
188 for (
int j = 0; j < 8; ++j) {
199 if (_cur_gps.grffile->grf_version >= 7) {
202 statspec->cargo_triggers = (CargoTypes)buf.
ReadDWord();
207 statspec->flags = StationSpecFlags{buf.
ReadByte()};
212 if (statspec->tileflags.size() < 8) statspec->tileflags.resize(8);
213 for (
int j = 0; j < 8; ++j) {
225 if (statspec->tileflags.size() < 8) statspec->tileflags.resize(8);
226 for (
int j = 0; j < 8; ++j) {
237 statspec->animation.frames = buf.
ReadByte();
242 statspec->animation.speed = buf.
ReadByte();
246 statspec->animation.triggers =
static_cast<StationAnimationTriggers
>(buf.
ReadWord());
253 statspec->renderdata.clear();
254 statspec->renderdata.reserve(tiles);
256 for (uint t = 0; t < tiles; t++) {
258 uint num_building_sprites = buf.
ReadByte();
264 if (statspec->renderdata.size() & 1) {
265 GrfMsg(1,
"StationChangeInfo: Station {} defines an odd number of sprite layouts, dropping the last item",
id);
266 statspec->renderdata.pop_back();
288 auto flags =
reinterpret_cast<const StationSpec::TileFlags *
>(buf.ReadBytes(tiles));
289 statspec->tileflags.assign(flags, flags + tiles);
299 if (statspec->bridgeable_info.size() < tiles) statspec->bridgeable_info.resize(tiles);
300 for (
int j = 0; j != tiles; ++j) {
301 statspec->bridgeable_info[j].height = buf.
ReadByte();
308 if (statspec->bridgeable_info.size() < tiles) statspec->bridgeable_info.resize(tiles);
309 for (
int j = 0; j != tiles; ++j) {
310 statspec->bridgeable_info[j].disallowed_pillars = BridgePillarFlags{buf.
ReadByte()};
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr enable_if_t< is_integral_v< T >, T > byteswap(T x) noexcept
Custom implementation of std::byteswap; remove once we build with C++23.
Class to read from a NewGRF file.
uint32_t PeekDWord()
Read a single DWord (32 bits).
uint32_t ReadDWord()
Read a single DWord (32 bits).
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).
StringID name
Name of this class.
static NewGRFClass * Get(StationClassID class_index)
static StationClassID Allocate(uint32_t global_id)
Functions related to debugging.
CargoTypes TranslateRefitMask(uint32_t refit_mask)
Translate the refit mask.
std::vector< BadgeID > ReadBadgeList(ByteReader &buf, GrfSpecFeature feature)
Read a list of badges.
static ChangeInfoResult StationChangeInfo(uint first, uint last, int prop, ByteReader &buf)
Define properties for stations.
static const uint NUM_STATIONS_PER_GRF
The maximum amount of stations a single GRF is allowed to add.
TileLayoutFlags ReadSpriteLayoutSprite(ByteReader &buf, bool read_flags, bool invert_action1_flag, bool use_cur_spritesets, GrfSpecFeature feature, PalSpriteID *grf_sprite, uint16_t *max_sprite_offset, uint16_t *max_palette_offset)
Read a sprite and a palette from the GRF and convert them into a format suitable to OpenTTD.
bool ReadSpriteLayout(ByteReader &buf, uint num_building_sprites, bool use_cur_spritesets, GrfSpecFeature feature, bool allow_var10, bool no_z_position, NewGRFSpriteLayout *dts)
Read a spritelayout from the GRF.
AnimationStatus
Statuses of animation within NewGRFs.
NewGRF buffer reader definition.
NewGRF internal processing state.
ChangeInfoResult
Possible return values for the GrfChangeInfoHandler functions.
@ CIR_INVALID_ID
Attempt to modify an invalid ID.
@ CIR_DISABLED
GRF was disabled due to error.
@ CIR_UNKNOWN
Variable is unknown.
@ CIR_UNHANDLED
Variable was parsed but unread.
@ CIR_SUCCESS
Variable was parsed and read.
Header file for NewGRF stations.
uint16_t GetStationLayoutKey(uint8_t platforms, uint8_t length)
Get the station layout key for a given station layout size.
void AddStringForMapping(GRFStringID source, std::function< void(StringID)> &&func)
Record a static StringID for getting translated later.
NewGRF string mapping definition.
StrongType::Typedef< uint32_t, struct GRFStringIDTag, StrongType::Compare, StrongType::Integer > GRFStringID
Type for GRF-internal string IDs.
A number of safeguards to prevent using unsafe methods.
Definition of base types and functions in a cross-platform compatible way.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
A tile child sprite and palette to draw for stations etc, with 3D bounding box.
Ground palette sprite of a tile, together with its sprite layout.
PalSpriteID ground
Palette and sprite for the ground.
NewGRF supplied spritelayout.
uint consistent_max_offset
Number of sprites in all referenced spritesets.
Coord3D< int8_t > origin
Position of northern corner within tile.
Coord3D< uint8_t > extent
Size of bounding box.
std::unordered_map< uint16_t, std::vector< uint8_t > > layouts
Custom platform layouts, keyed by platform and length combined.
std::vector< NewGRFSpriteLayout > renderdata
Number of tile layouts.
@ NoWires
Tile should NOT contain catenary wires.
@ Pylons
Tile should contain catenary pylons.
@ Blocked
Tile is blocked to vehicles.