mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-08-30 18:09:09 +00:00
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:
@@ -63,7 +63,7 @@ inline const BridgeSpec *GetBridgeSpec(BridgeType i)
|
||||
return &_bridge[i];
|
||||
}
|
||||
|
||||
void DrawBridgeMiddle(const TileInfo *ti);
|
||||
void DrawBridgeMiddle(const TileInfo *ti, BridgePillarFlags blocked_pillars);
|
||||
|
||||
CommandCost CheckBridgeAvailability(BridgeType bridge_type, uint bridge_len, DoCommandFlags flags = {});
|
||||
int CalcBridgeLenCostFactor(int x);
|
||||
|
@@ -152,7 +152,7 @@ static void DrawTile_Clear(TileInfo *ti)
|
||||
break;
|
||||
}
|
||||
|
||||
DrawBridgeMiddle(ti);
|
||||
DrawBridgeMiddle(ti, {});
|
||||
}
|
||||
|
||||
static int GetSlopePixelZ_Clear(TileIndex tile, uint x, uint y, bool)
|
||||
|
@@ -483,7 +483,7 @@ static void DrawTile_Object(TileInfo *ti)
|
||||
DrawNewObjectTile(ti, spec);
|
||||
}
|
||||
|
||||
DrawBridgeMiddle(ti);
|
||||
DrawBridgeMiddle(ti, {});
|
||||
}
|
||||
|
||||
static int GetSlopePixelZ_Object(TileIndex tile, uint x, uint y, bool)
|
||||
|
@@ -2409,6 +2409,7 @@ static void DrawSignals(TileIndex tile, TrackBits rails, const RailTypeInfo *rti
|
||||
static void DrawTile_Track(TileInfo *ti)
|
||||
{
|
||||
const RailTypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
||||
BridgePillarFlags blocked_pillars{};
|
||||
PaletteID pal = GetCompanyPalette(GetTileOwner(ti->tile));
|
||||
|
||||
if (IsPlainRail(ti->tile)) {
|
||||
@@ -2421,17 +2422,25 @@ static void DrawTile_Track(TileInfo *ti)
|
||||
if (HasRailCatenaryDrawn(GetRailType(ti->tile))) DrawRailCatenary(ti);
|
||||
|
||||
if (HasSignals(ti->tile)) DrawSignals(ti->tile, rails, rti);
|
||||
|
||||
if (IsBridgeAbove(ti->tile)) {
|
||||
if ((rails & TRACK_BIT_3WAY_NE) != 0) blocked_pillars.Set(BridgePillarFlag::EdgeNE);
|
||||
if ((rails & TRACK_BIT_3WAY_SE) != 0) blocked_pillars.Set(BridgePillarFlag::EdgeSE);
|
||||
if ((rails & TRACK_BIT_3WAY_SW) != 0) blocked_pillars.Set(BridgePillarFlag::EdgeSW);
|
||||
if ((rails & TRACK_BIT_3WAY_NW) != 0) blocked_pillars.Set(BridgePillarFlag::EdgeNW);
|
||||
}
|
||||
} else {
|
||||
/* draw depot */
|
||||
const DrawTileSprites *dts;
|
||||
DiagDirection dir = GetRailDepotDirection(ti->tile);
|
||||
|
||||
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
|
||||
|
||||
if (IsInvisibilitySet(TO_BUILDINGS)) {
|
||||
/* Draw rail instead of depot */
|
||||
dts = &_depot_invisible_gfx_table[GetRailDepotDirection(ti->tile)];
|
||||
dts = &_depot_invisible_gfx_table[dir];
|
||||
} else {
|
||||
dts = &_depot_gfx_table[GetRailDepotDirection(ti->tile)];
|
||||
dts = &_depot_gfx_table[dir];
|
||||
}
|
||||
|
||||
SpriteID image;
|
||||
@@ -2520,8 +2529,9 @@ static void DrawTile_Track(TileInfo *ti)
|
||||
if (HasRailCatenaryDrawn(GetRailType(ti->tile))) DrawRailCatenary(ti);
|
||||
|
||||
DrawRailTileSeq(ti, dts, TO_BUILDINGS, relocation, 0, pal);
|
||||
/* Depots can't have bridges above so no blocked pillars. */
|
||||
}
|
||||
DrawBridgeMiddle(ti);
|
||||
DrawBridgeMiddle(ti, blocked_pillars);
|
||||
}
|
||||
|
||||
void DrawTrainDepotSprite(int x, int y, int dir, RailType railtype)
|
||||
|
@@ -1699,9 +1699,18 @@ static void DrawRoadBits(TileInfo *ti)
|
||||
/** Tile callback function for rendering a road tile to the screen */
|
||||
static void DrawTile_Road(TileInfo *ti)
|
||||
{
|
||||
BridgePillarFlags blocked_pillars{};
|
||||
switch (GetRoadTileType(ti->tile)) {
|
||||
case ROAD_TILE_NORMAL:
|
||||
DrawRoadBits(ti);
|
||||
|
||||
if (IsBridgeAbove(ti->tile)) {
|
||||
RoadBits bits = GetAllRoadBits(ti->tile);
|
||||
if ((bits & ROAD_NE) != 0) blocked_pillars.Set(BridgePillarFlag::EdgeNE);
|
||||
if ((bits & ROAD_SE) != 0) blocked_pillars.Set(BridgePillarFlag::EdgeSE);
|
||||
if ((bits & ROAD_SW) != 0) blocked_pillars.Set(BridgePillarFlag::EdgeSW);
|
||||
if ((bits & ROAD_NW) != 0) blocked_pillars.Set(BridgePillarFlag::EdgeNW);
|
||||
}
|
||||
break;
|
||||
|
||||
case ROAD_TILE_CROSSING: {
|
||||
@@ -1809,7 +1818,7 @@ static void DrawTile_Road(TileInfo *ti)
|
||||
|
||||
/* Draw rail catenary */
|
||||
if (HasRailCatenaryDrawn(GetRailType(ti->tile))) DrawRailCatenary(ti);
|
||||
|
||||
blocked_pillars = {BridgePillarFlag::EdgeSW, BridgePillarFlag::EdgeNE, BridgePillarFlag::EdgeNW, BridgePillarFlag::EdgeSE};
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1855,10 +1864,11 @@ static void DrawTile_Road(TileInfo *ti)
|
||||
}
|
||||
|
||||
DrawRailTileSeq(ti, dts, TO_BUILDINGS, relocation, 0, palette);
|
||||
/* Depots can't have bridges above so no blocked pillars. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
DrawBridgeMiddle(ti);
|
||||
DrawBridgeMiddle(ti, blocked_pillars);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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);
|
||||
}
|
||||
|
||||
|
@@ -926,12 +926,14 @@ static void DrawTile_Water(TileInfo *ti)
|
||||
switch (GetWaterTileType(ti->tile)) {
|
||||
case WATER_TILE_CLEAR:
|
||||
DrawWaterClassGround(ti);
|
||||
DrawBridgeMiddle(ti);
|
||||
/* A plain water tile can be traversed in any direction, so setting blocked pillars here would mean all bridges
|
||||
* with edges would have no pillars above water. Instead prefer current behaviour of ships passing through. */
|
||||
DrawBridgeMiddle(ti, {});
|
||||
break;
|
||||
|
||||
case WATER_TILE_COAST: {
|
||||
DrawShoreTile(ti->tileh);
|
||||
DrawBridgeMiddle(ti);
|
||||
DrawBridgeMiddle(ti, {});
|
||||
break;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user