src/tunnelbridge_cmd.cpp
branchgamebalance
changeset 9908 0fa543611bbe
parent 9907 3b068c3a1c74
child 9909 dce9a6923bb7
equal deleted inserted replaced
9907:3b068c3a1c74 9908:0fa543611bbe
    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 = (!_is_old_ai_player
   261 	allow_on_slopes = (!_is_old_ai_player
   260 	                   && _current_player != OWNER_TOWN && _patches.build_on_slopes);
   262 	                   && _current_player != OWNER_TOWN && _patches.build_on_slopes);
   261 
   263 
   262 	TransportType transport_type = railtype == INVALID_RAILTYPE ? TRANSPORT_ROAD : TRANSPORT_RAIL;
   264 	TransportType transport_type = railtype == INVALID_RAILTYPE ? TRANSPORT_ROAD : TRANSPORT_RAIL;
   263 
   265 
   313 		/* Try and clear the end landscape */
   315 		/* Try and clear the end landscape */
   314 		ret = DoCommand(tile_end, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   316 		ret = DoCommand(tile_end, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   315 		if (CmdFailed(ret)) return ret;
   317 		if (CmdFailed(ret)) return ret;
   316 		cost += ret;
   318 		cost += ret;
   317 
   319 
   318 		// false - end tile slope check
   320 		/* false - end tile slope check */
   319 		terraformcost = CheckBridgeSlopeSouth(direction, tileh_end);
   321 		terraformcost = CheckBridgeSlopeSouth(direction, tileh_end);
   320 		if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes))
   322 		if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes))
   321 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   323 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   322 		cost += terraformcost;
   324 		cost += terraformcost;
   323 	}
   325 	}
   437 }
   439 }
   438 
   440 
   439 
   441 
   440 /** Build Tunnel.
   442 /** Build Tunnel.
   441  * @param tile start tile of tunnel
   443  * @param tile start tile of tunnel
       
   444  * @param flags type of operation
   442  * @param p1 railtype, 0x200 for road tunnel
   445  * @param p1 railtype, 0x200 for road tunnel
   443  * @param p2 unused
   446  * @param p2 unused
   444  */
   447  */
   445 int32 CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32 p2)
   448 int32 CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32 p2)
   446 {
   449 {
   494 	}
   497 	}
   495 
   498 
   496 	/* Add the cost of the entrance */
   499 	/* Add the cost of the entrance */
   497 	cost += _eco->GetPrice(CEconomy::BUILD_TUNNEL) + ret;
   500 	cost += _eco->GetPrice(CEconomy::BUILD_TUNNEL) + ret;
   498 
   501 
   499 	// if the command fails from here on we want the end tile to be highlighted
   502 	/* if the command fails from here on we want the end tile to be highlighted */
   500 	_build_tunnel_endtile = end_tile;
   503 	_build_tunnel_endtile = end_tile;
   501 
   504 
   502 	// slope of end tile must be complementary to the slope of the start tile
   505 	/* slope of end tile must be complementary to the slope of the start tile */
   503 	if (end_tileh != ComplementSlope(start_tileh)) {
   506 	if (end_tileh != ComplementSlope(start_tileh)) {
   504 		ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND);
   507 		ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND);
   505 		if (CmdFailed(ret)) return_cmd_error(STR_5005_UNABLE_TO_EXCAVATE_LAND);
   508 		if (CmdFailed(ret)) return_cmd_error(STR_5005_UNABLE_TO_EXCAVATE_LAND);
   506 	} else {
   509 	} else {
   507 		ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   510 		ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   589 			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
   592 			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
   590 		}
   593 		}
   591 	}
   594 	}
   592 
   595 
   593 	if (flags & DC_EXEC) {
   596 	if (flags & DC_EXEC) {
   594 		// We first need to request the direction before calling DoClearSquare
   597 		/* We first need to request the direction before calling DoClearSquare
   595 		//  else the direction is always 0.. dah!! ;)
   598 		 *  else the direction is always 0.. dah!! ;) */
   596 		DiagDirection dir = GetTunnelDirection(tile);
   599 		DiagDirection dir = GetTunnelDirection(tile);
   597 		Track track;
   600 		Track track;
   598 
   601 
   599 		// Adjust the town's player rating. Do this before removing the tile owner info.
   602 		/* Adjust the town's player rating. Do this before removing the tile owner info. */
   600 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   603 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   601 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   604 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   602 
   605 
   603 		DoClearSquare(tile);
   606 		DoClearSquare(tile);
   604 		DoClearSquare(endtile);
   607 		DoClearSquare(endtile);
   635 
   638 
   636 	if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
   639 	if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
   637 
   640 
   638 	endtile = GetOtherBridgeEnd(tile);
   641 	endtile = GetOtherBridgeEnd(tile);
   639 
   642 
   640 	if (!EnsureNoVehicle(tile) ||
   643 	if (!EnsureNoVehicleOnGround(tile) ||
   641 			!EnsureNoVehicle(endtile) ||
   644 			!EnsureNoVehicleOnGround(endtile) ||
   642 			IsVehicleOnBridge(tile, endtile, GetBridgeHeight(tile))) {
   645 			IsVehicleOnBridge(tile, endtile, GetBridgeHeight(tile))) {
   643 		return CMD_ERROR;
   646 		return CMD_ERROR;
   644 	}
   647 	}
   645 
   648 
   646 	direction = GetBridgeRampDirection(tile);
   649 	direction = GetBridgeRampDirection(tile);
   659 
   662 
   660 	if (flags & DC_EXEC) {
   663 	if (flags & DC_EXEC) {
   661 		TileIndex c;
   664 		TileIndex c;
   662 		Track track;
   665 		Track track;
   663 
   666 
   664 		//checks if the owner is town then decrease town rating by RATING_TUNNEL_BRIDGE_DOWN_STEP until
   667 		/* checks if the owner is town then decrease town rating by RATING_TUNNEL_BRIDGE_DOWN_STEP until
   665 		// you have a "Poor" (0) town rating
   668 		 * you have a "Poor" (0) town rating */
   666 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   669 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   667 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   670 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   668 
   671 
   669 		DoClearSquare(tile);
   672 		DoClearSquare(tile);
   670 		DoClearSquare(endtile);
   673 		DoClearSquare(endtile);
   715 
   718 
   716 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   719 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   717 
   720 
   718 		if (GetRailType(tile) == totype) return CMD_ERROR;
   721 		if (GetRailType(tile) == totype) return CMD_ERROR;
   719 
   722 
   720 		// 'hidden' elrails can't be downgraded to normal rail when elrails are disabled
   723 		/* 'hidden' elrails can't be downgraded to normal rail when elrails are disabled */
   721 		if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
   724 		if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
   722 
   725 
   723 		endtile = CheckTunnelBusy(tile, &length);
   726 		endtile = CheckTunnelBusy(tile, &length);
   724 		if (endtile == INVALID_TILE) return CMD_ERROR;
   727 		if (endtile == INVALID_TILE) return CMD_ERROR;
   725 
   728 
   739 
   742 
   740 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   743 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   741 
   744 
   742 		endtile = GetOtherBridgeEnd(tile);
   745 		endtile = GetOtherBridgeEnd(tile);
   743 
   746 
   744 		if (!EnsureNoVehicle(tile) ||
   747 		if (!EnsureNoVehicleOnGround(tile) ||
   745 				!EnsureNoVehicle(endtile) ||
   748 				!EnsureNoVehicleOnGround(endtile) ||
   746 				IsVehicleOnBridge(tile, endtile, GetBridgeHeight(tile))) {
   749 				IsVehicleOnBridge(tile, endtile, GetBridgeHeight(tile))) {
   747 			return CMD_ERROR;
   750 			return CMD_ERROR;
   748 		}
   751 		}
   749 
   752 
   750 		if (GetRailType(tile) == totype) return CMD_ERROR;
   753 		if (GetRailType(tile) == totype) return CMD_ERROR;
   790 			{ 1, 8, 4, 2,   2, 16, 9, 0 },
   793 			{ 1, 8, 4, 2,   2, 16, 9, 0 },
   791 			{ 4, 8, 1, 2,  16,  2, 0, 9 },
   794 			{ 4, 8, 1, 2,  16,  2, 0, 9 },
   792 			{ 2, 4, 8, 1,   2, 16, 9, 0 }
   795 			{ 2, 4, 8, 1,   2, 16, 9, 0 }
   793 		};
   796 		};
   794 
   797 
   795 		if (_display_opt & DO_TRANS_BUILDINGS) {
   798 		if (HASBIT(_transparent_opt, TO_BRIDGES)) {
   796 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
   799 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
   797 			pal = PALETTE_TO_TRANSPARENT;
   800 			pal = PALETTE_TO_TRANSPARENT;
   798 		} else {
   801 		} else {
   799 			pal = psid->pal;
   802 			pal = psid->pal;
   800 		}
   803 		}
   827 {
   830 {
   828 	uint i;
   831 	uint i;
   829 
   832 
   830 	if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) return tileh;
   833 	if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) return tileh;
   831 
   834 
   832 	// inclined sloped building
   835 	/* inclined sloped building */
   833 	switch (tileh) {
   836 	switch (tileh) {
   834 		case SLOPE_W:
   837 		case SLOPE_W:
   835 		case SLOPE_STEEP_W: i = 0; break;
   838 		case SLOPE_STEEP_W: i = 0; break;
   836 		case SLOPE_S:
   839 		case SLOPE_S:
   837 		case SLOPE_STEEP_S: i = 2; break;
   840 		case SLOPE_STEEP_S: i = 2; break;
   848 /**
   851 /**
   849  * Draws a tunnel of bridge tile.
   852  * Draws a tunnel of bridge tile.
   850  * For tunnels, this is rather simple, as you only needa draw the entrance.
   853  * For tunnels, this is rather simple, as you only needa draw the entrance.
   851  * Bridges are a bit more complex. base_offset is where the sprite selection comes into play
   854  * Bridges are a bit more complex. base_offset is where the sprite selection comes into play
   852  * and it works a bit like a bitmask.<p> For bridge heads:
   855  * and it works a bit like a bitmask.<p> For bridge heads:
       
   856  * @param ti TileInfo of the structure to draw
   853  * <ul><li>Bit 0: direction</li>
   857  * <ul><li>Bit 0: direction</li>
   854  * <li>Bit 1: northern or southern heads</li>
   858  * <li>Bit 1: northern or southern heads</li>
   855  * <li>Bit 2: Set if the bridge head is sloped</li>
   859  * <li>Bit 2: Set if the bridge head is sloped</li>
   856  * <li>Bit 3 and more: Railtype Specific subset</li>
   860  * <li>Bit 3 and more: Railtype Specific subset</li>
   857  * </ul>
   861  * </ul>
   882 		int base_offset;
   886 		int base_offset;
   883 		bool ice = HasBridgeSnowOrDesert(ti->tile);
   887 		bool ice = HasBridgeSnowOrDesert(ti->tile);
   884 
   888 
   885 		if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
   889 		if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
   886 			base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset;
   890 			base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset;
   887 			assert(base_offset != 8); /* This one is used for roads */
   891 			assert(base_offset != 8); // This one is used for roads
   888 		} else {
   892 		} else {
   889 			base_offset = 8;
   893 			base_offset = 8;
   890 		}
   894 		}
   891 
   895 
   892 		/* as the lower 3 bits are used for other stuff, make sure they are clear */
   896 		/* as the lower 3 bits are used for other stuff, make sure they are clear */
   895 		if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) {
   899 		if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) {
   896 			int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
   900 			int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
   897 			if (f != 0) DrawFoundation(ti, f);
   901 			if (f != 0) DrawFoundation(ti, f);
   898 		}
   902 		}
   899 
   903 
   900 		// HACK Wizardry to convert the bridge ramp direction into a sprite offset
   904 		/* HACK Wizardry to convert the bridge ramp direction into a sprite offset */
   901 		base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
   905 		base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
   902 
   906 
   903 		if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
   907 		if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
   904 
   908 
   905 		/* Table number 6 always refers to the bridge heads for any bridge type */
   909 		/* Table number 6 always refers to the bridge heads for any bridge type */
   913 
   917 
   914 		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
   918 		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
   915 
   919 
   916 		image = psid->sprite;
   920 		image = psid->sprite;
   917 
   921 
   918 		// draw ramp
   922 		/* draw ramp */
   919 		if (_display_opt & DO_TRANS_BUILDINGS) {
   923 		if (HASBIT(_transparent_opt, TO_BRIDGES)) {
   920 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
   924 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
   921 			pal = PALETTE_TO_TRANSPARENT;
   925 			pal = PALETTE_TO_TRANSPARENT;
   922 		} else {
   926 		} else {
   923 			pal = psid->pal;
   927 			pal = psid->pal;
   924 		}
   928 		}
  1006 	x = ti->x;
  1010 	x = ti->x;
  1007 	y = ti->y;
  1011 	y = ti->y;
  1008 	z = GetBridgeHeight(rampsouth) - 3;
  1012 	z = GetBridgeHeight(rampsouth) - 3;
  1009 
  1013 
  1010 	image = psid->sprite;
  1014 	image = psid->sprite;
  1011 	if (_display_opt & DO_TRANS_BUILDINGS) {
  1015 	if (HASBIT(_transparent_opt, TO_BRIDGES)) {
  1012 		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1016 		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1013 		pal = PALETTE_TO_TRANSPARENT;
  1017 		pal = PALETTE_TO_TRANSPARENT;
  1014 	} else {
  1018 	} else {
  1015 		pal = psid->pal;
  1019 		pal = psid->pal;
  1016 	}
  1020 	}
  1021 		AddSortableSpriteToDraw(image, pal, x, y, 11, 16, 1, z);
  1025 		AddSortableSpriteToDraw(image, pal, x, y, 11, 16, 1, z);
  1022 	}
  1026 	}
  1023 
  1027 
  1024 	psid++;
  1028 	psid++;
  1025 	image = psid->sprite;
  1029 	image = psid->sprite;
  1026 	if (_display_opt & DO_TRANS_BUILDINGS) {
  1030 	if (HASBIT(_transparent_opt, TO_BRIDGES)) {
  1027 		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1031 		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1028 		pal = PALETTE_TO_TRANSPARENT;
  1032 		pal = PALETTE_TO_TRANSPARENT;
  1029 	} else {
  1033 	} else {
  1030 		pal = psid->pal;
  1034 		pal = psid->pal;
  1031 	}
  1035 	}
  1032 
  1036 
  1033 	// draw roof, the component of the bridge which is logically between the vehicle and the camera
  1037 	/* draw roof, the component of the bridge which is logically between the vehicle and the camera */
  1034 	if (axis == AXIS_X) {
  1038 	if (axis == AXIS_X) {
  1035 		y += 12;
  1039 		y += 12;
  1036 		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, pal, x, y, 16, 1, 0x28, z);
  1040 		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, pal, x, y, 16, 1, 0x28, z);
  1037 	} else {
  1041 	} else {
  1038 		x += 12;
  1042 		x += 12;
  1041 
  1045 
  1042 	if (GetRailType(rampsouth) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
  1046 	if (GetRailType(rampsouth) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
  1043 
  1047 
  1044 	psid++;
  1048 	psid++;
  1045 	if (ti->z + 5 == z) {
  1049 	if (ti->z + 5 == z) {
  1046 		// draw poles below for small bridges
  1050 		/* draw poles below for small bridges */
  1047 		if (psid->sprite != 0) {
  1051 		if (psid->sprite != 0) {
  1048 			image = psid->sprite;
  1052 			image = psid->sprite;
  1049 			if (_display_opt & DO_TRANS_BUILDINGS) {
  1053 			if (HASBIT(_transparent_opt, TO_BRIDGES)) {
  1050 				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1054 				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1051 				pal = PALETTE_TO_TRANSPARENT;
  1055 				pal = PALETTE_TO_TRANSPARENT;
  1052 			} else {
  1056 			} else {
  1053 				pal = psid->pal;
  1057 				pal = psid->pal;
  1054 			}
  1058 			}
  1055 
  1059 
  1056 			DrawGroundSpriteAt(image, pal, x, y, z);
  1060 			DrawGroundSpriteAt(image, pal, x, y, z);
  1057 		}
  1061 		}
  1058 	} else if (_patches.bridge_pillars) {
  1062 	} else if (_patches.bridge_pillars) {
  1059 		// draw pillars below for high bridges
  1063 		/* draw pillars below for high bridges */
  1060 		DrawBridgePillars(psid, ti, axis, type, x, y, z);
  1064 		DrawBridgePillars(psid, ti, axis, type, x, y, z);
  1061 	}
  1065 	}
  1062 }
  1066 }
  1063 
  1067 
  1064 
  1068 
  1071 	y &= 0xF;
  1075 	y &= 0xF;
  1072 
  1076 
  1073 	if (IsTunnel(tile)) {
  1077 	if (IsTunnel(tile)) {
  1074 		uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x);
  1078 		uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x);
  1075 
  1079 
  1076 		// In the tunnel entrance?
  1080 		/* In the tunnel entrance? */
  1077 		if (5 <= pos && pos <= 10) return z;
  1081 		if (5 <= pos && pos <= 10) return z;
  1078 	} else {
  1082 	} else {
  1079 		DiagDirection dir = GetBridgeRampDirection(tile);
  1083 		DiagDirection dir = GetBridgeRampDirection(tile);
  1080 		uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
  1084 		uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
  1081 
  1085 
  1082 		// On the bridge ramp?
  1086 		/* On the bridge ramp? */
  1083 		if (5 <= pos && pos <= 10) {
  1087 		if (5 <= pos && pos <= 10) {
  1084 			uint delta;
  1088 			uint delta;
  1085 
  1089 
  1086 			if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2;
  1090 			if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2;
  1087 			if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT;
  1091 			if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT;
  1300 		} else if (v->type == VEH_ROAD) {
  1304 		} else if (v->type == VEH_ROAD) {
  1301 			fc = (x & 0xF) + (y << 4);
  1305 			fc = (x & 0xF) + (y << 4);
  1302 			dir = GetTunnelDirection(tile);
  1306 			dir = GetTunnelDirection(tile);
  1303 			vdir = DirToDiagDir(v->direction);
  1307 			vdir = DirToDiagDir(v->direction);
  1304 
  1308 
  1305 			// Enter tunnel?
  1309 			/* Enter tunnel? */
  1306 			if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) {
  1310 			if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) {
  1307 				if (fc == _tunnel_fractcoord_4[dir] ||
  1311 				if (fc == _tunnel_fractcoord_4[dir] ||
  1308 						fc == _tunnel_fractcoord_5[dir]) {
  1312 						fc == _tunnel_fractcoord_5[dir]) {
  1309 					v->tile = tile;
  1313 					v->tile = tile;
  1310 					v->u.road.state = RVSB_WORMHOLE;
  1314 					v->u.road.state = RVSB_WORMHOLE;