/** * Check whether growing on a half-tile coast tile ends up blocking a water connection * * @param tile The target tile * @return true if building here blocks a water connection */ static bool NewGrowingBlocksWaterConnection(TileIndex tile) { if (!IsValidTile(tile) || !IsCoastTile(tile)) return false; Slope slope = GetTileSlope(tile); /* Is this a coast tile with one corner raised ? */ if (!IsSlopeWithOneCornerRaised(slope)) return false; Corner corner = GetHighestSlopeCorner(slope); /* Test opposite tile is valid */ static const Direction corner_to_direction[] = { DIR_W, DIR_S, DIR_E, DIR_N }; TileIndex opposite_tile = AddTileIndexDiffCWrap(tile, TileIndexDiffCByDir(corner_to_direction[OppositeCorner(corner)])); if (!IsValidTile(opposite_tile)) return false; /* Test adjacent tiles are traversible. */ Track track = TrackBitsToTrack(TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0))); Trackdir main_trackdir = TrackToTrackdir(track); DiagDirection main_dir_1 = TrackdirToExitdir(main_trackdir); DiagDirection main_dir_2 = TrackdirToExitdir(ReverseTrackdir(main_trackdir)); TrackBits trackbits_1 = TrackStatusToTrackBits(GetTileTrackStatus(AddTileIndexDiffCWrap(tile, TileIndexDiffCByDiagDir(main_dir_1)), TRANSPORT_WATER, 0)); TrackBits trackbits_2 = TrackStatusToTrackBits(GetTileTrackStatus(AddTileIndexDiffCWrap(tile, TileIndexDiffCByDiagDir(main_dir_2)), TRANSPORT_WATER, 0)); TrackBits main_track_1 = trackbits_1 & DiagdirReachesTracks(main_dir_1); TrackBits main_track_2 = trackbits_2 & DiagdirReachesTracks(main_dir_2); /* Is main tile connected to adjacent tiles? */ if (!main_track_1 || !main_track_2) return false; Track opposite_track = TrackToOppositeTrack(track); Trackdir oppo_trackdir = TrackToTrackdir(opposite_track); TrackBits oppo_track_1 = trackbits_1 & DiagdirReachesTracks(TrackdirToExitdir(oppo_trackdir)); TrackBits oppo_track_2 = trackbits_2 & DiagdirReachesTracks(TrackdirToExitdir(ReverseTrackdir(oppo_trackdir))); TrackBits mirror = TRACK_BIT_CROSS | (corner & 1 ? TRACK_BIT_HORZ : TRACK_BIT_VERT); /* Is there a connection between tile_1 and tile_2 via opposite_tile? */ if (HasTrack(TrackStatusToTrackBits(GetTileTrackStatus(opposite_tile, TRANSPORT_WATER, 0)), opposite_track) && oppo_track_1 & (main_track_1 ^ mirror) && oppo_track_2 & (main_track_2 ^ mirror)) return false; /* There is either no track or an incomplete connection via opposite_tile. */ return true; }