(svn r11946) -Fix: slope detection of bridge ramps.
authorfrosch
Tue, 22 Jan 2008 16:08:17 +0000
changeset 8875 ffcab947226b
parent 8874 c165c8f53102
child 8876 a0b7938c6082
(svn r11946) -Fix: slope detection of bridge ramps.
YAPF failed for steep slopes.
Trolly failed for a lot.
src/ai/trolly/pathfinder.cpp
src/bridge.h
src/tunnelbridge_cmd.cpp
src/yapf/yapf_costbase.hpp
--- a/src/ai/trolly/pathfinder.cpp	Tue Jan 22 15:47:40 2008 +0000
+++ b/src/ai/trolly/pathfinder.cpp	Tue Jan 22 16:08:17 2008 +0000
@@ -359,10 +359,6 @@
 
 extern Foundation GetRailFoundation(Slope tileh, TrackBits bits); // XXX function declaration in .c
 extern Foundation GetRoadFoundation(Slope tileh, RoadBits bits); // XXX function declaration in .c
-extern Foundation GetBridgeFoundation(Slope tileh, Axis); // XXX function declaration in .c
-enum BridgeFoundation {
-	BRIDGE_NO_FOUNDATION = 1 << 0 | 1 << 3 | 1 << 6 | 1 << 9 | 1 << 12,
-};
 
 // The most important function: it calculates the g-value
 static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current, OpenListNode *parent)
@@ -403,10 +399,10 @@
 	if (parent_tileh != SLOPE_FLAT && parent->path.parent != NULL) {
 		// Skip if the tile was from a bridge or tunnel
 		if (parent->path.node.user_data[0] == 0 && current->user_data[0] == 0) {
+			static const uint32 SLOPED_TILEHS = (1 << SLOPE_NW) | (1 << SLOPE_SW) |  (1 << SLOPE_SE) | (1 << SLOPE_NE);
 			if (PathFinderInfo->rail_or_road) {
 				Foundation f = GetRailFoundation(parent_tileh, (TrackBits)(1 << AiNew_GetRailDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile)));
-				// Maybe is BRIDGE_NO_FOUNDATION a bit strange here, but it contains just the right information..
-				if (IsInclinedFoundation(f) || (!IsFoundation(f) && HasBit(BRIDGE_NO_FOUNDATION, parent_tileh))) {
+				if (IsInclinedFoundation(f) || (!IsFoundation(f) && HasBit(SLOPED_TILEHS, parent_tileh))) {
 					res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
 				} else {
 					res += AI_PATHFINDER_FOUNDATION_PENALTY;
@@ -414,7 +410,7 @@
 			} else {
 				if (!IsRoad(parent->path.node.tile) || !IsTileType(parent->path.node.tile, MP_TUNNELBRIDGE)) {
 					Foundation f = GetRoadFoundation(parent_tileh, (RoadBits)AiNew_GetRoadDirection(parent->path.parent->node.tile, parent->path.node.tile, current->tile));
-					if (IsInclinedFoundation(f) || (!IsFoundation(f) && HasBit(BRIDGE_NO_FOUNDATION, parent_tileh))) {
+					if (IsInclinedFoundation(f) || (!IsFoundation(f) && HasBit(SLOPED_TILEHS, parent_tileh))) {
 						res += AI_PATHFINDER_TILE_GOES_UP_PENALTY;
 					} else {
 						res += AI_PATHFINDER_FOUNDATION_PENALTY;
@@ -439,19 +435,9 @@
 		res += AI_PATHFINDER_BRIDGE_PENALTY * GetBridgeLength(current->tile, parent->path.node.tile);
 		// Check if we are going up or down, first for the starting point
 		// In user_data[0] is at the 8th bit the direction
-		if (!HasBit(BRIDGE_NO_FOUNDATION, parent_tileh)) {
-			if (IsLeveledFoundation(GetBridgeFoundation(parent_tileh, (Axis)((current->user_data[0] >> 8) & 1)))) {
-				res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
-			}
-		}
+		if (!HasBridgeFlatRamp(parent_tileh, (Axis)((current->user_data[0] >> 8) & 1))) res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
 		// Second for the end point
-		if (!HasBit(BRIDGE_NO_FOUNDATION, tileh)) {
-			if (IsLeveledFoundation(GetBridgeFoundation(tileh, (Axis)((current->user_data[0] >> 8) & 1)))) {
-				res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
-			}
-		}
-		if (parent_tileh == SLOPE_FLAT) res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
-		if (tileh == SLOPE_FLAT) res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
+		if (!HasBridgeFlatRamp(tileh, (Axis)((current->user_data[0] >> 8) & 1))) res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
 	}
 
 	//  To prevent the AI from taking the fastest way in tiles, but not the fastest way
--- a/src/bridge.h	Tue Jan 22 15:47:40 2008 +0000
+++ b/src/bridge.h	Tue Jan 22 16:08:17 2008 +0000
@@ -32,6 +32,7 @@
 extern Bridge _bridge[MAX_BRIDGES];
 
 Foundation GetBridgeFoundation(Slope tileh, Axis axis);
+bool HasBridgeFlatRamp(Slope tileh, Axis axis);
 
 static inline const Bridge *GetBridge(uint i)
 {
--- a/src/tunnelbridge_cmd.cpp	Tue Jan 22 15:47:40 2008 +0000
+++ b/src/tunnelbridge_cmd.cpp	Tue Jan 22 16:08:17 2008 +0000
@@ -90,6 +90,20 @@
 	return (HasSlopeHighestCorner(tileh) ? InclinedFoundation(axis) : FlatteningFoundation(tileh));
 }
 
+/**
+ * Determines if the track on a bridge ramp is flat or goes up/down.
+ *
+ * @param tileh Slope of the tile under the bridge head
+ * @param axis Orientation of bridge
+ * @return true iff the track is flat.
+ */
+bool HasBridgeFlatRamp(Slope tileh, Axis axis)
+{
+	ApplyFoundationToSlope(GetBridgeFoundation(tileh, axis), &tileh);
+	/* If the foundation slope is flat the bridge has a non-flat ramp and vice versa. */
+	return (tileh != SLOPE_FLAT);
+}
+
 static inline const PalSpriteID *GetBridgeSpriteTable(int index, byte table)
 {
 	const Bridge *bridge = &_bridge[index];
@@ -1084,7 +1098,6 @@
 
 static uint GetSlopeZ_TunnelBridge(TileIndex tile, uint x, uint y)
 {
-	static const uint32 BRIDGE_HORZ_RAMP = (1 << SLOPE_SW) | (1 << SLOPE_SE) | (1 << SLOPE_NW) | (1 << SLOPE_NE);
 	uint z;
 	Slope tileh = GetTileSlope(tile, &z);
 
@@ -1106,7 +1119,7 @@
 		if (5 <= pos && pos <= 10) {
 			uint delta;
 
-			if (HasBit(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT;
+			if (tileh != SLOPE_FLAT) return z + TILE_HEIGHT;
 
 			switch (dir) {
 				default: NOT_REACHED();
--- a/src/yapf/yapf_costbase.hpp	Tue Jan 22 15:47:40 2008 +0000
+++ b/src/yapf/yapf_costbase.hpp	Tue Jan 22 16:08:17 2008 +0000
@@ -13,11 +13,9 @@
 				// it is bridge ramp, check if we are entering the bridge
 				if (GetTunnelBridgeDirection(tile) != TrackdirToExitdir(td)) return false; // no, we are living it, no penalty
 				// we are entering the bridge
-				// if the tile slope is downwards, then bridge ramp has not upward slope
-				uint tile_slope = GetTileSlope(tile, NULL) & 0x0F;
-				if ((c_upwards_slopes[tile_slope] & TrackdirToTrackdirBits(ReverseTrackdir(td))) != 0) return false; // tile under ramp goes down, no penalty
-				// tile under ramp isn't going down, so ramp must go up
-				return true;
+				Slope tile_slope = GetTileSlope(tile, NULL);
+				Axis axis = DiagDirToAxis(GetTunnelBridgeDirection(tile));
+				return !HasBridgeFlatRamp(tile_slope, axis);
 			} else {
 				// not bridge ramp
 				if (IsTunnelTile(tile)) return false; // tunnel entry/exit doesn't slope