From b99c83246b4029f91579712ae9044fa9e1f6b2c9 Mon Sep 17 00:00:00 2001 From: frosch Date: Tue, 22 Jan 2008 16:08:17 +0000 Subject: [PATCH] (svn r11946) -Fix: slope detection of bridge ramps. YAPF failed for steep slopes. Trolly failed for a lot. --- src/ai/trolly/pathfinder.cpp | 24 +++++------------------- src/bridge.h | 1 + src/tunnelbridge_cmd.cpp | 17 +++++++++++++++-- src/yapf/yapf_costbase.hpp | 8 +++----- 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/ai/trolly/pathfinder.cpp b/src/ai/trolly/pathfinder.cpp index d3dcc96c2d..caef801476 100644 --- a/src/ai/trolly/pathfinder.cpp +++ b/src/ai/trolly/pathfinder.cpp @@ -359,10 +359,6 @@ static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *curr 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 @@ static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current, 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 @@ static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current, } 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 @@ static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current, 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 diff --git a/src/bridge.h b/src/bridge.h index 9ed6c559ee..0f17980b16 100644 --- a/src/bridge.h +++ b/src/bridge.h @@ -32,6 +32,7 @@ extern const Bridge orig_bridge[MAX_BRIDGES]; extern Bridge _bridge[MAX_BRIDGES]; Foundation GetBridgeFoundation(Slope tileh, Axis axis); +bool HasBridgeFlatRamp(Slope tileh, Axis axis); static inline const Bridge *GetBridge(uint i) { diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index c79f272abc..52762f9f5d 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -90,6 +90,20 @@ Foundation GetBridgeFoundation(Slope tileh, Axis axis) 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 @@ void DrawBridgeMiddle(const TileInfo* ti) 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 @@ static uint GetSlopeZ_TunnelBridge(TileIndex tile, uint x, uint y) 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(); diff --git a/src/yapf/yapf_costbase.hpp b/src/yapf/yapf_costbase.hpp index 2793aab9f3..010c53ce1a 100644 --- a/src/yapf/yapf_costbase.hpp +++ b/src/yapf/yapf_costbase.hpp @@ -13,11 +13,9 @@ struct CYapfCostBase { // 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