Change: Hide bridge pillars if obstructed by tile below.

Tiles can now control if pillars are drawn on a bridge above it. There is no visible change with default bridges.
This commit is contained in:
Peter Nelson
2025-08-14 17:32:05 +01:00
committed by Peter Nelson
parent 48b42492bc
commit 0a1c0b8b48
7 changed files with 70 additions and 13 deletions

View File

@@ -1445,7 +1445,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, *ti, rear_sep[tunnelbridge_direction]);
AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, *ti, front_sep[tunnelbridge_direction]);
DrawBridgeMiddle(ti);
DrawBridgeMiddle(ti, BridgePillarFlag::EdgeNE + tunnelbridge_direction);
} else { // IsBridge(ti->tile)
DrawFoundation(ti, GetBridgeFoundation(ti->tileh, DiagDirToAxis(tunnelbridge_direction)));
@@ -1536,7 +1536,13 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
}
}
DrawBridgeMiddle(ti);
BridgePillarFlags blocked_pillars;
if (DiagDirToAxis(tunnelbridge_direction) == AXIS_X) {
blocked_pillars = {BridgePillarFlag::EdgeSW, BridgePillarFlag::EdgeNE};
} else {
blocked_pillars = {BridgePillarFlag::EdgeNW, BridgePillarFlag::EdgeSE};
}
DrawBridgeMiddle(ti, blocked_pillars);
}
}
@@ -1574,11 +1580,36 @@ static BridgePieces CalcBridgePiece(uint north, uint south)
}
}
/**
* Get pillar information for a bridge middle tile.
* @param tile Tile of bridge middle.
* @param rampnorth Northern ramp tile of bridge.
* @param rampsouth Southern ramp tile of bridge.
* @param type Bridge type.
* @param transport_type Transport type of bridge.
* @return Pillar flags for bridge middle.
*/
static BridgePillarFlags GetBridgeTilePillarFlags(TileIndex tile, TileIndex rampnorth, TileIndex rampsouth, BridgeType type, TransportType transport_type)
{
if (transport_type == TRANSPORT_WATER) return BRIDGEPILLARFLAGS_ALL_CORNERS;
const BridgeSpec *spec = GetBridgeSpec(type);
if (!spec->ctrl_flags.Test(BridgeSpec::ControlFlag::InvalidPillarFlags)) {
BridgePieces piece = CalcBridgePiece(GetTunnelBridgeLength(tile, rampnorth) + 1, GetTunnelBridgeLength(tile, rampsouth) + 1);
Axis axis = TileX(rampnorth) == TileX(rampsouth) ? AXIS_Y : AXIS_X;
return spec->pillar_flags[piece][axis == AXIS_Y ? 1 : 0];
}
return BRIDGEPILLARFLAGS_ALL_CORNERS;
}
/**
* Draw the middle bits of a bridge.
* @param ti Tile information of the tile to draw it on.
* @param blocked_pillars Mask of pillar corners and edges blocked by tile below the bridge.
*/
void DrawBridgeMiddle(const TileInfo *ti)
void DrawBridgeMiddle(const TileInfo *ti, BridgePillarFlags blocked_pillars)
{
/* Sectional view of bridge bounding boxes:
*
@@ -1602,6 +1633,7 @@ void DrawBridgeMiddle(const TileInfo *ti)
TileIndex rampsouth = GetSouthernBridgeEnd(ti->tile);
TransportType transport_type = GetTunnelBridgeTransportType(rampsouth);
Axis axis = GetBridgeAxis(ti->tile);
BridgePillarFlags pillars;
uint base_offset = GetBridgeMiddleAxisBaseOffset(axis);
std::span<const PalSpriteID> psid;
@@ -1611,9 +1643,11 @@ void DrawBridgeMiddle(const TileInfo *ti)
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));
pillars = GetBridgeTilePillarFlags(ti->tile, rampnorth, rampsouth, bridge_type, transport_type);
} else {
drawfarpillar = true;
psid = _aqueduct_sprite_table_middle;
pillars = BRIDGEPILLARFLAGS_ALL_CORNERS;
}
psid = psid.subspan(base_offset, 3);
@@ -1682,6 +1716,7 @@ void DrawBridgeMiddle(const TileInfo *ti)
/* Do not draw anything more if bridges are invisible */
if (IsInvisibilitySet(TO_BRIDGES)) return;
if (blocked_pillars.Any(pillars)) return;
DrawBridgePillars(psid[2], ti, axis, drawfarpillar, x, y, z);
}