src/tunnelbridge_cmd.cpp
changeset 9044 a3b59d458c03
parent 9036 d3b132a4b97a
child 9045 fb5d8378b111
equal deleted inserted replaced
9043:dfcde0d0dc0a 9044:a3b59d458c03
   802  * Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3
   802  * Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3
   803  */
   803  */
   804 static void DrawTile_TunnelBridge(TileInfo *ti)
   804 static void DrawTile_TunnelBridge(TileInfo *ti)
   805 {
   805 {
   806 	SpriteID image;
   806 	SpriteID image;
       
   807 	DiagDirection tunnelbridge_direction = GetTunnelBridgeDirection(ti->tile);
   807 
   808 
   808 	if (IsTunnel(ti->tile)) {
   809 	if (IsTunnel(ti->tile)) {
   809 		/* Front view of tunnel bounding boxes:
   810 		/* Front view of tunnel bounding boxes:
   810 		 *
   811 		 *
   811 		 *   122223  <- BB_Z_SEPARATOR
   812 		 *   122223  <- BB_Z_SEPARATOR
   821 			{  1,  0, -15, -14,  0, 15, 16,  1, 0, 1, 16, 15 }, // NE
   822 			{  1,  0, -15, -14,  0, 15, 16,  1, 0, 1, 16, 15 }, // NE
   822 			{  0,  1, -14, -15, 15,  0,  1, 16, 1, 0, 15, 16 }, // SE
   823 			{  0,  1, -14, -15, 15,  0,  1, 16, 1, 0, 15, 16 }, // SE
   823 			{  1,  0, -15, -14,  0, 15, 16,  1, 0, 1, 16, 15 }, // SW
   824 			{  1,  0, -15, -14,  0, 15, 16,  1, 0, 1, 16, 15 }, // SW
   824 			{  0,  1, -14, -15, 15,  0,  1, 16, 1, 0, 15, 16 }, // NW
   825 			{  0,  1, -14, -15, 15,  0,  1, 16, 1, 0, 15, 16 }, // NW
   825 		};
   826 		};
   826 		const int *BB_data = _tunnel_BB[GetTunnelBridgeDirection(ti->tile)];
   827 		const int *BB_data = _tunnel_BB[tunnelbridge_direction];
   827 
   828 
   828 		bool catenary = false;
   829 		bool catenary = false;
   829 
   830 
   830 		if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
   831 		if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
   831 			image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.tunnel;
   832 			image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.tunnel;
   833 			image = SPR_TUNNEL_ENTRY_REAR_ROAD;
   834 			image = SPR_TUNNEL_ENTRY_REAR_ROAD;
   834 		}
   835 		}
   835 
   836 
   836 		if (HasTunnelBridgeSnowOrDesert(ti->tile)) image += 32;
   837 		if (HasTunnelBridgeSnowOrDesert(ti->tile)) image += 32;
   837 
   838 
   838 		image += GetTunnelBridgeDirection(ti->tile) * 2;
   839 		image += tunnelbridge_direction * 2;
   839 		DrawGroundSprite(image, PAL_NONE);
   840 		DrawGroundSprite(image, PAL_NONE);
   840 		if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_ROAD) {
   841 		if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_ROAD) {
   841 			DiagDirection dir = GetTunnelBridgeDirection(ti->tile);
       
   842 			RoadTypes rts = GetRoadTypes(ti->tile);
   842 			RoadTypes rts = GetRoadTypes(ti->tile);
   843 
   843 
   844 			if (HasBit(rts, ROADTYPE_TRAM)) {
   844 			if (HasBit(rts, ROADTYPE_TRAM)) {
   845 				static const SpriteID tunnel_sprites[2][4] = { { 28, 78, 79, 27 }, {  5, 76, 77,  4 } };
   845 				static const SpriteID tunnel_sprites[2][4] = { { 28, 78, 79, 27 }, {  5, 76, 77,  4 } };
   846 
   846 
   847 				DrawGroundSprite(SPR_TRAMWAY_BASE + tunnel_sprites[rts - ROADTYPES_TRAM][dir], PAL_NONE);
   847 				DrawGroundSprite(SPR_TRAMWAY_BASE + tunnel_sprites[rts - ROADTYPES_TRAM][tunnelbridge_direction], PAL_NONE);
   848 
   848 
   849 				catenary = true;
   849 				catenary = true;
   850 				StartSpriteCombine();
   850 				StartSpriteCombine();
   851 				AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + dir, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_CATENARY), BB_data[8], BB_data[9], BB_Z_SEPARATOR);
   851 				AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_CATENARY), BB_data[8], BB_data[9], BB_Z_SEPARATOR);
   852 			}
   852 			}
   853 		} else if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) {
   853 		} else if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) {
   854 			DrawCatenary(ti);
   854 			DrawCatenary(ti);
   855 
   855 
   856 			catenary = true;
   856 			catenary = true;
   880 		}
   880 		}
   881 
   881 
   882 		/* as the lower 3 bits are used for other stuff, make sure they are clear */
   882 		/* as the lower 3 bits are used for other stuff, make sure they are clear */
   883 		assert( (base_offset & 0x07) == 0x00);
   883 		assert( (base_offset & 0x07) == 0x00);
   884 
   884 
   885 		DrawFoundation(ti, GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetTunnelBridgeDirection(ti->tile))));
   885 		DrawFoundation(ti, GetBridgeFoundation(ti->tileh, DiagDirToAxis(tunnelbridge_direction)));
   886 
   886 
   887 		/* HACK Wizardry to convert the bridge ramp direction into a sprite offset */
   887 		/* HACK Wizardry to convert the bridge ramp direction into a sprite offset */
   888 		base_offset += (6 - GetTunnelBridgeDirection(ti->tile)) % 4;
   888 		base_offset += (6 - tunnelbridge_direction) % 4;
   889 
   889 
   890 		if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
   890 		if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
   891 
   891 
   892 		/* Table number 6 always refers to the bridge heads for any bridge type */
   892 		/* Table number 6 always refers to the bridge heads for any bridge type */
   893 		psid = &GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset];
   893 		psid = &GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset];
   912 
   912 
   913 		if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_ROAD) {
   913 		if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_ROAD) {
   914 			RoadTypes rts = GetRoadTypes(ti->tile);
   914 			RoadTypes rts = GetRoadTypes(ti->tile);
   915 
   915 
   916 			if (HasBit(rts, ROADTYPE_TRAM)) {
   916 			if (HasBit(rts, ROADTYPE_TRAM)) {
   917 				uint offset = GetTunnelBridgeDirection(ti->tile);
   917 				uint offset = tunnelbridge_direction;
   918 				uint z = ti->z;
   918 				uint z = ti->z;
   919 				if (ti->tileh != SLOPE_FLAT) {
   919 				if (ti->tileh != SLOPE_FLAT) {
   920 					offset = (offset + 1) & 1;
   920 					offset = (offset + 1) & 1;
   921 					z += TILE_HEIGHT;
   921 					z += TILE_HEIGHT;
   922 				} else {
   922 				} else {
  1227 static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex tile, int x, int y)
  1227 static VehicleEnterTileStatus VehicleEnter_TunnelBridge(Vehicle *v, TileIndex tile, int x, int y)
  1228 {
  1228 {
  1229 	int z = GetSlopeZ(x, y) - v->z_pos;
  1229 	int z = GetSlopeZ(x, y) - v->z_pos;
  1230 
  1230 
  1231 	if (abs(z) > 2) return VETSB_CANNOT_ENTER;
  1231 	if (abs(z) > 2) return VETSB_CANNOT_ENTER;
       
  1232 	const DiagDirection dir = GetTunnelBridgeDirection(tile);
  1232 
  1233 
  1233 	if (IsTunnel(tile)) {
  1234 	if (IsTunnel(tile)) {
  1234 		byte fc;
  1235 		byte fc;
  1235 		DiagDirection dir;
       
  1236 		DiagDirection vdir;
  1236 		DiagDirection vdir;
  1237 
  1237 
  1238 		if (v->type == VEH_TRAIN) {
  1238 		if (v->type == VEH_TRAIN) {
  1239 			fc = (x & 0xF) + (y << 4);
  1239 			fc = (x & 0xF) + (y << 4);
  1240 
  1240 
  1241 			dir = GetTunnelBridgeDirection(tile);
       
  1242 			vdir = DirToDiagDir(v->direction);
  1241 			vdir = DirToDiagDir(v->direction);
  1243 
  1242 
  1244 			if (v->u.rail.track != TRACK_BIT_WORMHOLE && dir == vdir) {
  1243 			if (v->u.rail.track != TRACK_BIT_WORMHOLE && dir == vdir) {
  1245 				if (IsFrontEngine(v) && fc == _tunnel_fractcoord_1[dir]) {
  1244 				if (IsFrontEngine(v) && fc == _tunnel_fractcoord_1[dir]) {
  1246 					if (!PlayVehicleSound(v, VSE_TUNNEL) && RailVehInfo(v->engine_type)->engclass == 0) {
  1245 					if (!PlayVehicleSound(v, VSE_TUNNEL) && RailVehInfo(v->engine_type)->engclass == 0) {
  1264 				v->vehstatus &= ~VS_HIDDEN;
  1263 				v->vehstatus &= ~VS_HIDDEN;
  1265 				return VETSB_ENTERED_WORMHOLE;
  1264 				return VETSB_ENTERED_WORMHOLE;
  1266 			}
  1265 			}
  1267 		} else if (v->type == VEH_ROAD) {
  1266 		} else if (v->type == VEH_ROAD) {
  1268 			fc = (x & 0xF) + (y << 4);
  1267 			fc = (x & 0xF) + (y << 4);
  1269 			dir = GetTunnelBridgeDirection(tile);
       
  1270 			vdir = DirToDiagDir(v->direction);
  1268 			vdir = DirToDiagDir(v->direction);
  1271 
  1269 
  1272 			/* Enter tunnel? */
  1270 			/* Enter tunnel? */
  1273 			if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) {
  1271 			if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) {
  1274 				if (fc == _tunnel_fractcoord_4[dir] ||
  1272 				if (fc == _tunnel_fractcoord_4[dir] ||
  1294 				v->vehstatus &= ~VS_HIDDEN;
  1292 				v->vehstatus &= ~VS_HIDDEN;
  1295 				return VETSB_ENTERED_WORMHOLE;
  1293 				return VETSB_ENTERED_WORMHOLE;
  1296 			}
  1294 			}
  1297 		}
  1295 		}
  1298 	} else { // IsBridge(tile)
  1296 	} else { // IsBridge(tile)
  1299 		DiagDirection dir;
       
  1300 
  1297 
  1301 		if (v->IsPrimaryVehicle()) {
  1298 		if (v->IsPrimaryVehicle()) {
  1302 			/* modify speed of vehicle */
  1299 			/* modify speed of vehicle */
  1303 			uint16 spd = GetBridgeSpec(GetBridgeType(tile))->speed;
  1300 			uint16 spd = GetBridgeSpec(GetBridgeType(tile))->speed;
  1304 
  1301 
  1305 			if (v->type == VEH_ROAD) spd *= 2;
  1302 			if (v->type == VEH_ROAD) spd *= 2;
  1306 			if (v->cur_speed > spd) v->cur_speed = spd;
  1303 			if (v->cur_speed > spd) v->cur_speed = spd;
  1307 		}
  1304 		}
  1308 
  1305 
  1309 		dir = GetTunnelBridgeDirection(tile);
       
  1310 		if (DirToDiagDir(v->direction) == dir) {
  1306 		if (DirToDiagDir(v->direction) == dir) {
  1311 			switch (dir) {
  1307 			switch (dir) {
  1312 				default: NOT_REACHED();
  1308 				default: NOT_REACHED();
  1313 				case DIAGDIR_NE: if ((x & 0xF) != 0)             return VETSB_CONTINUE; break;
  1309 				case DIAGDIR_NE: if ((x & 0xF) != 0)             return VETSB_CONTINUE; break;
  1314 				case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return VETSB_CONTINUE; break;
  1310 				case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return VETSB_CONTINUE; break;