Loading

Revision differences

Old revision #pee8qlkwuNew revision #pthkwwqir
6 */  6 */  
7static bool GrowingBlocksWaterConnection(TileIndex tile)  7static bool GrowingBlocksWaterConnection(TileIndex tile)  
8{  8{  
9    if (!IsValidTile(tile) || !IsCoastTile(tile)) return false;  9    if (!IsValidTile(tile)) return false;
10  10  
11    Slope slope = GetTileSlope(tile);  11    Slope slope = GetTileSlope(tile);  
12    /* Is this a coast tile with one corner raised ? */  12    /* Is this a coast tile with one corner raised ? */  
13    if (IsSlopeWithOneCornerRaised(slope)) {  13    if (IsSlopeWithOneCornerRaised(slope) && IsCoastTile(tile)) {
14        const Track main_track_mask = TrackBitsToTrack(TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0)));  14        Corner corner = GetHighestSlopeCorner(slope);
15        const Track oppo_track_mask = TrackToOppositeTrack(main_track_mask);  15        Corner opposite_corner = OppositeCorner(corner);
16        const Trackdir main_trackdir = TrackToTrackdir(main_track_mask);    
17        const Trackdir oppo_trackdir = TrackToTrackdir(oppo_track_mask);    
18        const DiagDirection main_dir_1 = TrackdirToExitdir(main_trackdir);    
19        const DiagDirection main_dir_2 = TrackdirToExitdir(ReverseTrackdir(main_trackdir));    
20        const DiagDirection oppo_dir_1 = TrackdirToExitdir(oppo_trackdir);    
21        const DiagDirection oppo_dir_2 = TrackdirToExitdir(ReverseTrackdir(oppo_trackdir));    
22  16  
23        TrackBits main_trackbits_mask_1 = DiagdirReachesTracks(main_dir_1);  23        static const Direction corner_to_direction[] = { DIR_W, DIR_S, DIR_E, DIR_N };
24        TrackBits main_trackbits_mask_2 = DiagdirReachesTracks(main_dir_2);  24        extern const TileIndexDiffC _tileoffs_by_dir[DIR_END];
25        TrackBits oppo_trackbits_mask_1 = DiagdirReachesTracks(oppo_dir_1);  25        TileIndexDiffC diffc = _tileoffs_by_dir[corner_to_direction[opposite_corner]];
26        TrackBits oppo_trackbits_mask_2 = DiagdirReachesTracks(oppo_dir_2);    
27  20  
28        if (_settings_game.pf.forbid_90_deg) {  21        TileIndex opposite_tile = TileAddWrap(tile, diffc.x, diffc.y);
29            main_trackbits_mask_1 &= ~TrackCrossesTracks(main_track_mask);  22        if (IsValidTile(opposite_tile)) {
30            main_trackbits_mask_2 &= ~TrackCrossesTracks(main_track_mask);  23            static const struct { TrackBits track_mask_1, track_mask_2, track_mask_1_90_deg, track_mask_2_90_deg; } track_bit_table[] = {
31            oppo_trackbits_mask_1 &= ~TrackCrossesTracks(oppo_track_mask);  24                /*         t1x,t1y,t2x,t2y,              track_mask_1          ,        track_mask_2          track_mask_1_90_deg, track_mask_2_90_deg, opposite_tile */
32            oppo_trackbits_mask_2 &= ~TrackCrossesTracks(oppo_track_mask);  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 */
33        }  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            };
34  30  
35        Corner corner = GetHighestSlopeCorner(slope);  35            TileIndex tile_1 = TileAddWrap(tile, opposite_corner & 1 ? diffc.x : 0, opposite_corner & 1 ? 0 : diffc.y);
36        static const Direction corner_to_direction[] = { DIR_W, DIR_S, DIR_E, DIR_N };  36            TileIndex tile_2 = TileAddWrap(tile, opposite_corner & 1 ? 0 : diffc.x, opposite_corner & 1 ? diffc.y : 0);
37        TileIndex opposite_tile = AddTileIndexDiffCWrap(tile, TileIndexDiffCByDir(corner_to_direction[OppositeCorner(corner)]));    
38  33  
39        if (IsValidTile(opposite_tile)) {  39            bool forbid_90_deg = _settings_game.pf.forbid_90_deg;
40            TileIndex tile_1 = AddTileIndexDiffCWrap(tile, TileIndexDiffCByDiagDir(main_dir_1));    
41            TileIndex tile_2 = AddTileIndexDiffCWrap(tile, TileIndexDiffCByDiagDir(main_dir_2));    
42  35  
43            TrackBits track_1 = TrackStatusToTrackBits(GetTileTrackStatus(tile_1, TRANSPORT_WATER, 0));  36            TrackBits track_1 = TrackStatusToTrackBits(GetTileTrackStatus(tile_1, TRANSPORT_WATER, 0));  
44            TrackBits track_2 = TrackStatusToTrackBits(GetTileTrackStatus(tile_2, TRANSPORT_WATER, 0));  37            TrackBits track_2 = TrackStatusToTrackBits(GetTileTrackStatus(tile_2, TRANSPORT_WATER, 0));  
45  38  
46            TrackBits main_track_1 = main_trackbits_mask_1 & track_1;  46            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;
47            TrackBits main_track_2 = main_trackbits_mask_2 & track_2;  47            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;
48            TrackBits oppo_track_1 = oppo_trackbits_mask_1 & track_1;  48            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;
49            TrackBits oppo_track_2 = oppo_trackbits_mask_2 & track_2;  49            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;
50  43  
51            /* Is there a connection between tile_1 and tile_2 via tile? */  44            /* Is there a connection between tile_1 and tile_2 via tile? */  
52            if (main_track_1 && main_track_2) {  45            if (main_track_1 && main_track_2) {  
53                TrackBits oppo_trackbits = TrackStatusToTrackBits(GetTileTrackStatus(opposite_tile, TRANSPORT_WATER, 0));  53                TrackBits opposite_track = TrackStatusToTrackBits(GetTileTrackStatus(opposite_tile, TRANSPORT_WATER, 0));
54                /* Is there a track in the opposite_tile that can be used to try an alternative connection? */  54                /* Is there an opposite_track that can be used to try an alternative connection? */
55                if (HasTrack(oppo_trackbits, oppo_track_mask)) {  55                if (CornerToTrackBits(corner) & opposite_track) {
56                    TrackBits mirror = TRACK_BIT_CROSS | (corner & 1 ? TRACK_BIT_HORZ : TRACK_BIT_VERT);  49                    TrackBits mirror = TRACK_BIT_CROSS | (corner & 1 ? TRACK_BIT_HORZ : TRACK_BIT_VERT);  
57                    /* Is there a connection between tile_1 and tile_2 via opposite_tile? */  50                    /* Is there a connection between tile_1 and tile_2 via opposite_tile? */  
58                    if (oppo_track_1 & (main_track_1 ^ mirror) && oppo_track_2 & (main_track_2 ^ mirror)) {  58                    if (next_track_1 & (main_track_1 ^ mirror) && next_track_2 & (main_track_2 ^ mirror)) {
59                        /* There is an alternative connection. Town can grow on tile. */  52                        /* There is an alternative connection. Town can grow on tile. */  
60                        return false;  53                        return false;  
61                    }  54                    }  
62                }  55                }  
63                /* There is either no track or an incomplete connection via opposite_tile. */  63                /* There is either no opposite_track, or an incomplete connection via opposite_tile. */
64                return true;  57                return true;  
65            }  58            }  
66        }  59        }