Loading

Paste #pdbjhwad9

  1. /**
  2.  * Check whether a river could (logically) flow into a lock.
  3.  * @param tile the middle tile of a lock.
  4.  * @recursive whether the function is being called recursively.
  5.  * @return true iff the water can be flowing into a lock.
  6.  */
  7. bool FlowsLock(TileIndex tile, bool recursive = false)
  8. {
  9.     DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile));
  10.     if (dir == INVALID_DIAGDIR) return false;
  11.  
  12.     int delta_mid = TileOffsByDiagDir(dir);
  13.     if (!IsTileFlat(tile + delta_mid)) return false;
  14.     if (!IsTileFlat(tile - delta_mid)) return false;
  15.  
  16.     if (!recursive) return true;
  17.  
  18.     DiagDirection dir_rot = ChangeDiagDir(dir, DIAGDIRDIFF_90RIGHT);
  19.     int delta = TileOffsByDiagDir(dir_rot);
  20.  
  21.     for (int m = -1; m <= 1; m += 2) {
  22.         if (IsValidTile(tile + m * delta_mid)) {
  23.             if (DistanceFromEdgeDir(tile + m * delta_mid, dir) == 0 || DistanceFromEdgeDir(tile + m * delta_mid, ReverseDiagDir(dir)) == 0) {
  24.                 return false;
  25.             }
  26.  
  27.             if (IsValidTile(tile + m * 2 * delta_mid)) {
  28.                 if (!IsTileFlat(tile + m * 2 * delta_mid)) {
  29.                     return false;
  30.                 }
  31.  
  32.                 if (IsValidTile(tile + m * 3 * delta_mid)) {
  33.                     if ((GetInclinedSlopeDirection(GetTileSlope(tile + m * 3 * delta_mid)) == dir ||
  34.                             GetInclinedSlopeDirection(GetTileSlope(tile + m * 3 * delta_mid)) == ReverseDiagDir(dir)) &&
  35.                             FlowsLock(tile + m * 3 * delta_mid)) {
  36.                         return false;
  37.                     }
  38.                 }
  39.             }
  40.         }
  41.  
  42.         for (int d = -1; d <= 1; d += 2) {
  43.             if (IsValidTile(tile + m * delta_mid + d * delta)) {
  44.                 if (!IsTileFlat(tile + m * delta_mid + d * delta) &&
  45.                         (GetInclinedSlopeDirection(GetTileSlope(tile + m * delta_mid + d * delta)) == dir_rot ||
  46.                         GetInclinedSlopeDirection(GetTileSlope(tile + m * delta_mid + d * delta)) == ReverseDiagDir(dir_rot)) &&
  47.                         FlowsLock(tile + m * delta_mid + d * delta)) {
  48.                     return false;
  49.                 }
  50.  
  51.                 if (IsValidTile(tile + m * delta_mid + d * 2 * delta)) {
  52.                     if (!IsTileFlat(tile + m * delta_mid + d * 2 * delta) &&
  53.                             (GetInclinedSlopeDirection(GetTileSlope(tile + m * delta_mid + d * 2 * delta)) == dir_rot ||
  54.                             GetInclinedSlopeDirection(GetTileSlope(tile + m * delta_mid + d * 2 * delta)) == ReverseDiagDir(dir_rot)) &&
  55.                             FlowsLock(tile + m * delta_mid + d * 2 * delta)) {
  56.                         return false;
  57.                     }
  58.                 }
  59.  
  60.                 if (IsValidTile(tile + m * 2 * delta_mid + d * delta)) {
  61.                     if (IsTileFlat(tile + m * delta_mid + d * delta) && !IsTileFlat(tile + m * 2 * delta_mid + d * delta)) {
  62.                         return false;
  63.                     }
  64.  
  65.                     if (!IsTileFlat(tile + m * 2 * delta_mid + d * delta) &&
  66.                             (GetInclinedSlopeDirection(GetTileSlope(tile + m * 2 * delta_mid + d * delta)) == dir_rot ||
  67.                             GetInclinedSlopeDirection(GetTileSlope(tile + m * 2 * delta_mid + d * delta)) == ReverseDiagDir(dir_rot)) &&
  68.                             FlowsLock(tile + m * 2 * delta_mid + d * delta)) {
  69.                         return false;
  70.                     }
  71.  
  72.                     if (IsValidTile(tile + m * 3 * delta_mid + d * delta)) {
  73.                         if ((GetInclinedSlopeDirection(GetTileSlope(tile + m * 3 * delta_mid + d * delta)) == dir ||
  74.                                 GetInclinedSlopeDirection(GetTileSlope(tile + m * 3 * delta_mid + d * delta)) == ReverseDiagDir(dir)) &&
  75.                                 FlowsLock(tile + m * 3 * delta_mid + d * delta)) {
  76.                             return false;
  77.                         }
  78.                     }
  79.                 }
  80.             }
  81.         }
  82.     }
  83.  
  84.     return true;
  85. }
  86.  
  87. /**
  88.  * Check whether a river at begin could (logically) flow down to end.
  89.  * @param begin The origin of the flow.
  90.  * @param end The destination of the flow.
  91.  * @return True iff the water can be flowing down.
  92.  */
  93. static bool FlowsDown(TileIndex begin, TileIndex end)
  94. {
  95.     assert(DistanceManhattan(begin, end) == 1);
  96.  
  97.     int heightBegin;
  98.     int heightEnd;
  99.     Slope slopeBegin = GetTileSlope(begin, &heightBegin);
  100.     Slope slopeEnd   = GetTileSlope(end, &heightEnd);
  101.  
  102.     return heightEnd <= heightBegin &&
  103.             /* Slope either is inclined or flat; rivers don't support other slopes. */
  104.             (slopeEnd == SLOPE_FLAT || (IsInclinedSlope(slopeEnd) && FlowsLock(end, true))) &&
  105.             /* Slope continues, then it must be lower... or either end must be flat. */
  106.             ((slopeEnd == slopeBegin && heightEnd < heightBegin) || slopeEnd == SLOPE_FLAT || (slopeBegin == SLOPE_FLAT && GetTileMaxZ(end) == heightBegin));
  107. }

Comments