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 |
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 } |