Change: Provide road and rail overlay sprites for bridge decks. (#14557)
This allows bridges designed primarily with NewGRF railtypes and roadtypes to be at least somewhat compatible with built-in rail and road.
This commit is contained in:
@@ -135,6 +135,19 @@ bool HasBridgeFlatRamp(Slope tileh, Axis axis)
|
||||
return (tileh != SLOPE_FLAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if bridge piece uses a custom sprite table.
|
||||
* @param bridge_type Bridge type.
|
||||
* @param piece Bridge piece.
|
||||
* @return True iff a custom sprite table is used for the bridge piece.
|
||||
*/
|
||||
static bool BridgeHasCustomSpriteTable(BridgeType bridge_type, BridgePieces piece)
|
||||
{
|
||||
assert(piece < NUM_BRIDGE_PIECES);
|
||||
const BridgeSpec *bridge = GetBridgeSpec(bridge_type);
|
||||
return piece < bridge->sprite_table.size() && !bridge->sprite_table[piece].empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the sprite table for a rail/road bridge piece.
|
||||
* @param bridge_type Bridge type.
|
||||
@@ -1158,8 +1171,9 @@ static void GetBridgeRoadCatenary(const RoadTypeInfo *rti, TileIndex head_tile,
|
||||
* @param z the z of the bridge
|
||||
* @param offset sprite offset identifying flat to sloped bridge tiles
|
||||
* @param head are we drawing bridge head?
|
||||
* @param is_custom_layout Set if the bridge uses a custom sprite layout.
|
||||
*/
|
||||
static void DrawBridgeRoadBits(TileIndex head_tile, int x, int y, int z, int offset, bool head)
|
||||
static void DrawBridgeRoadBits(TileIndex head_tile, int x, int y, int z, int offset, bool head, bool is_custom_layout)
|
||||
{
|
||||
RoadType road_rt = GetRoadTypeRoad(head_tile);
|
||||
RoadType tram_rt = GetRoadTypeTram(head_tile);
|
||||
@@ -1178,6 +1192,9 @@ static void DrawBridgeRoadBits(TileIndex head_tile, int x, int y, int z, int off
|
||||
if (road_rti != nullptr) {
|
||||
if (road_rti->UsesOverlay()) {
|
||||
seq_back[0] = GetCustomRoadSprite(road_rti, head_tile, ROTSG_BRIDGE, head ? TCX_NORMAL : TCX_ON_BRIDGE) + offset;
|
||||
} else if (is_custom_layout) {
|
||||
/* For custom layouts draw a custom bridge deck. */
|
||||
seq_back[0] = SPR_BRIDGE_DECKS_ROAD + offset;
|
||||
}
|
||||
} else if (tram_rti != nullptr) {
|
||||
if (tram_rti->UsesOverlay()) {
|
||||
@@ -1428,13 +1445,16 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||
DrawBridgeMiddle(ti, BridgePillarFlag::EdgeNE + tunnelbridge_direction);
|
||||
} else { // IsBridge(ti->tile)
|
||||
DrawFoundation(ti, GetBridgeFoundation(ti->tileh, DiagDirToAxis(tunnelbridge_direction)));
|
||||
bool is_custom_layout; // Set if rail/road bridge uses a custom layout.
|
||||
|
||||
uint base_offset = GetBridgeRampDirectionBaseOffset(tunnelbridge_direction);
|
||||
std::span<const PalSpriteID> psid;
|
||||
if (transport_type != TRANSPORT_WATER) {
|
||||
BridgeType bridge_type = GetBridgeType(ti->tile);
|
||||
if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
|
||||
base_offset += GetBridgeSpriteTableBaseOffset(transport_type, ti->tile);
|
||||
psid = GetBridgeSpriteTable(GetBridgeType(ti->tile), BRIDGE_PIECE_HEAD);
|
||||
psid = GetBridgeSpriteTable(bridge_type, BRIDGE_PIECE_HEAD);
|
||||
is_custom_layout = BridgeHasCustomSpriteTable(bridge_type, BRIDGE_PIECE_HEAD);
|
||||
} else {
|
||||
psid = _aqueduct_sprite_table_heads;
|
||||
}
|
||||
@@ -1473,23 +1493,18 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||
}
|
||||
|
||||
/* DrawBridgeRoadBits() calls EndSpriteCombine() and StartSpriteCombine() */
|
||||
DrawBridgeRoadBits(ti->tile, ti->x, ti->y, z, offset, true);
|
||||
DrawBridgeRoadBits(ti->tile, ti->x, ti->y, z, offset, true, is_custom_layout);
|
||||
|
||||
EndSpriteCombine();
|
||||
} else if (transport_type == TRANSPORT_RAIL) {
|
||||
const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
||||
if (rti->UsesOverlay()) {
|
||||
SpriteID surface = GetCustomRailSprite(rti, ti->tile, RTSG_BRIDGE);
|
||||
if (surface != 0) {
|
||||
if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) {
|
||||
AddSortableSpriteToDraw(surface + ((DiagDirToAxis(tunnelbridge_direction) == AXIS_X) ? RTBO_X : RTBO_Y), PAL_NONE, *ti, {{0, 0, TILE_HEIGHT}, {TILE_SIZE, TILE_SIZE, 0}, {}});
|
||||
} else {
|
||||
AddSortableSpriteToDraw(surface + RTBO_SLOPE + tunnelbridge_direction, PAL_NONE, *ti, {{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT}, {}});
|
||||
}
|
||||
SpriteID surface = rti->UsesOverlay() ? GetCustomRailSprite(rti, ti->tile, RTSG_BRIDGE) : rti->base_sprites.bridge_deck;
|
||||
if (surface != 0) {
|
||||
if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) {
|
||||
AddSortableSpriteToDraw(surface + ((DiagDirToAxis(tunnelbridge_direction) == AXIS_X) ? RTBO_X : RTBO_Y), PAL_NONE, *ti, {{0, 0, TILE_HEIGHT}, {TILE_SIZE, TILE_SIZE, 0}, {}});
|
||||
} else {
|
||||
AddSortableSpriteToDraw(surface + RTBO_SLOPE + tunnelbridge_direction, PAL_NONE, *ti, {{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT}, {}});
|
||||
}
|
||||
/* Don't fallback to non-overlay sprite -- the spec states that
|
||||
* if an overlay is present then the bridge surface must be
|
||||
* present. */
|
||||
}
|
||||
|
||||
/* PBS debugging, draw reserved tracks darker */
|
||||
@@ -1614,16 +1629,19 @@ void DrawBridgeMiddle(const TileInfo *ti, BridgePillarFlags blocked_pillars)
|
||||
TransportType transport_type = GetTunnelBridgeTransportType(rampsouth);
|
||||
Axis axis = GetBridgeAxis(ti->tile);
|
||||
BridgePillarFlags pillars;
|
||||
bool is_custom_layout; // Set if rail/road bridge uses a custom layout.
|
||||
|
||||
uint base_offset = GetBridgeMiddleAxisBaseOffset(axis);
|
||||
std::span<const PalSpriteID> psid;
|
||||
bool drawfarpillar;
|
||||
if (transport_type != TRANSPORT_WATER) {
|
||||
BridgeType bridge_type = GetBridgeType(rampsouth);
|
||||
BridgePieces bridge_piece = CalcBridgePiece(GetTunnelBridgeLength(ti->tile, rampnorth) + 1, GetTunnelBridgeLength(ti->tile, rampsouth) + 1);
|
||||
drawfarpillar = !HasBit(GetBridgeSpec(bridge_type)->flags, 0);
|
||||
base_offset += GetBridgeSpriteTableBaseOffset(transport_type, rampsouth);
|
||||
psid = GetBridgeSpriteTable(bridge_type, CalcBridgePiece(GetTunnelBridgeLength(ti->tile, rampnorth) + 1, GetTunnelBridgeLength(ti->tile, rampsouth) + 1));
|
||||
psid = GetBridgeSpriteTable(bridge_type, bridge_piece);
|
||||
pillars = GetBridgeTilePillarFlags(ti->tile, rampnorth, rampsouth, bridge_type, transport_type);
|
||||
is_custom_layout = BridgeHasCustomSpriteTable(bridge_type, bridge_piece);
|
||||
} else {
|
||||
drawfarpillar = true;
|
||||
psid = _aqueduct_sprite_table_middle;
|
||||
@@ -1653,11 +1671,11 @@ void DrawBridgeMiddle(const TileInfo *ti, BridgePillarFlags blocked_pillars)
|
||||
|
||||
if (transport_type == TRANSPORT_ROAD) {
|
||||
/* DrawBridgeRoadBits() calls EndSpriteCombine() and StartSpriteCombine() */
|
||||
DrawBridgeRoadBits(rampsouth, x, y, bridge_z, axis ^ 1, false);
|
||||
DrawBridgeRoadBits(rampsouth, x, y, bridge_z, axis ^ 1, false, is_custom_layout);
|
||||
} else if (transport_type == TRANSPORT_RAIL) {
|
||||
const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(rampsouth));
|
||||
if (rti->UsesOverlay() && !IsInvisibilitySet(TO_BRIDGES)) {
|
||||
SpriteID surface = GetCustomRailSprite(rti, rampsouth, RTSG_BRIDGE, TCX_ON_BRIDGE);
|
||||
if (!IsInvisibilitySet(TO_BRIDGES)) {
|
||||
SpriteID surface = rti->UsesOverlay() ? GetCustomRailSprite(rti, rampsouth, RTSG_BRIDGE, TCX_ON_BRIDGE) : rti->base_sprites.bridge_deck;
|
||||
if (surface != 0) {
|
||||
AddSortableSpriteToDraw(surface + axis, PAL_NONE, x, y, bridge_z, {{}, {TILE_SIZE, TILE_SIZE, 0}, {}}, IsTransparencySet(TO_BRIDGES));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user