Index: src/road.h
===================================================================
--- src/road.h (Revision 10850)
+++ src/road.h (Arbeitskopie)
@@ -6,6 +6,7 @@
#define ROAD_H
#include "helpers.hpp"
+#include "rail_map.h"
/**
* The different roadtypes we support
@@ -116,6 +117,19 @@
}
/**
+ * Calculate the mirrored RoadBits
+ *
+ * Simply move the bits to their new position.
+ *
+ * @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));
+}
+
+/**
* Create the road-part which belongs to the given DiagDirection
*
* This function returns a RoadBits value which belongs to
@@ -160,7 +174,56 @@
*/
bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road, RoadType rt);
+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);
+
+/**
+ * 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);
+}
+
+/**
* Draw the catenary for tram road bits
* @param ti information about the tile (position, slope)
* @param tram the roadbits to draw the catenary for
Index: src/town_cmd.cpp
===================================================================
--- src/town_cmd.cpp (Revision 10850)
+++ src/town_cmd.cpp (Arbeitskopie)
@@ -563,20 +563,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
@@ -791,34 +777,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;
}
}
@@ -947,22 +906,10 @@
* Always OK. */
_grow_town_result = 0;
- switch (_patches.town_layout) {
- default: NOT_REACHED();
+ if (_patches.town_layout == TL_NO_ROADS) return; ///< Disallow roads
- case TL_NO_ROADS: /* Disallow Roads */
- return;
+ rcmd = ROAD_ALL;
- 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;
bool allow_house = false;
@@ -1055,6 +1002,10 @@
default:
build_road_and_exit:
+ rcmd = CleanUpRoadBits(tile, rcmd);
+ /* If there are no more Roadbits further stuff is unneeded */
+ if (rcmd == ROAD_NONE) return;
+
if (CmdSucceeded(DoCommand(tile, rcmd, t1->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD))) {
_grow_town_result = -1;
}
Index: src/road.cpp
===================================================================
--- src/road.cpp (Revision 0)
+++ src/road.cpp (Revision 0)
@@ -0,0 +1,134 @@
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "road.h"
+#include "road_map.h"
+#include "water_map.h"
+#include "macros.h"
+
+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;
+}
+
Index: src/road_cmd.cpp
===================================================================
--- src/road_cmd.cpp (Revision 10850)
+++ src/road_cmd.cpp (Arbeitskopie)
@@ -1195,8 +1195,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);
@@ -1234,6 +1234,27 @@
}
} 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) {
+
+ /* Protect against roads with no roadbits */
+ if (new_rb == ROAD_NONE) {
+ const RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(ROADTYPE_ROAD));
+
+ if (rts == ROADTYPES_NONE) {
+ DoClearSquare(tile);
+ } else {
+ SetRoadBits(tile, ROAD_NONE, ROADTYPE_ROAD);
+ SetRoadTypes(tile, rts);
+ }
+ } else {
+ SetRoadBits(tile, new_rb, ROADTYPE_ROAD);
+ }
+ }
+
MarkTileDirtyByTile(tile);
}
}
Index: projects/openttd.vcproj
===================================================================
--- projects/openttd.vcproj (Revision 10850)
+++ projects/openttd.vcproj (Arbeitskopie)
@@ -320,6 +320,9 @@
RelativePath=".\..\src\rail.cpp">
+
+
+
+
Index: source.list
===================================================================
--- source.list (Revision 10850)
+++ source.list (Arbeitskopie)
@@ -57,6 +57,7 @@
players.cpp
queue.cpp
rail.cpp
+road.cpp
saveload.cpp
screenshot.cpp
#if SDL