tunnelbridge_cmd.c
changeset 3977 513433ebd092
parent 3938 3d936f853ed2
child 3996 5d30d315a2ed
equal deleted inserted replaced
3976:6135bc445350 3977:513433ebd092
    27 #include "train.h"
    27 #include "train.h"
    28 #include "water_map.h"
    28 #include "water_map.h"
    29 #include "yapf/yapf.h"
    29 #include "yapf/yapf.h"
    30 
    30 
    31 #include "table/bridge_land.h"
    31 #include "table/bridge_land.h"
       
    32 
       
    33 extern const byte _track_sloped_sprites[14];
       
    34 extern const SpriteID _water_shore_sprites[15];
       
    35 
       
    36 extern void DrawCanalWater(TileIndex tile);
    32 
    37 
    33 const Bridge orig_bridge[] = {
    38 const Bridge orig_bridge[] = {
    34 /*
    39 /*
    35 	   year of availablity
    40 	   year of availablity
    36 	   |  minimum length
    41 	   |  minimum length
   190 	uint z_start;
   195 	uint z_start;
   191 	uint z_end;
   196 	uint z_end;
   192 	TileIndex tile;
   197 	TileIndex tile;
   193 	TileIndexDiff delta;
   198 	TileIndexDiff delta;
   194 	uint bridge_len;
   199 	uint bridge_len;
       
   200 	uint odd_middle_part;
   195 	Axis direction;
   201 	Axis direction;
   196 	uint i;
   202 	uint i;
   197 	int32 cost, terraformcost, ret;
   203 	int32 cost, terraformcost, ret;
   198 	bool allow_on_slopes;
   204 	bool allow_on_slopes;
   199 
   205 
   281 	terraformcost = CheckBridgeSlope(direction, tileh_end, false);
   287 	terraformcost = CheckBridgeSlope(direction, tileh_end, false);
   282 	if (CmdFailed(terraformcost) || (terraformcost && !allow_on_slopes))
   288 	if (CmdFailed(terraformcost) || (terraformcost && !allow_on_slopes))
   283 		return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   289 		return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
   284 	cost += terraformcost;
   290 	cost += terraformcost;
   285 
   291 
   286 	{
       
   287 		TileIndex Heads[] = {tile_start, tile_end};
       
   288 		int i;
       
   289 
       
   290 		for (i = 0; i < 2; i++) {
       
   291 			if (MayHaveBridgeAbove(Heads[i])) {
       
   292 				if (IsBridgeAbove(Heads[i])) {
       
   293 					TileIndex north_head = GetNorthernBridgeEnd(Heads[i]);
       
   294 					int z1, z2;
       
   295 
       
   296 					if (direction == GetBridgeAxis(Heads[i])) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
       
   297 
       
   298 					z1 = GetBridgeHeight(north_head, GetBridgeAxis(Heads[i]));
       
   299 					z2 = GetBridgeHeight(Heads[i], direction);
       
   300 
       
   301 					if (z1 == z2) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
       
   302 				}
       
   303 			}
       
   304 		}
       
   305 	}
       
   306 
   292 
   307 	/* do the drill? */
   293 	/* do the drill? */
   308 	if (flags & DC_EXEC) {
   294 	if (flags & DC_EXEC) {
   309 		DiagDirection dir = AxisToDiagDir(direction);
   295 		DiagDirection dir = AxisToDiagDir(direction);
   310 
   296 
   317 		}
   303 		}
   318 		MarkTileDirtyByTile(tile_start);
   304 		MarkTileDirtyByTile(tile_start);
   319 		MarkTileDirtyByTile(tile_end);
   305 		MarkTileDirtyByTile(tile_end);
   320 	}
   306 	}
   321 
   307 
       
   308 	// position of middle part of the odd bridge (larger than MAX(i) otherwise)
       
   309 	odd_middle_part = (bridge_len % 2) ? (bridge_len / 2) : bridge_len;
       
   310 
   322 	tile = tile_start;
   311 	tile = tile_start;
   323 	delta = (direction == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
   312 	delta = (direction == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
   324 	for (i = 0; i != bridge_len; i++) {
   313 	for (i = 0; i != bridge_len; i++) {
       
   314 		TransportType transport_under;
       
   315 		Owner owner_under = OWNER_NONE;
       
   316 		RailType rail_under = INVALID_RAILTYPE;
   325 		uint z;
   317 		uint z;
   326 
   318 
   327 		tile += delta;
   319 		tile += delta;
   328 
   320 
   329 		if (GetTileSlope(tile, &z) != SLOPE_FLAT && z >= z_start) return_cmd_error(STR_5009_LEVEL_LAND_OR_WATER_REQUIRED);
   321 		if (GetTileSlope(tile, &z) != SLOPE_FLAT && z >= z_start) {
   330 
   322 			return_cmd_error(STR_5009_LEVEL_LAND_OR_WATER_REQUIRED);
   331 		if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) {
       
   332 			/* Disallow crossing bridges for the time being */
       
   333 			return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
       
   334 		}
   323 		}
   335 
   324 
   336 		switch (GetTileType(tile)) {
   325 		switch (GetTileType(tile)) {
   337 			case MP_WATER:
   326 			case MP_WATER:
   338 				if (!EnsureNoVehicle(tile)) return_cmd_error(STR_980E_SHIP_IN_THE_WAY);
   327 				if (!EnsureNoVehicle(tile)) return_cmd_error(STR_980E_SHIP_IN_THE_WAY);
   339 				if (!(IsWater(tile) || IsCoast(tile))) goto not_valid_below;
   328 				if (!(IsWater(tile) || IsCoast(tile))) goto not_valid_below;
       
   329 				transport_under = TRANSPORT_WATER;
       
   330 				owner_under = GetTileOwner(tile);
   340 				break;
   331 				break;
   341 
   332 
   342 			case MP_RAILWAY:
   333 			case MP_RAILWAY:
   343 				if (!IsPlainRailTile(tile)) goto not_valid_below;
   334 				if (GetRailTileType(tile) != RAIL_TILE_NORMAL ||
       
   335 						GetTrackBits(tile) != (direction == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X)) {
       
   336 					goto not_valid_below;
       
   337 				}
       
   338 				transport_under = TRANSPORT_RAIL;
       
   339 				owner_under = GetTileOwner(tile);
       
   340 				rail_under = GetRailType(tile);
   344 				break;
   341 				break;
   345 
   342 
   346 			case MP_STREET:
   343 			case MP_STREET:
   347 				if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) goto not_valid_below;
   344 				if (GetRoadTileType(tile) != ROAD_TILE_NORMAL ||
   348 				break;
   345 						GetRoadBits(tile) != (direction == AXIS_X ? ROAD_Y : ROAD_X)) {
   349 
   346 					goto not_valid_below;
   350 			case MP_TUNNELBRIDGE:
   347 				}
   351 				if (IsTunnel(tile)) break;
   348 				transport_under = TRANSPORT_ROAD;
   352 				if (direction == DiagDirToAxis(GetBridgeRampDirection(tile))) goto not_valid_below;
   349 				owner_under = GetTileOwner(tile);
   353 				if (GetBridgeHeight(tile_start, direction) == GetBridgeHeight(tile, DiagDirToAxis(GetBridgeRampDirection(tile)))) goto not_valid_below;
       
   354 				break;
       
   355 
       
   356 			case MP_CLEAR:
       
   357 				if (IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
       
   358 				break;
   350 				break;
   359 
   351 
   360 			default:
   352 			default:
   361 not_valid_below:;
   353 not_valid_below:;
   362 				/* try and clear the middle landscape */
   354 				/* try and clear the middle landscape */
   363 				ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   355 				ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
   364 				if (CmdFailed(ret)) return ret;
   356 				if (CmdFailed(ret)) return ret;
   365 				cost += ret;
   357 				cost += ret;
       
   358 				transport_under = INVALID_TRANSPORT;
   366 				break;
   359 				break;
   367 		}
   360 		}
   368 
   361 
   369 		if (flags & DC_EXEC) {
   362 		if (flags & DC_EXEC) {
   370 			SetBridgeMiddle(tile, direction);
   363 			uint piece;
       
   364 
       
   365 			//bridges pieces sequence (middle parts)
       
   366 			// bridge len 1: 0
       
   367 			// bridge len 2: 0 1
       
   368 			// bridge len 3: 0 4 1
       
   369 			// bridge len 4: 0 2 3 1
       
   370 			// bridge len 5: 0 2 5 3 1
       
   371 			// bridge len 6: 0 2 3 2 3 1
       
   372 			// bridge len 7: 0 2 3 4 2 3 1
       
   373 			// #0 - always as first, #1 - always as last (if len>1)
       
   374 			// #2,#3 are to pair in order
       
   375 			// for odd bridges: #5 is going in the bridge middle if on even position, #4 on odd (counting from 0)
       
   376 
       
   377 			if (i == 0) { // first tile
       
   378 				piece = 0;
       
   379 			} else if (i == bridge_len - 1) { // last tile
       
   380 				piece = 1;
       
   381 			} else if (i == odd_middle_part) { // we are on the middle of odd bridge: #5 on even pos, #4 on odd
       
   382 				piece = 5 - (i % 2);
       
   383 			} else {
       
   384 					// generate #2 and #3 in turns [i%2==0], after the middle of odd bridge
       
   385 					// this sequence swaps [... XOR (i>odd_middle_part)],
       
   386 					// for even bridges XOR does not apply as odd_middle_part==bridge_len
       
   387 					piece = 2 + ((i % 2 == 0) ^ (i > odd_middle_part));
       
   388 			}
       
   389 
       
   390 			if (transport == TRANSPORT_RAIL) {
       
   391 				MakeRailBridgeMiddle(tile, bridge_type, piece, direction, railtype);
       
   392 			} else {
       
   393 				MakeRoadBridgeMiddle(tile, bridge_type, piece, direction);
       
   394 			}
       
   395 			switch (transport_under) {
       
   396 				case TRANSPORT_RAIL: SetRailUnderBridge(tile, owner_under, rail_under); break;
       
   397 				case TRANSPORT_ROAD: SetRoadUnderBridge(tile, owner_under); break;
       
   398 
       
   399 				case TRANSPORT_WATER:
       
   400 					if (owner_under == OWNER_WATER) {
       
   401 						SetWaterUnderBridge(tile);
       
   402 					} else {
       
   403 						SetCanalUnderBridge(tile, owner_under);
       
   404 					}
       
   405 					break;
       
   406 
       
   407 				default: SetClearUnderBridge(tile); break;
       
   408 			}
       
   409 
   371 			MarkTileDirtyByTile(tile);
   410 			MarkTileDirtyByTile(tile);
   372 		}
   411 		}
   373 	}
   412 	}
   374 
   413 
   375 	SetSignalsOnBothDir(tile_start, direction == AXIS_X ? TRACK_X : TRACK_Y);
   414 	SetSignalsOnBothDir(tile_start, direction == AXIS_X ? TRACK_X : TRACK_Y);
   550 		YapfNotifyTrackLayoutChange(endtile, DiagDirToAxis(dir) == AXIS_X ? TRACK_X : TRACK_Y);
   589 		YapfNotifyTrackLayoutChange(endtile, DiagDirToAxis(dir) == AXIS_X ? TRACK_X : TRACK_Y);
   551 	}
   590 	}
   552 	return _price.clear_tunnel * (length + 1);
   591 	return _price.clear_tunnel * (length + 1);
   553 }
   592 }
   554 
   593 
   555 #if 0
   594 
   556 static uint GetBridgeHeightRamp(TileIndex t)
   595 static uint GetBridgeHeightRamp(TileIndex t)
   557 {
   596 {
   558 	/* Return the height there (the height of the NORTH CORNER)
   597 	/* Return the height there (the height of the NORTH CORNER)
   559 	 * If the end of the bridge is on a tile with all corners except the north corner raised,
   598 	 * If the end of the bridge is on a tile with all corners except the north corner raised,
   560 	 * the z coordinate is 1 height level too low. Compensate for that */
   599 	 * the z coordinate is 1 height level too low. Compensate for that */
   561 	return TilePixelHeight(t) + (GetTileSlope(t, NULL) == SLOPE_WSE ? TILE_HEIGHT : 0);
   600 	return TilePixelHeight(t) + (GetTileSlope(t, NULL) == SLOPE_WSE ? TILE_HEIGHT : 0);
   562 }
   601 }
   563 #endif
       
   564 
   602 
   565 
   603 
   566 static int32 DoClearBridge(TileIndex tile, uint32 flags)
   604 static int32 DoClearBridge(TileIndex tile, uint32 flags)
   567 {
   605 {
   568 	DiagDirection direction;
   606 	DiagDirection direction;
   569 	TileIndexDiff delta;
   607 	TileIndexDiff delta;
   570 	TileIndex endtile;
   608 	TileIndex endtile;
       
   609 	Vehicle *v;
   571 	Town *t;
   610 	Town *t;
   572 
   611 
   573 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   612 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
       
   613 
       
   614 	if (IsBridgeMiddle(tile)) {
       
   615 		if (IsTransportUnderBridge(tile)) {
       
   616 			/* delete transport route under the bridge */
       
   617 			int32 cost;
       
   618 
       
   619 			// check if we own the tile below the bridge..
       
   620 			if (_current_player != OWNER_WATER && (!CheckTileOwnership(tile) || !EnsureNoVehicleOnGround(tile)))
       
   621 				return CMD_ERROR;
       
   622 
       
   623 			if (GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
       
   624 				cost = _price.remove_rail;
       
   625 			} else {
       
   626 				cost = _price.remove_road * 2;
       
   627 			}
       
   628 
       
   629 			if (flags & DC_EXEC) {
       
   630 				SetClearUnderBridge(tile);
       
   631 				MarkTileDirtyByTile(tile);
       
   632 			}
       
   633 			return cost;
       
   634 		} else if (IsWaterUnderBridge(tile) && TilePixelHeight(tile) != 0) {
       
   635 			/* delete canal under bridge */
       
   636 
       
   637 			// check for vehicles under bridge
       
   638 			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
       
   639 
       
   640 			if (flags & DC_EXEC) {
       
   641 				SetClearUnderBridge(tile);
       
   642 				MarkTileDirtyByTile(tile);
       
   643 			}
       
   644 			return _price.clear_water;
       
   645 		}
       
   646 
       
   647 		tile = GetSouthernBridgeEnd(tile);
       
   648 	}
   574 
   649 
   575 	// floods, scenario editor can always destroy bridges
   650 	// floods, scenario editor can always destroy bridges
   576 	if (_current_player != OWNER_WATER && _game_mode != GM_EDITOR && !CheckTileOwnership(tile)) {
   651 	if (_current_player != OWNER_WATER && _game_mode != GM_EDITOR && !CheckTileOwnership(tile)) {
   577 		if (!(_patches.extra_dynamite || _cheats.magic_bulldozer.value) || !IsTileOwner(tile, OWNER_TOWN))
   652 		if (!(_patches.extra_dynamite || _cheats.magic_bulldozer.value) || !IsTileOwner(tile, OWNER_TOWN))
   578 			return CMD_ERROR;
   653 			return CMD_ERROR;
   582 
   657 
   583 	if (!EnsureNoVehicle(tile) || !EnsureNoVehicle(endtile)) return CMD_ERROR;
   658 	if (!EnsureNoVehicle(tile) || !EnsureNoVehicle(endtile)) return CMD_ERROR;
   584 
   659 
   585 	direction = GetBridgeRampDirection(tile);
   660 	direction = GetBridgeRampDirection(tile);
   586 	delta = TileOffsByDir(direction);
   661 	delta = TileOffsByDir(direction);
       
   662 
       
   663 	/*	Make sure there's no vehicle on the bridge
       
   664 			Omit tile and endtile, since these are already checked, thus solving the problem
       
   665 			of bridges over water, or higher bridges, where z is not increased, eg level bridge
       
   666 	*/
       
   667 	/* Bridges on slopes might have their Z-value offset..correct this */
       
   668 	v = FindVehicleBetween(
       
   669 		tile    + delta,
       
   670 		endtile - delta,
       
   671 		GetBridgeHeightRamp(tile) + TILE_HEIGHT
       
   672 	);
       
   673 	if (v != NULL) return_cmd_error(VehicleInTheWayErrMsg(v));
   587 
   674 
   588 	t = ClosestTownFromTile(tile, (uint)-1); //needed for town rating penalty
   675 	t = ClosestTownFromTile(tile, (uint)-1); //needed for town rating penalty
   589 	// check if you're allowed to remove the bridge owned by a town.
   676 	// check if you're allowed to remove the bridge owned by a town.
   590 	// removal allowal depends on difficulty settings
   677 	// removal allowal depends on difficulty settings
   591 	if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR) {
   678 	if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR) {
   601 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   688 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   602 
   689 
   603 		DoClearSquare(tile);
   690 		DoClearSquare(tile);
   604 		DoClearSquare(endtile);
   691 		DoClearSquare(endtile);
   605 		for (c = tile + delta; c != endtile; c += delta) {
   692 		for (c = tile + delta; c != endtile; c += delta) {
   606 			ClearBridgeMiddle(c);
   693 			if (IsTransportUnderBridge(c)) {
   607 			MarkTileDirtyByTile(c);
   694 				if (GetTransportTypeUnderBridge(c) == TRANSPORT_RAIL) {
       
   695 					MakeRailNormal(c, GetTileOwner(c), GetRailBitsUnderBridge(c), GetRailType(c));
       
   696 				} else {
       
   697 					uint town = IsTileOwner(c, OWNER_TOWN) ? ClosestTownFromTile(c, (uint)-1)->index : 0;
       
   698 					MakeRoadNormal(c, GetTileOwner(c), GetRoadBitsUnderBridge(c), town);
       
   699 				}
       
   700 				MarkTileDirtyByTile(c);
       
   701 			} else {
       
   702 				if (IsClearUnderBridge(c)) {
       
   703 					DoClearSquare(c);
       
   704 				} else {
       
   705 					if (GetTileSlope(c, NULL) == SLOPE_FLAT) {
       
   706 						MakeWater(c);
       
   707 					} else {
       
   708 						MakeShore(c);
       
   709 					}
       
   710 					MarkTileDirtyByTile(c);
       
   711 				}
       
   712 			}
   608 		}
   713 		}
   609 
   714 
   610 		UpdateSignalsOnSegment(tile, ReverseDiagDir(direction));
   715 		UpdateSignalsOnSegment(tile, ReverseDiagDir(direction));
   611 		UpdateSignalsOnSegment(endtile, direction);
   716 		UpdateSignalsOnSegment(endtile, direction);
   612 		YapfNotifyTrackLayoutChange(tile, DiagDirToAxis(direction) == AXIS_X ? TRACK_X : TRACK_Y);
   717 		YapfNotifyTrackLayoutChange(tile, DiagDirToAxis(direction) == AXIS_X ? TRACK_X : TRACK_Y);
   655 			endtrack = TrackdirToTrack(DiagdirToDiagTrackdir(GetTunnelDirection(endtile)));
   760 			endtrack = TrackdirToTrack(DiagdirToDiagTrackdir(GetTunnelDirection(endtile)));
   656 			YapfNotifyTrackLayoutChange(tile, track);
   761 			YapfNotifyTrackLayoutChange(tile, track);
   657 			YapfNotifyTrackLayoutChange(endtile, endtrack);
   762 			YapfNotifyTrackLayoutChange(endtile, endtrack);
   658 		}
   763 		}
   659 		return (length + 1) * (_price.build_rail >> 1);
   764 		return (length + 1) * (_price.build_rail >> 1);
   660 	} else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
   765 	} else if (IsBridge(tile) &&
       
   766 			IsBridgeMiddle(tile) &&
       
   767 			IsTransportUnderBridge(tile) &&
       
   768 			GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
       
   769 		// only check for train under bridge
       
   770 		if (!CheckTileOwnership(tile) || !EnsureNoVehicleOnGround(tile))
       
   771 			return CMD_ERROR;
       
   772 
       
   773 		if (GetRailType(tile) == totype) return CMD_ERROR;
       
   774 
       
   775 		if (exec) {
       
   776 			TrackBits tracks;
       
   777 			SetRailType(tile, totype);
       
   778 			MarkTileDirtyByTile(tile);
       
   779 
       
   780 			// notify YAPF about the track layout change
       
   781 			for (tracks = GetRailBitsUnderBridge(tile); tracks != TRACK_BIT_NONE; tracks = KILL_FIRST_BIT(tracks))
       
   782 				YapfNotifyTrackLayoutChange(tile, FIND_FIRST_BIT(tracks));
       
   783 		}
       
   784 		return _price.build_rail >> 1;
       
   785 	} else if (IsBridge(tile) && IsBridgeRamp(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
       
   786 		TileIndexDiff delta;
       
   787 		int32 cost;
   661 		uint z = TilePixelHeight(tile);
   788 		uint z = TilePixelHeight(tile);
   662 
   789 
   663 		z += TILE_HEIGHT;
   790 		z += TILE_HEIGHT;
   664 
   791 
   665 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   792 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   676 		}
   803 		}
   677 
   804 
   678 		if (GetRailType(tile) == totype) return CMD_ERROR;
   805 		if (GetRailType(tile) == totype) return CMD_ERROR;
   679 
   806 
   680 		if (exec) {
   807 		if (exec) {
   681 			TileIndexDiff delta;
   808 			Track track, endtrack;
   682 
       
   683 			SetRailType(tile, totype);
   809 			SetRailType(tile, totype);
   684 			SetRailType(endtile, totype);
   810 			SetRailType(endtile, totype);
   685 			MarkTileDirtyByTile(tile);
   811 			MarkTileDirtyByTile(tile);
   686 			MarkTileDirtyByTile(endtile);
   812 			MarkTileDirtyByTile(endtile);
   687 
   813 
   688 			delta = TileOffsByDir(GetBridgeRampDirection(tile));
   814 			// notify YAPF about the track layout change
   689 			for (tile += delta; tile != endtile; tile += delta) {
   815 			track = TrackdirToTrack(DiagdirToDiagTrackdir(GetBridgeRampDirection(tile)));
   690 				MarkTileDirtyByTile(tile); // TODO encapsulate this into a function
   816 			endtrack = TrackdirToTrack(DiagdirToDiagTrackdir(GetBridgeRampDirection(endtile)));
   691 			}
   817 			YapfNotifyTrackLayoutChange(tile, track);
   692 		}
   818 			YapfNotifyTrackLayoutChange(endtile, endtrack);
   693 
   819 		}
   694 		return (DistanceManhattan(tile, endtile) + 1) * (_price.build_rail >> 1);
   820 		cost = 2 * (_price.build_rail >> 1);
       
   821 		delta = TileOffsByDir(GetBridgeRampDirection(tile));
       
   822 		for (tile += delta; tile != endtile; tile += delta) {
       
   823 			if (exec) {
       
   824 				SetRailTypeOnBridge(tile, totype);
       
   825 				MarkTileDirtyByTile(tile);
       
   826 			}
       
   827 			cost += _price.build_rail >> 1;
       
   828 		}
       
   829 
       
   830 		return cost;
   695 	} else
   831 	} else
   696 		return CMD_ERROR;
   832 		return CMD_ERROR;
   697 }
   833 }
   698 
   834 
   699 
   835 
   700 static void DrawBridgePillars(PalSpriteID image, const TileInfo* ti, Axis axis, uint type, int x, int y, int z)
   836 // fast routine for getting the height of a middle bridge tile. 'tile' MUST be a middle bridge tile.
       
   837 uint GetBridgeHeight(TileIndex t)
       
   838 {
       
   839 	return GetBridgeHeightRamp(GetSouthernBridgeEnd(t));
       
   840 }
       
   841 
       
   842 static const byte _bridge_foundations[2][16] = {
       
   843 // 0 1  2  3  4 5 6 7  8 9 10 11 12 13 14 15
       
   844 	{0,16,18,3,20,5,0,7,22,0,10,11,12,13,14},
       
   845 	{0,15,17,0,19,5,6,7,21,9,10,11, 0,13,14},
       
   846 };
       
   847 
       
   848 extern const byte _road_sloped_sprites[14];
       
   849 
       
   850 static void DrawBridgePillars(PalSpriteID image, const TileInfo *ti, int x, int y, int z)
   701 {
   851 {
   702 	if (image != 0) {
   852 	if (image != 0) {
   703 		bool drawfarpillar = !HASBIT(GetBridgeFlags(type), 0);
   853 		Axis axis = GetBridgeAxis(ti->tile);
       
   854 		bool drawfarpillar = !HASBIT(GetBridgeFlags(GetBridgeType(ti->tile)), 0);
   704 		int back_height, front_height;
   855 		int back_height, front_height;
   705 		int i = z;
   856 		int i = z;
   706 		const byte *p;
   857 		const byte *p;
   707 
   858 
   708 		static const byte _tileh_bits[4][8] = {
   859 		static const byte _tileh_bits[4][8] = {
   761   * <ul><li>Bit 0: direction</li>
   912   * <ul><li>Bit 0: direction</li>
   762   * <li>Bit 1: northern or southern heads</li>
   913   * <li>Bit 1: northern or southern heads</li>
   763   * <li>Bit 2: Set if the bridge head is sloped</li>
   914   * <li>Bit 2: Set if the bridge head is sloped</li>
   764   * <li>Bit 3 and more: Railtype Specific subset</li>
   915   * <li>Bit 3 and more: Railtype Specific subset</li>
   765   * </ul>
   916   * </ul>
       
   917   * For middle parts:
       
   918   * <ul><li>Bits 0-1: need to be 0</li>
       
   919   * <li>Bit 2: direction</li>
       
   920   * <li>Bit 3 and above: Railtype Specific subset</li>
       
   921   * </ul>
   766   * Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3
   922   * Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3
   767   */
   923   */
   768 static void DrawTile_TunnelBridge(TileInfo *ti)
   924 static void DrawTile_TunnelBridge(TileInfo *ti)
   769 {
   925 {
   770 	uint32 image;
   926 	uint32 image;
       
   927 	const PalSpriteID *b;
   771 	bool ice = _m[ti->tile].m4 & 0x80;
   928 	bool ice = _m[ti->tile].m4 & 0x80;
   772 
   929 
   773 	if (IsTunnel(ti->tile)) {
   930 	if (IsTunnel(ti->tile)) {
   774 		if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL) {
   931 		if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL) {
   775 			image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.tunnel;
   932 			image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.tunnel;
   782 		image += GetTunnelDirection(ti->tile) * 2;
   939 		image += GetTunnelDirection(ti->tile) * 2;
   783 		DrawGroundSprite(image);
   940 		DrawGroundSprite(image);
   784 		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
   941 		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
   785 
   942 
   786 		AddSortableSpriteToDraw(image+1, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, 1, 1, 8, (byte)ti->z);
   943 		AddSortableSpriteToDraw(image+1, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, 1, 1, 8, (byte)ti->z);
   787 		DrawBridgeMiddle(ti);
       
   788 	} else if (IsBridge(ti->tile)) { // XXX is this necessary?
   944 	} else if (IsBridge(ti->tile)) { // XXX is this necessary?
   789 		int base_offset;
   945 		int base_offset;
   790 
   946 
   791 		if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
   947 		if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
   792 			base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset;
   948 			RailType rt;
       
   949 
       
   950 			if (IsBridgeRamp(ti->tile)) {
       
   951 				rt = GetRailType(ti->tile);
       
   952 			} else {
       
   953 				rt = GetRailTypeOnBridge(ti->tile);
       
   954 			}
       
   955 
       
   956 			base_offset = GetRailTypeInfo(rt)->bridge_offset;
   793 			assert(base_offset != 8); /* This one is used for roads */
   957 			assert(base_offset != 8); /* This one is used for roads */
   794 		} else {
   958 		} else {
   795 			base_offset = 8;
   959 			base_offset = 8;
   796 		}
   960 		}
   797 
   961 
   798 		/* as the lower 3 bits are used for other stuff, make sure they are clear */
   962 		/* as the lower 3 bits are used for other stuff, make sure they are clear */
   799 		assert( (base_offset & 0x07) == 0x00);
   963 		assert( (base_offset & 0x07) == 0x00);
   800 
   964 
   801 		if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) {
   965 		if (IsBridgeRamp(ti->tile)) {
   802 			int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
   966 			if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) {
   803 			if (f) DrawFoundation(ti, f);
   967 				int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
   804 		}
   968 				if (f) DrawFoundation(ti, f);
   805 
   969 			}
   806 		// HACK Wizardry to convert the bridge ramp direction into a sprite offset
   970 
   807 		base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
   971 			// HACK Wizardry to convert the bridge ramp direction into a sprite offset
   808 
   972 			base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
   809 		if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
   973 
   810 
   974 			if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
   811 		/* Table number 6 always refers to the bridge heads for any bridge type */
   975 
   812 		image = GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset];
   976 			/* Table number 6 always refers to the bridge heads for any bridge type */
   813 
   977 			image = GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset];
   814 		if (!ice) {
   978 
   815 			DrawClearLandTile(ti, 3);
   979 			if (!ice) {
       
   980 				DrawClearLandTile(ti, 3);
       
   981 			} else {
       
   982 				DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh]);
       
   983 			}
       
   984 
       
   985 			if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
       
   986 
       
   987 			// draw ramp
       
   988 			if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
       
   989 			AddSortableSpriteToDraw(image, ti->x, ti->y, 16, 16, 7, ti->z);
   816 		} else {
   990 		} else {
   817 			DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh]);
   991 			// bridge middle part.
   818 		}
   992 			Axis axis = GetBridgeAxis(ti->tile);
   819 
   993 			uint z;
   820 		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
   994 			int x,y;
   821 
   995 
   822 		// draw ramp
   996 			if (IsTransportUnderBridge(ti->tile)) {
   823 		if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
   997 				uint f = _bridge_foundations[axis][ti->tileh];
   824 		AddSortableSpriteToDraw(image, ti->x, ti->y, 16, 16, 7, ti->z);
   998 
   825 
   999 				if (f != 0) DrawFoundation(ti, f);
   826 		DrawBridgeMiddle(ti);
  1000 
   827 	}
  1001 				if (GetTransportTypeUnderBridge(ti->tile) == TRANSPORT_RAIL) {
   828 }
  1002 					const RailtypeInfo* rti = GetRailTypeInfo(GetRailType(ti->tile));
   829 
  1003 
   830 
  1004 					if (ti->tileh == SLOPE_FLAT) {
   831 //bridges pieces sequence (middle parts)
  1005 						image = (axis == AXIS_X ? SPR_RAIL_TRACK_Y : SPR_RAIL_TRACK_X);
   832 // bridge len 1: 0
  1006 					} else {
   833 // bridge len 2: 0 1
  1007 						image = SPR_RAIL_TRACK_Y + _track_sloped_sprites[ti->tileh - 1];
   834 // bridge len 3: 0 4 1
  1008 					}
   835 // bridge len 4: 0 2 3 1
  1009 					image += rti->total_offset;
   836 // bridge len 5: 0 2 5 3 1
  1010 					if (ice) image += rti->snow_offset;
   837 // bridge len 6: 0 2 3 2 3 1
  1011 				} else {
   838 // bridge len 7: 0 2 3 4 2 3 1
  1012 					if (ti->tileh == SLOPE_FLAT) {
   839 // #0 - always as first, #1 - always as last (if len>1)
  1013 						image = (axis == AXIS_X ? SPR_ROAD_Y : SPR_ROAD_X);
   840 // #2,#3 are to pair in order
  1014 					} else {
   841 // for odd bridges: #5 is going in the bridge middle if on even position, #4 on odd (counting from 0)
  1015 						image = _road_sloped_sprites[ti->tileh - 1] + 0x53F;
   842 static uint CalcBridgePiece(uint north, uint south)
  1016 					}
   843 {
  1017 					if (ice) image += 19;
   844 	if (north == 1) {
  1018 				}
   845 		return 0;
  1019 				DrawGroundSprite(image);
   846 	} else if (south == 1) {
  1020 			} else {
   847 		return 1;
  1021 				if (IsClearUnderBridge(ti->tile)) {
   848 	} else if (north < south) {
  1022 					image = (ice ? SPR_FLAT_SNOWY_TILE : SPR_FLAT_GRASS_TILE);
   849 		return north & 1 ? 3 : 2;
  1023 					DrawGroundSprite(image + _tileh_to_sprite[ti->tileh]);
   850 	} else if (north > south) {
  1024 				} else {
   851 		return south & 1 ? 2 : 3;
  1025 					if (ti->tileh == SLOPE_FLAT) {
   852 	} else {
  1026 						DrawGroundSprite(SPR_FLAT_WATER_TILE);
   853 		return north & 1 ? 5 : 4;
  1027 						if (ti->z != 0) DrawCanalWater(ti->tile);
   854 	}
  1028 					} else {
   855 }
  1029 						DrawGroundSprite(_water_shore_sprites[ti->tileh]);
   856 
  1030 					}
   857 void DrawBridgeMiddle(const TileInfo* ti)
  1031 				}
   858 {
  1032 			}
   859 	const PalSpriteID* b;
  1033 
   860 	PalSpriteID image;
  1034 			if (axis != AXIS_X) base_offset += 4;
   861 	uint base_offset;
  1035 
   862 	TileIndex rampnorth;
  1036 			/*  base_offset needs to be 0 due to the structure of the sprite table see table/bridge_land.h */
   863 	TileIndex rampsouth;
  1037 			assert( (base_offset & 0x03) == 0x00);
   864 	Axis axis;
  1038 			// get bridge sprites
   865 	uint piece;
  1039 			b = GetBridgeSpriteTable(GetBridgeType(ti->tile), GetBridgePiece(ti->tile)) + base_offset;
   866 	uint type;
  1040 
   867 	int x;
  1041 			z = GetBridgeHeight(ti->tile) + 5;
   868 	int y;
  1042 
   869 	uint z;
  1043 			// draw rail or road component
   870 
  1044 			image = b[0];
   871 	if (!IsBridgeAbove(ti->tile)) return;
       
   872 
       
   873 	rampnorth = GetNorthernBridgeEnd(ti->tile);
       
   874 	rampsouth = GetSouthernBridgeEnd(ti->tile);
       
   875 
       
   876 	axis = GetBridgeAxis(ti->tile);
       
   877 	piece = CalcBridgePiece(
       
   878 		DistanceManhattan(ti->tile, rampnorth),
       
   879 		DistanceManhattan(ti->tile, rampsouth)
       
   880 	);
       
   881 	type = GetBridgeType(rampsouth);
       
   882 
       
   883 	if (GetBridgeTransportType(rampsouth) == TRANSPORT_RAIL) {
       
   884 		base_offset = GetRailTypeInfo(GetRailType(rampsouth))->bridge_offset;
       
   885 	} else {
       
   886 		base_offset = 8;
       
   887 	}
       
   888 
       
   889 	b = base_offset + GetBridgeSpriteTable(type, piece);
       
   890 	if (axis != AXIS_X) b += 4;
       
   891 
       
   892 	x = ti->x;
       
   893 	y = ti->y;
       
   894 	z = GetBridgeHeight(rampsouth, axis) - 3;
       
   895 
       
   896 	image = b[0];
       
   897 	if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
       
   898 	if (axis == AXIS_X) {
       
   899 		AddSortableSpriteToDraw(image, x, y, 16, 11, 1, z);
       
   900 	} else {
       
   901 		AddSortableSpriteToDraw(image, x, y, 11, 16, 1, z);
       
   902 	}
       
   903 
       
   904 	image = b[1];
       
   905 	if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
       
   906 
       
   907 	// draw roof, the component of the bridge which is logically between the vehicle and the camera
       
   908 	if (axis == AXIS_X) {
       
   909 		y += 12;
       
   910 		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x, y, 16, 1, 0x28, z);
       
   911 	} else {
       
   912 		x += 12;
       
   913 		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x, y, 1, 16, 0x28, z);
       
   914 	}
       
   915 
       
   916 	if (GetRailType(rampsouth) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
       
   917 
       
   918 	if (ti->z + 5 == z) {
       
   919 		// draw poles below for small bridges
       
   920 		image = b[2];
       
   921 		if (image != 0) {
       
   922 			if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
  1045 			if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
   923 			DrawGroundSpriteAt(image, x, y, z);
  1046 			if (axis == AXIS_X) {
   924 		}
  1047 				AddSortableSpriteToDraw(image, ti->x, ti->y, 16, 11, 1, z);
   925 	} else if (_patches.bridge_pillars) {
  1048 			} else {
   926 		// draw pillars below for high bridges
  1049 				AddSortableSpriteToDraw(image, ti->x, ti->y, 11, 16, 1, z);
   927 		DrawBridgePillars(b[2], ti, axis, type, x, y, z);
  1050 			}
   928 	}
  1051 
   929 }
  1052 			x = ti->x;
   930 
  1053 			y = ti->y;
   931 
  1054 			image = b[1];
   932 uint SetSpeedLimitOnBridge(Vehicle *v)
  1055 			if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
   933 {
  1056 
   934 	uint bridge_speed;
  1057 			// draw roof, the component of the bridge which is logically between the vehicle and the camera
   935 	if (v->vehstatus & VS_HIDDEN) return v->max_speed; /* in tunnel */
  1058 			if (axis == AXIS_X) {
   936 
  1059 				y += 12;
   937 	bridge_speed = _bridge[GetBridgeType(v->tile)].speed;
  1060 				if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x, y, 16, 1, 0x28, z);
   938 
  1061 			} else {
   939 	if (v->type == VEH_Road) bridge_speed *= 2; /* XXX give vehicles proper speeds */
  1062 				x += 12;
   940 
  1063 				if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x, y, 1, 16, 0x28, z);
   941 	if (v->cur_speed > bridge_speed) v->cur_speed = bridge_speed;
  1064 			}
   942 	return bridge_speed;
  1065 
   943 }
  1066 			if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC || GetRailTypeOnBridge(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
   944 
  1067 
   945 
  1068 			if (ti->z + 5 == z) {
       
  1069 				// draw poles below for small bridges
       
  1070 				image = b[2];
       
  1071 				if (image != 0) {
       
  1072 					if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
       
  1073 					DrawGroundSpriteAt(image, x, y, z);
       
  1074 				}
       
  1075 			} else if (_patches.bridge_pillars) {
       
  1076 				// draw pillars below for high bridges
       
  1077 				DrawBridgePillars(b[2], ti, x, y, z);
       
  1078 			}
       
  1079 		}
       
  1080 	}
       
  1081 }
   946 
  1082 
   947 static uint GetSlopeZ_TunnelBridge(const TileInfo* ti)
  1083 static uint GetSlopeZ_TunnelBridge(const TileInfo* ti)
   948 {
  1084 {
   949 	TileIndex tile = ti->tile;
  1085 	TileIndex tile = ti->tile;
   950 	uint z = ti->z;
  1086 	uint z = ti->z;
   956 		uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x);
  1092 		uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x);
   957 
  1093 
   958 		// In the tunnel entrance?
  1094 		// In the tunnel entrance?
   959 		if (5 <= pos && pos <= 10) return z;
  1095 		if (5 <= pos && pos <= 10) return z;
   960 	} else {
  1096 	} else {
   961 		DiagDirection dir = GetBridgeRampDirection(tile);
  1097 		if (IsBridgeRamp(tile)) {
   962 		uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
  1098 			DiagDirection dir = GetBridgeRampDirection(tile);
   963 
  1099 			uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
   964 		// On the bridge ramp?
  1100 
   965 		if (5 <= pos && pos <= 10) {
  1101 			// On the bridge ramp?
   966 			uint delta;
  1102 			if (5 <= pos && pos <= 10) {
   967 
  1103 				uint delta;
   968 			if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT;
  1104 
   969 
  1105 				if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT;
   970 			if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) z += TILE_HEIGHT;
  1106 
   971 			switch (dir) {
  1107 				if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) z += TILE_HEIGHT;
   972 				default:
  1108 				switch (dir) {
   973 				case DIAGDIR_NE: delta = (TILE_SIZE - 1 - x) / 2; break;
  1109 					default:
   974 				case DIAGDIR_SE: delta = y / 2; break;
  1110 					case DIAGDIR_NE: delta = (TILE_SIZE - 1 - x) / 2; break;
   975 				case DIAGDIR_SW: delta = x / 2; break;
  1111 					case DIAGDIR_SE: delta = y / 2; break;
   976 				case DIAGDIR_NW: delta = (TILE_SIZE - 1 - y) / 2; break;
  1112 					case DIAGDIR_SW: delta = x / 2; break;
   977 			}
  1113 					case DIAGDIR_NW: delta = (TILE_SIZE - 1 - y) / 2; break;
   978 			return z + 1 + delta;
  1114 				}
       
  1115 				return z + 1 + delta;
       
  1116 			} else {
       
  1117 				uint f = GetBridgeFoundation(tileh, DiagDirToAxis(dir));
       
  1118 
       
  1119 				if (f != 0) {
       
  1120 					if (f < 15) return z + TILE_HEIGHT;
       
  1121 					tileh = _inclined_tileh[f - 15];
       
  1122 				}
       
  1123 			}
   979 		} else {
  1124 		} else {
   980 			uint f = GetBridgeFoundation(tileh, DiagDirToAxis(dir));
  1125 			// HACK on the bridge?
   981 
  1126 			if (_get_z_hint >= z + TILE_HEIGHT + (tileh == SLOPE_FLAT ? 0 : TILE_HEIGHT)) return _get_z_hint;
   982 			if (f != 0) {
  1127 
   983 				if (f < 15) return z + TILE_HEIGHT;
  1128 			if (IsTransportUnderBridge(tile)) {
   984 				tileh = _inclined_tileh[f - 15];
  1129 				uint f = _bridge_foundations[GetBridgeAxis(tile)][tileh];
       
  1130 
       
  1131 				if (f != 0) {
       
  1132 					if (f < 15) return z + TILE_HEIGHT;
       
  1133 					tileh = _inclined_tileh[f - 15];
       
  1134 				}
   985 			}
  1135 			}
   986 		}
  1136 		}
   987 	}
  1137 	}
   988 
  1138 
   989 	return z + GetPartialZ(x, y, tileh);
  1139 	return z + GetPartialZ(x, y, tileh);
  1038 	if (IsTunnel(tile)) {
  1188 	if (IsTunnel(tile)) {
  1039 		td->str = (GetTunnelTransportType(tile) == TRANSPORT_RAIL) ?
  1189 		td->str = (GetTunnelTransportType(tile) == TRANSPORT_RAIL) ?
  1040 			STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL;
  1190 			STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL;
  1041 	} else {
  1191 	} else {
  1042 		td->str = _bridge_tile_str[GetBridgeTransportType(tile) << 4 | GetBridgeType(tile)];
  1192 		td->str = _bridge_tile_str[GetBridgeTransportType(tile) << 4 | GetBridgeType(tile)];
       
  1193 
       
  1194 		// the owner is stored at the end of the bridge
       
  1195 		if (IsBridgeMiddle(tile)) tile = GetSouthernBridgeEnd(tile);
  1043 	}
  1196 	}
  1044 	td->owner = GetTileOwner(tile);
  1197 	td->owner = GetTileOwner(tile);
  1045 }
  1198 }
  1046 
  1199 
  1047 
  1200 
  1072 				_m[tile].m4 |= 0x80;
  1225 				_m[tile].m4 |= 0x80;
  1073 				MarkTileDirtyByTile(tile);
  1226 				MarkTileDirtyByTile(tile);
  1074 			}
  1227 			}
  1075 			break;
  1228 			break;
  1076 	}
  1229 	}
       
  1230 
       
  1231 	if (IsBridge(tile) && IsBridgeMiddle(tile) && IsWaterUnderBridge(tile)) {
       
  1232 		TileLoop_Water(tile);
       
  1233 	}
  1077 }
  1234 }
  1078 
  1235 
  1079 static void ClickTile_TunnelBridge(TileIndex tile)
  1236 static void ClickTile_TunnelBridge(TileIndex tile)
  1080 {
  1237 {
  1081 	/* not used */
  1238 	/* not used */
  1082 }
  1239 }
  1083 
  1240 
  1084 
  1241 
  1085 static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode)
  1242 static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode)
  1086 {
  1243 {
       
  1244 	uint32 result;
       
  1245 
  1087 	if (IsTunnel(tile)) {
  1246 	if (IsTunnel(tile)) {
  1088 		if (GetTunnelTransportType(tile) == mode) {
  1247 		if (GetTunnelTransportType(tile) == mode) {
  1089 			return DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? 0x101 : 0x202;
  1248 			return DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? 0x101 : 0x202;
  1090 		}
  1249 		}
  1091 	} else if (IsBridge(tile)) { // XXX is this necessary?
  1250 	} else if (IsBridge(tile)) { // XXX is this necessary?
  1092 		if (GetBridgeTransportType(tile) != mode) return 0;
  1251 		if (IsBridgeRamp(tile)) {
  1093 		return (DiagDirToAxis(GetBridgeRampDirection(tile)) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y) * 0x101;
  1252 			if (GetBridgeTransportType(tile) != mode) return 0;
       
  1253 			return (DiagDirToAxis(GetBridgeRampDirection(tile)) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y) * 0x101;
       
  1254 		} else {
       
  1255 			result = 0;
       
  1256 			if (GetBridgeTransportType(tile) == mode) {
       
  1257 				result = (GetBridgeAxis(tile) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y) * 0x101;
       
  1258 			}
       
  1259 			if (IsTransportUnderBridge(tile)) {
       
  1260 				if (GetTransportTypeUnderBridge(tile) != mode) return result;
       
  1261 			} else {
       
  1262 				if (IsClearUnderBridge(tile)) {
       
  1263 					return result;
       
  1264 				} else {
       
  1265 					if (mode != TRANSPORT_WATER) return result;
       
  1266 				}
       
  1267 			}
       
  1268 			/* If we've not returned yet, there is a compatible
       
  1269 			 * transport or water beneath, so we can add it to
       
  1270 			 * result */
       
  1271 			/* Why is this xor'd ? Can't it just be or'd? */
       
  1272 			result ^= (GetBridgeAxis(tile) == AXIS_X ? 0x202 : 0x101);
       
  1273 		}
       
  1274 		return result;
  1094 	} else {
  1275 	} else {
  1095 		assert(0); /* This should never occur */
  1276 		assert(0); /* This should never occur */
  1096 	}
  1277 	}
  1097 	return 0;
  1278 	return 0;
  1098 }
  1279 }
  1102 	if (!IsTileOwner(tile, old_player)) return;
  1283 	if (!IsTileOwner(tile, old_player)) return;
  1103 
  1284 
  1104 	if (new_player != OWNER_SPECTATOR) {
  1285 	if (new_player != OWNER_SPECTATOR) {
  1105 		SetTileOwner(tile, new_player);
  1286 		SetTileOwner(tile, new_player);
  1106 	}	else {
  1287 	}	else {
  1107 		DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
  1288 		if (IsBridge(tile) && IsBridgeMiddle(tile) && IsTransportUnderBridge(tile)) {
       
  1289 			// the stuff BELOW the middle part is owned by the deleted player.
       
  1290 			if (GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
       
  1291 				SetClearUnderBridge(tile);
       
  1292 			} else {
       
  1293 				SetTileOwner(tile, OWNER_NONE);
       
  1294 			}
       
  1295 		} else {
       
  1296 			DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
       
  1297 		}
  1108 	}
  1298 	}
  1109 }
  1299 }
  1110 
  1300 
  1111 
  1301 
  1112 static const byte _tunnel_fractcoord_1[4] = {0x8E,0x18,0x81,0xE8};
  1302 static const byte _tunnel_fractcoord_1[4] = {0x8E,0x18,0x81,0xE8};
  1122 static const byte _tunnel_fractcoord_6[4] = {0x92, 0x89, 0x56, 0x45};
  1312 static const byte _tunnel_fractcoord_6[4] = {0x92, 0x89, 0x56, 0x45};
  1123 static const byte _tunnel_fractcoord_7[4] = {0x52, 0x85, 0x96, 0x49};
  1313 static const byte _tunnel_fractcoord_7[4] = {0x52, 0x85, 0x96, 0x49};
  1124 
  1314 
  1125 static uint32 VehicleEnter_TunnelBridge(Vehicle *v, TileIndex tile, int x, int y)
  1315 static uint32 VehicleEnter_TunnelBridge(Vehicle *v, TileIndex tile, int x, int y)
  1126 {
  1316 {
  1127 	int z = GetSlopeZ(x, y) - v->z_pos;
       
  1128 
       
  1129 	if (myabs(z) > 2) return 8;
       
  1130 
       
  1131 	if (IsTunnel(tile)) {
  1317 	if (IsTunnel(tile)) {
       
  1318 		int z = GetSlopeZ(x, y) - v->z_pos;
  1132 		byte fc;
  1319 		byte fc;
  1133 		DiagDirection dir;
  1320 		DiagDirection dir;
  1134 		DiagDirection vdir;
  1321 		DiagDirection vdir;
       
  1322 
       
  1323 		if (myabs(z) > 2) return 8;
  1135 
  1324 
  1136 		if (v->type == VEH_Train) {
  1325 		if (v->type == VEH_Train) {
  1137 			fc = (x & 0xF) + (y << 4);
  1326 			fc = (x & 0xF) + (y << 4);
  1138 
  1327 
  1139 			dir = GetTunnelDirection(tile);
  1328 			dir = GetTunnelDirection(tile);
  1191 				v->vehstatus &= ~VS_HIDDEN;
  1380 				v->vehstatus &= ~VS_HIDDEN;
  1192 				return 4;
  1381 				return 4;
  1193 			}
  1382 			}
  1194 		}
  1383 		}
  1195 	} else if (IsBridge(tile)) { // XXX is this necessary?
  1384 	} else if (IsBridge(tile)) { // XXX is this necessary?
  1196 		DiagDirection dir;
       
  1197 
       
  1198 		if (v->type == VEH_Road || (v->type == VEH_Train && IsFrontEngine(v))) {
  1385 		if (v->type == VEH_Road || (v->type == VEH_Train && IsFrontEngine(v))) {
  1199 			/* modify speed of vehicle */
  1386 			if (IsBridgeRamp(tile) || v->z_pos > GetTileMaxZ(tile)) {
  1200 			uint16 spd = _bridge[GetBridgeType(tile)].speed;
  1387 				/* modify speed of vehicle */
  1201 
  1388 				uint16 spd = _bridge[GetBridgeType(tile)].speed;
  1202 			if (v->type == VEH_Road) spd *= 2;
  1389 				if (v->type == VEH_Road) spd *= 2;
  1203 			if (v->cur_speed > spd) v->cur_speed = spd;
  1390 				if (v->cur_speed > spd) v->cur_speed = spd;
  1204 		}
  1391 			}
  1205 
       
  1206 		dir = GetBridgeRampDirection(tile);
       
  1207 		if (DirToDiagDir(v->direction) == dir) {
       
  1208 			switch (dir) {
       
  1209 				default:
       
  1210 				case DIAGDIR_NE: if ((x & 0xF) != 0)             return 0; break;
       
  1211 				case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return 0; break;
       
  1212 				case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return 0; break;
       
  1213 				case DIAGDIR_NW: if ((y & 0xF) != 0)             return 0; break;
       
  1214 			}
       
  1215 			if (v->type == VEH_Train) {
       
  1216 				v->u.rail.track = 0x40;
       
  1217 				CLRBIT(v->u.rail.flags, VRF_GOINGUP);
       
  1218 				CLRBIT(v->u.rail.flags, VRF_GOINGDOWN);
       
  1219 			} else {
       
  1220 				v->u.road.state = 0xFF;
       
  1221 			}
       
  1222 			return 4;
       
  1223 		} else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) {
       
  1224 			v->tile = tile;
       
  1225 			if (v->type == VEH_Train) {
       
  1226 				if (v->u.rail.track == 0x40) {
       
  1227 					v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? 1 : 2);
       
  1228 					return 4;
       
  1229 				}
       
  1230 			} else {
       
  1231 				if (v->u.road.state == 0xFF) {
       
  1232 					v->u.road.state = _road_exit_tunnel_state[dir];
       
  1233 					v->u.road.frame = 0;
       
  1234 					return 4;
       
  1235 				}
       
  1236 			}
       
  1237 			return 0;
       
  1238 		}
  1392 		}
  1239 	}
  1393 	}
  1240 	return 0;
  1394 	return 0;
       
  1395 }
       
  1396 
       
  1397 TileIndex GetVehicleOutOfTunnelTile(const Vehicle *v)
       
  1398 {
       
  1399 	TileIndex tile;
       
  1400 	TileIndexDiff delta = (v->direction & 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
       
  1401 	byte z = v->z_pos;
       
  1402 
       
  1403 	for (tile = v->tile;; tile += delta) {
       
  1404 		if (IsTunnelTile(tile) && GetTileZ(tile) == z) break;
       
  1405 	}
       
  1406 	return tile;
  1241 }
  1407 }
  1242 
  1408 
  1243 const TileTypeProcs _tile_type_tunnelbridge_procs = {
  1409 const TileTypeProcs _tile_type_tunnelbridge_procs = {
  1244 	DrawTile_TunnelBridge,					/* draw_tile_proc */
  1410 	DrawTile_TunnelBridge,					/* draw_tile_proc */
  1245 	GetSlopeZ_TunnelBridge,					/* get_slope_z_proc */
  1411 	GetSlopeZ_TunnelBridge,					/* get_slope_z_proc */