=== src/road.h ================================================================== --- src/road.h (/trunk) (revision 166) +++ src/road.h (/branch/new_town) (revision 166) @@ -82,11 +82,26 @@ DECLARE_ENUM_AS_BIT_SET(RoadBits); +/** + * Invert the RoadBits + * @param r the current RoadBits + * @return the invers of the current RoadBits + */ static inline RoadBits ComplementRoadBits(RoadBits r) { return (RoadBits)(ROAD_ALL ^ r); } +/** + * Mirror the RoadBits + * @param r the current RoadBits + * @return the mirrored RoadBits + */ +static inline RoadBits MirrorRoadBits(RoadBits r) +{ + return ((RoadBits)GB(r, 2, 2) | (RoadBits)(GB(r, 0, 2) << 2)); +} + static inline RoadBits DiagDirToRoadBits(DiagDirection d) { return (RoadBits)(1U << (3 ^ d)); === src/town_cmd.cpp ================================================================== --- src/town_cmd.cpp (/trunk) (revision 166) +++ src/town_cmd.cpp (/branch/new_town) (revision 166) @@ -569,20 +569,6 @@ /* not used */ } - -static const TileIndexDiffC _roadblock_tileadd[] = { - { 0, -1}, - { 1, 0}, - { 0, 1}, - {-1, 0}, - - /* Store the first 3 elements again. - * Lets us rotate without using &3. */ - { 0, -1}, - { 1, 0}, - { 0, 1} -}; - /** * Distance multiplyer * Defines the possible distances between 2 road tiles @@ -797,34 +783,7 @@ } else if (!lx && ly) { ///< It is a X-dir road tile return ROAD_X; } else { ///< It is a crossing tile - /* Presets for junctions on slopes - * not nice :( */ - switch (GetTileSlope(tile, NULL)) { - case SLOPE_W: - return ROAD_NW | ROAD_SW; - case SLOPE_S: - return ROAD_SE | ROAD_SW; - case SLOPE_SW: - return ROAD_Y | ROAD_SW; - case SLOPE_E: - return ROAD_NE | ROAD_SE; - case SLOPE_SE: - return ROAD_X | ROAD_SE; - case SLOPE_N: - return ROAD_NW | ROAD_NE; - case SLOPE_NW: - return ROAD_X | ROAD_NW; - case SLOPE_NE: - return ROAD_Y | ROAD_NE; - case SLOPE_STEEP_W: - case SLOPE_STEEP_N: - return ROAD_X; - case SLOPE_STEEP_S: - case SLOPE_STEEP_E: - return ROAD_Y; - default: - return ROAD_ALL; - } + return ROAD_ALL; } } @@ -880,8 +839,6 @@ { RoadBits rcmd; TileIndex tmptile; - DiagDirection i; - int j; TileIndex tile = *tile_ptr; TILE_ASSERT(tile); @@ -954,20 +911,13 @@ _grow_town_result = 0; switch (_patches.town_layout) { - default: NOT_REACHED(); + default: + rcmd = ROAD_ALL; + break; case TL_NO_ROADS: /* Disallow Roads */ return; - case TL_3X3_GRID: - case TL_2X2_GRID: - rcmd = GetTownRoadGridElement(t1, tile); - break; - - case TL_BETTER_ROADS: - case TL_ORIGINAL: - rcmd = (RoadBits)(1 << (block ^ 2)); - break; } } else { int i; @@ -1051,14 +1001,19 @@ /* Return if a water tile */ if (IsClearWaterTile(tile)) return; - /* Determine direction of slope, - * and build a road if not a special slope. */ - switch (GetTileSlope(tile, NULL)) { - case SLOPE_SW: i = DIAGDIR_NE; break; - case SLOPE_SE: i = DIAGDIR_NW; break; - case SLOPE_NW: i = DIAGDIR_SE; break; - case SLOPE_NE: i = DIAGDIR_SW; break; + DiagDirection bridge_dir; + rcmd = CleanUpRoadBits(tile, rcmd); + switch (rcmd) { + case ROAD_NONE: return; break; ///< If there are no more RoadBits further actions are needless. + + /* Determine direction of slope, + * and build a road if not a special slope. */ + case ROAD_NW: bridge_dir = DIAGDIR_SE; break; + case ROAD_SW: bridge_dir = DIAGDIR_NE; break; + case ROAD_SE: bridge_dir = DIAGDIR_NW; break; + case ROAD_NE: bridge_dir = DIAGDIR_SW; break; + default: build_road_and_exit: if (CmdSucceeded(DoCommand(tile, rcmd, t1->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD))) { @@ -1067,28 +1022,22 @@ return; } - /* Check if the bridge is in the right direction */ - if ((rcmd == ROAD_X && (i == DIAGDIR_NW || i == DIAGDIR_SE)) || - (rcmd == ROAD_Y && (i == DIAGDIR_NE || i == DIAGDIR_SW))) { - goto build_road_and_exit; - } + /* Don't build bridges on flat slopes */ + if (GetTileSlope(tile, NULL) == SLOPE_FLAT) goto build_road_and_exit; + /* Get the end of the bridge. */ + int dist = 0; tmptile = tile; - - /* Now it contains the direction of the slope */ - j = -11; // max 11 tile long bridges do { - if (++j == 0) - goto build_road_and_exit; - tmptile = TILE_MASK(tmptile + TileOffsByDiagDir(i)); + if (++dist >= 11) return; ///< max 11 tile long bridges + tmptile = TILE_MASK(tmptile + TileOffsByDiagDir(bridge_dir)); } while (IsClearWaterTile(tmptile)); - /* no water tiles in between? */ - if (j == -10) - goto build_road_and_exit; + /* No water tiles in between? */ + if (dist == 1) goto build_road_and_exit; /* Quit if it selecting an appropiate bridge type fails a large number of times. */ - j = 22; + dist = 22; { int32 bridge_len = GetBridgeLength(tile, tmptile); do { @@ -1100,7 +1049,7 @@ /* obviously, if building any bridge would fail, there is no need to try other bridge-types */ return; } - } while (--j != 0); + } while (--dist != 0); } } === src/road_cmd.cpp ================================================================== --- src/road_cmd.cpp (/trunk) (revision 166) +++ src/road_cmd.cpp (/branch/new_town) (revision 166) @@ -1183,8 +1183,8 @@ /* 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 && CountRoadBits(GetAllRoadBits(tile)) > 1 ) { + if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && CHANCE16(1, 40)) { StartRoadWorks(tile); SndPlayTileFx(SND_21_JACKHAMMER, tile); @@ -1222,6 +1222,12 @@ } } else if (IncreaseRoadWorksCounter(tile)) { TerminateRoadWorks(tile); + + /* 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) SetRoadBits(tile, new_rb, ROADTYPE_ROAD); + MarkTileDirtyByTile(tile); } } === src/road_map.cpp ================================================================== --- src/road_map.cpp (/trunk) (revision 166) +++ src/road_map.cpp (/branch/new_town) (revision 166) @@ -59,3 +59,130 @@ return (TrackBits)(byte)(r | (r >> 8)); } + + +RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits rcmd) +{ + RoadBits prefered_rb = ROAD_NONE; + + for (uint8 i = 0 ; i <= 3 ; i++) { + /* Cycle counter around the tile NW->SW->SE->NE */ + const TileIndex neighbor_tile = AddTileIndexDiffCWrap(tile, _roadblock_tileadd[i]); + + /* Get the Roadbit pointing to the neighbor_tile */ + const RoadBits current_rb = (RoadBits)(ROAD_NW << i); + + /* If the roadbit is in the current plan */ + if (HASBITS(rcmd, current_rb)) { + bool connective = false; + const RoadBits mirrored_rb = MirrorRoadBits(current_rb); + + switch (GetTileType(neighbor_tile)) { + /* Allways connective ones */ + case MP_CLEAR: case MP_TREES: + connective = true; + break; + + /* The conditionaly connective ones */ + case MP_TUNNELBRIDGE: + case MP_STATION: + case MP_ROAD: { + const RoadBits neighbor_rb_road = GetAnyRoadBits(neighbor_tile, ROADTYPE_ROAD); + const RoadBits neighbor_rb_tram = GetAnyRoadBits(neighbor_tile, ROADTYPE_TRAM); + + /* Accept only connective tiles */ + connective = HASBITS(neighbor_rb_road | neighbor_rb_tram, mirrored_rb); + /* Prefer road */ + if (HASBITS(neighbor_rb_road, mirrored_rb)) prefered_rb |= current_rb; + + } break; + + case MP_RAILWAY: + connective = IsPossibleCrossing(neighbor_tile, current_rb | mirrored_rb); + break; + + case MP_WATER: + /* Check for real water tile */ + connective = !IsWater(neighbor_tile); + break; + + /* The defentetly not connective ones */ + default: break; + } + + /* If the neighbor tile is inconnective remove the planed road connection to it */ + if (!connective) rcmd ^= current_rb; + + } + } + + /* Optimise the Roadbits for slopes */ + RoadBits slope_rb[3]; ///< recommended RoadBits + switch (GetTileSlope(tile, NULL)) { + case SLOPE_N: + slope_rb[0] = ROAD_NW | ROAD_NE; + slope_rb[1] = ROAD_X; + slope_rb[2] = ROAD_Y; + break; + + case SLOPE_W: + slope_rb[0] = ROAD_NW | ROAD_SW; + slope_rb[1] = ROAD_X; + slope_rb[2] = ROAD_Y; + break; + + case SLOPE_S: + slope_rb[0] = ROAD_SW | ROAD_SE; + slope_rb[1] = ROAD_X; + slope_rb[2] = ROAD_Y; + break; + + case SLOPE_E: + slope_rb[0] = ROAD_SE | ROAD_NE; + slope_rb[1] = ROAD_X; + slope_rb[2] = ROAD_Y; + break; + + case SLOPE_NW: + slope_rb[0] = ROAD_X | ROAD_NW; + slope_rb[1] = ROAD_Y; + slope_rb[2] = ROAD_NONE; + break; + + case SLOPE_SW: + slope_rb[0] = ROAD_Y | ROAD_SW; + slope_rb[1] = ROAD_X; + slope_rb[2] = ROAD_NONE; + break; + + case SLOPE_SE: + slope_rb[0] = ROAD_X | ROAD_SE; + slope_rb[1] = ROAD_Y; + slope_rb[2] = ROAD_NONE; + break; + + case SLOPE_NE: + slope_rb[0] = ROAD_Y | ROAD_NE; + slope_rb[1] = ROAD_X; + slope_rb[2] = ROAD_NONE; + break; + + default: + slope_rb[0] = ROAD_ALL; + break; + } + + for (uint cur = 0; cur < 3; cur++) { + + if (slope_rb[cur] == ROAD_ALL) + return rcmd; + + if (slope_rb[cur] == ROAD_NONE && cur > 0) + return rcmd & slope_rb[cur - 1]; + + if (HASBITS(prefered_rb, slope_rb[cur])) + return prefered_rb & slope_rb[cur]; + } + + return ROAD_NONE; +} === src/road_map.h ================================================================== --- src/road_map.h (/trunk) (revision 166) +++ src/road_map.h (/branch/new_town) (revision 166) @@ -7,6 +7,7 @@ #include "macros.h" #include "rail.h" +#include "rail_map.h" #include "road.h" #include "tile.h" @@ -174,17 +175,55 @@ SB(_m[t].m5, 4, 2, drd); } +/** + * Returns the axis of the a crossing. + * @param t the current tile + * @return the axis of the road over the rail + */ static inline Axis GetCrossingRoadAxis(TileIndex t) { assert(GetRoadTileType(t) == ROAD_TILE_CROSSING); return (Axis)GB(_m[t].m4, 6, 1); } +/** + * Returns the roadbits of the a crossing. + * @param t the current tile + * @return the roadbits of the road over the rail + */ static inline RoadBits GetCrossingRoadBits(TileIndex tile) { return GetCrossingRoadAxis(tile) == AXIS_X ? ROAD_X : ROAD_Y; } +/** + * Return if the tile is a valid tile for a crossing. + * + * @note function is overloaded + * @param tile the curent tile + * @param ax the axis of the road over the rail + * @return true if it is a valid tile + */ +static inline bool IsPossibleCrossing(const TileIndex tile, Axis ax) +{ + return (IsTileType(tile, MP_RAILWAY) && + !HasSignals(tile) && + GetTrackBits(tile) == (ax == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X) && + GetTileSlope(tile, NULL) == SLOPE_FLAT); +} + +/** + * Return if the tile is a valid tile for a crossing. + * + * @note function is overloaded + * @param tile the curent tile + * @param rb the roadbits of the road over the rail + * @return true if it is a valid tile + */ +static inline bool IsPossibleCrossing(const TileIndex tile, RoadBits rb) { + return IsPossibleCrossing(tile, rb == ROAD_X ? AXIS_X : AXIS_Y); +} + static inline TrackBits GetCrossingRailBits(TileIndex tile) { return AxisToTrackBits(OtherAxis(GetCrossingRoadAxis(tile))); @@ -304,7 +343,27 @@ */ TrackBits GetAnyRoadTrackBits(TileIndex tile, RoadType rt); +static const TileIndexDiffC _roadblock_tileadd[] = { + { 0, -1}, ///< Direction NW + { 1, 0}, ///< Direction SW + { 0, 1}, ///< Direction SE + {-1, 0}, ///< Direction NE + /* Store the first 3 elements again. + * Lets us rotate without using &3. */ + { 0, -1}, ///< Direction NW + { 1, 0}, ///< Direction SW + { 0, 1} ///< Direction SE +}; + +/** + * Clean up unneccesary RoadBits of a planed tile. + * @param tile current tile + * @param rcmd planed RoadBits + * @return optimised RoadBits + */ +RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits rcmd); + static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, TownID town, Owner road, Owner tram, Owner hway) { SetTileType(t, MP_ROAD); Property changes on: ___________________________________________________________________ Name: svk:merge +6aa0318a-3be1-0310-93fa-89fd2396df07:/trunk:10749