src/tunnelbridge_cmd.cpp
branchNewGRF_ports
changeset 6719 4cc327ad39d5
parent 6694 a10a42eefd52
child 6720 35756db7e577
equal deleted inserted replaced
6718:5a8b295aa345 6719:4cc327ad39d5
    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 or road types.
       
   176  * - p2 = (bit 15  ) - set means road bridge.
   174  */
   177  */
   175 int32 CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
   178 int32 CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
   176 {
   179 {
   177 	uint bridge_type;
   180 	uint bridge_type;
   178 	RailType railtype;
   181 	RailType railtype;
       
   182 	RoadTypes roadtypes;
   179 	uint x;
   183 	uint x;
   180 	uint y;
   184 	uint y;
   181 	uint sx;
   185 	uint sx;
   182 	uint sy;
   186 	uint sy;
   183 	TileIndex tile_start;
   187 	TileIndex tile_start;
   200 	/* unpack parameters */
   204 	/* unpack parameters */
   201 	bridge_type = GB(p2, 0, 8);
   205 	bridge_type = GB(p2, 0, 8);
   202 
   206 
   203 	if (p1 >= MapSize()) return CMD_ERROR;
   207 	if (p1 >= MapSize()) return CMD_ERROR;
   204 
   208 
   205 	// type of bridge
   209 	/* type of bridge */
   206 	if (HASBIT(p2, 15)) {
   210 	if (HASBIT(p2, 15)) {
   207 		railtype = INVALID_RAILTYPE; // road bridge
   211 		railtype = INVALID_RAILTYPE; // road bridge
       
   212 		roadtypes = (RoadTypes)GB(p2, 8, 3);
       
   213 		if (!AreValidRoadTypes(roadtypes)) return CMD_ERROR;
   208 	} else {
   214 	} else {
   209 		if (!ValParamRailtype(GB(p2, 8, 8))) return CMD_ERROR;
   215 		if (!ValParamRailtype(GB(p2, 8, 8))) return CMD_ERROR;
   210 		railtype = (RailType)GB(p2, 8, 8);
   216 		railtype = (RailType)GB(p2, 8, 8);
       
   217 		roadtypes = ROADTYPES_NONE;
   211 	}
   218 	}
   212 
   219 
   213 	x = TileX(end_tile);
   220 	x = TileX(end_tile);
   214 	y = TileY(end_tile);
   221 	y = TileY(end_tile);
   215 	sx = TileX(p1);
   222 	sx = TileX(p1);
   253 		tileh_end = SLOPE_FLAT;
   260 		tileh_end = SLOPE_FLAT;
   254 	}
   261 	}
   255 
   262 
   256 	if (z_start != z_end) return_cmd_error(STR_5009_LEVEL_LAND_OR_WATER_REQUIRED);
   263 	if (z_start != z_end) return_cmd_error(STR_5009_LEVEL_LAND_OR_WATER_REQUIRED);
   257 
   264 
   258 	// Towns are not allowed to use bridges on slopes.
   265 	/* Towns are not allowed to use bridges on slopes. */
   259 	allow_on_slopes = (!_is_old_ai_player
   266 	allow_on_slopes = (!_is_old_ai_player
   260 	                   && _current_player != OWNER_TOWN && _patches.build_on_slopes);
   267 	                   && _current_player != OWNER_TOWN && _patches.build_on_slopes);
   261 
   268 
   262 	TransportType transport_type = railtype == INVALID_RAILTYPE ? TRANSPORT_ROAD : TRANSPORT_RAIL;
   269 	TransportType transport_type = railtype == INVALID_RAILTYPE ? TRANSPORT_ROAD : TRANSPORT_RAIL;
   263 
   270 
   295 		}
   302 		}
   296 
   303 
   297 		cost = (bridge_len + 1) * _price.clear_bridge; // The cost of clearing the current bridge.
   304 		cost = (bridge_len + 1) * _price.clear_bridge; // The cost of clearing the current bridge.
   298 		replace_bridge = true;
   305 		replace_bridge = true;
   299 		replaced_bridge_type = GetBridgeType(tile_start);
   306 		replaced_bridge_type = GetBridgeType(tile_start);
       
   307 
       
   308 		/* Do not remove road types when upgrading a bridge */
       
   309 		roadtypes |= GetRoadTypes(tile_start);
   300 	} else {
   310 	} else {
   301 		/* Build a new bridge. */
   311 		/* Build a new bridge. */
   302 
   312 
   303 		/* Try and clear the start landscape */
   313 		/* Try and clear the start landscape */
   304 		ret = DoCommand(tile_start, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   314 		ret = DoCommand(tile_start, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   313 		/* Try and clear the end landscape */
   323 		/* Try and clear the end landscape */
   314 		ret = DoCommand(tile_end, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   324 		ret = DoCommand(tile_end, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   315 		if (CmdFailed(ret)) return ret;
   325 		if (CmdFailed(ret)) return ret;
   316 		cost += ret;
   326 		cost += ret;
   317 
   327 
   318 		// false - end tile slope check
   328 		/* false - end tile slope check */
   319 		terraformcost = CheckBridgeSlopeSouth(direction, tileh_end);
   329 		terraformcost = CheckBridgeSlopeSouth(direction, tileh_end);
   320 		if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes))
   330 		if (CmdFailed(terraformcost) || (terraformcost != 0 && !allow_on_slopes))
   321 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   331 			return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   322 		cost += terraformcost;
   332 		cost += terraformcost;
   323 	}
   333 	}
   348 
   358 
   349 		if (railtype != INVALID_RAILTYPE) {
   359 		if (railtype != INVALID_RAILTYPE) {
   350 			MakeRailBridgeRamp(tile_start, owner, bridge_type, dir, railtype);
   360 			MakeRailBridgeRamp(tile_start, owner, bridge_type, dir, railtype);
   351 			MakeRailBridgeRamp(tile_end,   owner, bridge_type, ReverseDiagDir(dir), railtype);
   361 			MakeRailBridgeRamp(tile_end,   owner, bridge_type, ReverseDiagDir(dir), railtype);
   352 		} else {
   362 		} else {
   353 			MakeRoadBridgeRamp(tile_start, owner, bridge_type, dir);
   363 			MakeRoadBridgeRamp(tile_start, owner, bridge_type, dir, roadtypes);
   354 			MakeRoadBridgeRamp(tile_end,   owner, bridge_type, ReverseDiagDir(dir));
   364 			MakeRoadBridgeRamp(tile_end,   owner, bridge_type, ReverseDiagDir(dir), roadtypes);
   355 		}
   365 		}
   356 		MarkTileDirtyByTile(tile_start);
   366 		MarkTileDirtyByTile(tile_start);
   357 		MarkTileDirtyByTile(tile_end);
   367 		MarkTileDirtyByTile(tile_end);
   358 	}
   368 	}
   359 
   369 
   436 	return cost;
   446 	return cost;
   437 }
   447 }
   438 
   448 
   439 
   449 
   440 /** Build Tunnel.
   450 /** Build Tunnel.
   441  * @param tile start tile of tunnel
   451  * @param start_tile start tile of tunnel
   442  * @param p1 railtype, 0x200 for road tunnel
   452  * @param flags type of operation
       
   453  * @param p1 railtype or roadtypes. bit 9 set means road tunnel
   443  * @param p2 unused
   454  * @param p2 unused
   444  */
   455  */
   445 int32 CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32 p2)
   456 int32 CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32 p2)
   446 {
   457 {
   447 	TileIndexDiff delta;
   458 	TileIndexDiff delta;
   453 	uint end_z;
   464 	uint end_z;
   454 	int32 cost;
   465 	int32 cost;
   455 	int32 ret;
   466 	int32 ret;
   456 
   467 
   457 	_build_tunnel_endtile = 0;
   468 	_build_tunnel_endtile = 0;
   458 
   469 	if (!HASBIT(p1, 9)) {
   459 	if (p1 != 0x200 && !ValParamRailtype(p1)) return CMD_ERROR;
   470 		if (!ValParamRailtype(p1)) return CMD_ERROR;
       
   471 	} else if (!AreValidRoadTypes((RoadTypes)GB(p1, 0, 3))) {
       
   472 		return CMD_ERROR;
       
   473 	}
   460 
   474 
   461 	start_tileh = GetTileSlope(start_tile, &start_z);
   475 	start_tileh = GetTileSlope(start_tile, &start_z);
   462 
   476 
   463 	switch (start_tileh) {
   477 	switch (start_tileh) {
   464 		case SLOPE_SW: direction = DIAGDIR_SW; break;
   478 		case SLOPE_SW: direction = DIAGDIR_SW; break;
   494 	}
   508 	}
   495 
   509 
   496 	/* Add the cost of the entrance */
   510 	/* Add the cost of the entrance */
   497 	cost += _price.build_tunnel + ret;
   511 	cost += _price.build_tunnel + ret;
   498 
   512 
   499 	// if the command fails from here on we want the end tile to be highlighted
   513 	/* if the command fails from here on we want the end tile to be highlighted */
   500 	_build_tunnel_endtile = end_tile;
   514 	_build_tunnel_endtile = end_tile;
   501 
   515 
   502 	// slope of end tile must be complementary to the slope of the start tile
   516 	/* slope of end tile must be complementary to the slope of the start tile */
   503 	if (end_tileh != ComplementSlope(start_tileh)) {
   517 	if (end_tileh != ComplementSlope(start_tileh)) {
   504 		ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND);
   518 		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);
   519 		if (CmdFailed(ret)) return_cmd_error(STR_5005_UNABLE_TO_EXCAVATE_LAND);
   506 	} else {
   520 	} else {
   507 		ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   521 		ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   514 			MakeRailTunnel(start_tile, _current_player, direction,                 (RailType)GB(p1, 0, 4));
   528 			MakeRailTunnel(start_tile, _current_player, direction,                 (RailType)GB(p1, 0, 4));
   515 			MakeRailTunnel(end_tile,   _current_player, ReverseDiagDir(direction), (RailType)GB(p1, 0, 4));
   529 			MakeRailTunnel(end_tile,   _current_player, ReverseDiagDir(direction), (RailType)GB(p1, 0, 4));
   516 			UpdateSignalsOnSegment(start_tile, direction);
   530 			UpdateSignalsOnSegment(start_tile, direction);
   517 			YapfNotifyTrackLayoutChange(start_tile, AxisToTrack(DiagDirToAxis(direction)));
   531 			YapfNotifyTrackLayoutChange(start_tile, AxisToTrack(DiagDirToAxis(direction)));
   518 		} else {
   532 		} else {
   519 			MakeRoadTunnel(start_tile, _current_player, direction);
   533 			MakeRoadTunnel(start_tile, _current_player, direction,                 (RoadTypes)GB(p1, 0, 3));
   520 			MakeRoadTunnel(end_tile,   _current_player, ReverseDiagDir(direction));
   534 			MakeRoadTunnel(end_tile,   _current_player, ReverseDiagDir(direction), (RoadTypes)GB(p1, 0, 3));
   521 		}
   535 		}
   522 	}
   536 	}
   523 
   537 
   524 	return cost;
   538 	return cost;
   525 }
   539 }
   589 			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
   603 			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
   590 		}
   604 		}
   591 	}
   605 	}
   592 
   606 
   593 	if (flags & DC_EXEC) {
   607 	if (flags & DC_EXEC) {
   594 		// We first need to request the direction before calling DoClearSquare
   608 		/* We first need to request the direction before calling DoClearSquare
   595 		//  else the direction is always 0.. dah!! ;)
   609 		 *  else the direction is always 0.. dah!! ;) */
   596 		DiagDirection dir = GetTunnelDirection(tile);
   610 		DiagDirection dir = GetTunnelDirection(tile);
   597 		Track track;
   611 		Track track;
   598 
   612 
   599 		// Adjust the town's player rating. Do this before removing the tile owner info.
   613 		/* Adjust the town's player rating. Do this before removing the tile owner info. */
   600 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   614 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   601 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   615 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   602 
   616 
   603 		DoClearSquare(tile);
   617 		DoClearSquare(tile);
   604 		DoClearSquare(endtile);
   618 		DoClearSquare(endtile);
   634 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   648 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   635 
   649 
   636 	if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
   650 	if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
   637 
   651 
   638 	endtile = GetOtherBridgeEnd(tile);
   652 	endtile = GetOtherBridgeEnd(tile);
   639 
   653 	byte bridge_height = GetBridgeHeight(tile);
   640 	if (!EnsureNoVehicle(tile) ||
   654 
   641 			!EnsureNoVehicle(endtile) ||
   655 	if (FindVehicleOnTileZ(tile, bridge_height) != NULL ||
   642 			IsVehicleOnBridge(tile, endtile, GetBridgeHeight(tile))) {
   656 			FindVehicleOnTileZ(endtile, bridge_height) != NULL ||
       
   657 			IsVehicleOnBridge(tile, endtile, bridge_height)) {
   643 		return CMD_ERROR;
   658 		return CMD_ERROR;
   644 	}
   659 	}
   645 
   660 
   646 	direction = GetBridgeRampDirection(tile);
   661 	direction = GetBridgeRampDirection(tile);
   647 	delta = TileOffsByDiagDir(direction);
   662 	delta = TileOffsByDiagDir(direction);
   659 
   674 
   660 	if (flags & DC_EXEC) {
   675 	if (flags & DC_EXEC) {
   661 		TileIndex c;
   676 		TileIndex c;
   662 		Track track;
   677 		Track track;
   663 
   678 
   664 		//checks if the owner is town then decrease town rating by RATING_TUNNEL_BRIDGE_DOWN_STEP until
   679 		/* 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
   680 		 * you have a "Poor" (0) town rating */
   666 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   681 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   667 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   682 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   668 
   683 
   669 		DoClearSquare(tile);
   684 		DoClearSquare(tile);
   670 		DoClearSquare(endtile);
   685 		DoClearSquare(endtile);
   715 
   730 
   716 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   731 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   717 
   732 
   718 		if (GetRailType(tile) == totype) return CMD_ERROR;
   733 		if (GetRailType(tile) == totype) return CMD_ERROR;
   719 
   734 
   720 		// 'hidden' elrails can't be downgraded to normal rail when elrails are disabled
   735 		/* '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;
   736 		if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR;
   722 
   737 
   723 		endtile = CheckTunnelBusy(tile, &length);
   738 		endtile = CheckTunnelBusy(tile, &length);
   724 		if (endtile == INVALID_TILE) return CMD_ERROR;
   739 		if (endtile == INVALID_TILE) return CMD_ERROR;
   725 
   740 
   738 	} else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
   753 	} else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
   739 
   754 
   740 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   755 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   741 
   756 
   742 		endtile = GetOtherBridgeEnd(tile);
   757 		endtile = GetOtherBridgeEnd(tile);
   743 
   758 		byte bridge_height = GetBridgeHeight(tile);
   744 		if (!EnsureNoVehicle(tile) ||
   759 
   745 				!EnsureNoVehicle(endtile) ||
   760 		if (FindVehicleOnTileZ(tile, bridge_height) != NULL ||
   746 				IsVehicleOnBridge(tile, endtile, GetBridgeHeight(tile))) {
   761 				FindVehicleOnTileZ(endtile, bridge_height) != NULL ||
       
   762 				IsVehicleOnBridge(tile, endtile, bridge_height)) {
   747 			return CMD_ERROR;
   763 			return CMD_ERROR;
   748 		}
   764 		}
   749 
   765 
   750 		if (GetRailType(tile) == totype) return CMD_ERROR;
   766 		if (GetRailType(tile) == totype) return CMD_ERROR;
   751 
   767 
   790 			{ 1, 8, 4, 2,   2, 16, 9, 0 },
   806 			{ 1, 8, 4, 2,   2, 16, 9, 0 },
   791 			{ 4, 8, 1, 2,  16,  2, 0, 9 },
   807 			{ 4, 8, 1, 2,  16,  2, 0, 9 },
   792 			{ 2, 4, 8, 1,   2, 16, 9, 0 }
   808 			{ 2, 4, 8, 1,   2, 16, 9, 0 }
   793 		};
   809 		};
   794 
   810 
   795 		if (_display_opt & DO_TRANS_BUILDINGS) {
   811 		if (HASBIT(_transparent_opt, TO_BRIDGES)) {
   796 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
   812 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
   797 			pal = PALETTE_TO_TRANSPARENT;
   813 			pal = PALETTE_TO_TRANSPARENT;
   798 		} else {
   814 		} else {
   799 			pal = psid->pal;
   815 			pal = psid->pal;
   800 		}
   816 		}
   827 {
   843 {
   828 	uint i;
   844 	uint i;
   829 
   845 
   830 	if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) return tileh;
   846 	if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) return tileh;
   831 
   847 
   832 	// inclined sloped building
   848 	/* inclined sloped building */
   833 	switch (tileh) {
   849 	switch (tileh) {
   834 		case SLOPE_W:
   850 		case SLOPE_W:
   835 		case SLOPE_STEEP_W: i = 0; break;
   851 		case SLOPE_STEEP_W: i = 0; break;
   836 		case SLOPE_S:
   852 		case SLOPE_S:
   837 		case SLOPE_STEEP_S: i = 2; break;
   853 		case SLOPE_STEEP_S: i = 2; break;
   844 	if (axis != AXIS_X) ++i;
   860 	if (axis != AXIS_X) ++i;
   845 	return i + 15;
   861 	return i + 15;
   846 }
   862 }
   847 
   863 
   848 /**
   864 /**
       
   865  * Draws the trambits over an already drawn (lower end) of a bridge.
       
   866  * @param x       the x of the bridge
       
   867  * @param y       the y of the bridge
       
   868  * @param z       the z of the bridge
       
   869  * @param offset  number representing whether to level or sloped and the direction
       
   870  * @param overlay do we want to still see the road?
       
   871  */
       
   872 static void DrawBridgeTramBits(int x, int y, byte z, int offset, bool overlay)
       
   873 {
       
   874 	static const SpriteID tram_offsets[2][6] = { { 107, 108, 109, 110, 111, 112 }, { 4, 5, 15, 16, 17, 18 } };
       
   875 	static const SpriteID back_offsets[6]    =   {  95,  95,  99, 102, 100, 101 };
       
   876 	static const SpriteID front_offsets[6]   =   {  97,  98, 103, 106, 104, 105 };
       
   877 
       
   878 	static const uint size_x[6] = { 11, 16, 16, 16, 16, 16 };
       
   879 	static const uint size_y[6] = { 16, 11, 16, 16, 16, 16 };
       
   880 
       
   881 	AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + tram_offsets[overlay][offset], PAL_NONE, x, y, size_x[offset], size_y[offset], offset >= 2 ? 1 : 0, z);
       
   882 
       
   883 	SpriteID front = SPR_TRAMWAY_BASE + front_offsets[offset];
       
   884 	SpriteID back  = SPR_TRAMWAY_BASE + back_offsets[offset];
       
   885 	SpriteID pal   = PAL_NONE;
       
   886 	if (HASBIT(_transparent_opt, TO_BUILDINGS)) {
       
   887 		SETBIT(front, PALETTE_MODIFIER_TRANSPARENT);
       
   888 		SETBIT(back,  PALETTE_MODIFIER_TRANSPARENT);
       
   889 		pal = PALETTE_TO_TRANSPARENT;
       
   890 	}
       
   891 
       
   892 	AddSortableSpriteToDraw(back,  pal, x, y, size_x[offset], size_y[offset], 0, z);
       
   893 	/* For sloped sprites the bounding box needs to be higher, as the pylons stop on a higher point */
       
   894 	AddSortableSpriteToDraw(front, pal, x, y, size_x[offset], size_y[offset], offset >= 2 ? 0x30 : 0x10, z);
       
   895 }
       
   896 
       
   897 /**
   849  * Draws a tunnel of bridge tile.
   898  * Draws a tunnel of bridge tile.
   850  * For tunnels, this is rather simple, as you only needa draw the entrance.
   899  * 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
   900  * 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:
   901  * and it works a bit like a bitmask.<p> For bridge heads:
       
   902  * @param ti TileInfo of the structure to draw
   853  * <ul><li>Bit 0: direction</li>
   903  * <ul><li>Bit 0: direction</li>
   854  * <li>Bit 1: northern or southern heads</li>
   904  * <li>Bit 1: northern or southern heads</li>
   855  * <li>Bit 2: Set if the bridge head is sloped</li>
   905  * <li>Bit 2: Set if the bridge head is sloped</li>
   856  * <li>Bit 3 and more: Railtype Specific subset</li>
   906  * <li>Bit 3 and more: Railtype Specific subset</li>
   857  * </ul>
   907  * </ul>
   871 
   921 
   872 		if (HasTunnelSnowOrDesert(ti->tile)) image += 32;
   922 		if (HasTunnelSnowOrDesert(ti->tile)) image += 32;
   873 
   923 
   874 		image += GetTunnelDirection(ti->tile) * 2;
   924 		image += GetTunnelDirection(ti->tile) * 2;
   875 		DrawGroundSprite(image, PAL_NONE);
   925 		DrawGroundSprite(image, PAL_NONE);
   876 		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
   926 		if (GetTunnelTransportType(ti->tile) == TRANSPORT_ROAD) {
   877 
   927 			DiagDirection dir = GetTunnelDirection(ti->tile);
   878 		AddSortableSpriteToDraw(image+1, PAL_NONE, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, 1, 1, 8, (byte)ti->z);
   928 			RoadTypes rts = GetRoadTypes(ti->tile);
       
   929 
       
   930 			if (HASBIT(rts, ROADTYPE_TRAM)) {
       
   931 				static const SpriteID tunnel_sprites[2][4] = { { 28, 78, 79, 27 }, {  5, 76, 77,  4 } };
       
   932 
       
   933 				DrawGroundSprite(SPR_TRAMWAY_BASE + tunnel_sprites[rts - ROADTYPES_TRAM][dir], PAL_NONE);
       
   934 				AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + dir, PAL_NONE, ti->x, ti->y, 16, 16, 16, (byte)ti->z);
       
   935 			}
       
   936 		} else if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) {
       
   937 			DrawCatenary(ti);
       
   938 		}
       
   939 
       
   940 		AddSortableSpriteToDraw(image + 1, PAL_NONE, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, 1, 1, 8, (byte)ti->z);
   879 		DrawBridgeMiddle(ti);
   941 		DrawBridgeMiddle(ti);
   880 	} else if (IsBridge(ti->tile)) { // XXX is this necessary?
   942 	} else if (IsBridge(ti->tile)) { // XXX is this necessary?
   881 		const PalSpriteID *psid;
   943 		const PalSpriteID *psid;
   882 		int base_offset;
   944 		int base_offset;
   883 		bool ice = HasBridgeSnowOrDesert(ti->tile);
   945 		bool ice = HasBridgeSnowOrDesert(ti->tile);
   884 
   946 
   885 		if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
   947 		if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
   886 			base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset;
   948 			base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset;
   887 			assert(base_offset != 8); /* This one is used for roads */
   949 			assert(base_offset != 8); // This one is used for roads
   888 		} else {
   950 		} else {
   889 			base_offset = 8;
   951 			base_offset = 8;
   890 		}
   952 		}
   891 
   953 
   892 		/* as the lower 3 bits are used for other stuff, make sure they are clear */
   954 		/* as the lower 3 bits are used for other stuff, make sure they are clear */
   895 		if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) {
   957 		if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) {
   896 			int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
   958 			int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
   897 			if (f != 0) DrawFoundation(ti, f);
   959 			if (f != 0) DrawFoundation(ti, f);
   898 		}
   960 		}
   899 
   961 
   900 		// HACK Wizardry to convert the bridge ramp direction into a sprite offset
   962 		/* HACK Wizardry to convert the bridge ramp direction into a sprite offset */
   901 		base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
   963 		base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
   902 
   964 
   903 		if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
   965 		if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
   904 
   966 
   905 		/* Table number 6 always refers to the bridge heads for any bridge type */
   967 		/* Table number 6 always refers to the bridge heads for any bridge type */
   909 			DrawClearLandTile(ti, 3);
   971 			DrawClearLandTile(ti, 3);
   910 		} else {
   972 		} else {
   911 			DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh], PAL_NONE);
   973 			DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh], PAL_NONE);
   912 		}
   974 		}
   913 
   975 
   914 		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
       
   915 
       
   916 		image = psid->sprite;
   976 		image = psid->sprite;
   917 
   977 
   918 		// draw ramp
   978 		/* draw ramp */
   919 		if (_display_opt & DO_TRANS_BUILDINGS) {
   979 		if (HASBIT(_transparent_opt, TO_BRIDGES)) {
   920 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
   980 			SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
   921 			pal = PALETTE_TO_TRANSPARENT;
   981 			pal = PALETTE_TO_TRANSPARENT;
   922 		} else {
   982 		} else {
   923 			pal = psid->pal;
   983 			pal = psid->pal;
   924 		}
   984 		}
   925 
   985 
   926 		/* HACK set the height of the BB of a sloped ramp to 1 so a vehicle on
   986 		/* HACK set the height of the BB of a sloped ramp to 1 so a vehicle on
   927 		 * it doesn't disappear behind it
   987 		 * it doesn't disappear behind it
   928 		 */
   988 		 */
   929 		AddSortableSpriteToDraw(
   989 		AddSortableSpriteToDraw(
   930 			image, pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 1 : 8, ti->z
   990 			image, pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 0 : 8, ti->z
   931 		);
   991 		);
       
   992 
       
   993 		if (GetBridgeTransportType(ti->tile) == TRANSPORT_ROAD) {
       
   994 			RoadTypes rts = GetRoadTypes(ti->tile);
       
   995 
       
   996 			if (HASBIT(rts, ROADTYPE_TRAM)) {
       
   997 				uint offset = GetBridgeRampDirection(ti->tile);
       
   998 				uint z = ti->z;
       
   999 				if (ti->tileh != SLOPE_FLAT) {
       
  1000 					offset = (offset + 1) & 1;
       
  1001 					z += TILE_HEIGHT;
       
  1002 				} else {
       
  1003 					offset += 2;
       
  1004 				}
       
  1005 				DrawBridgeTramBits(ti->x, ti->y, z, offset, HASBIT(rts, ROADTYPE_ROAD));
       
  1006 			}
       
  1007 		} else if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) {
       
  1008 			DrawCatenary(ti);
       
  1009 		}
   932 
  1010 
   933 		DrawBridgeMiddle(ti);
  1011 		DrawBridgeMiddle(ti);
   934 	}
  1012 	}
   935 }
  1013 }
   936 
  1014 
  1003 	psid = base_offset + GetBridgeSpriteTable(type, piece);
  1081 	psid = base_offset + GetBridgeSpriteTable(type, piece);
  1004 	if (axis != AXIS_X) psid += 4;
  1082 	if (axis != AXIS_X) psid += 4;
  1005 
  1083 
  1006 	x = ti->x;
  1084 	x = ti->x;
  1007 	y = ti->y;
  1085 	y = ti->y;
  1008 	z = GetBridgeHeight(rampsouth) - 3;
  1086 	uint bridge_z = GetBridgeHeight(rampsouth);
       
  1087 	z = bridge_z - 3;
  1009 
  1088 
  1010 	image = psid->sprite;
  1089 	image = psid->sprite;
  1011 	if (_display_opt & DO_TRANS_BUILDINGS) {
  1090 	if (HASBIT(_transparent_opt, TO_BRIDGES)) {
  1012 		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1091 		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1013 		pal = PALETTE_TO_TRANSPARENT;
  1092 		pal = PALETTE_TO_TRANSPARENT;
  1014 	} else {
  1093 	} else {
  1015 		pal = psid->pal;
  1094 		pal = psid->pal;
  1016 	}
  1095 	}
  1021 		AddSortableSpriteToDraw(image, pal, x, y, 11, 16, 1, z);
  1100 		AddSortableSpriteToDraw(image, pal, x, y, 11, 16, 1, z);
  1022 	}
  1101 	}
  1023 
  1102 
  1024 	psid++;
  1103 	psid++;
  1025 	image = psid->sprite;
  1104 	image = psid->sprite;
  1026 	if (_display_opt & DO_TRANS_BUILDINGS) {
  1105 	if (HASBIT(_transparent_opt, TO_BRIDGES)) {
  1027 		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1106 		SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1028 		pal = PALETTE_TO_TRANSPARENT;
  1107 		pal = PALETTE_TO_TRANSPARENT;
  1029 	} else {
  1108 	} else {
  1030 		pal = psid->pal;
  1109 		pal = psid->pal;
  1031 	}
  1110 	}
  1032 
  1111 
  1033 	// draw roof, the component of the bridge which is logically between the vehicle and the camera
  1112 	if (GetBridgeTransportType(rampsouth) == TRANSPORT_ROAD) {
       
  1113 		RoadTypes rts = GetRoadTypes(rampsouth);
       
  1114 
       
  1115 		if (HASBIT(rts, ROADTYPE_TRAM)) {
       
  1116 			DrawBridgeTramBits(x, y, bridge_z, axis ^ 1, HASBIT(rts, ROADTYPE_ROAD));
       
  1117 		}
       
  1118 	} else if (GetRailType(rampsouth) == RAILTYPE_ELECTRIC) {
       
  1119 		DrawCatenary(ti);
       
  1120 	}
       
  1121 
       
  1122 	/* draw roof, the component of the bridge which is logically between the vehicle and the camera */
  1034 	if (axis == AXIS_X) {
  1123 	if (axis == AXIS_X) {
  1035 		y += 12;
  1124 		y += 12;
  1036 		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, pal, x, y, 16, 1, 0x28, z);
  1125 		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, pal, x, y, 16, 1, 0x28, z);
  1037 	} else {
  1126 	} else {
  1038 		x += 12;
  1127 		x += 12;
  1039 		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, pal, x, y, 1, 16, 0x28, z);
  1128 		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, pal, x, y, 1, 16, 0x28, z);
  1040 	}
  1129 	}
  1041 
  1130 
  1042 	if (GetRailType(rampsouth) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
       
  1043 
       
  1044 	psid++;
  1131 	psid++;
  1045 	if (ti->z + 5 == z) {
  1132 	if (ti->z + 5 == z) {
  1046 		// draw poles below for small bridges
  1133 		/* draw poles below for small bridges */
  1047 		if (psid->sprite != 0) {
  1134 		if (psid->sprite != 0) {
  1048 			image = psid->sprite;
  1135 			image = psid->sprite;
  1049 			if (_display_opt & DO_TRANS_BUILDINGS) {
  1136 			if (HASBIT(_transparent_opt, TO_BRIDGES)) {
  1050 				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1137 				SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
  1051 				pal = PALETTE_TO_TRANSPARENT;
  1138 				pal = PALETTE_TO_TRANSPARENT;
  1052 			} else {
  1139 			} else {
  1053 				pal = psid->pal;
  1140 				pal = psid->pal;
  1054 			}
  1141 			}
  1055 
  1142 
  1056 			DrawGroundSpriteAt(image, pal, x, y, z);
  1143 			DrawGroundSpriteAt(image, pal, x, y, z);
  1057 		}
  1144 		}
  1058 	} else if (_patches.bridge_pillars) {
  1145 	} else if (_patches.bridge_pillars) {
  1059 		// draw pillars below for high bridges
  1146 		/* draw pillars below for high bridges */
  1060 		DrawBridgePillars(psid, ti, axis, type, x, y, z);
  1147 		DrawBridgePillars(psid, ti, axis, type, x, y, z);
  1061 	}
  1148 	}
  1062 }
  1149 }
  1063 
  1150 
  1064 
  1151 
  1071 	y &= 0xF;
  1158 	y &= 0xF;
  1072 
  1159 
  1073 	if (IsTunnel(tile)) {
  1160 	if (IsTunnel(tile)) {
  1074 		uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x);
  1161 		uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x);
  1075 
  1162 
  1076 		// In the tunnel entrance?
  1163 		/* In the tunnel entrance? */
  1077 		if (5 <= pos && pos <= 10) return z;
  1164 		if (5 <= pos && pos <= 10) return z;
  1078 	} else {
  1165 	} else {
  1079 		DiagDirection dir = GetBridgeRampDirection(tile);
  1166 		DiagDirection dir = GetBridgeRampDirection(tile);
  1080 		uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
  1167 		uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
  1081 
  1168 
  1082 		// On the bridge ramp?
  1169 		/* On the bridge ramp? */
  1083 		if (5 <= pos && pos <= 10) {
  1170 		if (5 <= pos && pos <= 10) {
  1084 			uint delta;
  1171 			uint delta;
  1085 
  1172 
  1086 			if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2;
  1173 			if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2;
  1087 			if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT;
  1174 			if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT;
  1216 {
  1303 {
  1217 	/* not used */
  1304 	/* not used */
  1218 }
  1305 }
  1219 
  1306 
  1220 
  1307 
  1221 static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode)
  1308 static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode, uint sub_mode)
  1222 {
  1309 {
  1223 	if (IsTunnel(tile)) {
  1310 	if (IsTunnel(tile)) {
  1224 		if (GetTunnelTransportType(tile) != mode) return 0;
  1311 		if (GetTunnelTransportType(tile) != mode) return 0;
       
  1312 		if (GetTunnelTransportType(tile) == TRANSPORT_ROAD && (GetRoadTypes(tile) & sub_mode) == 0) return 0;
  1225 		return AxisToTrackBits(DiagDirToAxis(GetTunnelDirection(tile))) * 0x101;
  1313 		return AxisToTrackBits(DiagDirToAxis(GetTunnelDirection(tile))) * 0x101;
  1226 	} else {
  1314 	} else {
  1227 		if (GetBridgeTransportType(tile) != mode) return 0;
  1315 		if (GetBridgeTransportType(tile) != mode) return 0;
       
  1316 		if (GetBridgeTransportType(tile) == TRANSPORT_ROAD && (GetRoadTypes(tile) & sub_mode) == 0) return 0;
  1228 		return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(tile))) * 0x101;
  1317 		return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(tile))) * 0x101;
  1229 	}
  1318 	}
  1230 }
  1319 }
  1231 
  1320 
  1232 static void ChangeTileOwner_TunnelBridge(TileIndex tile, PlayerID old_player, PlayerID new_player)
  1321 static void ChangeTileOwner_TunnelBridge(TileIndex tile, PlayerID old_player, PlayerID new_player)
  1234 	if (!IsTileOwner(tile, old_player)) return;
  1323 	if (!IsTileOwner(tile, old_player)) return;
  1235 
  1324 
  1236 	if (new_player != PLAYER_SPECTATOR) {
  1325 	if (new_player != PLAYER_SPECTATOR) {
  1237 		SetTileOwner(tile, new_player);
  1326 		SetTileOwner(tile, new_player);
  1238 	} else {
  1327 	} else {
  1239 		DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
  1328 		if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) {
       
  1329 			/* When clearing the bridge/tunnel failed there are still vehicles on/in
       
  1330 			 * the bridge/tunnel. As all *our* vehicles are already removed, they
       
  1331 			 * must be of another owner. Therefor this must be a road bridge/tunnel.
       
  1332 			 * In that case we can safely reassign the ownership to OWNER_NONE. */
       
  1333 			assert((IsTunnel(tile) ? GetTunnelTransportType(tile) : GetBridgeTransportType(tile)) == TRANSPORT_ROAD);
       
  1334 			SetTileOwner(tile, OWNER_NONE);
       
  1335 		}
  1240 	}
  1336 	}
  1241 }
  1337 }
  1242 
  1338 
  1243 
  1339 
  1244 static const byte _tunnel_fractcoord_1[4]    = {0x8E, 0x18, 0x81, 0xE8};
  1340 static const byte _tunnel_fractcoord_1[4]    = {0x8E, 0x18, 0x81, 0xE8};
  1300 		} else if (v->type == VEH_ROAD) {
  1396 		} else if (v->type == VEH_ROAD) {
  1301 			fc = (x & 0xF) + (y << 4);
  1397 			fc = (x & 0xF) + (y << 4);
  1302 			dir = GetTunnelDirection(tile);
  1398 			dir = GetTunnelDirection(tile);
  1303 			vdir = DirToDiagDir(v->direction);
  1399 			vdir = DirToDiagDir(v->direction);
  1304 
  1400 
  1305 			// Enter tunnel?
  1401 			/* Enter tunnel? */
  1306 			if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) {
  1402 			if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) {
  1307 				if (fc == _tunnel_fractcoord_4[dir] ||
  1403 				if (fc == _tunnel_fractcoord_4[dir] ||
  1308 						fc == _tunnel_fractcoord_5[dir]) {
  1404 						fc == _tunnel_fractcoord_5[dir]) {
  1309 					v->tile = tile;
  1405 					v->tile = tile;
  1310 					v->u.road.state = RVSB_WORMHOLE;
  1406 					v->u.road.state = RVSB_WORMHOLE;