Loading

Paste #pthkwwqir

  1. /**
  2.  * Check whether growing on a half-tile coast tile ends up blocking a water connection
  3.  *
  4.  * @param tile The target tile
  5.  * @return true if building here blocks a water connection
  6.  */
  7. static bool GrowingBlocksWaterConnection(TileIndex tile)
  8. {
  9.     if (!IsValidTile(tile)) return false;
  10.  
  11.     Slope slope = GetTileSlope(tile);
  12.     /* Is this a coast tile with one corner raised ? */
  13.     if (IsSlopeWithOneCornerRaised(slope) && IsCoastTile(tile)) {
  14.         Corner corner = GetHighestSlopeCorner(slope);
  15.         Corner opposite_corner = OppositeCorner(corner);
  16.  
  17.         static const Direction corner_to_direction[] = { DIR_W, DIR_S, DIR_E, DIR_N };
  18.         extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
  19.         TileIndexDiffC diffc = _tileoffs_by_dir[corner_to_direction[opposite_corner]];
  20.  
  21.         TileIndex opposite_tile = TileAddWrap(tile, diffc.x, diffc.y);
  22.         if (IsValidTile(opposite_tile)) {
  23.             static const struct { TrackBits track_mask_1, track_mask_2, track_mask_1_90_deg, track_mask_2_90_deg; } track_bit_table[] = {
  24.                 /*         t1x,t1y,t2x,t2y,              track_mask_1          ,        track_mask_2          track_mask_1_90_deg, track_mask_2_90_deg, opposite_tile */
  25.                 /* CORNER_W  0,  1, -1,  0,  */ { TRACK_BIT_X | TRACK_BIT_RIGHT, TRACK_BIT_Y | TRACK_BIT_RIGHT, TRACK_BIT_3WAY_NE, TRACK_BIT_3WAY_SE }, /* -1,  1 */
  26.                 /* CORNER_S  1,  0,  0,  1,  */ { TRACK_BIT_Y | TRACK_BIT_UPPER, TRACK_BIT_X | TRACK_BIT_UPPER, TRACK_BIT_3WAY_NW, TRACK_BIT_3WAY_NE }, /*  1,  1 */
  27.                 /* CORNER_E  0, -1,  1,  0,  */ { TRACK_BIT_X | TRACK_BIT_LEFT , TRACK_BIT_Y | TRACK_BIT_LEFT , TRACK_BIT_3WAY_SW, TRACK_BIT_3WAY_NW }, /*  1, -1 */
  28.                 /* CORNER_N -1,  0,  0, -1,  */ { TRACK_BIT_Y | TRACK_BIT_LOWER, TRACK_BIT_X | TRACK_BIT_LOWER, TRACK_BIT_3WAY_SE, TRACK_BIT_3WAY_SW }, /* -1, -1 */
  29.             };
  30.  
  31.             TileIndex tile_1 = TileAddWrap(tile, opposite_corner & 1 ? diffc.x : 0, opposite_corner & 1 ? 0 : diffc.y);
  32.             TileIndex tile_2 = TileAddWrap(tile, opposite_corner & 1 ? 0 : diffc.x, opposite_corner & 1 ? diffc.y : 0);
  33.  
  34.             bool forbid_90_deg = _settings_game.pf.forbid_90_deg;
  35.  
  36.             TrackBits track_1 = TrackStatusToTrackBits(GetTileTrackStatus(tile_1, TRANSPORT_WATER, 0));
  37.             TrackBits track_2 = TrackStatusToTrackBits(GetTileTrackStatus(tile_2, TRANSPORT_WATER, 0));
  38.  
  39.             TrackBits next_track_1 = (forbid_90_deg ? track_bit_table[corner].track_mask_1 : track_bit_table[corner].track_mask_1_90_deg) & track_1;
  40.             TrackBits next_track_2 = (forbid_90_deg ? track_bit_table[corner].track_mask_2 : track_bit_table[corner].track_mask_2_90_deg) & track_2;
  41.             TrackBits main_track_1 = (forbid_90_deg ? track_bit_table[opposite_corner].track_mask_2 : track_bit_table[opposite_corner].track_mask_2_90_deg) & track_1;
  42.             TrackBits main_track_2 = (forbid_90_deg ? track_bit_table[opposite_corner].track_mask_1 : track_bit_table[opposite_corner].track_mask_1_90_deg) & track_2;
  43.  
  44.             /* Is there a connection between tile_1 and tile_2 via tile? */
  45.             if (main_track_1 && main_track_2) {
  46.                 TrackBits opposite_track = TrackStatusToTrackBits(GetTileTrackStatus(opposite_tile, TRANSPORT_WATER, 0));
  47.                 /* Is there an opposite_track that can be used to try an alternative connection? */
  48.                 if (CornerToTrackBits(corner) & opposite_track) {
  49.                     TrackBits mirror = TRACK_BIT_CROSS | (corner & 1 ? TRACK_BIT_HORZ : TRACK_BIT_VERT);
  50.                     /* Is there a connection between tile_1 and tile_2 via opposite_tile? */
  51.                     if (next_track_1 & (main_track_1 ^ mirror) && next_track_2 & (main_track_2 ^ mirror)) {
  52.                         /* There is an alternative connection. Town can grow on tile. */
  53.                         return false;
  54.                     }
  55.                 }
  56.                 /* There is either no opposite_track, or an incomplete connection via opposite_tile. */
  57.                 return true;
  58.             }
  59.         }
  60.     }
  61.     /* There was no connection via tile, or it was incomplete, or the opposite_tile is outside the map. */
  62.     return false;
  63. }

Version history

Revision # Author Created at
pee8qlkwu Anonymous 24 Feb 2019, 14:39:29 UTC Diff

Comments