Loading

Revision differences

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