File diff r7640:7448cde64dcb → r7641:2b26b5be3fd7
src/road_cmd.cpp
Show inline comments
 
@@ -259,70 +259,121 @@ CommandCost CmdRemoveRoad(TileIndex tile
 
static const RoadBits _valid_tileh_slopes_road[][15] = {
 
	/* set of normal ones */
 
	{
 
		ROAD_ALL, ROAD_NONE, ROAD_NONE,
 
		ROAD_X,   ROAD_NONE, ROAD_NONE,  // 3, 4, 5
 
		ROAD_Y,   ROAD_NONE, ROAD_NONE,
 
		ROAD_Y,   ROAD_NONE, ROAD_NONE,  // 9, 10, 11
 
		ROAD_X,   ROAD_NONE, ROAD_NONE
 
		ROAD_ALL,  // SLOPE_FLAT
 
		ROAD_NONE, // SLOPE_W
 
		ROAD_NONE, // SLOPE_S
 

	
 
		ROAD_X,    // SLOPE_SW
 
		ROAD_NONE, // SLOPE_E
 
		ROAD_NONE, // SLOPE_EW
 

	
 
		ROAD_Y,    // SLOPE_SE
 
		ROAD_NONE, // SLOPE_WSE
 
		ROAD_NONE, // SLOPE_N
 

	
 
		ROAD_Y,    // SLOPE_NW
 
		ROAD_NONE, // SLOPE_NS
 
		ROAD_NONE, // SLOPE_NE
 

	
 
		ROAD_X,    // SLOPE_ENW
 
		ROAD_NONE, // SLOPE_SEN
 
		ROAD_NONE  // SLOPE_ELEVATED
 
	},
 
	/* allowed road for an evenly raised platform */
 
	{
 
		ROAD_NONE,
 
		ROAD_SW | ROAD_NW,
 
		ROAD_SW | ROAD_SE,
 
		ROAD_Y  | ROAD_SW,
 
		ROAD_NONE,         // SLOPE_FLAT
 
		ROAD_SW | ROAD_NW, // SLOPE_W
 
		ROAD_SW | ROAD_SE, // SLOPE_S
 

	
 
		ROAD_Y  | ROAD_SW, // SLOPE_SW
 
		ROAD_SE | ROAD_NE, // SLOPE_E
 
		ROAD_ALL,          // SLOPE_EW
 

	
 
		ROAD_X  | ROAD_SE, // SLOPE_SE
 
		ROAD_ALL,          // SLOPE_WSE
 
		ROAD_NW | ROAD_NE, // SLOPE_N
 

	
 
		ROAD_X  | ROAD_NW, // SLOPE_NW
 
		ROAD_ALL,          // SLOPE_NS
 
		ROAD_ALL,          // SLOPE_NE
 

	
 
		ROAD_SE | ROAD_NE, // 4
 
		ROAD_ALL,
 
		ROAD_X  | ROAD_SE,
 
		ROAD_ALL,
 
		ROAD_Y  | ROAD_NE, // SLOPE_ENW
 
		ROAD_ALL,          // SLOPE_SEN
 
		ROAD_ALL           // SLOPE_ELEVATED
 
	},
 
	/* Singe bits on slopes */
 
	{
 
		ROAD_ALL,          // SLOPE_FLAT
 
		ROAD_NE | ROAD_SE, // SLOPE_W
 
		ROAD_NE | ROAD_NW, // SLOPE_S
 

	
 
		ROAD_NW | ROAD_NE, // 8
 
		ROAD_X  | ROAD_NW,
 
		ROAD_ALL,
 
		ROAD_ALL,
 
		ROAD_NE,           // SLOPE_SW
 
		ROAD_NW | ROAD_SW, // SLOPE_E
 
		ROAD_ALL,          // SLOPE_EW
 

	
 
		ROAD_NW,           // SLOPE_SE
 
		ROAD_ALL,          // SLOPE_WSE
 
		ROAD_SE | ROAD_SW, // SLOPE_N
 

	
 
		ROAD_Y  | ROAD_NE, // 12
 
		ROAD_ALL,
 
		ROAD_ALL
 
		ROAD_SE,           // SLOPE_NW
 
		ROAD_ALL,          // SLOPE_NS
 
		ROAD_ALL,          // SLOPE_NE
 

	
 
		ROAD_SW,           // SLOPE_ENW
 
		ROAD_ALL,          // SLOPE_SEN
 
		ROAD_ALL,          // SLOPE_ELEVATED
 
	},
 
};
 

	
 

	
 
/**
 
 * Calculate the costs for roads on slopes
 
 *  Aside modify the RoadBits to fit on the slopes
 
 *
 
 * @note The RoadBits are modified too!
 
 * @param tileh The current slope
 
 * @param pieces The RoadBits we want to add
 
 * @param existing The existent RoadBits
 
 * @return The costs for these RoadBits on this slope
 
 */
 
static CommandCost CheckRoadSlope(Slope tileh, RoadBits* pieces, RoadBits existing)
 
{
 
	RoadBits road_bits;
 
	if (IsSteepSlope(tileh)) {
 
		/* Force straight roads. */
 
		*pieces |= MirrorRoadBits(*pieces);
 

	
 
	if (IsSteepSlope(tileh)) {
 
		/* force full pieces. */
 
		*pieces |= (RoadBits)((*pieces & 0xC) >> 2);
 
		*pieces |= (RoadBits)((*pieces & 0x3) << 2);
 

	
 
		if (existing == 0 || existing == *pieces) {
 
		if (existing == ROAD_NONE || existing == *pieces) {
 
			if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
 
		}
 
		return CMD_ERROR;
 
	}
 
	road_bits = *pieces | existing;
 

	
 
	RoadBits road_bits = *pieces | existing;
 

	
 
	/* Single bits on slopes.
 
	 * We check for the roads that need at least 2 bits */
 
	if (_patches.build_on_slopes && !_is_old_ai_player &&
 
			existing == ROAD_NONE && COUNTBITS(*pieces) == 1 &&
 
			(_valid_tileh_slopes_road[2][tileh] & *pieces) == ROAD_NONE) {
 
		return CommandCost(_price.terraform);
 
	}
 

	
 
	/* no special foundation */
 
	if ((~_valid_tileh_slopes_road[0][tileh] & road_bits) == 0) {
 
	if ((~_valid_tileh_slopes_road[0][tileh] & road_bits) == ROAD_NONE) {
 
		/* force that all bits are set when we have slopes */
 
		if (tileh != SLOPE_FLAT) *pieces |= _valid_tileh_slopes_road[0][tileh];
 
		return CommandCost(); // no extra cost
 
	}
 

	
 
	/* foundation is used. Whole tile is leveled up */
 
	if ((~_valid_tileh_slopes_road[1][tileh] & road_bits) == 0) {
 
		return CommandCost(existing != 0 ? 0 : _price.terraform);
 
	if ((~_valid_tileh_slopes_road[1][tileh] & road_bits) == ROAD_NONE) {
 
		return CommandCost(existing != ROAD_NONE ? 0 : _price.terraform);
 
	}
 

	
 
	*pieces |= (RoadBits)((*pieces & 0xC) >> 2);
 
	*pieces |= (RoadBits)((*pieces & 0x3) << 2);
 
	/* Force straight roads. */
 
	*pieces |= MirrorRoadBits(*pieces);
 

	
 
	/* partly leveled up tile, only if there's no road on that tile */
 
	if ((existing == 0 || existing == *pieces) && (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)) {
 
		/* force full pieces. */
 
	if ((existing == ROAD_NONE || existing == *pieces) && (tileh == SLOPE_W || tileh == SLOPE_S || tileh == SLOPE_E || tileh == SLOPE_N)) {
 
		if (*pieces == ROAD_X || *pieces == ROAD_Y) return _price.terraform;
 
	}
 
	return CMD_ERROR;
 
@@ -1182,8 +1233,8 @@ static void TileLoop_Road(TileIndex tile
 

	
 
	if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) return;
 

	
 
	const Town* t = ClosestTownFromTile(tile, (uint)-1);
 
	if (!HasRoadWorks(tile)) {
 
		const Town* t = ClosestTownFromTile(tile, (uint)-1);
 
		int grp = 0;
 

	
 
		if (t != NULL) {
 
@@ -1192,8 +1243,8 @@ static void TileLoop_Road(TileIndex tile
 
			/* Show an animation to indicate road work */
 
			if (t->road_build_months != 0 &&
 
					(DistanceManhattan(t->xy, tile) < 8 || grp != 0) &&
 
					GetRoadTileType(tile) == ROAD_TILE_NORMAL && (GetAllRoadBits(tile) == ROAD_X || GetAllRoadBits(tile) == ROAD_Y)) {
 
				if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && CHANCE16(1, 20)) {
 
					GetRoadTileType(tile) == ROAD_TILE_NORMAL && COUNTBITS(GetAllRoadBits(tile)) > 1 ) {
 
				if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && CHANCE16(1, 40)) {
 
					StartRoadWorks(tile);
 

	
 
					SndPlayTileFx(SND_21_JACKHAMMER, tile);
 
@@ -1231,6 +1282,17 @@ static void TileLoop_Road(TileIndex tile
 
		}
 
	} else if (IncreaseRoadWorksCounter(tile)) {
 
		TerminateRoadWorks(tile);
 

	
 
		if (_patches.mod_road_rebuild) {
 
			/* Generate a nicer town surface */
 
			const RoadBits old_rb = GetAnyRoadBits(tile, ROADTYPE_ROAD);
 
			const RoadBits new_rb = CleanUpRoadBits(tile, old_rb);
 

	
 
			if (old_rb != new_rb) {
 
				DoCommand(tile, (old_rb ^ new_rb), t->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_REMOVE_ROAD);
 
			}
 
		}
 

	
 
		MarkTileDirtyByTile(tile);
 
	}
 
}