785 if (axis != AXIS_X) ++i; |
786 if (axis != AXIS_X) ++i; |
786 return i + 15; |
787 return i + 15; |
787 } |
788 } |
788 |
789 |
789 /** |
790 /** |
790 * Draws a tunnel of bridge tile. |
791 * Draws a tunnel tile. |
791 * For tunnels, this is rather simple, as you only needa draw the entrance. |
792 * Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3 |
792 * Bridges are a bit more complex. base_offset is where the sprite selection comes into play |
793 */ |
|
794 static void DrawTile_Tunnel(TileInfo *ti) |
|
795 { |
|
796 uint32 image; |
|
797 |
|
798 if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL) { |
|
799 image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.tunnel; |
|
800 } else { |
|
801 image = SPR_TUNNEL_ENTRY_REAR_ROAD; |
|
802 } |
|
803 |
|
804 if (HasTunnelSnowOrDesert(ti->tile)) image += 32; |
|
805 |
|
806 image += GetTunnelDirection(ti->tile) * 2; |
|
807 DrawGroundSprite(image); |
|
808 if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); |
|
809 |
|
810 AddSortableSpriteToDraw(image+1, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, 1, 1, 8, (byte)ti->z); |
|
811 DrawBridgeMiddle(ti); |
|
812 } |
|
813 |
|
814 /** |
|
815 * Draws a bridge tile. |
|
816 * base_offset is where the sprite selection comes into play |
793 * and it works a bit like a bitmask.<p> For bridge heads: |
817 * and it works a bit like a bitmask.<p> For bridge heads: |
794 * <ul><li>Bit 0: direction</li> |
818 * <ul><li>Bit 0: direction</li> |
795 * <li>Bit 1: northern or southern heads</li> |
819 * <li>Bit 1: northern or southern heads</li> |
796 * <li>Bit 2: Set if the bridge head is sloped</li> |
820 * <li>Bit 2: Set if the bridge head is sloped</li> |
797 * <li>Bit 3 and more: Railtype Specific subset</li> |
821 * <li>Bit 3 and more: Railtype Specific subset</li> |
798 * </ul> |
822 * </ul> |
799 * Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3 |
823 * Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3 |
800 */ |
824 */ |
801 static void DrawTile_TunnelBridge(TileInfo *ti) |
825 static void DrawTile_Bridge(TileInfo *ti) |
802 { |
826 { |
803 uint32 image; |
827 uint32 image; |
804 |
828 |
805 if (IsTunnelTile(ti->tile)) { |
829 int base_offset; |
806 if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL) { |
830 bool ice = HasBridgeSnowOrDesert(ti->tile); |
807 image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.tunnel; |
831 |
808 } else { |
832 if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) { |
809 image = SPR_TUNNEL_ENTRY_REAR_ROAD; |
833 base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset; |
810 } |
834 assert(base_offset != 8); /* This one is used for roads */ |
811 |
835 } else { |
812 if (HasTunnelSnowOrDesert(ti->tile)) image += 32; |
836 base_offset = 8; |
813 |
837 } |
814 image += GetTunnelDirection(ti->tile) * 2; |
838 |
815 DrawGroundSprite(image); |
839 /* as the lower 3 bits are used for other stuff, make sure they are clear */ |
816 if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); |
840 assert( (base_offset & 0x07) == 0x00); |
817 |
841 |
818 AddSortableSpriteToDraw(image+1, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, 1, 1, 8, (byte)ti->z); |
842 if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) { |
819 DrawBridgeMiddle(ti); |
843 int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile))); |
820 } else if (IsBridgeTile(ti->tile)) { // XXX is this necessary? |
844 if (f != 0) DrawFoundation(ti, f); |
821 int base_offset; |
845 } |
822 bool ice = HasBridgeSnowOrDesert(ti->tile); |
846 |
823 |
847 // HACK Wizardry to convert the bridge ramp direction into a sprite offset |
824 if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) { |
848 base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4; |
825 base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset; |
849 |
826 assert(base_offset != 8); /* This one is used for roads */ |
850 if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head |
827 } else { |
851 |
828 base_offset = 8; |
852 /* Table number 6 always refers to the bridge heads for any bridge type */ |
829 } |
853 image = GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset]; |
830 |
854 |
831 /* as the lower 3 bits are used for other stuff, make sure they are clear */ |
855 if (!ice) { |
832 assert( (base_offset & 0x07) == 0x00); |
856 DrawClearLandTile(ti, 3); |
833 |
857 } else { |
834 if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) { |
858 DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh]); |
835 int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile))); |
859 } |
836 if (f != 0) DrawFoundation(ti, f); |
860 |
837 } |
861 if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); |
838 |
862 |
839 // HACK Wizardry to convert the bridge ramp direction into a sprite offset |
863 // draw ramp |
840 base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4; |
864 if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image); |
841 |
865 /* HACK set the height of the BB of a sloped ramp to 1 so a vehicle on |
842 if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head |
866 * it doesn't disappear behind it |
843 |
867 */ |
844 /* Table number 6 always refers to the bridge heads for any bridge type */ |
868 AddSortableSpriteToDraw( |
845 image = GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset]; |
869 image, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 1 : 8, ti->z |
846 |
870 ); |
847 if (!ice) { |
871 |
848 DrawClearLandTile(ti, 3); |
872 DrawBridgeMiddle(ti); |
849 } else { |
|
850 DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh]); |
|
851 } |
|
852 |
|
853 if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti); |
|
854 |
|
855 // draw ramp |
|
856 if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image); |
|
857 /* HACK set the height of the BB of a sloped ramp to 1 so a vehicle on |
|
858 * it doesn't disappear behind it |
|
859 */ |
|
860 AddSortableSpriteToDraw( |
|
861 image, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 1 : 8, ti->z |
|
862 ); |
|
863 |
|
864 DrawBridgeMiddle(ti); |
|
865 } |
|
866 } |
873 } |
867 |
874 |
868 |
875 |
869 /** Compute bridge piece. Computes the bridge piece to display depending on the position inside the bridge. |
876 /** Compute bridge piece. Computes the bridge piece to display depending on the position inside the bridge. |
870 * bridges pieces sequence (middle parts) |
877 * bridges pieces sequence (middle parts) |
985 if (v->cur_speed > bridge_speed) v->cur_speed = bridge_speed; |
992 if (v->cur_speed > bridge_speed) v->cur_speed = bridge_speed; |
986 return bridge_speed; |
993 return bridge_speed; |
987 } |
994 } |
988 |
995 |
989 |
996 |
990 |
997 /** Gets the absolute z coordinate of a point inside a tunnel tile |
991 static uint GetSlopeZ_TunnelBridge(TileIndex tile, uint x, uint y) |
998 * When we're on the track (that means between position 5 and 10) |
992 { |
999 * on the coordinate perpendicular to the track it returns only the |
993 uint z; |
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; |
994 Slope tileh = GetTileSlope(tile, &z); |
1011 Slope tileh = GetTileSlope(tile, &z); |
995 |
1012 |
996 x &= 0xF; |
1013 x &= 0xF; |
997 y &= 0xF; |
1014 y &= 0xF; |
998 |
1015 |
999 if (IsTunnelTile(tile)) { |
1016 pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x); |
1000 uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x); |
1017 |
1001 |
1018 // In the tunnel entrance? |
1002 // In the tunnel entrance? |
1019 if (5 <= pos && pos <= 10) return z; |
1003 if (5 <= pos && pos <= 10) return z; |
1020 |
1004 } else { |
1021 return z + GetPartialZ(x, y, tileh); |
1005 DiagDirection dir = GetBridgeRampDirection(tile); |
1022 } |
1006 uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x); |
1023 |
1007 |
1024 /** Gets the absolute z coordinate of a point inside a bridge tile |
1008 // On the bridge ramp? |
1025 * When we're on the track (that means between position 5 and 10) |
1009 if (5 <= pos && pos <= 10) { |
1026 * on the coordinate perpendicular to the track it returns the base |
1010 uint delta; |
1027 * height of the ramp |
1011 |
1028 * Outside this range (from 0 to 4 and from 11 to 15) it returns the |
1012 if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2; |
1029 * "true" Z coordinate of the tile by taking the slope into account |
1013 if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT; |
1030 * @param tile The index of the tile we are talking about |
1014 |
1031 * @param x Absolute or relative x coordinate |
1015 if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) z += TILE_HEIGHT; |
1032 * @param y Absolute or relative y coordinate |
1016 switch (dir) { |
1033 * @return Absolute z coordinate |
1017 default: NOT_REACHED(); |
1034 */ |
1018 case DIAGDIR_NE: delta = (TILE_SIZE - 1 - x) / 2; break; |
1035 static uint GetSlopeZ_Bridge(TileIndex tile, uint x, uint y) |
1019 case DIAGDIR_SE: delta = y / 2; break; |
1036 { |
1020 case DIAGDIR_SW: delta = x / 2; break; |
1037 uint z, pos; |
1021 case DIAGDIR_NW: delta = (TILE_SIZE - 1 - y) / 2; break; |
1038 Slope tileh = GetTileSlope(tile, &z); |
|
1039 DiagDirection dir = GetBridgeRampDirection(tile); |
|
1040 |
|
1041 x &= 0xF; |
|
1042 y &= 0xF; |
|
1043 |
|
1044 pos = (DiagDirToAxis(dir) == AXIS_X ? y : x); |
|
1045 |
|
1046 // On the bridge ramp? |
|
1047 if (5 <= pos && pos <= 10) { |
|
1048 uint delta; |
|
1049 |
|
1050 if (IsSteepSlope(tileh)) return z + TILE_HEIGHT * 2; |
|
1051 |
|
1052 if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT; |
|
1053 |
|
1054 if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) z += TILE_HEIGHT; |
|
1055 switch (dir) { |
|
1056 default: NOT_REACHED(); |
|
1057 case DIAGDIR_NE: delta = (TILE_SIZE - 1 - x) / 2; break; |
|
1058 case DIAGDIR_SE: delta = y / 2; break; |
|
1059 case DIAGDIR_SW: delta = x / 2; break; |
|
1060 case DIAGDIR_NW: delta = (TILE_SIZE - 1 - y) / 2; break; |
|
1061 } |
|
1062 return z + 1 + delta; |
|
1063 } else { |
|
1064 uint f = GetBridgeFoundation(tileh, DiagDirToAxis(dir)); |
|
1065 |
|
1066 if (f != 0) { |
|
1067 if (IsSteepSlope(tileh)) { |
|
1068 z += TILE_HEIGHT; |
|
1069 } else if (f < 15) { |
|
1070 return z + TILE_HEIGHT; |
1022 } |
1071 } |
1023 return z + 1 + delta; |
1072 tileh = _inclined_tileh[f - 15]; |
1024 } else { |
1073 } |
1025 uint f = GetBridgeFoundation(tileh, DiagDirToAxis(dir)); |
1074 } |
1026 |
|
1027 if (f != 0) { |
|
1028 if (IsSteepSlope(tileh)) { |
|
1029 z += TILE_HEIGHT; |
|
1030 } else if (f < 15) { |
|
1031 return z + TILE_HEIGHT; |
|
1032 } |
|
1033 tileh = _inclined_tileh[f - 15]; |
|
1034 } |
|
1035 } |
|
1036 } |
|
1037 |
|
1038 return z + GetPartialZ(x, y, tileh); |
1075 return z + GetPartialZ(x, y, tileh); |
1039 } |
1076 } |
1040 |
1077 |
1041 static Slope GetSlopeTileh_TunnelBridge(TileIndex tile, Slope tileh) |
1078 static Slope GetSlopeTileh_Tunnel(TileIndex tile, Slope tileh) |
1042 { |
1079 { |
1043 if (IsTunnelTile(tile)) { |
1080 return tileh; |
|
1081 } |
|
1082 |
|
1083 static Slope GetSlopeTileh_Bridge(TileIndex tile, Slope tileh) |
|
1084 { |
|
1085 if (HASBIT(BRIDGE_NO_FOUNDATION, tileh)) { |
1044 return tileh; |
1086 return tileh; |
1045 } else { |
1087 } else { |
1046 if (HASBIT(BRIDGE_NO_FOUNDATION, tileh)) { |
1088 uint f = GetBridgeFoundation(tileh, DiagDirToAxis(GetBridgeRampDirection(tile))); |
1047 return tileh; |
1089 |
1048 } else { |
1090 if (f == 0) return tileh; |
1049 uint f = GetBridgeFoundation(tileh, DiagDirToAxis(GetBridgeRampDirection(tile))); |
1091 if (f < 15) return SLOPE_FLAT; |
1050 |
1092 return _inclined_tileh[f - 15]; |
1051 if (f == 0) return tileh; |
1093 } |
1052 if (f < 15) return SLOPE_FLAT; |
1094 } |
1053 return _inclined_tileh[f - 15]; |
1095 |
1054 } |
1096 static void GetAcceptedCargo_Tunnel(TileIndex tile, AcceptedCargo ac) |
1055 } |
1097 { |
1056 } |
1098 /* not used */ |
1057 |
1099 } |
1058 |
1100 |
1059 static void GetAcceptedCargo_TunnelBridge(TileIndex tile, AcceptedCargo ac) |
1101 static void GetAcceptedCargo_Bridge(TileIndex tile, AcceptedCargo ac) |
1060 { |
1102 { |
1061 /* not used */ |
1103 /* not used */ |
1062 } |
1104 } |
1063 |
1105 |
1064 static const StringID _bridge_tile_str[(MAX_BRIDGES + 3) + (MAX_BRIDGES + 3)] = { |
1106 static const StringID _bridge_tile_str[(MAX_BRIDGES + 3) + (MAX_BRIDGES + 3)] = { |
1091 STR_5028_TUBULAR_ROAD_BRIDGE, |
1133 STR_5028_TUBULAR_ROAD_BRIDGE, |
1092 STR_5028_TUBULAR_ROAD_BRIDGE, |
1134 STR_5028_TUBULAR_ROAD_BRIDGE, |
1093 0, 0, 0, |
1135 0, 0, 0, |
1094 }; |
1136 }; |
1095 |
1137 |
1096 static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td) |
1138 static void GetTileDesc_Tunnel(TileIndex tile, TileDesc *td) |
1097 { |
1139 { |
1098 if (IsTunnelTile(tile)) { |
1140 td->str = (GetTunnelTransportType(tile) == TRANSPORT_RAIL) ? STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL; |
1099 td->str = (GetTunnelTransportType(tile) == TRANSPORT_RAIL) ? |
|
1100 STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL; |
|
1101 } else { |
|
1102 td->str = _bridge_tile_str[GetBridgeTransportType(tile) << 4 | GetBridgeType(tile)]; |
|
1103 } |
|
1104 td->owner = GetTileOwner(tile); |
1141 td->owner = GetTileOwner(tile); |
1105 } |
1142 } |
1106 |
1143 |
1107 |
1144 static void GetTileDesc_Bridge(TileIndex tile, TileDesc *td) |
1108 static void AnimateTile_TunnelBridge(TileIndex tile) |
1145 { |
|
1146 td->str = _bridge_tile_str[GetBridgeTransportType(tile) << 4 | GetBridgeType(tile)]; |
|
1147 td->owner = GetTileOwner(tile); |
|
1148 } |
|
1149 |
|
1150 |
|
1151 static void AnimateTile_Tunnel(TileIndex tile) |
1109 { |
1152 { |
1110 /* not used */ |
1153 /* not used */ |
1111 } |
1154 } |
1112 |
1155 |
1113 static void TileLoop_TunnelBridge(TileIndex tile) |
1156 static void AnimateTile_Bridge(TileIndex tile) |
1114 { |
1157 { |
1115 bool snow_or_desert = IsTunnelTile(tile) ? HasTunnelSnowOrDesert(tile) : HasBridgeSnowOrDesert(tile); |
1158 /* not used */ |
|
1159 } |
|
1160 |
|
1161 static void TileLoop_Tunnel(TileIndex tile) |
|
1162 { |
|
1163 bool snow_or_desert = HasTunnelSnowOrDesert(tile); |
1116 switch (_opt.landscape) { |
1164 switch (_opt.landscape) { |
1117 case LT_HILLY: |
1165 case LT_HILLY: |
1118 if (snow_or_desert != (GetTileZ(tile) > _opt.snow_line)) { |
1166 if (snow_or_desert != (GetTileZ(tile) > _opt.snow_line)) { |
1119 if (IsTunnelTile(tile)) { |
1167 SetTunnelSnowOrDesert(tile, !snow_or_desert); |
1120 SetTunnelSnowOrDesert(tile, !snow_or_desert); |
|
1121 } else { |
|
1122 SetBridgeSnowOrDesert(tile, !snow_or_desert); |
|
1123 } |
|
1124 MarkTileDirtyByTile(tile); |
1168 MarkTileDirtyByTile(tile); |
1125 } |
1169 } |
1126 break; |
1170 break; |
1127 |
1171 |
1128 case LT_DESERT: |
1172 case LT_DESERT: |
1129 if (GetTropicZone(tile) == TROPICZONE_DESERT && !snow_or_desert) { |
1173 if (GetTropicZone(tile) == TROPICZONE_DESERT && !snow_or_desert) { |
1130 if (IsTunnelTile(tile)) { |
1174 SetTunnelSnowOrDesert(tile, true); |
1131 SetTunnelSnowOrDesert(tile, true); |
|
1132 } else { |
|
1133 SetBridgeSnowOrDesert(tile, true); |
|
1134 } |
|
1135 MarkTileDirtyByTile(tile); |
1175 MarkTileDirtyByTile(tile); |
1136 } |
1176 } |
1137 break; |
1177 break; |
1138 } |
1178 } |
1139 } |
1179 } |
1140 |
1180 |
1141 static void ClickTile_TunnelBridge(TileIndex tile) |
1181 static void TileLoop_Bridge(TileIndex tile) |
|
1182 { |
|
1183 bool snow_or_desert = HasBridgeSnowOrDesert(tile); |
|
1184 switch (_opt.landscape) { |
|
1185 case LT_HILLY: |
|
1186 if (snow_or_desert != (GetTileZ(tile) > _opt.snow_line)) { |
|
1187 SetBridgeSnowOrDesert(tile, !snow_or_desert); |
|
1188 MarkTileDirtyByTile(tile); |
|
1189 } |
|
1190 break; |
|
1191 |
|
1192 case LT_DESERT: |
|
1193 if (GetTropicZone(tile) == TROPICZONE_DESERT && !snow_or_desert) { |
|
1194 SetBridgeSnowOrDesert(tile, true); |
|
1195 MarkTileDirtyByTile(tile); |
|
1196 } |
|
1197 break; |
|
1198 } |
|
1199 } |
|
1200 |
|
1201 static void ClickTile_Tunnel(TileIndex tile) |
1142 { |
1202 { |
1143 /* not used */ |
1203 /* not used */ |
1144 } |
1204 } |
1145 |
1205 |
1146 |
1206 static void ClickTile_Bridge(TileIndex tile) |
1147 static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode) |
1207 { |
1148 { |
1208 /* not used */ |
1149 if (IsTunnelTile(tile)) { |
1209 } |
1150 if (GetTunnelTransportType(tile) != mode) return 0; |
1210 |
1151 return AxisToTrackBits(DiagDirToAxis(GetTunnelDirection(tile))) * 0x101; |
1211 |
1152 } else { |
1212 static uint32 GetTileTrackStatus_Tunnel(TileIndex tile, TransportType mode) |
1153 if (GetBridgeTransportType(tile) != mode) return 0; |
1213 { |
1154 return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(tile))) * 0x101; |
1214 if (GetTunnelTransportType(tile) != mode) return 0; |
1155 } |
1215 return AxisToTrackBits(DiagDirToAxis(GetTunnelDirection(tile))) * 0x101; |
1156 } |
1216 } |
1157 |
1217 |
1158 static void ChangeTileOwner_TunnelBridge(TileIndex tile, PlayerID old_player, PlayerID new_player) |
1218 static uint32 GetTileTrackStatus_Bridge(TileIndex tile, TransportType mode) |
|
1219 { |
|
1220 if (GetBridgeTransportType(tile) != mode) return 0; |
|
1221 return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(tile))) * 0x101; |
|
1222 } |
|
1223 |
|
1224 static void ChangeTileOwner_Tunnel(TileIndex tile, PlayerID old_player, PlayerID new_player) |
|
1225 { |
|
1226 if (!IsTileOwner(tile, old_player)) return; |
|
1227 |
|
1228 if (new_player != PLAYER_SPECTATOR) { |
|
1229 SetTileOwner(tile, new_player); |
|
1230 } else { |
|
1231 DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); |
|
1232 } |
|
1233 } |
|
1234 |
|
1235 static void ChangeTileOwner_Bridge(TileIndex tile, PlayerID old_player, PlayerID new_player) |
1159 { |
1236 { |
1160 if (!IsTileOwner(tile, old_player)) return; |
1237 if (!IsTileOwner(tile, old_player)) return; |
1161 |
1238 |
1162 if (new_player != PLAYER_SPECTATOR) { |
1239 if (new_player != PLAYER_SPECTATOR) { |
1163 SetTileOwner(tile, new_player); |
1240 SetTileOwner(tile, new_player); |
1178 static const byte _tunnel_fractcoord_4[4] = {0x52, 0x85, 0x98, 0x29}; |
1255 static const byte _tunnel_fractcoord_4[4] = {0x52, 0x85, 0x98, 0x29}; |
1179 static const byte _tunnel_fractcoord_5[4] = {0x92, 0x89, 0x58, 0x25}; |
1256 static const byte _tunnel_fractcoord_5[4] = {0x92, 0x89, 0x58, 0x25}; |
1180 static const byte _tunnel_fractcoord_6[4] = {0x92, 0x89, 0x56, 0x45}; |
1257 static const byte _tunnel_fractcoord_6[4] = {0x92, 0x89, 0x56, 0x45}; |
1181 static const byte _tunnel_fractcoord_7[4] = {0x52, 0x85, 0x96, 0x49}; |
1258 static const byte _tunnel_fractcoord_7[4] = {0x52, 0x85, 0x96, 0x49}; |
1182 |
1259 |
1183 static uint32 VehicleEnter_TunnelBridge(Vehicle *v, TileIndex tile, int x, int y) |
1260 static uint32 VehicleEnter_Tunnel(Vehicle *v, TileIndex tile, int x, int y) |
1184 { |
1261 { |
1185 int z = GetSlopeZ(x, y) - v->z_pos; |
1262 int z = GetSlopeZ(x, y) - v->z_pos; |
1186 |
1263 |
|
1264 byte fc; |
|
1265 DiagDirection dir; |
|
1266 DiagDirection vdir; |
|
1267 |
1187 if (myabs(z) > 2) return 8; |
1268 if (myabs(z) > 2) return 8; |
1188 |
1269 |
1189 if (IsTunnelTile(tile)) { |
1270 if (v->type == VEH_Train) { |
1190 byte fc; |
1271 fc = (x & 0xF) + (y << 4); |
1191 DiagDirection dir; |
1272 |
1192 DiagDirection vdir; |
1273 dir = GetTunnelDirection(tile); |
1193 |
1274 vdir = DirToDiagDir(v->direction); |
1194 if (v->type == VEH_Train) { |
1275 |
1195 fc = (x & 0xF) + (y << 4); |
1276 if (v->u.rail.track != 0x40 && dir == vdir) { |
1196 |
1277 if (IsFrontEngine(v) && fc == _tunnel_fractcoord_1[dir]) { |
1197 dir = GetTunnelDirection(tile); |
1278 if (!PlayVehicleSound(v, VSE_TUNNEL) && v->spritenum < 4) { |
1198 vdir = DirToDiagDir(v->direction); |
1279 SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v); |
1199 |
|
1200 if (v->u.rail.track != 0x40 && dir == vdir) { |
|
1201 if (IsFrontEngine(v) && fc == _tunnel_fractcoord_1[dir]) { |
|
1202 if (!PlayVehicleSound(v, VSE_TUNNEL) && v->spritenum < 4) { |
|
1203 SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v); |
|
1204 } |
|
1205 return 0; |
|
1206 } |
1280 } |
1207 if (fc == _tunnel_fractcoord_2[dir]) { |
1281 return 0; |
1208 v->tile = tile; |
|
1209 v->u.rail.track = 0x40; |
|
1210 v->vehstatus |= VS_HIDDEN; |
|
1211 return 4; |
|
1212 } |
|
1213 } |
1282 } |
1214 |
1283 if (fc == _tunnel_fractcoord_2[dir]) { |
1215 if (dir == ReverseDiagDir(vdir) && fc == _tunnel_fractcoord_3[dir] && z == 0) { |
|
1216 /* We're at the tunnel exit ?? */ |
|
1217 v->tile = tile; |
1284 v->tile = tile; |
1218 v->u.rail.track = _exit_tunnel_track[dir]; |
1285 v->u.rail.track = 0x40; |
1219 assert(v->u.rail.track); |
1286 v->vehstatus |= VS_HIDDEN; |
1220 v->vehstatus &= ~VS_HIDDEN; |
|
1221 return 4; |
1287 return 4; |
1222 } |
1288 } |
1223 } else if (v->type == VEH_Road) { |
1289 } |
1224 fc = (x & 0xF) + (y << 4); |
1290 |
1225 dir = GetTunnelDirection(tile); |
1291 if (dir == ReverseDiagDir(vdir) && fc == _tunnel_fractcoord_3[dir] && z == 0) { |
1226 vdir = DirToDiagDir(v->direction); |
1292 /* We're at the tunnel exit ?? */ |
1227 |
1293 v->tile = tile; |
1228 // Enter tunnel? |
1294 v->u.rail.track = _exit_tunnel_track[dir]; |
1229 if (v->u.road.state != 0xFF && dir == vdir) { |
1295 assert(v->u.rail.track); |
1230 if (fc == _tunnel_fractcoord_4[dir] || |
1296 v->vehstatus &= ~VS_HIDDEN; |
1231 fc == _tunnel_fractcoord_5[dir]) { |
1297 return 4; |
1232 v->tile = tile; |
1298 } |
1233 v->u.road.state = 0xFF; |
1299 } else if (v->type == VEH_Road) { |
1234 v->vehstatus |= VS_HIDDEN; |
1300 fc = (x & 0xF) + (y << 4); |
1235 return 4; |
1301 dir = GetTunnelDirection(tile); |
1236 } else { |
1302 vdir = DirToDiagDir(v->direction); |
1237 return 0; |
1303 |
1238 } |
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; |
1239 } |
1314 } |
1240 |
1315 } |
1241 if (dir == ReverseDiagDir(vdir) && ( |
1316 |
1242 /* We're at the tunnel exit ?? */ |
1317 if (dir == ReverseDiagDir(vdir) && ( |
1243 fc == _tunnel_fractcoord_6[dir] || |
1318 /* We're at the tunnel exit ?? */ |
1244 fc == _tunnel_fractcoord_7[dir] |
1319 fc == _tunnel_fractcoord_6[dir] || |
1245 ) && |
1320 fc == _tunnel_fractcoord_7[dir] |
1246 z == 0) { |
1321 ) && |
1247 v->tile = tile; |
1322 z == 0) { |
1248 v->u.road.state = _road_exit_tunnel_state[dir]; |
1323 v->tile = tile; |
1249 v->u.road.frame = _road_exit_tunnel_frame[dir]; |
1324 v->u.road.state = _road_exit_tunnel_state[dir]; |
1250 v->vehstatus &= ~VS_HIDDEN; |
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 |
|
1333 static uint32 VehicleEnter_Bridge(Vehicle *v, TileIndex tile, int x, int y) |
|
1334 { |
|
1335 int z = GetSlopeZ(x, y) - v->z_pos; |
|
1336 |
|
1337 DiagDirection dir; |
|
1338 |
|
1339 if (myabs(z) > 2) return 8; |
|
1340 |
|
1341 if (v->type == VEH_Road || (v->type == VEH_Train && IsFrontEngine(v))) { |
|
1342 /* modify speed of vehicle */ |
|
1343 uint16 spd = _bridge[GetBridgeType(tile)].speed; |
|
1344 |
|
1345 if (v->type == VEH_Road) spd *= 2; |
|
1346 if (v->cur_speed > spd) v->cur_speed = spd; |
|
1347 } |
|
1348 |
|
1349 dir = GetBridgeRampDirection(tile); |
|
1350 if (DirToDiagDir(v->direction) == dir) { |
|
1351 switch (dir) { |
|
1352 default: NOT_REACHED(); |
|
1353 case DIAGDIR_NE: if ((x & 0xF) != 0) return 0; break; |
|
1354 case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return 0; break; |
|
1355 case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return 0; break; |
|
1356 case DIAGDIR_NW: if ((y & 0xF) != 0) return 0; break; |
|
1357 } |
|
1358 if (v->type == VEH_Train) { |
|
1359 v->u.rail.track = 0x40; |
|
1360 CLRBIT(v->u.rail.flags, VRF_GOINGUP); |
|
1361 CLRBIT(v->u.rail.flags, VRF_GOINGDOWN); |
|
1362 } else { |
|
1363 v->u.road.state = 0xFF; |
|
1364 } |
|
1365 return 4; |
|
1366 } else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) { |
|
1367 v->tile = tile; |
|
1368 if (v->type == VEH_Train) { |
|
1369 if (v->u.rail.track == 0x40) { |
|
1370 v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? 1 : 2); |
1251 return 4; |
1371 return 4; |
1252 } |
1372 } |
1253 } |
1373 } else { |
1254 } else if (IsBridgeTile(tile)) { // XXX is this necessary? |
1374 if (v->u.road.state == 0xFF) { |
1255 DiagDirection dir; |
1375 v->u.road.state = _road_exit_tunnel_state[dir]; |
1256 |
1376 v->u.road.frame = 0; |
1257 if (v->type == VEH_Road || (v->type == VEH_Train && IsFrontEngine(v))) { |
1377 return 4; |
1258 /* modify speed of vehicle */ |
|
1259 uint16 spd = _bridge[GetBridgeType(tile)].speed; |
|
1260 |
|
1261 if (v->type == VEH_Road) spd *= 2; |
|
1262 if (v->cur_speed > spd) v->cur_speed = spd; |
|
1263 } |
|
1264 |
|
1265 dir = GetBridgeRampDirection(tile); |
|
1266 if (DirToDiagDir(v->direction) == dir) { |
|
1267 switch (dir) { |
|
1268 default: NOT_REACHED(); |
|
1269 case DIAGDIR_NE: if ((x & 0xF) != 0) return 0; break; |
|
1270 case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return 0; break; |
|
1271 case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return 0; break; |
|
1272 case DIAGDIR_NW: if ((y & 0xF) != 0) return 0; break; |
|
1273 } |
1378 } |
1274 if (v->type == VEH_Train) { |
1379 } |
1275 v->u.rail.track = 0x40; |
1380 return 0; |
1276 CLRBIT(v->u.rail.flags, VRF_GOINGUP); |
|
1277 CLRBIT(v->u.rail.flags, VRF_GOINGDOWN); |
|
1278 } else { |
|
1279 v->u.road.state = 0xFF; |
|
1280 } |
|
1281 return 4; |
|
1282 } else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) { |
|
1283 v->tile = tile; |
|
1284 if (v->type == VEH_Train) { |
|
1285 if (v->u.rail.track == 0x40) { |
|
1286 v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? 1 : 2); |
|
1287 return 4; |
|
1288 } |
|
1289 } else { |
|
1290 if (v->u.road.state == 0xFF) { |
|
1291 v->u.road.state = _road_exit_tunnel_state[dir]; |
|
1292 v->u.road.frame = 0; |
|
1293 return 4; |
|
1294 } |
|
1295 } |
|
1296 return 0; |
|
1297 } |
|
1298 } |
1381 } |
1299 return 0; |
1382 return 0; |
1300 } |
1383 } |
1301 |
1384 |
1302 const TileTypeProcs _tile_type_tunnelbridge_procs = { |
1385 const TileTypeProcs _tile_type_tunnel_procs = { |
1303 DrawTile_TunnelBridge, /* draw_tile_proc */ |
1386 DrawTile_Tunnel, /* draw_tile_proc */ |
1304 GetSlopeZ_TunnelBridge, /* get_slope_z_proc */ |
1387 GetSlopeZ_Tunnel, /* get_slope_z_proc */ |
1305 ClearTile_TunnelBridge, /* clear_tile_proc */ |
1388 ClearTile_Tunnel, /* clear_tile_proc */ |
1306 GetAcceptedCargo_TunnelBridge, /* get_accepted_cargo_proc */ |
1389 GetAcceptedCargo_Tunnel, /* get_accepted_cargo_proc */ |
1307 GetTileDesc_TunnelBridge, /* get_tile_desc_proc */ |
1390 GetTileDesc_Tunnel, /* get_tile_desc_proc */ |
1308 GetTileTrackStatus_TunnelBridge, /* get_tile_track_status_proc */ |
1391 GetTileTrackStatus_Tunnel, /* get_tile_track_status_proc */ |
1309 ClickTile_TunnelBridge, /* click_tile_proc */ |
1392 ClickTile_Tunnel, /* click_tile_proc */ |
1310 AnimateTile_TunnelBridge, /* animate_tile_proc */ |
1393 AnimateTile_Tunnel, /* animate_tile_proc */ |
1311 TileLoop_TunnelBridge, /* tile_loop_clear */ |
1394 TileLoop_Tunnel, /* tile_loop_clear */ |
1312 ChangeTileOwner_TunnelBridge, /* change_tile_owner_clear */ |
1395 ChangeTileOwner_Tunnel, /* change_tile_owner_clear */ |
1313 NULL, /* get_produced_cargo_proc */ |
1396 NULL, /* get_produced_cargo_proc */ |
1314 VehicleEnter_TunnelBridge, /* vehicle_enter_tile_proc */ |
1397 VehicleEnter_Tunnel, /* vehicle_enter_tile_proc */ |
1315 GetSlopeTileh_TunnelBridge, /* get_slope_tileh_proc */ |
1398 GetSlopeTileh_Tunnel, /* get_slope_tileh_proc */ |
1316 }; |
1399 }; |
|
1400 |
|
1401 const TileTypeProcs _tile_type_bridge_procs = { |
|
1402 DrawTile_Bridge, /* draw_tile_proc */ |
|
1403 GetSlopeZ_Bridge, /* get_slope_z_proc */ |
|
1404 ClearTile_Bridge, /* clear_tile_proc */ |
|
1405 GetAcceptedCargo_Bridge, /* get_accepted_cargo_proc */ |
|
1406 GetTileDesc_Bridge, /* get_tile_desc_proc */ |
|
1407 GetTileTrackStatus_Bridge, /* get_tile_track_status_proc */ |
|
1408 ClickTile_Bridge, /* click_tile_proc */ |
|
1409 AnimateTile_Bridge, /* animate_tile_proc */ |
|
1410 TileLoop_Bridge, /* tile_loop_clear */ |
|
1411 ChangeTileOwner_Bridge, /* change_tile_owner_clear */ |
|
1412 NULL, /* get_produced_cargo_proc */ |
|
1413 VehicleEnter_Bridge, /* vehicle_enter_tile_proc */ |
|
1414 GetSlopeTileh_Bridge, /* get_slope_tileh_proc */ |
|
1415 }; |