75 x -= n; |
75 x -= n; |
76 } |
76 } |
77 } |
77 } |
78 |
78 |
79 #define M(x) (1 << (x)) |
79 #define M(x) (1 << (x)) |
80 typedef enum BridgeFoundations{ |
80 enum BridgeFoundation { |
81 // foundation, whole tile is leveled up --> 3 corners raised |
81 // foundation, whole tile is leveled up --> 3 corners raised |
82 BRIDGE_FULL_LEVELED_FOUNDATION = M(SLOPE_WSE) | M(SLOPE_NWS) | M(SLOPE_ENW) | M(SLOPE_SEN), |
82 BRIDGE_FULL_LEVELED_FOUNDATION = M(SLOPE_WSE) | M(SLOPE_NWS) | M(SLOPE_ENW) | M(SLOPE_SEN), |
83 // foundation, tile is partly leveled up --> 1 corner raised |
83 // foundation, tile is partly leveled up --> 1 corner raised |
84 BRIDGE_PARTLY_LEVELED_FOUNDATION = M(SLOPE_W) | M(SLOPE_S) | M(SLOPE_E) | M(SLOPE_N), |
84 BRIDGE_PARTLY_LEVELED_FOUNDATION = M(SLOPE_W) | M(SLOPE_S) | M(SLOPE_E) | M(SLOPE_N), |
85 // no foundations (X,Y direction) |
85 // no foundations (X,Y direction) |
86 BRIDGE_NO_FOUNDATION = M(SLOPE_FLAT) | M(SLOPE_SW) | M(SLOPE_SE) | M(SLOPE_NW) | M(SLOPE_NE), |
86 BRIDGE_NO_FOUNDATION = M(SLOPE_FLAT) | M(SLOPE_SW) | M(SLOPE_SE) | M(SLOPE_NW) | M(SLOPE_NE), |
87 BRIDGE_HORZ_RAMP = (BRIDGE_PARTLY_LEVELED_FOUNDATION | BRIDGE_NO_FOUNDATION) & ~M(SLOPE_FLAT) |
87 BRIDGE_HORZ_RAMP = (BRIDGE_PARTLY_LEVELED_FOUNDATION | BRIDGE_NO_FOUNDATION) & ~M(SLOPE_FLAT) |
88 } BridgeFoundataion; |
88 }; |
89 #undef M |
89 #undef M |
90 |
90 |
91 static inline const PalSpriteID *GetBridgeSpriteTable(int index, byte table) |
91 static inline const PalSpriteID *GetBridgeSpriteTable(int index, byte table) |
92 { |
92 { |
93 const Bridge *bridge = &_bridge[index]; |
93 const Bridge *bridge = &_bridge[index]; |
541 GetTileZ(tile) != z |
541 GetTileZ(tile) != z |
542 ); |
542 ); |
543 |
543 |
544 v = FindVehicleBetween(starttile, tile, z); |
544 v = FindVehicleBetween(starttile, tile, z); |
545 if (v != NULL) { |
545 if (v != NULL) { |
546 _error_message = v->type == VEH_Train ? |
546 _error_message = v->type == VEH_TRAIN ? |
547 STR_5000_TRAIN_IN_TUNNEL : STR_5001_ROAD_VEHICLE_IN_TUNNEL; |
547 STR_5000_TRAIN_IN_TUNNEL : STR_5001_ROAD_VEHICLE_IN_TUNNEL; |
548 return INVALID_TILE; |
548 return INVALID_TILE; |
549 } |
549 } |
550 |
550 |
551 if (length != NULL) *length = len; |
551 if (length != NULL) *length = len; |
1284 v->u.rail.track = (TrackBits)_exit_tunnel_track[dir]; |
1284 v->u.rail.track = (TrackBits)_exit_tunnel_track[dir]; |
1285 assert(v->u.rail.track); |
1285 assert(v->u.rail.track); |
1286 v->vehstatus &= ~VS_HIDDEN; |
1286 v->vehstatus &= ~VS_HIDDEN; |
1287 return VETSB_ENTERED_WORMHOLE; |
1287 return VETSB_ENTERED_WORMHOLE; |
1288 } |
1288 } |
1289 } else if (v->type == VEH_Road) { |
1289 } else if (v->type == VEH_ROAD) { |
1290 fc = (x & 0xF) + (y << 4); |
1290 fc = (x & 0xF) + (y << 4); |
1291 dir = GetTunnelDirection(tile); |
1291 dir = GetTunnelDirection(tile); |
1292 vdir = DirToDiagDir(v->direction); |
1292 vdir = DirToDiagDir(v->direction); |
1293 |
1293 |
1294 // Enter tunnel? |
1294 // Enter tunnel? |
1318 } |
1318 } |
1319 } |
1319 } |
1320 } else if (IsBridge(tile)) { // XXX is this necessary? |
1320 } else if (IsBridge(tile)) { // XXX is this necessary? |
1321 DiagDirection dir; |
1321 DiagDirection dir; |
1322 |
1322 |
1323 if (v->type == VEH_Road || (v->type == VEH_Train && IsFrontEngine(v))) { |
1323 if (v->type == VEH_ROAD || (v->type == VEH_TRAIN && IsFrontEngine(v))) { |
1324 /* modify speed of vehicle */ |
1324 /* modify speed of vehicle */ |
1325 uint16 spd = _bridge[GetBridgeType(tile)].speed; |
1325 uint16 spd = _bridge[GetBridgeType(tile)].speed; |
1326 |
1326 |
1327 if (v->type == VEH_Road) spd *= 2; |
1327 if (v->type == VEH_ROAD) spd *= 2; |
1328 if (v->cur_speed > spd) v->cur_speed = spd; |
1328 if (v->cur_speed > spd) v->cur_speed = spd; |
1329 } |
1329 } |
1330 |
1330 |
1331 dir = GetBridgeRampDirection(tile); |
1331 dir = GetBridgeRampDirection(tile); |
1332 if (DirToDiagDir(v->direction) == dir) { |
1332 if (DirToDiagDir(v->direction) == dir) { |
1335 case DIAGDIR_NE: if ((x & 0xF) != 0) return VETSB_CONTINUE; break; |
1335 case DIAGDIR_NE: if ((x & 0xF) != 0) return VETSB_CONTINUE; break; |
1336 case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return VETSB_CONTINUE; break; |
1336 case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return VETSB_CONTINUE; break; |
1337 case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return VETSB_CONTINUE; break; |
1337 case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return VETSB_CONTINUE; break; |
1338 case DIAGDIR_NW: if ((y & 0xF) != 0) return VETSB_CONTINUE; break; |
1338 case DIAGDIR_NW: if ((y & 0xF) != 0) return VETSB_CONTINUE; break; |
1339 } |
1339 } |
1340 if (v->type == VEH_Train) { |
1340 if (v->type == VEH_TRAIN) { |
1341 v->u.rail.track = TRACK_BIT_WORMHOLE; |
1341 v->u.rail.track = TRACK_BIT_WORMHOLE; |
1342 CLRBIT(v->u.rail.flags, VRF_GOINGUP); |
1342 CLRBIT(v->u.rail.flags, VRF_GOINGUP); |
1343 CLRBIT(v->u.rail.flags, VRF_GOINGDOWN); |
1343 CLRBIT(v->u.rail.flags, VRF_GOINGDOWN); |
1344 } else { |
1344 } else { |
1345 v->u.road.state = RVSB_WORMHOLE; |
1345 v->u.road.state = RVSB_WORMHOLE; |
1346 } |
1346 } |
1347 return VETSB_ENTERED_WORMHOLE; |
1347 return VETSB_ENTERED_WORMHOLE; |
1348 } else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) { |
1348 } else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) { |
1349 v->tile = tile; |
1349 v->tile = tile; |
1350 if (v->type == VEH_Train) { |
1350 if (v->type == VEH_TRAIN) { |
1351 if (v->u.rail.track == TRACK_BIT_WORMHOLE) { |
1351 if (v->u.rail.track == TRACK_BIT_WORMHOLE) { |
1352 v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); |
1352 v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); |
1353 return VETSB_ENTERED_WORMHOLE; |
1353 return VETSB_ENTERED_WORMHOLE; |
1354 } |
1354 } |
1355 } else { |
1355 } else { |