1248 static const byte _tunnel_fractcoord_1[4] = {0x8E, 0x18, 0x81, 0xE8}; |
1248 static const byte _tunnel_fractcoord_1[4] = {0x8E, 0x18, 0x81, 0xE8}; |
1249 static const byte _tunnel_fractcoord_2[4] = {0x81, 0x98, 0x87, 0x38}; |
1249 static const byte _tunnel_fractcoord_2[4] = {0x81, 0x98, 0x87, 0x38}; |
1250 static const byte _tunnel_fractcoord_3[4] = {0x82, 0x88, 0x86, 0x48}; |
1250 static const byte _tunnel_fractcoord_3[4] = {0x82, 0x88, 0x86, 0x48}; |
1251 static const byte _exit_tunnel_track[4] = {1, 2, 1, 2}; |
1251 static const byte _exit_tunnel_track[4] = {1, 2, 1, 2}; |
1252 |
1252 |
1253 static const byte _road_exit_tunnel_state[4] = {8, 9, 0, 1}; |
1253 /** Get the trackdir of the exit of a tunnel */ |
|
1254 static const Trackdir _road_exit_tunnel_state[DIAGDIR_END] = { |
|
1255 TRACKDIR_X_SW, TRACKDIR_Y_NW, TRACKDIR_X_NE, TRACKDIR_Y_SE |
|
1256 }; |
1254 static const byte _road_exit_tunnel_frame[4] = {2, 7, 9, 4}; |
1257 static const byte _road_exit_tunnel_frame[4] = {2, 7, 9, 4}; |
1255 |
1258 |
1256 static const byte _tunnel_fractcoord_4[4] = {0x52, 0x85, 0x98, 0x29}; |
1259 static const byte _tunnel_fractcoord_4[4] = {0x52, 0x85, 0x98, 0x29}; |
1257 static const byte _tunnel_fractcoord_5[4] = {0x92, 0x89, 0x58, 0x25}; |
1260 static const byte _tunnel_fractcoord_5[4] = {0x92, 0x89, 0x58, 0x25}; |
1258 static const byte _tunnel_fractcoord_6[4] = {0x92, 0x89, 0x56, 0x45}; |
1261 static const byte _tunnel_fractcoord_6[4] = {0x92, 0x89, 0x56, 0x45}; |
1273 fc = (x & 0xF) + (y << 4); |
1276 fc = (x & 0xF) + (y << 4); |
1274 |
1277 |
1275 dir = GetTunnelDirection(tile); |
1278 dir = GetTunnelDirection(tile); |
1276 vdir = DirToDiagDir(v->direction); |
1279 vdir = DirToDiagDir(v->direction); |
1277 |
1280 |
1278 if (v->u.rail.track != 0x40 && dir == vdir) { |
1281 if (v->u.rail.track != TRACK_BIT_WORMHOLE && dir == vdir) { |
1279 if (IsFrontEngine(v) && fc == _tunnel_fractcoord_1[dir]) { |
1282 if (IsFrontEngine(v) && fc == _tunnel_fractcoord_1[dir]) { |
1280 if (!PlayVehicleSound(v, VSE_TUNNEL) && v->spritenum < 4) { |
1283 if (!PlayVehicleSound(v, VSE_TUNNEL) && v->spritenum < 4) { |
1281 SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v); |
1284 SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v); |
1282 } |
1285 } |
1283 return 0; |
1286 return VETSB_CONTINUE; |
1284 } |
1287 } |
1285 if (fc == _tunnel_fractcoord_2[dir]) { |
1288 if (fc == _tunnel_fractcoord_2[dir]) { |
1286 v->tile = tile; |
1289 v->tile = tile; |
1287 v->u.rail.track = TRACK_BIT_WORMHOLE; |
1290 v->u.rail.track = TRACK_BIT_WORMHOLE; |
1288 v->vehstatus |= VS_HIDDEN; |
1291 v->vehstatus |= VS_HIDDEN; |
1289 return 4; |
1292 return VETSB_ENTERED_WORMHOLE; |
1290 } |
1293 } |
1291 } |
1294 } |
1292 |
1295 |
1293 if (dir == ReverseDiagDir(vdir) && fc == _tunnel_fractcoord_3[dir] && z == 0) { |
1296 if (dir == ReverseDiagDir(vdir) && fc == _tunnel_fractcoord_3[dir] && z == 0) { |
1294 /* We're at the tunnel exit ?? */ |
1297 /* We're at the tunnel exit ?? */ |
1295 v->tile = tile; |
1298 v->tile = tile; |
1296 v->u.rail.track = (TrackBits)_exit_tunnel_track[dir]; |
1299 v->u.rail.track = (TrackBits)_exit_tunnel_track[dir]; |
1297 assert(v->u.rail.track); |
1300 assert(v->u.rail.track); |
1298 v->vehstatus &= ~VS_HIDDEN; |
1301 v->vehstatus &= ~VS_HIDDEN; |
1299 return 4; |
1302 return VETSB_ENTERED_WORMHOLE; |
1300 } |
1303 } |
1301 } else if (v->type == VEH_Road) { |
1304 } else if (v->type == VEH_Road) { |
1302 fc = (x & 0xF) + (y << 4); |
1305 fc = (x & 0xF) + (y << 4); |
1303 dir = GetTunnelDirection(tile); |
1306 dir = GetTunnelDirection(tile); |
1304 vdir = DirToDiagDir(v->direction); |
1307 vdir = DirToDiagDir(v->direction); |
1305 |
1308 |
1306 // Enter tunnel? |
1309 // Enter tunnel? |
1307 if (v->u.road.state != 0xFF && dir == vdir) { |
1310 if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) { |
1308 if (fc == _tunnel_fractcoord_4[dir] || |
1311 if (fc == _tunnel_fractcoord_4[dir] || |
1309 fc == _tunnel_fractcoord_5[dir]) { |
1312 fc == _tunnel_fractcoord_5[dir]) { |
1310 v->tile = tile; |
1313 v->tile = tile; |
1311 v->u.road.state = 0xFF; |
1314 v->u.road.state = RVSB_WORMHOLE; |
1312 v->vehstatus |= VS_HIDDEN; |
1315 v->vehstatus |= VS_HIDDEN; |
1313 return 4; |
1316 return VETSB_ENTERED_WORMHOLE; |
1314 } else { |
1317 } else { |
1315 return 0; |
1318 return VETSB_CONTINUE; |
1316 } |
1319 } |
1317 } |
1320 } |
1318 |
1321 |
1319 if (dir == ReverseDiagDir(vdir) && ( |
1322 if (dir == ReverseDiagDir(vdir) && ( |
1320 /* We're at the tunnel exit ?? */ |
1323 /* We're at the tunnel exit ?? */ |
1342 |
1345 |
1343 dir = GetBridgeRampDirection(tile); |
1346 dir = GetBridgeRampDirection(tile); |
1344 if (DirToDiagDir(v->direction) == dir) { |
1347 if (DirToDiagDir(v->direction) == dir) { |
1345 switch (dir) { |
1348 switch (dir) { |
1346 default: NOT_REACHED(); |
1349 default: NOT_REACHED(); |
1347 case DIAGDIR_NE: if ((x & 0xF) != 0) return 0; break; |
1350 case DIAGDIR_NE: if ((x & 0xF) != 0) return VETSB_CONTINUE; break; |
1348 case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return 0; break; |
1351 case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return VETSB_CONTINUE; break; |
1349 case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return 0; break; |
1352 case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return VETSB_CONTINUE; break; |
1350 case DIAGDIR_NW: if ((y & 0xF) != 0) return 0; break; |
1353 case DIAGDIR_NW: if ((y & 0xF) != 0) return VETSB_CONTINUE; break; |
1351 } |
1354 } |
1352 if (v->type == VEH_Train) { |
1355 if (v->type == VEH_Train) { |
1353 v->u.rail.track = TRACK_BIT_WORMHOLE; |
1356 v->u.rail.track = TRACK_BIT_WORMHOLE; |
1354 CLRBIT(v->u.rail.flags, VRF_GOINGUP); |
1357 CLRBIT(v->u.rail.flags, VRF_GOINGUP); |
1355 CLRBIT(v->u.rail.flags, VRF_GOINGDOWN); |
1358 CLRBIT(v->u.rail.flags, VRF_GOINGDOWN); |
1356 } else { |
1359 } else { |
1357 v->u.road.state = 0xFF; |
1360 v->u.road.state = RVSB_WORMHOLE; |
1358 } |
1361 } |
1359 return 4; |
1362 return VETSB_ENTERED_WORMHOLE; |
1360 } else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) { |
1363 } else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) { |
1361 v->tile = tile; |
1364 v->tile = tile; |
1362 if (v->type == VEH_Train) { |
1365 if (v->type == VEH_Train) { |
1363 if (v->u.rail.track == 0x40) { |
1366 if (v->u.rail.track == TRACK_BIT_WORMHOLE) { |
1364 v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); |
1367 v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); |
1365 return 4; |
1368 return VETSB_ENTERED_WORMHOLE; |
1366 } |
1369 } |
1367 } else { |
1370 } else { |
1368 if (v->u.road.state == 0xFF) { |
1371 if (v->u.road.state == RVSB_WORMHOLE) { |
1369 v->u.road.state = _road_exit_tunnel_state[dir]; |
1372 v->u.road.state = _road_exit_tunnel_state[dir]; |
1370 v->u.road.frame = 0; |
1373 v->u.road.frame = 0; |
1371 return 4; |
1374 return VETSB_ENTERED_WORMHOLE; |
1372 } |
1375 } |
1373 } |
1376 } |
1374 return 0; |
1377 return VETSB_CONTINUE; |
1375 } |
1378 } |
1376 } |
1379 } |
1377 return 0; |
1380 return VETSB_CONTINUE; |
1378 } |
1381 } |
1379 |
1382 |
1380 extern const TileTypeProcs _tile_type_tunnelbridge_procs = { |
1383 extern const TileTypeProcs _tile_type_tunnelbridge_procs = { |
1381 DrawTile_TunnelBridge, /* draw_tile_proc */ |
1384 DrawTile_TunnelBridge, /* draw_tile_proc */ |
1382 GetSlopeZ_TunnelBridge, /* get_slope_z_proc */ |
1385 GetSlopeZ_TunnelBridge, /* get_slope_z_proc */ |