src/tunnelbridge_cmd.cpp
branchnoai
changeset 9574 698395509d12
parent 9517 be1775555bbd
child 9601 b499fdd106d5
equal deleted inserted replaced
9573:fa56261c7142 9574:698395509d12
    59 };
    59 };
    60 
    60 
    61 Bridge _bridge[MAX_BRIDGES];
    61 Bridge _bridge[MAX_BRIDGES];
    62 
    62 
    63 
    63 
    64 // calculate the price factor for building a long bridge.
    64 /** calculate the price factor for building a long bridge.
    65 // basically the cost delta is 1,1, 1, 2,2, 3,3,3, 4,4,4,4, 5,5,5,5,5, 6,6,6,6,6,6,  7,7,7,7,7,7,7,  8,8,8,8,8,8,8,8,
    65  * basically the cost delta is 1,1, 1, 2,2, 3,3,3, 4,4,4,4, 5,5,5,5,5, 6,6,6,6,6,6,  7,7,7,7,7,7,7,  8,8,8,8,8,8,8,8,
       
    66  */
    66 int CalcBridgeLenCostFactor(int x)
    67 int CalcBridgeLenCostFactor(int x)
    67 {
    68 {
    68 	int n;
    69 	int n;
    69 	int r;
    70 	int r;
    70 
    71 
    77 	}
    78 	}
    78 }
    79 }
    79 
    80 
    80 #define M(x) (1 << (x))
    81 #define M(x) (1 << (x))
    81 enum BridgeFoundation {
    82 enum BridgeFoundation {
    82 	// foundation, whole tile is leveled up --> 3 corners raised
    83 	/* foundation, whole tile is leveled up --> 3 corners raised */
    83 	BRIDGE_FULL_LEVELED_FOUNDATION = M(SLOPE_WSE) | M(SLOPE_NWS) | M(SLOPE_ENW) | M(SLOPE_SEN),
    84 	BRIDGE_FULL_LEVELED_FOUNDATION = M(SLOPE_WSE) | M(SLOPE_NWS) | M(SLOPE_ENW) | M(SLOPE_SEN),
    84 	// foundation, tile is partly leveled up --> 1 corner raised
    85 	/* foundation, tile is partly leveled up --> 1 corner raised */
    85 	BRIDGE_PARTLY_LEVELED_FOUNDATION = M(SLOPE_W) | M(SLOPE_S) | M(SLOPE_E) | M(SLOPE_N),
    86 	BRIDGE_PARTLY_LEVELED_FOUNDATION = M(SLOPE_W) | M(SLOPE_S) | M(SLOPE_E) | M(SLOPE_N),
    86 	// no foundations (X,Y direction)
    87 	/* no foundations (X,Y direction) */
    87 	BRIDGE_NO_FOUNDATION = M(SLOPE_FLAT) | M(SLOPE_SW) | M(SLOPE_SE) | M(SLOPE_NW) | M(SLOPE_NE),
    88 	BRIDGE_NO_FOUNDATION = M(SLOPE_FLAT) | M(SLOPE_SW) | M(SLOPE_SE) | M(SLOPE_NW) | M(SLOPE_NE),
    88 	BRIDGE_HORZ_RAMP = (BRIDGE_PARTLY_LEVELED_FOUNDATION | BRIDGE_NO_FOUNDATION) & ~M(SLOPE_FLAT)
    89 	BRIDGE_HORZ_RAMP = (BRIDGE_PARTLY_LEVELED_FOUNDATION | BRIDGE_NO_FOUNDATION) & ~M(SLOPE_FLAT)
    89 };
    90 };
    90 #undef M
    91 #undef M
    91 
    92 
   165 	return b->min_length <= bridge_len && bridge_len <= max;
   166 	return b->min_length <= bridge_len && bridge_len <= max;
   166 }
   167 }
   167 
   168 
   168 /** Build a Bridge
   169 /** Build a Bridge
   169  * @param end_tile end tile
   170  * @param end_tile end tile
       
   171  * @param flags type of operation
   170  * @param p1 packed start tile coords (~ dx)
   172  * @param p1 packed start tile coords (~ dx)
   171  * @param p2 various bitstuffed elements
   173  * @param p2 various bitstuffed elements
   172  * - p2 = (bit 0- 7) - bridge type (hi bh)
   174  * - p2 = (bit 0- 7) - bridge type (hi bh)
   173  * - p2 = (bit 8-..) - rail type. bit15 ((x>>8)&0x80) means road bridge.
   175  * - p2 = (bit 8-..) - rail type. bit15 ((x>>8)&0x80) means road bridge.
   174  */
   176  */
   200 	/* unpack parameters */
   202 	/* unpack parameters */
   201 	bridge_type = GB(p2, 0, 8);
   203 	bridge_type = GB(p2, 0, 8);
   202 
   204 
   203 	if (p1 >= MapSize()) return CMD_ERROR;
   205 	if (p1 >= MapSize()) return CMD_ERROR;
   204 
   206 
   205 	// type of bridge
   207 	/* type of bridge */
   206 	if (HASBIT(p2, 15)) {
   208 	if (HASBIT(p2, 15)) {
   207 		railtype = INVALID_RAILTYPE; // road bridge
   209 		railtype = INVALID_RAILTYPE; // road bridge
   208 	} else {
   210 	} else {
   209 		if (!ValParamRailtype(GB(p2, 8, 8))) return CMD_ERROR;
   211 		if (!ValParamRailtype(GB(p2, 8, 8))) return CMD_ERROR;
   210 		railtype = (RailType)GB(p2, 8, 8);
   212 		railtype = (RailType)GB(p2, 8, 8);
   253 		tileh_end = SLOPE_FLAT;
   255 		tileh_end = SLOPE_FLAT;
   254 	}
   256 	}
   255 
   257 
   256 	if (z_start != z_end) return_cmd_error(STR_5009_LEVEL_LAND_OR_WATER_REQUIRED);
   258 	if (z_start != z_end) return_cmd_error(STR_5009_LEVEL_LAND_OR_WATER_REQUIRED);
   257 
   259 
   258 	// Towns are not allowed to use bridges on slopes.
   260 	/* Towns are not allowed to use bridges on slopes. */
   259 	allow_on_slopes = ( _current_player != OWNER_TOWN && _patches.build_on_slopes);
   261 	allow_on_slopes = ( _current_player != OWNER_TOWN && _patches.build_on_slopes);
   260 
   262 
   261 	TransportType transport_type = railtype == INVALID_RAILTYPE ? TRANSPORT_ROAD : TRANSPORT_RAIL;
   263 	TransportType transport_type = railtype == INVALID_RAILTYPE ? TRANSPORT_ROAD : TRANSPORT_RAIL;
   262 
   264 
   263 	if (IsBridgeTile(tile_start) && IsBridgeTile(tile_end) &&
   265 	if (IsBridgeTile(tile_start) && IsBridgeTile(tile_end) &&
   312 		/* Try and clear the end landscape */
   314 		/* Try and clear the end landscape */
   313 		ret = DoCommand(tile_end, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   315 		ret = DoCommand(tile_end, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   314 		if (CmdFailed(ret)) return ret;
   316 		if (CmdFailed(ret)) return ret;
   315 		cost += ret;
   317 		cost += ret;
   316 
   318 
   317 		// false - end tile slope check
   319 		/* false - end tile slope check */
   318 		terraformcost = CheckBridgeSlopeSouth(direction, tileh_end);
   320 		terraformcost = CheckBridgeSlopeSouth(direction, tileh_end);
   319 		if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes))
   321 		if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes))
   320 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   322 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   321 		cost += terraformcost;
   323 		cost += terraformcost;
   322 	}
   324 	}
   436 }
   438 }
   437 
   439 
   438 
   440 
   439 /** Build Tunnel.
   441 /** Build Tunnel.
   440  * @param tile start tile of tunnel
   442  * @param tile start tile of tunnel
       
   443  * @param flags type of operation
   441  * @param p1 railtype, 0x200 for road tunnel
   444  * @param p1 railtype, 0x200 for road tunnel
   442  * @param p2 unused
   445  * @param p2 unused
   443  */
   446  */
   444 int32 CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32 p2)
   447 int32 CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32 p2)
   445 {
   448 {
   493 	}
   496 	}
   494 
   497 
   495 	/* Add the cost of the entrance */
   498 	/* Add the cost of the entrance */
   496 	cost += _price.build_tunnel + ret;
   499 	cost += _price.build_tunnel + ret;
   497 
   500 
   498 	// if the command fails from here on we want the end tile to be highlighted
   501 	/* if the command fails from here on we want the end tile to be highlighted */
   499 	_build_tunnel_endtile = end_tile;
   502 	_build_tunnel_endtile = end_tile;
   500 
   503 
   501 	// slope of end tile must be complementary to the slope of the start tile
   504 	/* slope of end tile must be complementary to the slope of the start tile */
   502 	if (end_tileh != ComplementSlope(start_tileh)) {
   505 	if (end_tileh != ComplementSlope(start_tileh)) {
   503 		ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND);
   506 		ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND);
   504 		if (CmdFailed(ret)) return_cmd_error(STR_5005_UNABLE_TO_EXCAVATE_LAND);
   507 		if (CmdFailed(ret)) return_cmd_error(STR_5005_UNABLE_TO_EXCAVATE_LAND);
   505 	} else {
   508 	} else {
   506 		ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   509 		ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   588 			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
   591 			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
   589 		}
   592 		}
   590 	}
   593 	}
   591 
   594 
   592 	if (flags & DC_EXEC) {
   595 	if (flags & DC_EXEC) {
   593 		// We first need to request the direction before calling DoClearSquare
   596 		/* We first need to request the direction before calling DoClearSquare
   594 		//  else the direction is always 0.. dah!! ;)
   597 		 *  else the direction is always 0.. dah!! ;) */
   595 		DiagDirection dir = GetTunnelDirection(tile);
   598 		DiagDirection dir = GetTunnelDirection(tile);
   596 		Track track;
   599 		Track track;
   597 
   600 
   598 		// Adjust the town's player rating. Do this before removing the tile owner info.
   601 		/* Adjust the town's player rating. Do this before removing the tile owner info. */
   599 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   602 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   600 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   603 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   601 
   604 
   602 		DoClearSquare(tile);
   605 		DoClearSquare(tile);
   603 		DoClearSquare(endtile);
   606 		DoClearSquare(endtile);
   634 
   637 
   635 	if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
   638 	if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
   636 
   639 
   637 	endtile = GetOtherBridgeEnd(tile);
   640 	endtile = GetOtherBridgeEnd(tile);
   638 
   641 
   639 	if (!EnsureNoVehicle(tile) ||
   642 	if (!EnsureNoVehicleOnGround(tile) ||
   640 			!EnsureNoVehicle(endtile) ||
   643 			!EnsureNoVehicleOnGround(endtile) ||
   641 			IsVehicleOnBridge(tile, endtile, GetBridgeHeight(tile))) {
   644 			IsVehicleOnBridge(tile, endtile, GetBridgeHeight(tile))) {
   642 		return CMD_ERROR;
   645 		return CMD_ERROR;
   643 	}
   646 	}
   644 
   647 
   645 	direction = GetBridgeRampDirection(tile);
   648 	direction = GetBridgeRampDirection(tile);
   658 
   661 
   659 	if (flags & DC_EXEC) {
   662 	if (flags & DC_EXEC) {
   660 		TileIndex c;
   663 		TileIndex c;
   661 		Track track;
   664 		Track track;
   662 
   665 
   663 		//checks if the owner is town then decrease town rating by RATING_TUNNEL_BRIDGE_DOWN_STEP until
   666 		/* checks if the owner is town then decrease town rating by RATING_TUNNEL_BRIDGE_DOWN_STEP until
   664 		// you have a "Poor" (0) town rating
   667 		 * you have a "Poor" (0) town rating */
   665 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   668 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   666 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   669 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   667 
   670 
   668 		DoClearSquare(tile);
   671 		DoClearSquare(tile);
   669 		DoClearSquare(endtile);
   672 		DoClearSquare(endtile);
   714 
   717 
   715 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   718 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   716 
   719 
   717 		if (GetRailType(tile) == totype) return CMD_ERROR;
   720 		if (GetRailType(tile) == totype) return CMD_ERROR;
   718 
   721 
   719 		// 'hidden' elrails can't be downgraded to normal rail when elrails are disabled
   722 		/* 'hidden' elrails can't be downgraded to normal rail when elrails are disabled */
   720 		if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
   723 		if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
   721 
   724 
   722 		endtile = CheckTunnelBusy(tile, &length);
   725 		endtile = CheckTunnelBusy(tile, &length);
   723 		if (endtile == INVALID_TILE) return CMD_ERROR;
   726 		if (endtile == INVALID_TILE) return CMD_ERROR;
   724 
   727 
   738 
   741 
   739 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   742 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   740 
   743 
   741 		endtile = GetOtherBridgeEnd(tile);
   744 		endtile = GetOtherBridgeEnd(tile);
   742 
   745 
   743 		if (!EnsureNoVehicle(tile) ||
   746 		if (!EnsureNoVehicleOnGround(tile) ||
   744 				!EnsureNoVehicle(endtile) ||
   747 				!EnsureNoVehicleOnGround(endtile) ||
   745 				IsVehicleOnBridge(tile, endtile, GetBridgeHeight(tile))) {
   748 				IsVehicleOnBridge(tile, endtile, GetBridgeHeight(tile))) {
   746 			return CMD_ERROR;
   749 			return CMD_ERROR;
   747 		}
   750 		}
   748 
   751 
   749 		if (GetRailType(tile) == totype) return CMD_ERROR;
   752 		if (GetRailType(tile) == totype) return CMD_ERROR;
   789 			{ 1, 8, 4, 2,   2, 16, 9, 0 },
   792 			{ 1, 8, 4, 2,   2, 16, 9, 0 },
   790 			{ 4, 8, 1, 2,  16,  2, 0, 9 },
   793 			{ 4, 8, 1, 2,  16,  2, 0, 9 },
   791 			{ 2, 4, 8, 1,   2, 16, 9, 0 }
   794 			{ 2, 4, 8, 1,   2, 16, 9, 0 }
   792 		};
   795 		};
   793 
   796 
   794 		if (_display_opt & DO_TRANS_BUILDINGS) {
   797 		if (HASBIT(_transparent_opt, TO_BRIDGES)) {
   795 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
   798 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
   796 			pal = PALETTE_TO_TRANSPARENT;
   799 			pal = PALETTE_TO_TRANSPARENT;
   797 		} else {
   800 		} else {
   798 			pal = psid->pal;
   801 			pal = psid->pal;
   799 		}
   802 		}
   826 {
   829 {
   827 	uint i;
   830 	uint i;
   828 
   831 
   829 	if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) return tileh;
   832 	if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) return tileh;
   830 
   833 
   831 	// inclined sloped building
   834 	/* inclined sloped building */
   832 	switch (tileh) {
   835 	switch (tileh) {
   833 		case SLOPE_W:
   836 		case SLOPE_W:
   834 		case SLOPE_STEEP_W: i = 0; break;
   837 		case SLOPE_STEEP_W: i = 0; break;
   835 		case SLOPE_S:
   838 		case SLOPE_S:
   836 		case SLOPE_STEEP_S: i = 2; break;
   839 		case SLOPE_STEEP_S: i = 2; break;
   847 /**
   850 /**
   848  * Draws a tunnel of bridge tile.
   851  * Draws a tunnel of bridge tile.
   849  * For tunnels, this is rather simple, as you only needa draw the entrance.
   852  * For tunnels, this is rather simple, as you only needa draw the entrance.
   850  * Bridges are a bit more complex. base_offset is where the sprite selection comes into play
   853  * Bridges are a bit more complex. base_offset is where the sprite selection comes into play
   851  * and it works a bit like a bitmask.<p> For bridge heads:
   854  * and it works a bit like a bitmask.<p> For bridge heads:
       
   855  * @param ti TileInfo of the structure to draw
   852  * <ul><li>Bit 0: direction</li>
   856  * <ul><li>Bit 0: direction</li>
   853  * <li>Bit 1: northern or southern heads</li>
   857  * <li>Bit 1: northern or southern heads</li>
   854  * <li>Bit 2: Set if the bridge head is sloped</li>
   858  * <li>Bit 2: Set if the bridge head is sloped</li>
   855  * <li>Bit 3 and more: Railtype Specific subset</li>
   859  * <li>Bit 3 and more: Railtype Specific subset</li>
   856  * </ul>
   860  * </ul>
   881 		int base_offset;
   885 		int base_offset;
   882 		bool ice = HasBridgeSnowOrDesert(ti->tile);
   886 		bool ice = HasBridgeSnowOrDesert(ti->tile);
   883 
   887 
   884 		if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
   888 		if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
   885 			base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset;
   889 			base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset;
   886 			assert(base_offset != 8); /* This one is used for roads */
   890 			assert(base_offset != 8); // This one is used for roads
   887 		} else {
   891 		} else {
   888 			base_offset = 8;
   892 			base_offset = 8;
   889 		}
   893 		}
   890 
   894 
   891 		/* as the lower 3 bits are used for other stuff, make sure they are clear */
   895 		/* as the lower 3 bits are used for other stuff, make sure they are clear */
   894 		if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) {
   898 		if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) {
   895 			int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
   899 			int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
   896 			if (f != 0) DrawFoundation(ti, f);
   900 			if (f != 0) DrawFoundation(ti, f);
   897 		}
   901 		}
   898 
   902 
   899 		// HACK Wizardry to convert the bridge ramp direction into a sprite offset
   903 		/* HACK Wizardry to convert the bridge ramp direction into a sprite offset */
   900 		base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
   904 		base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
   901 
   905 
   902 		if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
   906 		if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
   903 
   907 
   904 		/* Table number 6 always refers to the bridge heads for any bridge type */
   908 		/* Table number 6 always refers to the bridge heads for any bridge type */
   912 
   916 
   913 		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
   917 		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
   914 
   918 
   915 		image = psid->sprite;
   919 		image = psid->sprite;
   916 
   920 
   917 		// draw ramp
   921 		/* draw ramp */
   918 		if (_display_opt & DO_TRANS_BUILDINGS) {
   922 		if (HASBIT(_transparent_opt, TO_BRIDGES)) {
   919 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
   923 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
   920 			pal = PALETTE_TO_TRANSPARENT;
   924 			pal = PALETTE_TO_TRANSPARENT;
   921 		} else {
   925 		} else {
   922 			pal = psid->pal;
   926 			pal = psid->pal;
   923 		}
   927 		}
  1005 	x = ti->x;
  1009 	x = ti->x;
  1006 	y = ti->y;
  1010 	y = ti->y;
  1007 	z = GetBridgeHeight(rampsouth) - 3;
  1011 	z = GetBridgeHeight(rampsouth) - 3;
  1008 
  1012 
  1009 	image = psid->sprite;
  1013 	image = psid->sprite;
  1010 	if (_display_opt & DO_TRANS_BUILDINGS) {
  1014 	if (HASBIT(_transparent_opt, TO_BRIDGES)) {
  1011 		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1015 		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1012 		pal = PALETTE_TO_TRANSPARENT;
  1016 		pal = PALETTE_TO_TRANSPARENT;
  1013 	} else {
  1017 	} else {
  1014 		pal = psid->pal;
  1018 		pal = psid->pal;
  1015 	}
  1019 	}
  1020 		AddSortableSpriteToDraw(image, pal, x, y, 11, 16, 1, z);
  1024 		AddSortableSpriteToDraw(image, pal, x, y, 11, 16, 1, z);
  1021 	}
  1025 	}
  1022 
  1026 
  1023 	psid++;
  1027 	psid++;
  1024 	image = psid->sprite;
  1028 	image = psid->sprite;
  1025 	if (_display_opt & DO_TRANS_BUILDINGS) {
  1029 	if (HASBIT(_transparent_opt, TO_BRIDGES)) {
  1026 		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1030 		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1027 		pal = PALETTE_TO_TRANSPARENT;
  1031 		pal = PALETTE_TO_TRANSPARENT;
  1028 	} else {
  1032 	} else {
  1029 		pal = psid->pal;
  1033 		pal = psid->pal;
  1030 	}
  1034 	}
  1031 
  1035 
  1032 	// draw roof, the component of the bridge which is logically between the vehicle and the camera
  1036 	/* draw roof, the component of the bridge which is logically between the vehicle and the camera */
  1033 	if (axis == AXIS_X) {
  1037 	if (axis == AXIS_X) {
  1034 		y += 12;
  1038 		y += 12;
  1035 		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, pal, x, y, 16, 1, 0x28, z);
  1039 		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, pal, x, y, 16, 1, 0x28, z);
  1036 	} else {
  1040 	} else {
  1037 		x += 12;
  1041 		x += 12;
  1040 
  1044 
  1041 	if (GetRailType(rampsouth) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
  1045 	if (GetRailType(rampsouth) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
  1042 
  1046 
  1043 	psid++;
  1047 	psid++;
  1044 	if (ti->z + 5 == z) {
  1048 	if (ti->z + 5 == z) {
  1045 		// draw poles below for small bridges
  1049 		/* draw poles below for small bridges */
  1046 		if (psid->sprite != 0) {
  1050 		if (psid->sprite != 0) {
  1047 			image = psid->sprite;
  1051 			image = psid->sprite;
  1048 			if (_display_opt & DO_TRANS_BUILDINGS) {
  1052 			if (HASBIT(_transparent_opt, TO_BRIDGES)) {
  1049 				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1053 				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1050 				pal = PALETTE_TO_TRANSPARENT;
  1054 				pal = PALETTE_TO_TRANSPARENT;
  1051 			} else {
  1055 			} else {
  1052 				pal = psid->pal;
  1056 				pal = psid->pal;
  1053 			}
  1057 			}
  1054 
  1058 
  1055 			DrawGroundSpriteAt(image, pal, x, y, z);
  1059 			DrawGroundSpriteAt(image, pal, x, y, z);
  1056 		}
  1060 		}
  1057 	} else if (_patches.bridge_pillars) {
  1061 	} else if (_patches.bridge_pillars) {
  1058 		// draw pillars below for high bridges
  1062 		/* draw pillars below for high bridges */
  1059 		DrawBridgePillars(psid, ti, axis, type, x, y, z);
  1063 		DrawBridgePillars(psid, ti, axis, type, x, y, z);
  1060 	}
  1064 	}
  1061 }
  1065 }
  1062 
  1066 
  1063 
  1067 
  1070 	y &= 0xF;
  1074 	y &= 0xF;
  1071 
  1075 
  1072 	if (IsTunnel(tile)) {
  1076 	if (IsTunnel(tile)) {
  1073 		uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x);
  1077 		uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x);
  1074 
  1078 
  1075 		// In the tunnel entrance?
  1079 		/* In the tunnel entrance? */
  1076 		if (5 <= pos && pos <= 10) return z;
  1080 		if (5 <= pos && pos <= 10) return z;
  1077 	} else {
  1081 	} else {
  1078 		DiagDirection dir = GetBridgeRampDirection(tile);
  1082 		DiagDirection dir = GetBridgeRampDirection(tile);
  1079 		uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
  1083 		uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
  1080 
  1084 
  1081 		// On the bridge ramp?
  1085 		/* On the bridge ramp? */
  1082 		if (5 <= pos && pos <= 10) {
  1086 		if (5 <= pos && pos <= 10) {
  1083 			uint delta;
  1087 			uint delta;
  1084 
  1088 
  1085 			if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2;
  1089 			if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2;
  1086 			if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT;
  1090 			if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT;
  1299 		} else if (v->type == VEH_ROAD) {
  1303 		} else if (v->type == VEH_ROAD) {
  1300 			fc = (x & 0xF) + (y << 4);
  1304 			fc = (x & 0xF) + (y << 4);
  1301 			dir = GetTunnelDirection(tile);
  1305 			dir = GetTunnelDirection(tile);
  1302 			vdir = DirToDiagDir(v->direction);
  1306 			vdir = DirToDiagDir(v->direction);
  1303 
  1307 
  1304 			// Enter tunnel?
  1308 			/* Enter tunnel? */
  1305 			if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) {
  1309 			if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) {
  1306 				if (fc == _tunnel_fractcoord_4[dir] ||
  1310 				if (fc == _tunnel_fractcoord_4[dir] ||
  1307 						fc == _tunnel_fractcoord_5[dir]) {
  1311 						fc == _tunnel_fractcoord_5[dir]) {
  1308 					v->tile = tile;
  1312 					v->tile = tile;
  1309 					v->u.road.state = RVSB_WORMHOLE;
  1313 					v->u.road.state = RVSB_WORMHOLE;