src/road_cmd.cpp
branchnoai
changeset 9732 f8eb3e208514
parent 9724 b39bc69bb2f2
child 9800 ab08ca2a2018
equal deleted inserted replaced
9731:9b1552d0fd9b 9732:f8eb3e208514
   223 				return CMD_ERROR;
   223 				return CMD_ERROR;
   224 			}
   224 			}
   225 
   225 
   226 			/* Don't allow road to be removed from the crossing when there is tram;
   226 			/* Don't allow road to be removed from the crossing when there is tram;
   227 			 * we can't draw the crossing without trambits ;) */
   227 			 * we can't draw the crossing without trambits ;) */
   228 			if (rt == ROADTYPE_ROAD && HasBit(GetRoadTypes(tile), ROADTYPE_TRAM) && (flags & DC_EXEC || crossing_check)) return CMD_ERROR;
   228 			if (rt == ROADTYPE_ROAD && HasTileRoadType(tile, ROADTYPE_TRAM) && (flags & DC_EXEC || crossing_check)) return CMD_ERROR;
   229 
   229 
   230 			if (rt == ROADTYPE_ROAD) {
   230 			if (rt == ROADTYPE_ROAD) {
   231 				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
   231 				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
   232 			}
   232 			}
   233 
   233 
   424 	switch (GetTileType(tile)) {
   424 	switch (GetTileType(tile)) {
   425 		case MP_ROAD:
   425 		case MP_ROAD:
   426 			switch (GetRoadTileType(tile)) {
   426 			switch (GetRoadTileType(tile)) {
   427 				case ROAD_TILE_NORMAL: {
   427 				case ROAD_TILE_NORMAL: {
   428 					if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
   428 					if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
   429 					if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
       
   430 
   429 
   431 					all_bits = GetAllRoadBits(tile);
   430 					all_bits = GetAllRoadBits(tile);
   432 					if (!HasBit(GetRoadTypes(tile), rt)) break;
   431 					if (!HasTileRoadType(tile, rt)) break;
   433 
   432 
   434 					existing = GetRoadBits(tile, rt);
   433 					existing = GetRoadBits(tile, rt);
   435 					RoadBits merged = existing | pieces;
   434 					RoadBits merged = existing | pieces;
   436 					bool crossing = (merged != ROAD_X && merged != ROAD_Y);
   435 					bool crossing = (merged != ROAD_X && merged != ROAD_Y);
   437 					if (rt != ROADTYPE_TRAM && (GetDisallowedRoadDirections(tile) != DRD_NONE || toggle_drd != DRD_NONE) && crossing) {
   436 					if (rt != ROADTYPE_TRAM && (GetDisallowedRoadDirections(tile) != DRD_NONE || toggle_drd != DRD_NONE) && crossing) {
   441 					if ((existing & pieces) == pieces) {
   440 					if ((existing & pieces) == pieces) {
   442 						/* We only want to set the (dis)allowed road directions */
   441 						/* We only want to set the (dis)allowed road directions */
   443 						if (toggle_drd != DRD_NONE && rt != ROADTYPE_TRAM && GetRoadOwner(tile, ROADTYPE_ROAD) == _current_player) {
   442 						if (toggle_drd != DRD_NONE && rt != ROADTYPE_TRAM && GetRoadOwner(tile, ROADTYPE_ROAD) == _current_player) {
   444 							if (crossing) return_cmd_error(STR_ERR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION);
   443 							if (crossing) return_cmd_error(STR_ERR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION);
   445 
   444 
       
   445 							if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
       
   446 
   446 							/* Ignore half built tiles */
   447 							/* Ignore half built tiles */
   447 							if (flags & DC_EXEC && rt != ROADTYPE_TRAM && (existing == ROAD_X || existing == ROAD_Y)) {
   448 							if (flags & DC_EXEC && rt != ROADTYPE_TRAM && (existing == ROAD_X || existing == ROAD_Y)) {
   448 								SetDisallowedRoadDirections(tile, GetDisallowedRoadDirections(tile) ^ toggle_drd);
   449 								SetDisallowedRoadDirections(tile, GetDisallowedRoadDirections(tile) ^ toggle_drd);
   449 								MarkTileDirtyByTile(tile);
   450 								MarkTileDirtyByTile(tile);
   450 							}
   451 							}
   453 						return_cmd_error(STR_1007_ALREADY_BUILT);
   454 						return_cmd_error(STR_1007_ALREADY_BUILT);
   454 					}
   455 					}
   455 				} break;
   456 				} break;
   456 
   457 
   457 				case ROAD_TILE_CROSSING:
   458 				case ROAD_TILE_CROSSING:
   458 					if (HasBit(GetRoadTypes(tile), rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
   459 					if (HasTileRoadType(tile, rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
   459 					all_bits = GetCrossingRoadBits(tile);
   460 					all_bits = GetCrossingRoadBits(tile);
   460 					if (pieces & ComplementRoadBits(all_bits)) goto do_clear;
   461 					if (pieces & ComplementRoadBits(all_bits)) goto do_clear;
   461 					break;
   462 					break;
   462 
   463 
   463 				default:
   464 				default:
   505 			return CommandCost(EXPENSES_CONSTRUCTION, _price.build_road * (rt == ROADTYPE_ROAD ? 2 : 4));
   506 			return CommandCost(EXPENSES_CONSTRUCTION, _price.build_road * (rt == ROADTYPE_ROAD ? 2 : 4));
   506 		}
   507 		}
   507 
   508 
   508 		case MP_STATION:
   509 		case MP_STATION:
   509 			if (!IsDriveThroughStopTile(tile)) return CMD_ERROR;
   510 			if (!IsDriveThroughStopTile(tile)) return CMD_ERROR;
   510 			if (HasBit(GetRoadTypes(tile), rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
   511 			if (HasTileRoadType(tile, rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
   511 			/* Don't allow adding roadtype to the roadstop when vehicles are already driving on it */
       
   512 			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
       
   513 			break;
   512 			break;
   514 
   513 
   515 		case MP_TUNNELBRIDGE:
   514 		case MP_TUNNELBRIDGE:
   516 			if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
   515 			if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
   517 			if (HasBit(GetRoadTypes(tile), rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
   516 			if (HasTileRoadType(tile, rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
   518 			/* Don't allow adding roadtype to the bridge/tunnel when vehicles are already driving on it */
   517 			/* Don't allow adding roadtype to the bridge/tunnel when vehicles are already driving on it */
   519 			if (GetVehicleTunnelBridge(tile, GetOtherTunnelBridgeEnd(tile)) != NULL) return CMD_ERROR;
   518 			if (GetVehicleTunnelBridge(tile, GetOtherTunnelBridgeEnd(tile)) != NULL) return CMD_ERROR;
   520 			break;
   519 			break;
   521 
   520 
   522 		default:
   521 		default:
   540 	if (IsTileType(tile, MP_ROAD)) {
   539 	if (IsTileType(tile, MP_ROAD)) {
   541 		/* Don't put the pieces that already exist */
   540 		/* Don't put the pieces that already exist */
   542 		pieces &= ComplementRoadBits(existing);
   541 		pieces &= ComplementRoadBits(existing);
   543 
   542 
   544 		/* Check if new road bits will have the same foundation as other existing road types */
   543 		/* Check if new road bits will have the same foundation as other existing road types */
   545 		if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
   544 		if (IsNormalRoad(tile)) {
   546 			Slope slope = GetTileSlope(tile, NULL);
   545 			Slope slope = GetTileSlope(tile, NULL);
   547 			Foundation found_new = GetRoadFoundation(slope, pieces | existing);
   546 			Foundation found_new = GetRoadFoundation(slope, pieces | existing);
   548 
   547 
   549 			/* Test if all other roadtypes can be built at that foundation */
   548 			/* Test if all other roadtypes can be built at that foundation */
   550 			for (RoadType rtest = ROADTYPE_ROAD; rtest < ROADTYPE_END; rtest++) {
   549 			for (RoadType rtest = ROADTYPE_ROAD; rtest < ROADTYPE_END; rtest++) {
   557 				}
   556 				}
   558 			}
   557 			}
   559 		}
   558 		}
   560 	}
   559 	}
   561 
   560 
       
   561 	if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
       
   562 
   562 	cost.AddCost(CountBits(pieces) * _price.build_road);
   563 	cost.AddCost(CountBits(pieces) * _price.build_road);
   563 	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
   564 	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
   564 		/* Pay for *every* tile of the bridge or tunnel */
   565 		/* Pay for *every* tile of the bridge or tunnel */
   565 		cost.MultiplyCost(GetTunnelBridgeLength(GetOtherTunnelBridgeEnd(tile), tile) + 2);
   566 		cost.MultiplyCost(GetTunnelBridgeLength(GetOtherTunnelBridgeEnd(tile), tile) + 2);
   566 	}
   567 	}
   600 			default:
   601 			default:
   601 				MakeRoadNormal(tile, pieces, RoadTypeToRoadTypes(rt), p2, _current_player, _current_player, _current_player);
   602 				MakeRoadNormal(tile, pieces, RoadTypeToRoadTypes(rt), p2, _current_player, _current_player, _current_player);
   602 				break;
   603 				break;
   603 		}
   604 		}
   604 
   605 
   605 		if (rt != ROADTYPE_TRAM && IsTileType(tile, MP_ROAD) && GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
   606 		if (rt != ROADTYPE_TRAM && IsNormalRoadTile(tile)) {
   606 			existing |= pieces;
   607 			existing |= pieces;
   607 			SetDisallowedRoadDirections(tile, (existing == ROAD_X || existing == ROAD_Y) ?
   608 			SetDisallowedRoadDirections(tile, (existing == ROAD_X || existing == ROAD_Y) ?
   608 					GetDisallowedRoadDirections(tile) ^ toggle_drd : DRD_NONE);
   609 					GetDisallowedRoadDirections(tile) ^ toggle_drd : DRD_NONE);
   609 		}
   610 		}
   610 
   611 
   631 	bool had_bridge = false;
   632 	bool had_bridge = false;
   632 	bool had_tunnel = false;
   633 	bool had_tunnel = false;
   633 	bool had_success = false;
   634 	bool had_success = false;
   634 	DisallowedRoadDirections drd = DRD_NORTHBOUND;
   635 	DisallowedRoadDirections drd = DRD_NORTHBOUND;
   635 
   636 
       
   637 	_error_message = INVALID_STRING_ID;
       
   638 
   636 	if (p1 >= MapSize()) return CMD_ERROR;
   639 	if (p1 >= MapSize()) return CMD_ERROR;
   637 
   640 
   638 	start_tile = p1;
   641 	start_tile = p1;
   639 	RoadType rt = (RoadType)GB(p2, 3, 2);
   642 	RoadType rt = (RoadType)GB(p2, 3, 2);
   640 	if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR;
   643 	if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR;
   668 		if (tile == start_tile && HasBit(p2, 0)) bits &= ROAD_SE | ROAD_SW;
   671 		if (tile == start_tile && HasBit(p2, 0)) bits &= ROAD_SE | ROAD_SW;
   669 
   672 
   670 		ret = DoCommand(tile, drd << 6 | rt << 4 | bits, 0, flags, CMD_BUILD_ROAD);
   673 		ret = DoCommand(tile, drd << 6 | rt << 4 | bits, 0, flags, CMD_BUILD_ROAD);
   671 		if (CmdFailed(ret)) {
   674 		if (CmdFailed(ret)) {
   672 			if (_error_message != STR_1007_ALREADY_BUILT) return CMD_ERROR;
   675 			if (_error_message != STR_1007_ALREADY_BUILT) return CMD_ERROR;
   673 			_error_message = INVALID_STRING_ID;
       
   674 		} else {
   676 		} else {
   675 			had_success = true;
   677 			had_success = true;
   676 			/* Only pay for the upgrade on one side of the bridges and tunnels */
   678 			/* Only pay for the upgrade on one side of the bridges and tunnels */
   677 			if (IsTileType(tile, MP_TUNNELBRIDGE)) {
   679 			if (IsTileType(tile, MP_TUNNELBRIDGE)) {
   678 				if (IsBridge(tile)) {
   680 				if (IsBridge(tile)) {
   942  * @param tram the roadbits for the tram
   944  * @param tram the roadbits for the tram
   943  */
   945  */
   944 void DrawTramCatenary(TileInfo *ti, RoadBits tram)
   946 void DrawTramCatenary(TileInfo *ti, RoadBits tram)
   945 {
   947 {
   946 	/* Don't draw the catenary under a low bridge */
   948 	/* Don't draw the catenary under a low bridge */
   947 	if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile) && !IsTransparencySet(TO_BUILDINGS)) {
   949 	if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile) && !IsTransparencySet(TO_CATENARY)) {
   948 		uint height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile));
   950 		uint height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile));
   949 
   951 
   950 		if (height <= GetTileMaxZ(ti->tile) + TILE_HEIGHT) return;
   952 		if (height <= GetTileMaxZ(ti->tile) + TILE_HEIGHT) return;
   951 	}
   953 	}
   952 
   954 
   959 	} else {
   961 	} else {
   960 		back  = SPR_TRAMWAY_BASE + _road_backpole_sprites_1[tram];
   962 		back  = SPR_TRAMWAY_BASE + _road_backpole_sprites_1[tram];
   961 		front = SPR_TRAMWAY_BASE + _road_frontwire_sprites_1[tram];
   963 		front = SPR_TRAMWAY_BASE + _road_frontwire_sprites_1[tram];
   962 	}
   964 	}
   963 
   965 
   964 	AddSortableSpriteToDraw(back,  PAL_NONE, ti->x, ti->y, 16, 16, TILE_HEIGHT + BB_HEIGHT_UNDER_BRIDGE, ti->z, IsTransparencySet(TO_BUILDINGS));
   966 	AddSortableSpriteToDraw(back,  PAL_NONE, ti->x, ti->y, 16, 16, TILE_HEIGHT + BB_HEIGHT_UNDER_BRIDGE, ti->z, IsTransparencySet(TO_CATENARY));
   965 	AddSortableSpriteToDraw(front, PAL_NONE, ti->x, ti->y, 16, 16, TILE_HEIGHT + BB_HEIGHT_UNDER_BRIDGE, ti->z, IsTransparencySet(TO_BUILDINGS));
   967 	AddSortableSpriteToDraw(front, PAL_NONE, ti->x, ti->y, 16, 16, TILE_HEIGHT + BB_HEIGHT_UNDER_BRIDGE, ti->z, IsTransparencySet(TO_CATENARY));
   966 }
   968 }
   967 
   969 
   968 /**
   970 /**
   969  * Draws details on/around the road
   971  * Draws details on/around the road
   970  * @param img the sprite to draw
   972  * @param img the sprite to draw
  1050 	if (tram != ROAD_NONE) DrawTramCatenary(ti, tram);
  1052 	if (tram != ROAD_NONE) DrawTramCatenary(ti, tram);
  1051 
  1053 
  1052 	/* Return if full detail is disabled, or we are zoomed fully out. */
  1054 	/* Return if full detail is disabled, or we are zoomed fully out. */
  1053 	if (!HasBit(_display_opt, DO_FULL_DETAIL) || _cur_dpi->zoom > ZOOM_LVL_DETAIL) return;
  1055 	if (!HasBit(_display_opt, DO_FULL_DETAIL) || _cur_dpi->zoom > ZOOM_LVL_DETAIL) return;
  1054 
  1056 
       
  1057 	/* Do not draw details (street lights, trees) under low bridge */
       
  1058 	if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile) && (roadside == ROADSIDE_TREES || roadside == ROADSIDE_STREET_LIGHTS)) {
       
  1059 		uint height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile));
       
  1060 		uint minz = GetTileMaxZ(ti->tile) + 2 * TILE_HEIGHT;
       
  1061 
       
  1062 		if (roadside == ROADSIDE_TREES) minz += TILE_HEIGHT;
       
  1063 
       
  1064 		if (height < minz) return;
       
  1065 	}
       
  1066 
  1055 	/* Draw extra details. */
  1067 	/* Draw extra details. */
  1056 	for (drts = _road_display_table[roadside][road]; drts->image != 0; drts++) {
  1068 	for (drts = _road_display_table[roadside][road]; drts->image != 0; drts++) {
  1057 		DrawRoadDetail(drts->image, ti, drts->subcoord_x, drts->subcoord_y, 0x10);
  1069 		DrawRoadDetail(drts->image, ti, drts->subcoord_x, drts->subcoord_y, 0x10);
  1058 	}
  1070 	}
  1059 }
  1071 }
  1086 					default:              image += 4; break; // Paved
  1098 					default:              image += 4; break; // Paved
  1087 				}
  1099 				}
  1088 			}
  1100 			}
  1089 
  1101 
  1090 			DrawGroundSprite(image, pal);
  1102 			DrawGroundSprite(image, pal);
  1091 			if (HasBit(GetRoadTypes(ti->tile), ROADTYPE_TRAM)) {
  1103 			if (HasTileRoadType(ti->tile, ROADTYPE_TRAM)) {
  1092 				DrawGroundSprite(SPR_TRAMWAY_OVERLAY + (GetCrossingRoadAxis(ti->tile) ^ 1), pal);
  1104 				DrawGroundSprite(SPR_TRAMWAY_OVERLAY + (GetCrossingRoadAxis(ti->tile) ^ 1), pal);
  1093 				DrawTramCatenary(ti, GetCrossingRoadBits(ti->tile));
  1105 				DrawTramCatenary(ti, GetCrossingRoadBits(ti->tile));
  1094 			}
  1106 			}
  1095 			if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
  1107 			if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
  1096 			break;
  1108 			break;
  1104 
  1116 
  1105 			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
  1117 			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
  1106 
  1118 
  1107 			palette = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
  1119 			palette = PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile));
  1108 
  1120 
  1109 			if (HasBit(GetRoadTypes(ti->tile), ROADTYPE_TRAM)) {
  1121 			if (HasTileRoadType(ti->tile, ROADTYPE_TRAM)) {
  1110 				dts =  &_tram_depot[GetRoadDepotDirection(ti->tile)];
  1122 				dts =  &_tram_depot[GetRoadDepotDirection(ti->tile)];
  1111 			} else {
  1123 			} else {
  1112 				dts =  &_road_depot[GetRoadDepotDirection(ti->tile)];
  1124 				dts =  &_road_depot[GetRoadDepotDirection(ti->tile)];
  1113 			}
  1125 			}
  1114 
  1126 
  1115 			DrawGroundSprite(dts->ground_sprite, PAL_NONE);
  1127 			DrawGroundSprite(dts->ground.sprite, PAL_NONE);
  1116 
  1128 
  1117 			for (dtss = dts->seq; dtss->image != 0; dtss++) {
  1129 			for (dtss = dts->seq; dtss->image.sprite != 0; dtss++) {
  1118 				SpriteID image = dtss->image;
  1130 				SpriteID image = dtss->image.sprite;
  1119 				SpriteID pal;
  1131 				SpriteID pal;
  1120 
  1132 
  1121 				if (!IsTransparencySet(TO_BUILDINGS) && HasBit(image, PALETTE_MODIFIER_COLOR)) {
  1133 				if (!IsTransparencySet(TO_BUILDINGS) && HasBit(image, PALETTE_MODIFIER_COLOR)) {
  1122 					pal = palette;
  1134 					pal = palette;
  1123 				} else {
  1135 				} else {
  1145 	const DrawTileSeqStruct* dtss;
  1157 	const DrawTileSeqStruct* dtss;
  1146 
  1158 
  1147 	x += 33;
  1159 	x += 33;
  1148 	y += 17;
  1160 	y += 17;
  1149 
  1161 
  1150 	DrawSprite(dts->ground_sprite, PAL_NONE, x, y);
  1162 	DrawSprite(dts->ground.sprite, PAL_NONE, x, y);
  1151 
  1163 
  1152 	for (dtss = dts->seq; dtss->image != 0; dtss++) {
  1164 	for (dtss = dts->seq; dtss->image.sprite != 0; dtss++) {
  1153 		Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
  1165 		Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
  1154 		SpriteID image = dtss->image;
  1166 		SpriteID image = dtss->image.sprite;
  1155 
  1167 
  1156 		DrawSprite(image, HasBit(image, PALETTE_MODIFIER_COLOR) ? palette : PAL_NONE, x + pt.x, y + pt.y);
  1168 		DrawSprite(image, HasBit(image, PALETTE_MODIFIER_COLOR) ? palette : PAL_NONE, x + pt.x, y + pt.y);
  1157 	}
  1169 	}
  1158 }
  1170 }
  1159 
  1171 
  1161 {
  1173 {
  1162 	uint z;
  1174 	uint z;
  1163 	Slope tileh = GetTileSlope(tile, &z);
  1175 	Slope tileh = GetTileSlope(tile, &z);
  1164 
  1176 
  1165 	if (tileh == SLOPE_FLAT) return z;
  1177 	if (tileh == SLOPE_FLAT) return z;
  1166 	if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
  1178 	if (IsNormalRoad(tile)) {
  1167 		Foundation f = GetRoadFoundation(tileh, GetAllRoadBits(tile));
  1179 		Foundation f = GetRoadFoundation(tileh, GetAllRoadBits(tile));
  1168 		z += ApplyFoundationToSlope(f, &tileh);
  1180 		z += ApplyFoundationToSlope(f, &tileh);
  1169 		return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
  1181 		return z + GetPartialZ(x & 0xF, y & 0xF, tileh);
  1170 	} else {
  1182 	} else {
  1171 		return z + TILE_HEIGHT;
  1183 		return z + TILE_HEIGHT;
  1172 	}
  1184 	}
  1173 }
  1185 }
  1174 
  1186 
  1175 static Foundation GetFoundation_Road(TileIndex tile, Slope tileh)
  1187 static Foundation GetFoundation_Road(TileIndex tile, Slope tileh)
  1176 {
  1188 {
  1177 	if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
  1189 	if (IsNormalRoad(tile)) {
  1178 		return GetRoadFoundation(tileh, GetAllRoadBits(tile));
  1190 		return GetRoadFoundation(tileh, GetAllRoadBits(tile));
  1179 	} else {
  1191 	} else {
  1180 		return FlatteningFoundation(tileh);
  1192 		return FlatteningFoundation(tileh);
  1181 	}
  1193 	}
  1182 }
  1194 }
  1225 				MarkTileDirtyByTile(tile);
  1237 				MarkTileDirtyByTile(tile);
  1226 			}
  1238 			}
  1227 			break;
  1239 			break;
  1228 	}
  1240 	}
  1229 
  1241 
  1230 	if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) return;
  1242 	if (IsRoadDepot(tile)) return;
  1231 
  1243 
  1232 	const Town* t = ClosestTownFromTile(tile, (uint)-1);
  1244 	const Town* t = ClosestTownFromTile(tile, (uint)-1);
  1233 	if (!HasRoadWorks(tile)) {
  1245 	if (!HasRoadWorks(tile)) {
  1234 		HouseZonesBits grp = HZB_TOWN_EDGE;
  1246 		HouseZonesBits grp = HZB_TOWN_EDGE;
  1235 
  1247 
  1237 			grp = GetTownRadiusGroup(t, tile);
  1249 			grp = GetTownRadiusGroup(t, tile);
  1238 
  1250 
  1239 			/* Show an animation to indicate road work */
  1251 			/* Show an animation to indicate road work */
  1240 			if (t->road_build_months != 0 &&
  1252 			if (t->road_build_months != 0 &&
  1241 					(DistanceManhattan(t->xy, tile) < 8 || grp != HZB_TOWN_EDGE) &&
  1253 					(DistanceManhattan(t->xy, tile) < 8 || grp != HZB_TOWN_EDGE) &&
  1242 					GetRoadTileType(tile) == ROAD_TILE_NORMAL && CountBits(GetAllRoadBits(tile)) > 1 ) {
  1254 					IsNormalRoad(tile) && CountBits(GetAllRoadBits(tile)) > 1 ) {
  1243 				if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && Chance16(1, 40)) {
  1255 				if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && Chance16(1, 40)) {
  1244 					StartRoadWorks(tile);
  1256 					StartRoadWorks(tile);
  1245 
  1257 
  1246 					SndPlayTileFx(SND_21_JACKHAMMER, tile);
  1258 					SndPlayTileFx(SND_21_JACKHAMMER, tile);
  1247 					CreateEffectVehicleAbove(
  1259 					CreateEffectVehicleAbove(
  1293 	}
  1305 	}
  1294 }
  1306 }
  1295 
  1307 
  1296 static void ClickTile_Road(TileIndex tile)
  1308 static void ClickTile_Road(TileIndex tile)
  1297 {
  1309 {
  1298 	if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) ShowDepotWindow(tile, VEH_ROAD);
  1310 	if (IsRoadDepot(tile)) ShowDepotWindow(tile, VEH_ROAD);
  1299 }
  1311 }
  1300 
  1312 
       
  1313 /* Converts RoadBits to TrackBits */
  1301 static const byte _road_trackbits[16] = {
  1314 static const byte _road_trackbits[16] = {
  1302 	0x0, 0x0, 0x0, 0x10, 0x0, 0x2, 0x8, 0x1A, 0x0, 0x4, 0x1, 0x15, 0x20, 0x26, 0x29, 0x3F,
  1315 	0x0, 0x0, 0x0, 0x10, 0x0, 0x2, 0x8, 0x1A, 0x0, 0x4, 0x1, 0x15, 0x20, 0x26, 0x29, 0x3F,
  1303 };
  1316 };
  1304 
  1317 
  1305 static uint32 GetTileTrackStatus_Road(TileIndex tile, TransportType mode, uint sub_mode)
  1318 static TrackStatus GetTileTrackStatus_Road(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
  1306 {
  1319 {
  1307 
  1320 	TrackdirBits trackdirbits = TRACKDIR_BIT_NONE;
       
  1321 	TrackdirBits red_signals = TRACKDIR_BIT_NONE; // crossing barred
  1308 	switch (mode) {
  1322 	switch (mode) {
  1309 		case TRANSPORT_RAIL:
  1323 		case TRANSPORT_RAIL:
  1310 			if (!IsLevelCrossing(tile)) return 0;
  1324 			if (IsLevelCrossing(tile)) trackdirbits = TrackBitsToTrackdirBits(GetCrossingRailBits(tile));
  1311 			return GetCrossingRailBits(tile) * 0x101;
  1325 			break;
  1312 
  1326 
  1313 		case TRANSPORT_ROAD:
  1327 		case TRANSPORT_ROAD:
  1314 			if ((GetRoadTypes(tile) & sub_mode) == 0) return 0;
  1328 			if ((GetRoadTypes(tile) & sub_mode) == 0) break;
  1315 			switch (GetRoadTileType(tile)) {
  1329 			switch (GetRoadTileType(tile)) {
  1316 				case ROAD_TILE_NORMAL: {
  1330 				case ROAD_TILE_NORMAL: {
       
  1331 					const uint drd_to_multiplier[DRD_END] = { 0x101, 0x100, 0x1, 0x0 };
  1317 					RoadType rt = (RoadType)FindFirstBit(sub_mode);
  1332 					RoadType rt = (RoadType)FindFirstBit(sub_mode);
  1318 					const uint drd_to_multiplier[DRD_END] = { 0x101, 0x100, 0x1, 0x0 };
  1333 					RoadBits bits = GetRoadBits(tile, rt);
       
  1334 
       
  1335 					/* no roadbit at this side of tile, return 0 */
       
  1336 					if (side != INVALID_DIAGDIR && (DiagDirToRoadBits(side) & bits) == 0) break;
       
  1337 
  1319 					uint multiplier = drd_to_multiplier[rt == ROADTYPE_TRAM ? DRD_NONE : GetDisallowedRoadDirections(tile)];
  1338 					uint multiplier = drd_to_multiplier[rt == ROADTYPE_TRAM ? DRD_NONE : GetDisallowedRoadDirections(tile)];
  1320 					return HasRoadWorks(tile) ? 0 : _road_trackbits[GetRoadBits(tile, rt)] * multiplier;
  1339 					if (!HasRoadWorks(tile)) trackdirbits = (TrackdirBits)(_road_trackbits[bits] * multiplier);
       
  1340 					break;
  1321 				}
  1341 				}
  1322 
  1342 
  1323 				case ROAD_TILE_CROSSING: {
  1343 				case ROAD_TILE_CROSSING: {
  1324 					uint32 r = AxisToTrackBits(GetCrossingRoadAxis(tile)) * 0x101;
  1344 					Axis axis = GetCrossingRoadAxis(tile);
  1325 
  1345 
  1326 					if (IsCrossingBarred(tile)) r *= 0x10001;
  1346 					if (side != INVALID_DIAGDIR && axis != DiagDirToAxis(side)) break;
  1327 					return r;
  1347 
       
  1348 					trackdirbits = TrackBitsToTrackdirBits(AxisToTrackBits(axis));
       
  1349 					if (IsCrossingBarred(tile)) red_signals = trackdirbits;
       
  1350 					break;
  1328 				}
  1351 				}
  1329 
  1352 
  1330 				default:
  1353 				default:
  1331 				case ROAD_TILE_DEPOT:
  1354 				case ROAD_TILE_DEPOT: {
  1332 					return AxisToTrackBits(DiagDirToAxis(GetRoadDepotDirection(tile))) * 0x101;
  1355 					DiagDirection dir = GetRoadDepotDirection(tile);
       
  1356 
       
  1357 					if (side != INVALID_DIAGDIR && side != dir) break;
       
  1358 
       
  1359 					trackdirbits = TrackBitsToTrackdirBits(AxisToTrackBits(DiagDirToAxis(dir)));
       
  1360 					break;
       
  1361 				}
  1333 			}
  1362 			}
  1334 			break;
  1363 			break;
  1335 
  1364 
  1336 		default: break;
  1365 		default: break;
  1337 	}
  1366 	}
  1338 	return 0;
  1367 	return CombineTrackStatus(trackdirbits, red_signals);
  1339 }
  1368 }
  1340 
  1369 
  1341 static const StringID _road_tile_strings[] = {
  1370 static const StringID _road_tile_strings[] = {
  1342 	STR_1814_ROAD,
  1371 	STR_1814_ROAD,
  1343 	STR_1814_ROAD,
  1372 	STR_1814_ROAD,
  1398 }
  1427 }
  1399 
  1428 
  1400 
  1429 
  1401 static void ChangeTileOwner_Road(TileIndex tile, PlayerID old_player, PlayerID new_player)
  1430 static void ChangeTileOwner_Road(TileIndex tile, PlayerID old_player, PlayerID new_player)
  1402 {
  1431 {
  1403 	if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) {
  1432 	if (IsRoadDepot(tile)) {
  1404 		if (GetTileOwner(tile) == old_player) {
  1433 		if (GetTileOwner(tile) == old_player) {
  1405 			if (new_player == PLAYER_SPECTATOR) {
  1434 			if (new_player == PLAYER_SPECTATOR) {
  1406 				DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
  1435 				DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR);
  1407 			} else {
  1436 			} else {
  1408 				SetTileOwner(tile, new_player);
  1437 				SetTileOwner(tile, new_player);
  1409 			}
  1438 			}
  1410 		}
  1439 		}
  1411 		return;
  1440 		return;
  1412 	}
  1441 	}
  1413 
  1442 
  1414 	for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
  1443 	for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
  1415 		if (!HasBit(GetRoadTypes(tile), rt)) continue;
  1444 		/* ROADTYPE_ROAD denotes the tile owner, so update it too */
       
  1445 		if (rt != ROADTYPE_ROAD && !HasTileRoadType(tile, rt)) continue;
  1416 
  1446 
  1417 		if (GetRoadOwner(tile, rt) == old_player) {
  1447 		if (GetRoadOwner(tile, rt) == old_player) {
  1418 			SetRoadOwner(tile, rt, new_player == PLAYER_SPECTATOR ? OWNER_NONE : new_player);
  1448 			SetRoadOwner(tile, rt, new_player == PLAYER_SPECTATOR ? OWNER_NONE : new_player);
  1419 		}
  1449 		}
  1420 	}
  1450 	}
  1421 
  1451 
  1422 	if (IsLevelCrossing(tile)) {
  1452 	if (IsLevelCrossing(tile)) {
  1423 		if (GetTileOwner(tile) == old_player) {
  1453 		if (GetTileOwner(tile) == old_player) {
  1424 			if (new_player == PLAYER_SPECTATOR) {
  1454 			if (new_player == PLAYER_SPECTATOR) {
  1425 				MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY));
  1455 				DoCommand(tile, 0, GetCrossingRailTrack(tile), DC_EXEC | DC_BANKRUPT, CMD_REMOVE_SINGLE_RAIL);
  1426 			} else {
  1456 			} else {
  1427 				SetTileOwner(tile, new_player);
  1457 				SetTileOwner(tile, new_player);
  1428 			}
  1458 			}
  1429 		}
  1459 		}
  1430 	}
  1460 	}