Add: [NewGRF] Station property 1E, extended station tile flags.

Properties 11, 14 and 15 to set pylons/nowires/blocked intrinsically only support 8 station tiles.

Add new property to define all three flags for each station tile layout.
master
Peter Nelson 5 months ago committed by Peter Nelson
parent 6e553410d3
commit a03ddb3ccb

@ -2075,9 +2075,18 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte
statspec->cargo_threshold = buf.ReadWord();
break;
case 0x11: // Pylon placement
statspec->pylons = buf.ReadByte();
case 0x11: { // Pylon placement
uint8_t pylons = buf.ReadByte();
if (statspec->tileflags.size() < 8) statspec->tileflags.resize(8);
for (int j = 0; j < 8; ++j) {
if (HasBit(pylons, j)) {
statspec->tileflags[j] |= StationSpec::TileFlags::Pylons;
} else {
statspec->tileflags[j] &= ~StationSpec::TileFlags::Pylons;
}
}
break;
}
case 0x12: // Cargo types for random triggers
if (_cur.grffile->grf_version >= 7) {
@ -2091,13 +2100,31 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte
statspec->flags = buf.ReadByte();
break;
case 0x14: // Overhead wire placement
statspec->wires = buf.ReadByte();
case 0x14: { // Overhead wire placement
uint8_t wires = buf.ReadByte();
if (statspec->tileflags.size() < 8) statspec->tileflags.resize(8);
for (int j = 0; j < 8; ++j) {
if (HasBit(wires, j)) {
statspec->tileflags[j] |= StationSpec::TileFlags::NoWires;
} else {
statspec->tileflags[j] &= ~StationSpec::TileFlags::NoWires;
}
}
break;
}
case 0x15: // Blocked tiles
statspec->blocked = buf.ReadByte();
case 0x15: { // Blocked tiles
uint8_t blocked = buf.ReadByte();
if (statspec->tileflags.size() < 8) statspec->tileflags.resize(8);
for (int j = 0; j < 8; ++j) {
if (HasBit(blocked, j)) {
statspec->tileflags[j] |= StationSpec::TileFlags::Blocked;
} else {
statspec->tileflags[j] &= ~StationSpec::TileFlags::Blocked;
}
}
break;
}
case 0x16: // Animation info
statspec->animation.frames = buf.ReadByte();
@ -2149,6 +2176,13 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte
AddStringForMapping(buf.ReadWord(), [statspec](StringID str) { StationClass::Get(statspec->class_index)->name = str; });
break;
case 0x1E: { // Extended tile flags (replaces prop 11, 14 and 15)
uint16_t tiles = buf.ReadExtendedByte();
auto flags = reinterpret_cast<const StationSpec::TileFlags *>(buf.ReadBytes(tiles));
statspec->tileflags.assign(flags, flags + tiles);
break;
}
default:
ret = CIR_UNKNOWN;
break;

@ -10,6 +10,7 @@
#ifndef NEWGRF_STATION_H
#define NEWGRF_STATION_H
#include "core/enum_type.hpp"
#include "newgrf_animation_type.h"
#include "newgrf_callbacks.h"
#include "newgrf_class.h"
@ -115,7 +116,7 @@ struct StationSpec : NewGRFSpecBase<StationClassID> {
StationSpec() : name(0),
disallowed_platforms(0), disallowed_lengths(0),
cargo_threshold(0), cargo_triggers(0),
callback_mask(0), flags(0), pylons(0), wires(0), blocked(0),
callback_mask(0), flags(0),
animation({0, 0, 0, 0}) {}
/**
* Properties related the the grf file.
@ -159,9 +160,13 @@ struct StationSpec : NewGRFSpecBase<StationClassID> {
uint8_t flags; ///< Bitmask of flags, bit 0: use different sprite set; bit 1: divide cargo about by station size
uint8_t pylons; ///< Bitmask of base tiles (0 - 7) which should contain elrail pylons
uint8_t wires; ///< Bitmask of base tiles (0 - 7) which should contain elrail wires
uint8_t blocked; ///< Bitmask of base tiles (0 - 7) which are blocked to trains
enum class TileFlags : uint8_t {
None = 0,
Pylons = 1U << 0, ///< Tile should contain catenary pylons.
NoWires = 1U << 1, ///< Tile should NOT contain catenary wires.
Blocked = 1U << 2, ///< Tile is blocked to vehicles.
};
std::vector<TileFlags> tileflags; ///< List of tile flags.
AnimationInfo animation;
@ -175,6 +180,7 @@ struct StationSpec : NewGRFSpecBase<StationClassID> {
*/
std::vector<std::vector<std::vector<uint8_t>>> layouts;
};
DECLARE_ENUM_AS_BIT_SET(StationSpec::TileFlags);
/** Class containing information relating to station classes. */
using StationClass = NewGRFClass<StationSpec, StationClassID, STAT_CLASS_MAX>;

@ -1305,6 +1305,19 @@ static CommandCost CalculateRailStationCost(TileArea tile_area, DoCommandFlag fl
return cost;
}
/**
* Get station tile flags for the given StationGfx.
* @param gfx StationGfx of station tile.
* @param statspec Station spec of station tile.
* @return Tile flags to apply.
*/
static StationSpec::TileFlags GetStationTileFlags(StationGfx gfx, const StationSpec *statspec)
{
/* Default stations do not draw pylons under roofs (gfx >= 4) */
if (statspec == nullptr || gfx >= statspec->tileflags.size()) return gfx < 4 ? StationSpec::TileFlags::Pylons : StationSpec::TileFlags::None;
return statspec->tileflags[gfx];
}
/**
* Set rail station tile flags for the given tile.
* @param tile Tile to set flags on.
@ -1312,15 +1325,10 @@ static CommandCost CalculateRailStationCost(TileArea tile_area, DoCommandFlag fl
*/
void SetRailStationTileFlags(TileIndex tile, const StationSpec *statspec)
{
const StationGfx gfx = GetStationGfx(tile);
bool blocked = statspec != nullptr && HasBit(statspec->blocked, gfx);
/* Default stations do not draw pylons under roofs (gfx >= 4) */
bool pylons = statspec != nullptr ? HasBit(statspec->pylons, gfx) : gfx < 4;
bool wires = statspec == nullptr || !HasBit(statspec->wires, gfx);
SetStationTileBlocked(tile, blocked);
SetStationTileHavePylons(tile, pylons);
SetStationTileHaveWires(tile, wires);
const auto flags = GetStationTileFlags(GetStationGfx(tile), statspec);
SetStationTileBlocked(tile, (flags & StationSpec::TileFlags::Blocked) == StationSpec::TileFlags::Blocked);
SetStationTileHavePylons(tile, (flags & StationSpec::TileFlags::Pylons) == StationSpec::TileFlags::Pylons);
SetStationTileHaveWires(tile, (flags & StationSpec::TileFlags::NoWires) != StationSpec::TileFlags::NoWires);
}
/**

Loading…
Cancel
Save