tunnelbridge_cmd.c
changeset 2049 538e73c53f54
parent 2008 cdb444f6d43c
child 2085 876f20a0e843
equal deleted inserted replaced
2048:54fd558314dc 2049:538e73c53f54
   346 			m5 = 0xC0;
   346 			m5 = 0xC0;
   347 		}
   347 		}
   348 
   348 
   349 		/* do middle part of bridge */
   349 		/* do middle part of bridge */
   350 		if (flags & DC_EXEC) {
   350 		if (flags & DC_EXEC) {
   351 			_map5[ti.tile] = (byte)(m5 | direction | rail_or_road);
   351 			_m[ti.tile].m5 = (byte)(m5 | direction | rail_or_road);
   352 			SetTileType(ti.tile, MP_TUNNELBRIDGE);
   352 			SetTileType(ti.tile, MP_TUNNELBRIDGE);
   353 
   353 
   354 			//bridges pieces sequence (middle parts)
   354 			//bridges pieces sequence (middle parts)
   355 			// bridge len 1: 0
   355 			// bridge len 1: 0
   356 			// bridge len 2: 0 1
   356 			// bridge len 2: 0 1
   374 					// this sequence swaps [... XOR (i>odd_middle_part)],
   374 					// this sequence swaps [... XOR (i>odd_middle_part)],
   375 					// for even bridges XOR does not apply as odd_middle_part==bridge_len
   375 					// for even bridges XOR does not apply as odd_middle_part==bridge_len
   376 					m5 = 2 + ((i%2==0)^(i>odd_middle_part));
   376 					m5 = 2 + ((i%2==0)^(i>odd_middle_part));
   377 			}
   377 			}
   378 
   378 
   379 			_map2[ti.tile] = (bridge_type << 4) | m5;
   379 			_m[ti.tile].m2 = (bridge_type << 4) | m5;
   380 			_map3_lo[ti.tile] &= 0xF;
   380 			_m[ti.tile].m3 &= 0xF;
   381 			_map3_lo[ti.tile] |= (byte)(railtype << 4);
   381 			_m[ti.tile].m3 |= (byte)(railtype << 4);
   382 
   382 
   383 			MarkTileDirtyByTile(ti.tile);
   383 			MarkTileDirtyByTile(ti.tile);
   384 		}
   384 		}
   385 	}
   385 	}
   386 
   386 
   588 }
   588 }
   589 
   589 
   590 TileIndex CheckTunnelBusy(TileIndex tile, uint *length)
   590 TileIndex CheckTunnelBusy(TileIndex tile, uint *length)
   591 {
   591 {
   592 	uint z = GetTileZ(tile);
   592 	uint z = GetTileZ(tile);
   593 	byte m5 = _map5[tile];
   593 	byte m5 = _m[tile].m5;
   594 	int delta = TileOffsByDir(m5 & 3);
   594 	int delta = TileOffsByDir(m5 & 3);
   595 	uint len = 0;
   595 	uint len = 0;
   596 	TileIndex starttile = tile;
   596 	TileIndex starttile = tile;
   597 	Vehicle *v;
   597 	Vehicle *v;
   598 
   598 
   599 	do {
   599 	do {
   600 		tile += delta;
   600 		tile += delta;
   601 		len++;
   601 		len++;
   602 	} while (
   602 	} while (
   603 		!IsTileType(tile, MP_TUNNELBRIDGE) ||
   603 		!IsTileType(tile, MP_TUNNELBRIDGE) ||
   604 		(_map5[tile] & 0xF0) != 0 ||
   604 		(_m[tile].m5 & 0xF0) != 0 ||
   605 		(byte)(_map5[tile] ^ 2) != m5 ||
   605 		(byte)(_m[tile].m5 ^ 2) != m5 ||
   606 		GetTileZ(tile) != z
   606 		GetTileZ(tile) != z
   607 	);
   607 	);
   608 
   608 
   609 	v = FindVehicleBetween(starttile, tile, z);
   609 	v = FindVehicleBetween(starttile, tile, z);
   610 	if (v != NULL) {
   610 	if (v != NULL) {
   648 	}
   648 	}
   649 
   649 
   650 	if (flags & DC_EXEC) {
   650 	if (flags & DC_EXEC) {
   651 		// We first need to request the direction before calling DoClearSquare
   651 		// We first need to request the direction before calling DoClearSquare
   652 		//  else the direction is always 0.. dah!! ;)
   652 		//  else the direction is always 0.. dah!! ;)
   653 		byte tile_dir = _map5[tile]&3;
   653 		byte tile_dir = _m[tile].m5&3;
   654 		byte endtile_dir = _map5[endtile]&3;
   654 		byte endtile_dir = _m[endtile].m5&3;
   655 		DoClearSquare(tile);
   655 		DoClearSquare(tile);
   656 		DoClearSquare(endtile);
   656 		DoClearSquare(endtile);
   657 		UpdateSignalsOnSegment(tile, _updsignals_tunnel_dir[tile_dir]);
   657 		UpdateSignalsOnSegment(tile, _updsignals_tunnel_dir[tile_dir]);
   658 		UpdateSignalsOnSegment(endtile, _updsignals_tunnel_dir[endtile_dir]);
   658 		UpdateSignalsOnSegment(endtile, _updsignals_tunnel_dir[endtile_dir]);
   659 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   659 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   662 	return  _price.clear_tunnel * (length + 1);
   662 	return  _price.clear_tunnel * (length + 1);
   663 }
   663 }
   664 
   664 
   665 static TileIndex FindEdgesOfBridge(TileIndex tile, TileIndex *endtile)
   665 static TileIndex FindEdgesOfBridge(TileIndex tile, TileIndex *endtile)
   666 {
   666 {
   667 	int direction = _map5[tile] & 1;
   667 	int direction = _m[tile].m5 & 1;
   668 	TileIndex start;
   668 	TileIndex start;
   669 
   669 
   670 	// find start of bridge
   670 	// find start of bridge
   671 	for(;;) {
   671 	for(;;) {
   672 		if (IsTileType(tile, MP_TUNNELBRIDGE) && (_map5[tile] & 0xE0) == 0x80)
   672 		if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0xE0) == 0x80)
   673 			break;
   673 			break;
   674 		tile += direction ? TileDiffXY(0, -1) : TileDiffXY(-1, 0);
   674 		tile += direction ? TileDiffXY(0, -1) : TileDiffXY(-1, 0);
   675 	}
   675 	}
   676 
   676 
   677 	start = tile;
   677 	start = tile;
   678 
   678 
   679 	// find end of bridge
   679 	// find end of bridge
   680 	for(;;) {
   680 	for(;;) {
   681 		if (IsTileType(tile, MP_TUNNELBRIDGE) && (_map5[tile] & 0xE0) == 0xA0)
   681 		if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0xE0) == 0xA0)
   682 			break;
   682 			break;
   683 		tile += direction ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
   683 		tile += direction ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
   684 	}
   684 	}
   685 
   685 
   686 	*endtile = tile;
   686 	*endtile = tile;
   695 	Town *t;
   695 	Town *t;
   696 	int direction;
   696 	int direction;
   697 
   697 
   698 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   698 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
   699 
   699 
   700 	direction = _map5[tile]&1;
   700 	direction = _m[tile].m5&1;
   701 
   701 
   702 	/* delete stuff under the middle part if there's a transport route there..? */
   702 	/* delete stuff under the middle part if there's a transport route there..? */
   703 	if ((_map5[tile] & 0xE0) == 0xE0) {
   703 	if ((_m[tile].m5 & 0xE0) == 0xE0) {
   704 		int32 cost;
   704 		int32 cost;
   705 
   705 
   706 		// check if we own the tile below the bridge..
   706 		// check if we own the tile below the bridge..
   707 		if (_current_player != OWNER_WATER && (!CheckTileOwnership(tile) || !EnsureNoVehicleZ(tile, TilePixelHeight(tile))))
   707 		if (_current_player != OWNER_WATER && (!CheckTileOwnership(tile) || !EnsureNoVehicleZ(tile, TilePixelHeight(tile))))
   708 			return CMD_ERROR;
   708 			return CMD_ERROR;
   709 
   709 
   710 		cost = (_map5[tile] & 8) ? _price.remove_road * 2 : _price.remove_rail;
   710 		cost = (_m[tile].m5 & 8) ? _price.remove_road * 2 : _price.remove_rail;
   711 
   711 
   712 		if (flags & DC_EXEC) {
   712 		if (flags & DC_EXEC) {
   713 			_map5[tile] = _map5[tile] & ~0x38;
   713 			_m[tile].m5 = _m[tile].m5 & ~0x38;
   714 			SetTileOwner(tile, OWNER_NONE);
   714 			SetTileOwner(tile, OWNER_NONE);
   715 			MarkTileDirtyByTile(tile);
   715 			MarkTileDirtyByTile(tile);
   716 		}
   716 		}
   717 		return cost;
   717 		return cost;
   718 
   718 
   719 	/* delete canal under bridge */
   719 	/* delete canal under bridge */
   720 	} else if ((_map5[tile] & 0xC8) == 0xC8 && TilePixelHeight(tile) != 0) {
   720 	} else if ((_m[tile].m5 & 0xC8) == 0xC8 && TilePixelHeight(tile) != 0) {
   721 		int32 cost;
   721 		int32 cost;
   722 
   722 
   723 		// check for vehicles under bridge
   723 		// check for vehicles under bridge
   724 		if (!EnsureNoVehicleZ(tile, TilePixelHeight(tile)))
   724 		if (!EnsureNoVehicleZ(tile, TilePixelHeight(tile)))
   725 			return CMD_ERROR;
   725 			return CMD_ERROR;
   726 		cost = _price.clear_water;
   726 		cost = _price.clear_water;
   727 		if (flags & DC_EXEC) {
   727 		if (flags & DC_EXEC) {
   728 			_map5[tile] = _map5[tile] & ~0x38;
   728 			_m[tile].m5 = _m[tile].m5 & ~0x38;
   729 			SetTileOwner(tile, OWNER_NONE);
   729 			SetTileOwner(tile, OWNER_NONE);
   730 			MarkTileDirtyByTile(tile);
   730 			MarkTileDirtyByTile(tile);
   731 		}
   731 		}
   732 		return cost;
   732 		return cost;
   733 	}
   733 	}
   778 		// you have a "Poor" (0) town rating
   778 		// you have a "Poor" (0) town rating
   779 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   779 		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
   780 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   780 			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
   781 
   781 
   782 		do {
   782 		do {
   783 			m5 = _map5[c];
   783 			m5 = _m[c].m5;
   784 			pbs = PBSTileReserved(c);
   784 			pbs = PBSTileReserved(c);
   785 
   785 
   786 			if (m5 & 0x40) {
   786 			if (m5 & 0x40) {
   787 				if (m5 & 0x20) {
   787 				if (m5 & 0x20) {
   788 					static const uint16 _new_data_table[] = {0x1002, 0x1001, 0x2005, 0x200A, 0, 0, 0, 0};
   788 					static const uint16 _new_data_table[] = {0x1002, 0x1001, 0x2005, 0x200A, 0, 0, 0, 0};
   791 					if (!(m5 & 0x18)) goto clear_it;
   791 					if (!(m5 & 0x18)) goto clear_it;
   792 					new_data = (GetTileSlope(c, NULL) == 0) ? 0x6000 : 0x6001;
   792 					new_data = (GetTileSlope(c, NULL) == 0) ? 0x6000 : 0x6001;
   793 				}
   793 				}
   794 
   794 
   795 				SetTileType(c, new_data >> 12);
   795 				SetTileType(c, new_data >> 12);
   796 				_map5[c] = (byte)new_data;
   796 				_m[c].m5 = (byte)new_data;
   797 				_map2[c] = 0;
   797 				_m[c].m2 = 0;
   798 				_map3_hi[c] &= 0x0F;
   798 				_m[c].m4 &= 0x0F;
   799 				if (direction ? HASBIT(pbs,0) : HASBIT(pbs,1))
   799 				if (direction ? HASBIT(pbs,0) : HASBIT(pbs,1))
   800 					PBSReserveTrack(c, direction ? 0 : 1);
   800 					PBSReserveTrack(c, direction ? 0 : 1);
   801 
   801 
   802 				MarkTileDirtyByTile(c);
   802 				MarkTileDirtyByTile(c);
   803 
   803 
   816 	return ((((endtile - tile) >> (direction?8:0))&0xFF)+1) * _price.clear_bridge;
   816 	return ((((endtile - tile) >> (direction?8:0))&0xFF)+1) * _price.clear_bridge;
   817 }
   817 }
   818 
   818 
   819 static int32 ClearTile_TunnelBridge(TileIndex tile, byte flags)
   819 static int32 ClearTile_TunnelBridge(TileIndex tile, byte flags)
   820 {
   820 {
   821 	byte m5 = _map5[tile];
   821 	byte m5 = _m[tile].m5;
   822 
   822 
   823 	if ((m5 & 0xF0) == 0) {
   823 	if ((m5 & 0xF0) == 0) {
   824 		if (flags & DC_AUTO)
   824 		if (flags & DC_AUTO)
   825 			return_cmd_error(STR_5006_MUST_DEMOLISH_TUNNEL_FIRST);
   825 			return_cmd_error(STR_5006_MUST_DEMOLISH_TUNNEL_FIRST);
   826 
   826 
   839 {
   839 {
   840 	TileIndex endtile;
   840 	TileIndex endtile;
   841 	uint length;
   841 	uint length;
   842 	Vehicle *v;
   842 	Vehicle *v;
   843 
   843 
   844 	if ((_map5[tile] & 0xFC) == 0x00) {
   844 	if ((_m[tile].m5 & 0xFC) == 0x00) {
   845 		// railway tunnel
   845 		// railway tunnel
   846 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   846 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
   847 
   847 
   848 		if ( (uint)(_map3_lo[tile] & 0xF) == totype) return CMD_ERROR;
   848 		if ( (uint)(_m[tile].m3 & 0xF) == totype) return CMD_ERROR;
   849 
   849 
   850 		endtile = CheckTunnelBusy(tile, &length);
   850 		endtile = CheckTunnelBusy(tile, &length);
   851 		if (endtile == INVALID_TILE) return CMD_ERROR;
   851 		if (endtile == INVALID_TILE) return CMD_ERROR;
   852 
   852 
   853 		if (exec) {
   853 		if (exec) {
   854 			_map3_lo[tile] = (_map3_lo[tile] & 0xF0) + totype;
   854 			_m[tile].m3 = (_m[tile].m3 & 0xF0) + totype;
   855 			_map3_lo[endtile] = (_map3_lo[endtile] & 0xF0) + totype;
   855 			_m[endtile].m3 = (_m[endtile].m3 & 0xF0) + totype;
   856 			MarkTileDirtyByTile(tile);
   856 			MarkTileDirtyByTile(tile);
   857 			MarkTileDirtyByTile(endtile);
   857 			MarkTileDirtyByTile(endtile);
   858 		}
   858 		}
   859 		return (length + 1) * (_price.build_rail >> 1);
   859 		return (length + 1) * (_price.build_rail >> 1);
   860 	} else if ((_map5[tile] & 0xF8) == 0xE0) {
   860 	} else if ((_m[tile].m5 & 0xF8) == 0xE0) {
   861 		// bridge middle part with rail below
   861 		// bridge middle part with rail below
   862 		// only check for train under bridge
   862 		// only check for train under bridge
   863 		if (!CheckTileOwnership(tile) || !EnsureNoVehicleZ(tile, TilePixelHeight(tile)))
   863 		if (!CheckTileOwnership(tile) || !EnsureNoVehicleZ(tile, TilePixelHeight(tile)))
   864 			return CMD_ERROR;
   864 			return CMD_ERROR;
   865 
   865 
   866 		// tile is already of requested type?
   866 		// tile is already of requested type?
   867 		if ( (uint)(_map3_lo[tile] & 0xF) == totype) return CMD_ERROR;
   867 		if ( (uint)(_m[tile].m3 & 0xF) == totype) return CMD_ERROR;
   868 		// change type.
   868 		// change type.
   869 		if (exec) {
   869 		if (exec) {
   870 			_map3_lo[tile] = (_map3_lo[tile] & 0xF0) + totype;
   870 			_m[tile].m3 = (_m[tile].m3 & 0xF0) + totype;
   871 			MarkTileDirtyByTile(tile);
   871 			MarkTileDirtyByTile(tile);
   872 		}
   872 		}
   873 		return _price.build_rail >> 1;
   873 		return _price.build_rail >> 1;
   874 	} else if ((_map5[tile]&0xC6) == 0x80) {
   874 	} else if ((_m[tile].m5&0xC6) == 0x80) {
   875 		TileIndex starttile;
   875 		TileIndex starttile;
   876 		int32 cost;
   876 		int32 cost;
   877 		uint z = TilePixelHeight(tile);
   877 		uint z = TilePixelHeight(tile);
   878 
   878 
   879 		z += 8;
   879 		z += 8;
   891 		if (!EnsureNoVehicle(starttile) || !EnsureNoVehicle(endtile)) {
   891 		if (!EnsureNoVehicle(starttile) || !EnsureNoVehicle(endtile)) {
   892 			_error_message = STR_8803_TRAIN_IN_THE_WAY;
   892 			_error_message = STR_8803_TRAIN_IN_THE_WAY;
   893 			return CMD_ERROR;
   893 			return CMD_ERROR;
   894 		}
   894 		}
   895 
   895 
   896 		if ( (uint)(_map3_lo[tile] & 0xF) == totype) return CMD_ERROR;
   896 		if ( (uint)(_m[tile].m3 & 0xF) == totype) return CMD_ERROR;
   897 		cost = 0;
   897 		cost = 0;
   898 		do {
   898 		do {
   899 			if (exec) {
   899 			if (exec) {
   900 				if (tile == starttile || tile == endtile) {
   900 				if (tile == starttile || tile == endtile) {
   901 					_map3_lo[tile] = (_map3_lo[tile] & 0xF0) + totype;
   901 					_m[tile].m3 = (_m[tile].m3 & 0xF0) + totype;
   902 				} else {
   902 				} else {
   903 					_map3_lo[tile] = (_map3_lo[tile] & 0x0F) + (totype << 4);
   903 					_m[tile].m3 = (_m[tile].m3 & 0x0F) + (totype << 4);
   904 				}
   904 				}
   905 				MarkTileDirtyByTile(tile);
   905 				MarkTileDirtyByTile(tile);
   906 			}
   906 			}
   907 			cost += (_price.build_rail>>1);
   907 			cost += (_price.build_rail>>1);
   908 			tile += _map5[tile] & 1 ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
   908 			tile += _m[tile].m5 & 1 ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
   909 		} while (tile <= endtile);
   909 		} while (tile <= endtile);
   910 
   910 
   911 		return cost;
   911 		return cost;
   912 	} else
   912 	} else
   913 		return CMD_ERROR;
   913 		return CMD_ERROR;
   919 {
   919 {
   920 	TileIndexDiff delta;
   920 	TileIndexDiff delta;
   921 	TileIndex tile = ti->tile;
   921 	TileIndex tile = ti->tile;
   922 
   922 
   923 	// find the end tile of the bridge.
   923 	// find the end tile of the bridge.
   924 	delta = (_map5[tile] & 1) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
   924 	delta = (_m[tile].m5 & 1) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
   925 	do {
   925 	do {
   926 		assert((_map5[tile] & 0xC0) == 0xC0);	// bridge and middle part
   926 		assert((_m[tile].m5 & 0xC0) == 0xC0);	// bridge and middle part
   927 		tile += delta;
   927 		tile += delta;
   928 	} while (_map5[tile] & 0x40);	// while bridge middle parts
   928 	} while (_m[tile].m5 & 0x40);	// while bridge middle parts
   929 
   929 
   930 	/* Return the height there (the height of the NORTH CORNER)
   930 	/* Return the height there (the height of the NORTH CORNER)
   931 	 * If the end of the bridge is on a tileh 7 (all raised, except north corner),
   931 	 * If the end of the bridge is on a tileh 7 (all raised, except north corner),
   932 	 * the z coordinate is 1 height level too low. Compensate for that */
   932 	 * the z coordinate is 1 height level too low. Compensate for that */
   933 	return TilePixelHeight(tile) + (GetTileSlope(tile, NULL) == 7 ? 8 : 0);
   933 	return TilePixelHeight(tile) + (GetTileSlope(tile, NULL) == 7 ? 8 : 0);
   950 {
   950 {
   951 	const uint32 *b;
   951 	const uint32 *b;
   952 	uint32 image;
   952 	uint32 image;
   953 	int piece;
   953 	int piece;
   954 
   954 
   955 	b = _bridge_poles_table[_map2[ti->tile]>>4];
   955 	b = _bridge_poles_table[_m[ti->tile].m2>>4];
   956 
   956 
   957 	// Draw first piece
   957 	// Draw first piece
   958 	// (necessary for cantilever bridges)
   958 	// (necessary for cantilever bridges)
   959 	image = b[12 + (ti->map5&0x01)];
   959 	image = b[12 + (ti->map5&0x01)];
   960 	piece = _map2[ti->tile]&0xF;
   960 	piece = _m[ti->tile].m2&0xF;
   961 	if (image != 0 && piece != 0) {
   961 	if (image != 0 && piece != 0) {
   962 		if (_display_opt & DO_TRANS_BUILDINGS) image = (image & 0x3FFF) | 0x03224000;
   962 		if (_display_opt & DO_TRANS_BUILDINGS) image = (image & 0x3FFF) | 0x03224000;
   963 		DrawGroundSpriteAt(image, x, y, z);
   963 		DrawGroundSpriteAt(image, x, y, z);
   964 	}
   964 	}
   965 
   965 
  1010 static void DrawTile_TunnelBridge(TileInfo *ti)
  1010 static void DrawTile_TunnelBridge(TileInfo *ti)
  1011 {
  1011 {
  1012 	uint32 image;
  1012 	uint32 image;
  1013 	uint tmp;
  1013 	uint tmp;
  1014 	const uint32 *b;
  1014 	const uint32 *b;
  1015 	bool ice = _map3_hi[ti->tile] & 0x80;
  1015 	bool ice = _m[ti->tile].m4 & 0x80;
  1016 
  1016 
  1017 	// draw tunnel?
  1017 	// draw tunnel?
  1018 	if ( (byte)(ti->map5&0xF0) == 0) {
  1018 	if ( (byte)(ti->map5&0xF0) == 0) {
  1019 		/* railway type */
  1019 		/* railway type */
  1020 		image = (_map3_lo[ti->tile] & 0xF) * 8;
  1020 		image = (_m[ti->tile].m3 & 0xF) * 8;
  1021 
  1021 
  1022 		/* ice? */
  1022 		/* ice? */
  1023 		if (ice)
  1023 		if (ice)
  1024 			image += 32;
  1024 			image += 32;
  1025 
  1025 
  1029 
  1029 
  1030 		AddSortableSpriteToDraw(image+1, ti->x + 15, ti->y + 15, 1, 1, 8, (byte)ti->z);
  1030 		AddSortableSpriteToDraw(image+1, ti->x + 15, ti->y + 15, 1, 1, 8, (byte)ti->z);
  1031 	// draw bridge?
  1031 	// draw bridge?
  1032 	} else if ((byte)ti->map5 & 0x80) {
  1032 	} else if ((byte)ti->map5 & 0x80) {
  1033 		// get type of track on the bridge.
  1033 		// get type of track on the bridge.
  1034 		tmp = _map3_lo[ti->tile];
  1034 		tmp = _m[ti->tile].m3;
  1035 		if (ti->map5 & 0x40) tmp >>= 4;
  1035 		if (ti->map5 & 0x40) tmp >>= 4;
  1036 		tmp &= 0xF;
  1036 		tmp &= 0xF;
  1037 
  1037 
  1038 		// 0 = rail bridge
  1038 		// 0 = rail bridge
  1039 		// 1 = road bridge
  1039 		// 1 = road bridge
  1053 				// default sloped sprites..
  1053 				// default sloped sprites..
  1054 				if (ti->tileh != 0) image = _track_sloped_sprites[ti->tileh - 1] + 0x3F3;
  1054 				if (ti->tileh != 0) image = _track_sloped_sprites[ti->tileh - 1] + 0x3F3;
  1055 			}
  1055 			}
  1056 
  1056 
  1057 			// bridge ending.
  1057 			// bridge ending.
  1058 			b = _bridge_sprite_table[(_map2[ti->tile] >> 4) & 0xF][6];
  1058 			b = _bridge_sprite_table[(_m[ti->tile].m2 >> 4) & 0xF][6];
  1059 			b += (tmp&(3<<1))*4; /* actually ((tmp>>2)&3)*8 */
  1059 			b += (tmp&(3<<1))*4; /* actually ((tmp>>2)&3)*8 */
  1060 			b += (tmp&1); // direction
  1060 			b += (tmp&1); // direction
  1061 			if (ti->tileh == 0) b += 4; // sloped "entrance" ?
  1061 			if (ti->tileh == 0) b += 4; // sloped "entrance" ?
  1062 			if (ti->map5 & 0x20) b += 2; // which side
  1062 			if (ti->map5 & 0x20) b += 2; // which side
  1063 
  1063 
  1102 
  1102 
  1103 				if (!(image&1)) {
  1103 				if (!(image&1)) {
  1104 					// railway
  1104 					// railway
  1105 					image = 0x3F3 + (ti->map5 & 1);
  1105 					image = 0x3F3 + (ti->map5 & 1);
  1106 					if (ti->tileh != 0) image = _track_sloped_sprites[ti->tileh - 1] + 0x3F3;
  1106 					if (ti->tileh != 0) image = _track_sloped_sprites[ti->tileh - 1] + 0x3F3;
  1107 					image += (_map3_lo[ti->tile] & 0xF) * TRACKTYPE_SPRITE_PITCH;
  1107 					image += (_m[ti->tile].m3 & 0xF) * TRACKTYPE_SPRITE_PITCH;
  1108 					if (ice) image += 26; // ice?
  1108 					if (ice) image += 26; // ice?
  1109 				} else {
  1109 				} else {
  1110 					// road
  1110 					// road
  1111 					image = 1332 + (ti->map5 & 1);
  1111 					image = 1332 + (ti->map5 & 1);
  1112 					if (ti->tileh != 0) image = _road_sloped_sprites[ti->tileh - 1] + 0x53F;
  1112 					if (ti->tileh != 0) image = _road_sloped_sprites[ti->tileh - 1] + 0x53F;
  1113 					if (ice) image += 19; // ice?
  1113 					if (ice) image += 19; // ice?
  1114 				}
  1114 				}
  1115 				DrawGroundSprite(image);
  1115 				DrawGroundSprite(image);
  1116 			}
  1116 			}
  1117 			// get bridge sprites
  1117 			// get bridge sprites
  1118 			b = _bridge_sprite_table[(_map2[ti->tile] >> 4) & 0xF][_map2[ti->tile]&0xF] + tmp * 4;
  1118 			b = _bridge_sprite_table[(_m[ti->tile].m2 >> 4) & 0xF][_m[ti->tile].m2&0xF] + tmp * 4;
  1119 
  1119 
  1120 			z = GetBridgeHeight(ti) + 5;
  1120 			z = GetBridgeHeight(ti) + 5;
  1121 
  1121 
  1122 			// draw rail
  1122 			// draw rail
  1123 			image = b[0];
  1123 			image = b[0];
  1282 	0,0,0,
  1282 	0,0,0,
  1283 };
  1283 };
  1284 
  1284 
  1285 static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td)
  1285 static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td)
  1286 {
  1286 {
  1287 	if ((_map5[tile] & 0x80) == 0) {
  1287 	if ((_m[tile].m5 & 0x80) == 0) {
  1288 		td->str = STR_5017_RAILROAD_TUNNEL + ((_map5[tile] >> 2) & 3);
  1288 		td->str = STR_5017_RAILROAD_TUNNEL + ((_m[tile].m5 >> 2) & 3);
  1289 	} else {
  1289 	} else {
  1290 		td->str = _bridge_tile_str[ (_map2[tile] >> 4) + (((_map5[tile]>>1)&3)<<4) ];
  1290 		td->str = _bridge_tile_str[ (_m[tile].m2 >> 4) + (((_m[tile].m5>>1)&3)<<4) ];
  1291 
  1291 
  1292 		/* scan to the end of the bridge, that's where the owner is stored */
  1292 		/* scan to the end of the bridge, that's where the owner is stored */
  1293 		if (_map5[tile] & 0x40) {
  1293 		if (_m[tile].m5 & 0x40) {
  1294 			TileIndexDiff delta = _map5[tile] & 1 ? TileDiffXY(0, -1) : TileDiffXY(-1, 0);
  1294 			TileIndexDiff delta = _m[tile].m5 & 1 ? TileDiffXY(0, -1) : TileDiffXY(-1, 0);
  1295 
  1295 
  1296 			do tile += delta; while (_map5[tile] & 0x40);
  1296 			do tile += delta; while (_m[tile].m5 & 0x40);
  1297 		}
  1297 		}
  1298 	}
  1298 	}
  1299 	td->owner = GetTileOwner(tile);
  1299 	td->owner = GetTileOwner(tile);
  1300 }
  1300 }
  1301 
  1301 
  1307 
  1307 
  1308 static void TileLoop_TunnelBridge(TileIndex tile)
  1308 static void TileLoop_TunnelBridge(TileIndex tile)
  1309 {
  1309 {
  1310 	if (_opt.landscape == LT_HILLY) {
  1310 	if (_opt.landscape == LT_HILLY) {
  1311 		if ( GetTileZ(tile) > _opt.snow_line) {
  1311 		if ( GetTileZ(tile) > _opt.snow_line) {
  1312 			if (!(_map3_hi[tile] & 0x80)) {
  1312 			if (!(_m[tile].m4 & 0x80)) {
  1313 				_map3_hi[tile] |= 0x80;
  1313 				_m[tile].m4 |= 0x80;
  1314 				MarkTileDirtyByTile(tile);
  1314 				MarkTileDirtyByTile(tile);
  1315 			}
  1315 			}
  1316 		} else {
  1316 		} else {
  1317 			if (_map3_hi[tile] & 0x80) {
  1317 			if (_m[tile].m4 & 0x80) {
  1318 				_map3_hi[tile] &= ~0x80;
  1318 				_m[tile].m4 &= ~0x80;
  1319 				MarkTileDirtyByTile(tile);
  1319 				MarkTileDirtyByTile(tile);
  1320 			}
  1320 			}
  1321 		}
  1321 		}
  1322 	} else if (_opt.landscape == LT_DESERT) {
  1322 	} else if (_opt.landscape == LT_DESERT) {
  1323 		if (GetMapExtraBits(tile) == 1 && !(_map3_hi[tile]&0x80)) {
  1323 		if (GetMapExtraBits(tile) == 1 && !(_m[tile].m4&0x80)) {
  1324 			_map3_hi[tile] |= 0x80;
  1324 			_m[tile].m4 |= 0x80;
  1325 			MarkTileDirtyByTile(tile);
  1325 			MarkTileDirtyByTile(tile);
  1326 		}
  1326 		}
  1327 	}
  1327 	}
  1328 
  1328 
  1329 	// if it's a bridge with water below, call tileloop_water on it.
  1329 	// if it's a bridge with water below, call tileloop_water on it.
  1330 	if ((_map5[tile] & 0xF8) == 0xC8) TileLoop_Water(tile);
  1330 	if ((_m[tile].m5 & 0xF8) == 0xC8) TileLoop_Water(tile);
  1331 }
  1331 }
  1332 
  1332 
  1333 static void ClickTile_TunnelBridge(TileIndex tile)
  1333 static void ClickTile_TunnelBridge(TileIndex tile)
  1334 {
  1334 {
  1335 	/* not used */
  1335 	/* not used */
  1337 
  1337 
  1338 
  1338 
  1339 static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode)
  1339 static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode)
  1340 {
  1340 {
  1341 	uint32 result;
  1341 	uint32 result;
  1342 	byte m5 = _map5[tile];
  1342 	byte m5 = _m[tile].m5;
  1343 
  1343 
  1344 	if ((m5 & 0xF0) == 0) {
  1344 	if ((m5 & 0xF0) == 0) {
  1345 		/* This is a tunnel */
  1345 		/* This is a tunnel */
  1346 		if (((m5 & 0xCU) >> 2) == mode) {
  1346 		if (((m5 & 0xCU) >> 2) == mode) {
  1347 			/* Tranport in the tunnel is compatible */
  1347 			/* Tranport in the tunnel is compatible */
  1388 	if (!IsTileOwner(tile, old_player)) return;
  1388 	if (!IsTileOwner(tile, old_player)) return;
  1389 
  1389 
  1390 	if (new_player != 255) {
  1390 	if (new_player != 255) {
  1391 		SetTileOwner(tile, new_player);
  1391 		SetTileOwner(tile, new_player);
  1392 	}	else {
  1392 	}	else {
  1393 		if((_map5[tile] & 0xC0)==0xC0) {
  1393 		if((_m[tile].m5 & 0xC0)==0xC0) {
  1394 			// the stuff BELOW the middle part is owned by the deleted player.
  1394 			// the stuff BELOW the middle part is owned by the deleted player.
  1395 			if (!(_map5[tile] & (1 << 4 | 1 << 3))) {
  1395 			if (!(_m[tile].m5 & (1 << 4 | 1 << 3))) {
  1396 				// convert railway into grass.
  1396 				// convert railway into grass.
  1397 				_map5[tile] &= ~(1 << 5 | 1 << 4 | 1 << 3); // no transport route under bridge anymore..
  1397 				_m[tile].m5 &= ~(1 << 5 | 1 << 4 | 1 << 3); // no transport route under bridge anymore..
  1398 			} else {
  1398 			} else {
  1399 				// for road, change the owner of the road to local authority
  1399 				// for road, change the owner of the road to local authority
  1400 				SetTileOwner(tile, OWNER_NONE);
  1400 				SetTileOwner(tile, OWNER_NONE);
  1401 			}
  1401 			}
  1402 		} else {
  1402 		} else {
  1423 {
  1423 {
  1424 	int z;
  1424 	int z;
  1425 	int dir, vdir;
  1425 	int dir, vdir;
  1426 	byte fc;
  1426 	byte fc;
  1427 
  1427 
  1428 	if ((_map5[tile] & 0xF0) == 0) {
  1428 	if ((_m[tile].m5 & 0xF0) == 0) {
  1429 		z = GetSlopeZ(x, y) - v->z_pos;
  1429 		z = GetSlopeZ(x, y) - v->z_pos;
  1430 		if (myabs(z) > 2)
  1430 		if (myabs(z) > 2)
  1431 			return 8;
  1431 			return 8;
  1432 
  1432 
  1433 		if (v->type == VEH_Train) {
  1433 		if (v->type == VEH_Train) {
  1434 			fc = (x&0xF)+(y<<4);
  1434 			fc = (x&0xF)+(y<<4);
  1435 
  1435 
  1436 			dir = _map5[tile] & 3;
  1436 			dir = _m[tile].m5 & 3;
  1437 			vdir = v->direction >> 1;
  1437 			vdir = v->direction >> 1;
  1438 
  1438 
  1439 			if (v->u.rail.track != 0x40 && dir == vdir) {
  1439 			if (v->u.rail.track != 0x40 && dir == vdir) {
  1440 				if (v->subtype == TS_Front_Engine && fc == _tunnel_fractcoord_1[dir]) {
  1440 				if (v->subtype == TS_Front_Engine && fc == _tunnel_fractcoord_1[dir]) {
  1441 					if (v->spritenum < 4)
  1441 					if (v->spritenum < 4)
  1460 				v->vehstatus &= ~VS_HIDDEN;
  1460 				v->vehstatus &= ~VS_HIDDEN;
  1461 				return 4;
  1461 				return 4;
  1462 			}
  1462 			}
  1463 		} else if (v->type == VEH_Road) {
  1463 		} else if (v->type == VEH_Road) {
  1464 			fc = (x&0xF)+(y<<4);
  1464 			fc = (x&0xF)+(y<<4);
  1465 			dir = _map5[tile] & 3;
  1465 			dir = _m[tile].m5 & 3;
  1466 			vdir = v->direction >> 1;
  1466 			vdir = v->direction >> 1;
  1467 
  1467 
  1468 			// Enter tunnel?
  1468 			// Enter tunnel?
  1469 			if (v->u.road.state != 0xFF && dir == vdir) {
  1469 			if (v->u.road.state != 0xFF && dir == vdir) {
  1470 				if (fc == _tunnel_fractcoord_4[dir] ||
  1470 				if (fc == _tunnel_fractcoord_4[dir] ||
  1489 				v->u.road.frame = _road_exit_tunnel_frame[dir];
  1489 				v->u.road.frame = _road_exit_tunnel_frame[dir];
  1490 				v->vehstatus &= ~VS_HIDDEN;
  1490 				v->vehstatus &= ~VS_HIDDEN;
  1491 				return 4;
  1491 				return 4;
  1492 			}
  1492 			}
  1493 		}
  1493 		}
  1494 	} else if (_map5[tile] & 0x80) {
  1494 	} else if (_m[tile].m5 & 0x80) {
  1495 		if (v->type == VEH_Road || (v->type == VEH_Train && v->subtype == TS_Front_Engine)) {
  1495 		if (v->type == VEH_Road || (v->type == VEH_Train && v->subtype == TS_Front_Engine)) {
  1496 			uint h;
  1496 			uint h;
  1497 
  1497 
  1498 			if (GetTileSlope(tile, &h) != 0)
  1498 			if (GetTileSlope(tile, &h) != 0)
  1499 				h += 8; // Compensate for possible foundation
  1499 				h += 8; // Compensate for possible foundation
  1500 			if (!(_map5[tile] & 0x40) || // start/end tile of bridge
  1500 			if (!(_m[tile].m5 & 0x40) || // start/end tile of bridge
  1501 					myabs(h - v->z_pos) > 2) { // high above the ground -> on the bridge
  1501 					myabs(h - v->z_pos) > 2) { // high above the ground -> on the bridge
  1502 				/* modify speed of vehicle */
  1502 				/* modify speed of vehicle */
  1503 				uint16 spd = _bridge_speeds[_map2[tile] >> 4];
  1503 				uint16 spd = _bridge_speeds[_m[tile].m2 >> 4];
  1504 				if (v->type == VEH_Road) spd<<=1;
  1504 				if (v->type == VEH_Road) spd<<=1;
  1505 				if (spd < v->cur_speed)
  1505 				if (spd < v->cur_speed)
  1506 					v->cur_speed = spd;
  1506 					v->cur_speed = spd;
  1507 			}
  1507 			}
  1508 		}
  1508 		}
  1515 	TileIndex tile;
  1515 	TileIndex tile;
  1516 	TileIndexDiff delta = (v->direction & 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
  1516 	TileIndexDiff delta = (v->direction & 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
  1517 	byte z = v->z_pos;
  1517 	byte z = v->z_pos;
  1518 
  1518 
  1519 	for (tile = v->tile;; tile += delta) {
  1519 	for (tile = v->tile;; tile += delta) {
  1520 		if (IsTileType(tile, MP_TUNNELBRIDGE) && (_map5[tile] & 0xF0) == 0 &&
  1520 		if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0xF0) == 0 &&
  1521 				GetTileZ(tile) == z)
  1521 				GetTileZ(tile) == z)
  1522 			break;
  1522 			break;
  1523 	}
  1523 	}
  1524 	return tile;
  1524 	return tile;
  1525 }
  1525 }