393 |
393 |
394 return cost; |
394 return cost; |
395 } |
395 } |
396 |
396 |
397 |
397 |
398 /** Build Tunnel. |
398 static inline bool CheckAllowRemoveBridge(TileIndex tile) |
399 * @param tile start tile of tunnel |
|
400 * @param p1 railtype, 0x200 for road tunnel |
|
401 * @param p2 unused |
|
402 */ |
|
403 int32 CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32 p2) |
|
404 { |
|
405 TileIndexDiff delta; |
|
406 TileIndex end_tile; |
|
407 DiagDirection direction; |
|
408 Slope start_tileh; |
|
409 Slope end_tileh; |
|
410 uint start_z; |
|
411 uint end_z; |
|
412 int32 cost; |
|
413 int32 ret; |
|
414 |
|
415 _build_tunnel_endtile = 0; |
|
416 |
|
417 if (p1 != 0x200 && !ValParamRailtype(p1)) return CMD_ERROR; |
|
418 |
|
419 start_tileh = GetTileSlope(start_tile, &start_z); |
|
420 |
|
421 switch (start_tileh) { |
|
422 case SLOPE_SW: direction = DIAGDIR_SW; break; |
|
423 case SLOPE_SE: direction = DIAGDIR_SE; break; |
|
424 case SLOPE_NW: direction = DIAGDIR_NW; break; |
|
425 case SLOPE_NE: direction = DIAGDIR_NE; break; |
|
426 default: return_cmd_error(STR_500B_SITE_UNSUITABLE_FOR_TUNNEL); |
|
427 } |
|
428 |
|
429 ret = DoCommand(start_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
|
430 if (CmdFailed(ret)) return ret; |
|
431 |
|
432 /* XXX - do NOT change 'ret' in the loop, as it is used as the price |
|
433 * for the clearing of the entrance of the tunnel. Assigning it to |
|
434 * cost before the loop will yield different costs depending on start- |
|
435 * position, because of increased-cost-by-length: 'cost += cost >> 3' */ |
|
436 cost = 0; |
|
437 delta = TileOffsByDiagDir(direction); |
|
438 end_tile = start_tile; |
|
439 for (;;) { |
|
440 end_tile += delta; |
|
441 end_tileh = GetTileSlope(end_tile, &end_z); |
|
442 |
|
443 if (start_z == end_z) break; |
|
444 |
|
445 if (!_cheats.crossing_tunnels.value && IsTunnelInWay(end_tile, start_z)) { |
|
446 return_cmd_error(STR_5003_ANOTHER_TUNNEL_IN_THE_WAY); |
|
447 } |
|
448 |
|
449 cost += _price.build_tunnel; |
|
450 cost += cost >> 3; // add a multiplier for longer tunnels |
|
451 if (cost >= 400000000) cost = 400000000; |
|
452 } |
|
453 |
|
454 /* Add the cost of the entrance */ |
|
455 cost += _price.build_tunnel + ret; |
|
456 |
|
457 // if the command fails from here on we want the end tile to be highlighted |
|
458 _build_tunnel_endtile = end_tile; |
|
459 |
|
460 // slope of end tile must be complementary to the slope of the start tile |
|
461 if (end_tileh != ComplementSlope(start_tileh)) { |
|
462 ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND); |
|
463 if (CmdFailed(ret)) return_cmd_error(STR_5005_UNABLE_TO_EXCAVATE_LAND); |
|
464 } else { |
|
465 ret = DoCommand(end_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
|
466 if (CmdFailed(ret)) return ret; |
|
467 } |
|
468 cost += _price.build_tunnel + ret; |
|
469 |
|
470 if (flags & DC_EXEC) { |
|
471 if (GB(p1, 9, 1) == TRANSPORT_RAIL) { |
|
472 MakeRailTunnel(start_tile, _current_player, direction, GB(p1, 0, 4)); |
|
473 MakeRailTunnel(end_tile, _current_player, ReverseDiagDir(direction), GB(p1, 0, 4)); |
|
474 UpdateSignalsOnSegment(start_tile, direction); |
|
475 YapfNotifyTrackLayoutChange(start_tile, AxisToTrack(DiagDirToAxis(direction))); |
|
476 } else { |
|
477 MakeRoadTunnel(start_tile, _current_player, direction); |
|
478 MakeRoadTunnel(end_tile, _current_player, ReverseDiagDir(direction)); |
|
479 } |
|
480 } |
|
481 |
|
482 return cost; |
|
483 } |
|
484 |
|
485 TileIndex CheckTunnelBusy(TileIndex tile, uint *length) |
|
486 { |
|
487 uint z = GetTileZ(tile); |
|
488 DiagDirection dir = GetTunnelDirection(tile); |
|
489 TileIndexDiff delta = TileOffsByDiagDir(dir); |
|
490 uint len = 0; |
|
491 TileIndex starttile = tile; |
|
492 Vehicle *v; |
|
493 |
|
494 do { |
|
495 tile += delta; |
|
496 len++; |
|
497 } while ( |
|
498 !IsTunnelTile(tile) || |
|
499 ReverseDiagDir(GetTunnelDirection(tile)) != dir || |
|
500 GetTileZ(tile) != z |
|
501 ); |
|
502 |
|
503 v = FindVehicleBetween(starttile, tile, z); |
|
504 if (v != NULL) { |
|
505 _error_message = v->type == VEH_Train ? |
|
506 STR_5000_TRAIN_IN_TUNNEL : STR_5001_ROAD_VEHICLE_IN_TUNNEL; |
|
507 return INVALID_TILE; |
|
508 } |
|
509 |
|
510 if (length != NULL) *length = len; |
|
511 return tile; |
|
512 } |
|
513 |
|
514 static inline bool CheckAllowRemoveTunnelBridge(TileIndex tile) |
|
515 { |
399 { |
516 /* Floods can remove anything as well as the scenario editor */ |
400 /* Floods can remove anything as well as the scenario editor */ |
517 if (_current_player == OWNER_WATER || _game_mode == GM_EDITOR) return true; |
401 if (_current_player == OWNER_WATER || _game_mode == GM_EDITOR) return true; |
518 /* Obviously if the bridge/tunnel belongs to us, or no-one, we can remove it */ |
402 /* Obviously if the bridge/tunnel belongs to us, or no-one, we can remove it */ |
519 if (CheckTileOwnership(tile) || IsTileOwner(tile, OWNER_NONE)) return true; |
403 if (CheckTileOwnership(tile) || IsTileOwner(tile, OWNER_NONE)) return true; |
520 /* Otherwise we can only remove town-owned stuff with extra patch-settings, or cheat */ |
404 /* Otherwise we can only remove town-owned stuff with extra patch-settings, or cheat */ |
521 if (IsTileOwner(tile, OWNER_TOWN) && (_patches.extra_dynamite || _cheats.magic_bulldozer.value)) return true; |
405 if (IsTileOwner(tile, OWNER_TOWN) && (_patches.extra_dynamite || _cheats.magic_bulldozer.value)) return true; |
522 return false; |
406 return false; |
523 } |
407 } |
524 |
408 |
525 static int32 DoClearTunnel(TileIndex tile, uint32 flags) |
|
526 { |
|
527 Town *t = NULL; |
|
528 TileIndex endtile; |
|
529 uint length; |
|
530 |
|
531 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
|
532 |
|
533 if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR; |
|
534 |
|
535 endtile = CheckTunnelBusy(tile, &length); |
|
536 if (endtile == INVALID_TILE) return CMD_ERROR; |
|
537 |
|
538 _build_tunnel_endtile = endtile; |
|
539 |
|
540 if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR) { |
|
541 t = ClosestTownFromTile(tile, (uint)-1); // town penalty rating |
|
542 |
|
543 /* Check if you are allowed to remove the tunnel owned by a town |
|
544 * Removal depends on difficulty settings */ |
|
545 if (!CheckforTownRating(flags, t, TUNNELBRIDGE_REMOVE)) { |
|
546 SetDParam(0, t->index); |
|
547 return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES); |
|
548 } |
|
549 } |
|
550 |
|
551 if (flags & DC_EXEC) { |
|
552 // We first need to request the direction before calling DoClearSquare |
|
553 // else the direction is always 0.. dah!! ;) |
|
554 DiagDirection dir = GetTunnelDirection(tile); |
|
555 Track track; |
|
556 |
|
557 // Adjust the town's player rating. Do this before removing the tile owner info. |
|
558 if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR) |
|
559 ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM); |
|
560 |
|
561 DoClearSquare(tile); |
|
562 DoClearSquare(endtile); |
|
563 UpdateSignalsOnSegment(tile, ReverseDiagDir(dir)); |
|
564 UpdateSignalsOnSegment(endtile, dir); |
|
565 track = AxisToTrack(DiagDirToAxis(dir)); |
|
566 YapfNotifyTrackLayoutChange(tile, track); |
|
567 YapfNotifyTrackLayoutChange(endtile, track); |
|
568 } |
|
569 return _price.clear_tunnel * (length + 1); |
|
570 } |
|
571 |
|
572 |
|
573 static bool IsVehicleOnBridge(TileIndex starttile, TileIndex endtile, uint z) |
409 static bool IsVehicleOnBridge(TileIndex starttile, TileIndex endtile, uint z) |
574 { |
410 { |
575 const Vehicle *v; |
411 const Vehicle *v; |
576 FOR_ALL_VEHICLES(v) { |
412 FOR_ALL_VEHICLES(v) { |
577 if ((v->tile == starttile || v->tile == endtile) && v->z_pos == z) { |
413 if ((v->tile == starttile || v->tile == endtile) && v->z_pos == z) { |
639 } |
475 } |
640 |
476 |
641 return (DistanceManhattan(tile, endtile) + 1) * _price.clear_bridge; |
477 return (DistanceManhattan(tile, endtile) + 1) * _price.clear_bridge; |
642 } |
478 } |
643 |
479 |
644 static int32 ClearTile_Tunnel(TileIndex tile, byte flags) |
|
645 { |
|
646 assert(IsTunnelTile(tile)); |
|
647 if (flags & DC_AUTO) return_cmd_error(STR_5006_MUST_DEMOLISH_TUNNEL_FIRST); |
|
648 return DoClearTunnel(tile, flags); |
|
649 } |
|
650 |
480 |
651 static int32 ClearTile_Bridge(TileIndex tile, byte flags) |
481 static int32 ClearTile_Bridge(TileIndex tile, byte flags) |
652 { |
482 { |
653 assert(IsBridgeTile(tile)); |
483 assert(IsBridgeTile(tile)); |
654 if (flags & DC_AUTO) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); |
484 if (flags & DC_AUTO) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); |
655 return DoClearBridge(tile, flags); |
485 return DoClearBridge(tile, flags); |
656 } |
486 } |
657 |
487 |
658 int32 DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec) |
488 int32 DoConvertBridgeRail(TileIndex tile, RailType totype, bool exec) |
659 { |
489 { |
660 TileIndex endtile; |
490 TileIndex endtile; |
661 |
491 |
662 if (IsTunnelTile(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) { |
492 if (GetBridgeTransportType(tile) == TRANSPORT_RAIL) { |
663 uint length; |
|
664 |
|
665 if (!CheckTileOwnership(tile)) return CMD_ERROR; |
|
666 |
|
667 if (GetRailType(tile) == totype) return CMD_ERROR; |
|
668 |
|
669 // 'hidden' elrails can't be downgraded to normal rail when elrails are disabled |
|
670 if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR; |
|
671 |
|
672 endtile = CheckTunnelBusy(tile, &length); |
|
673 if (endtile == INVALID_TILE) return CMD_ERROR; |
|
674 |
|
675 if (exec) { |
|
676 Track track; |
|
677 SetRailType(tile, totype); |
|
678 SetRailType(endtile, totype); |
|
679 MarkTileDirtyByTile(tile); |
|
680 MarkTileDirtyByTile(endtile); |
|
681 |
|
682 track = AxisToTrack(DiagDirToAxis(GetTunnelDirection(tile))); |
|
683 YapfNotifyTrackLayoutChange(tile, track); |
|
684 YapfNotifyTrackLayoutChange(endtile, track); |
|
685 } |
|
686 return (length + 1) * (_price.build_rail >> 1); |
|
687 } else if (IsBridgeTile(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) { |
|
688 |
|
689 if (!CheckTileOwnership(tile)) return CMD_ERROR; |
493 if (!CheckTileOwnership(tile)) return CMD_ERROR; |
690 |
494 |
691 endtile = GetOtherBridgeEnd(tile); |
495 endtile = GetOtherBridgeEnd(tile); |
692 |
496 |
693 if (!EnsureNoVehicle(tile) || |
497 if (!EnsureNoVehicle(tile) || |
992 if (v->cur_speed > bridge_speed) v->cur_speed = bridge_speed; |
773 if (v->cur_speed > bridge_speed) v->cur_speed = bridge_speed; |
993 return bridge_speed; |
774 return bridge_speed; |
994 } |
775 } |
995 |
776 |
996 |
777 |
997 /** Gets the absolute z coordinate of a point inside a tunnel tile |
|
998 * When we're on the track (that means between position 5 and 10) |
|
999 * on the coordinate perpendicular to the track it returns only the |
|
1000 * base height of the tile (because the track is horizontal). |
|
1001 * Outside this range (from 0 to 4 and from 11 to 15) it returns the |
|
1002 * "true" Z coordinate of the tile by taking the slope into account |
|
1003 * @param tile The index of the tile we are talking about |
|
1004 * @param x Absolute or relative x coordinate |
|
1005 * @param y Absolute or relative y coordinate |
|
1006 * @return Absolute z coordinate |
|
1007 */ |
|
1008 static uint GetSlopeZ_Tunnel(TileIndex tile, uint x, uint y) |
|
1009 { |
|
1010 uint z, pos; |
|
1011 Slope tileh = GetTileSlope(tile, &z); |
|
1012 |
|
1013 x &= 0xF; |
|
1014 y &= 0xF; |
|
1015 |
|
1016 pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x); |
|
1017 |
|
1018 // In the tunnel entrance? |
|
1019 if (5 <= pos && pos <= 10) return z; |
|
1020 |
|
1021 return z + GetPartialZ(x, y, tileh); |
|
1022 } |
|
1023 |
|
1024 /** Gets the absolute z coordinate of a point inside a bridge tile |
778 /** Gets the absolute z coordinate of a point inside a bridge tile |
1025 * When we're on the track (that means between position 5 and 10) |
779 * When we're on the track (that means between position 5 and 10) |
1026 * on the coordinate perpendicular to the track it returns the base |
780 * on the coordinate perpendicular to the track it returns the base |
1027 * height of the ramp |
781 * height of the ramp |
1028 * Outside this range (from 0 to 4 and from 11 to 15) it returns the |
782 * Outside this range (from 0 to 4 and from 11 to 15) it returns the |
1133 STR_5028_TUBULAR_ROAD_BRIDGE, |
877 STR_5028_TUBULAR_ROAD_BRIDGE, |
1134 STR_5028_TUBULAR_ROAD_BRIDGE, |
878 STR_5028_TUBULAR_ROAD_BRIDGE, |
1135 0, 0, 0, |
879 0, 0, 0, |
1136 }; |
880 }; |
1137 |
881 |
1138 static void GetTileDesc_Tunnel(TileIndex tile, TileDesc *td) |
|
1139 { |
|
1140 td->str = (GetTunnelTransportType(tile) == TRANSPORT_RAIL) ? STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL; |
|
1141 td->owner = GetTileOwner(tile); |
|
1142 } |
|
1143 |
|
1144 static void GetTileDesc_Bridge(TileIndex tile, TileDesc *td) |
882 static void GetTileDesc_Bridge(TileIndex tile, TileDesc *td) |
1145 { |
883 { |
1146 td->str = _bridge_tile_str[GetBridgeTransportType(tile) << 4 | GetBridgeType(tile)]; |
884 td->str = _bridge_tile_str[GetBridgeTransportType(tile) << 4 | GetBridgeType(tile)]; |
1147 td->owner = GetTileOwner(tile); |
885 td->owner = GetTileOwner(tile); |
1148 } |
886 } |
1149 |
887 |
1150 |
888 |
1151 static void AnimateTile_Tunnel(TileIndex tile) |
889 static void AnimateTile_Bridge(TileIndex tile) |
1152 { |
890 { |
1153 /* not used */ |
891 /* not used */ |
1154 } |
892 } |
1155 |
893 |
1156 static void AnimateTile_Bridge(TileIndex tile) |
|
1157 { |
|
1158 /* not used */ |
|
1159 } |
|
1160 |
|
1161 static void TileLoop_Tunnel(TileIndex tile) |
|
1162 { |
|
1163 bool snow_or_desert = HasTunnelSnowOrDesert(tile); |
|
1164 switch (_opt.landscape) { |
|
1165 case LT_HILLY: |
|
1166 if (snow_or_desert != (GetTileZ(tile) > _opt.snow_line)) { |
|
1167 SetTunnelSnowOrDesert(tile, !snow_or_desert); |
|
1168 MarkTileDirtyByTile(tile); |
|
1169 } |
|
1170 break; |
|
1171 |
|
1172 case LT_DESERT: |
|
1173 if (GetTropicZone(tile) == TROPICZONE_DESERT && !snow_or_desert) { |
|
1174 SetTunnelSnowOrDesert(tile, true); |
|
1175 MarkTileDirtyByTile(tile); |
|
1176 } |
|
1177 break; |
|
1178 } |
|
1179 } |
|
1180 |
894 |
1181 static void TileLoop_Bridge(TileIndex tile) |
895 static void TileLoop_Bridge(TileIndex tile) |
1182 { |
896 { |
1183 bool snow_or_desert = HasBridgeSnowOrDesert(tile); |
897 bool snow_or_desert = HasBridgeSnowOrDesert(tile); |
1184 switch (_opt.landscape) { |
898 switch (_opt.landscape) { |
1196 } |
910 } |
1197 break; |
911 break; |
1198 } |
912 } |
1199 } |
913 } |
1200 |
914 |
1201 static void ClickTile_Tunnel(TileIndex tile) |
915 static void ClickTile_Bridge(TileIndex tile) |
1202 { |
916 { |
1203 /* not used */ |
917 /* not used */ |
1204 } |
918 } |
1205 |
919 |
1206 static void ClickTile_Bridge(TileIndex tile) |
|
1207 { |
|
1208 /* not used */ |
|
1209 } |
|
1210 |
|
1211 |
|
1212 static uint32 GetTileTrackStatus_Tunnel(TileIndex tile, TransportType mode) |
|
1213 { |
|
1214 if (GetTunnelTransportType(tile) != mode) return 0; |
|
1215 return AxisToTrackBits(DiagDirToAxis(GetTunnelDirection(tile))) * 0x101; |
|
1216 } |
|
1217 |
920 |
1218 static uint32 GetTileTrackStatus_Bridge(TileIndex tile, TransportType mode) |
921 static uint32 GetTileTrackStatus_Bridge(TileIndex tile, TransportType mode) |
1219 { |
922 { |
1220 if (GetBridgeTransportType(tile) != mode) return 0; |
923 if (GetBridgeTransportType(tile) != mode) return 0; |
1221 return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(tile))) * 0x101; |
924 return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(tile))) * 0x101; |
1222 } |
925 } |
1223 |
926 |
1224 static void ChangeTileOwner_Tunnel(TileIndex tile, PlayerID old_player, PlayerID new_player) |
927 |
|
928 static void ChangeTileOwner_Bridge(TileIndex tile, PlayerID old_player, PlayerID new_player) |
1225 { |
929 { |
1226 if (!IsTileOwner(tile, old_player)) return; |
930 if (!IsTileOwner(tile, old_player)) return; |
1227 |
931 |
1228 if (new_player != PLAYER_SPECTATOR) { |
932 if (new_player != PLAYER_SPECTATOR) { |
1229 SetTileOwner(tile, new_player); |
933 SetTileOwner(tile, new_player); |
1230 } else { |
934 } else { |
1231 DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); |
935 DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); |
1232 } |
936 } |
1233 } |
937 } |
1234 |
938 |
1235 static void ChangeTileOwner_Bridge(TileIndex tile, PlayerID old_player, PlayerID new_player) |
|
1236 { |
|
1237 if (!IsTileOwner(tile, old_player)) return; |
|
1238 |
|
1239 if (new_player != PLAYER_SPECTATOR) { |
|
1240 SetTileOwner(tile, new_player); |
|
1241 } else { |
|
1242 DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); |
|
1243 } |
|
1244 } |
|
1245 |
|
1246 |
|
1247 static const byte _tunnel_fractcoord_1[4] = {0x8E, 0x18, 0x81, 0xE8}; |
|
1248 static const byte _tunnel_fractcoord_2[4] = {0x81, 0x98, 0x87, 0x38}; |
|
1249 static const byte _tunnel_fractcoord_3[4] = {0x82, 0x88, 0x86, 0x48}; |
|
1250 static const byte _exit_tunnel_track[4] = {1, 2, 1, 2}; |
|
1251 |
|
1252 static const byte _road_exit_tunnel_state[4] = {8, 9, 0, 1}; |
|
1253 static const byte _road_exit_tunnel_frame[4] = {2, 7, 9, 4}; |
|
1254 |
|
1255 static const byte _tunnel_fractcoord_4[4] = {0x52, 0x85, 0x98, 0x29}; |
|
1256 static const byte _tunnel_fractcoord_5[4] = {0x92, 0x89, 0x58, 0x25}; |
|
1257 static const byte _tunnel_fractcoord_6[4] = {0x92, 0x89, 0x56, 0x45}; |
|
1258 static const byte _tunnel_fractcoord_7[4] = {0x52, 0x85, 0x96, 0x49}; |
|
1259 |
|
1260 static uint32 VehicleEnter_Tunnel(Vehicle *v, TileIndex tile, int x, int y) |
|
1261 { |
|
1262 int z = GetSlopeZ(x, y) - v->z_pos; |
|
1263 |
|
1264 byte fc; |
|
1265 DiagDirection dir; |
|
1266 DiagDirection vdir; |
|
1267 |
|
1268 if (myabs(z) > 2) return 8; |
|
1269 |
|
1270 if (v->type == VEH_Train) { |
|
1271 fc = (x & 0xF) + (y << 4); |
|
1272 |
|
1273 dir = GetTunnelDirection(tile); |
|
1274 vdir = DirToDiagDir(v->direction); |
|
1275 |
|
1276 if (v->u.rail.track != 0x40 && dir == vdir) { |
|
1277 if (IsFrontEngine(v) && fc == _tunnel_fractcoord_1[dir]) { |
|
1278 if (!PlayVehicleSound(v, VSE_TUNNEL) && v->spritenum < 4) { |
|
1279 SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v); |
|
1280 } |
|
1281 return 0; |
|
1282 } |
|
1283 if (fc == _tunnel_fractcoord_2[dir]) { |
|
1284 v->tile = tile; |
|
1285 v->u.rail.track = 0x40; |
|
1286 v->vehstatus |= VS_HIDDEN; |
|
1287 return 4; |
|
1288 } |
|
1289 } |
|
1290 |
|
1291 if (dir == ReverseDiagDir(vdir) && fc == _tunnel_fractcoord_3[dir] && z == 0) { |
|
1292 /* We're at the tunnel exit ?? */ |
|
1293 v->tile = tile; |
|
1294 v->u.rail.track = _exit_tunnel_track[dir]; |
|
1295 assert(v->u.rail.track); |
|
1296 v->vehstatus &= ~VS_HIDDEN; |
|
1297 return 4; |
|
1298 } |
|
1299 } else if (v->type == VEH_Road) { |
|
1300 fc = (x & 0xF) + (y << 4); |
|
1301 dir = GetTunnelDirection(tile); |
|
1302 vdir = DirToDiagDir(v->direction); |
|
1303 |
|
1304 // Enter tunnel? |
|
1305 if (v->u.road.state != 0xFF && dir == vdir) { |
|
1306 if (fc == _tunnel_fractcoord_4[dir] || |
|
1307 fc == _tunnel_fractcoord_5[dir]) { |
|
1308 v->tile = tile; |
|
1309 v->u.road.state = 0xFF; |
|
1310 v->vehstatus |= VS_HIDDEN; |
|
1311 return 4; |
|
1312 } else { |
|
1313 return 0; |
|
1314 } |
|
1315 } |
|
1316 |
|
1317 if (dir == ReverseDiagDir(vdir) && ( |
|
1318 /* We're at the tunnel exit ?? */ |
|
1319 fc == _tunnel_fractcoord_6[dir] || |
|
1320 fc == _tunnel_fractcoord_7[dir] |
|
1321 ) && |
|
1322 z == 0) { |
|
1323 v->tile = tile; |
|
1324 v->u.road.state = _road_exit_tunnel_state[dir]; |
|
1325 v->u.road.frame = _road_exit_tunnel_frame[dir]; |
|
1326 v->vehstatus &= ~VS_HIDDEN; |
|
1327 return 4; |
|
1328 } |
|
1329 } |
|
1330 return 0; |
|
1331 } |
|
1332 |
939 |
1333 static uint32 VehicleEnter_Bridge(Vehicle *v, TileIndex tile, int x, int y) |
940 static uint32 VehicleEnter_Bridge(Vehicle *v, TileIndex tile, int x, int y) |
1334 { |
941 { |
1335 int z = GetSlopeZ(x, y) - v->z_pos; |
942 int z = GetSlopeZ(x, y) - v->z_pos; |
1336 |
943 |
1370 v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? 1 : 2); |
977 v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? 1 : 2); |
1371 return 4; |
978 return 4; |
1372 } |
979 } |
1373 } else { |
980 } else { |
1374 if (v->u.road.state == 0xFF) { |
981 if (v->u.road.state == 0xFF) { |
1375 v->u.road.state = _road_exit_tunnel_state[dir]; |
982 static const byte road_exit_bridge_state[4] = {8, 9, 0, 1}; |
|
983 v->u.road.state = road_exit_bridge_state[dir]; |
1376 v->u.road.frame = 0; |
984 v->u.road.frame = 0; |
1377 return 4; |
985 return 4; |
1378 } |
986 } |
1379 } |
987 } |
1380 return 0; |
988 return 0; |
1381 } |
989 } |
1382 return 0; |
990 return 0; |
1383 } |
991 } |
1384 |
|
1385 const TileTypeProcs _tile_type_tunnel_procs = { |
|
1386 DrawTile_Tunnel, /* draw_tile_proc */ |
|
1387 GetSlopeZ_Tunnel, /* get_slope_z_proc */ |
|
1388 ClearTile_Tunnel, /* clear_tile_proc */ |
|
1389 GetAcceptedCargo_Tunnel, /* get_accepted_cargo_proc */ |
|
1390 GetTileDesc_Tunnel, /* get_tile_desc_proc */ |
|
1391 GetTileTrackStatus_Tunnel, /* get_tile_track_status_proc */ |
|
1392 ClickTile_Tunnel, /* click_tile_proc */ |
|
1393 AnimateTile_Tunnel, /* animate_tile_proc */ |
|
1394 TileLoop_Tunnel, /* tile_loop_clear */ |
|
1395 ChangeTileOwner_Tunnel, /* change_tile_owner_clear */ |
|
1396 NULL, /* get_produced_cargo_proc */ |
|
1397 VehicleEnter_Tunnel, /* vehicle_enter_tile_proc */ |
|
1398 GetSlopeTileh_Tunnel, /* get_slope_tileh_proc */ |
|
1399 }; |
|
1400 |
992 |
1401 const TileTypeProcs _tile_type_bridge_procs = { |
993 const TileTypeProcs _tile_type_bridge_procs = { |
1402 DrawTile_Bridge, /* draw_tile_proc */ |
994 DrawTile_Bridge, /* draw_tile_proc */ |
1403 GetSlopeZ_Bridge, /* get_slope_z_proc */ |
995 GetSlopeZ_Bridge, /* get_slope_z_proc */ |
1404 ClearTile_Bridge, /* clear_tile_proc */ |
996 ClearTile_Bridge, /* clear_tile_proc */ |