Example #1
0
/**
 * Finds the distance for the closest tile with water/land given a tile
 * @param tile  the tile to find the distance too
 * @param water whether to find water or land
 * @return distance to nearest water (max 0x7F) / land (max 0x1FF; 0x200 if there is no land)
 */

        uint GetClosestWaterDistance(TileIndex tile, bool water)
        {
            if (WaterMap.HasTileWaterGround(tile) == water)
            {
                return(0);
            }

            uint max_dist = (uint)(water ? 0x7F : 0x200);

            int x = (int)TileX(tile);
            int y = (int)TileY(tile);

            uint max_x  = MapMaxX();
            uint max_y  = MapMaxY();
            uint min_xy = (uint)(_settings_game.construction.freeform_edges ? 1 : 0);

            /* go in a 'spiral' with increasing manhattan distance in each iteration */
            for (uint dist = 1; dist < max_dist; dist++)
            {
                /* next 'diameter' */
                y--;

                /* going counter-clockwise around this square */
                for (var dir = (int)DiagDirection.DIAGDIR_BEGIN; dir < (int)DiagDirection.DIAGDIR_END; dir++)
                {
                    int dx = ddx[dir];
                    int dy = ddy[dir];

                    /* each side of this square has length 'dist' */
                    for (uint a = 0; a < dist; a++)
                    {
                        /* MP_VOID tiles are not checked (interval is [min; max) for IsInsideMM())*/
                        if (MathFuncs.IsInsideMM(x, min_xy, max_x) && MathFuncs.IsInsideMM(y, min_xy, max_y))
                        {
                            TileIndex t = TileXY((uint)x, (uint)y);
                            if (WaterMap.HasTileWaterGround(t) == water)
                            {
                                return(dist);
                            }
                        }
                        x += dx;
                        y += dy;
                    }
                }
            }

            if (!water)
            {
                /* no land found - is this a water-only map? */
                for (TileIndex t = 0; t < MapSize(); t++)
                {
                    if (!TileMap.IsTileType(t, TileType.MP_VOID) && !TileMap.IsTileType(t, TileType.MP_WATER))
                    {
                        return(0x1FF);
                    }
                }
            }

            return(max_dist);
        }
Example #2
0
/**
 * Make the given tile a station tile.
 * @param t the tile to make a station tile
 * @param o the owner of the station
 * @param sid the station to which this tile belongs
 * @param st the type this station tile
 * @param section the StationGfx to be used for this tile
 * @param wc The water class of the station
 */
        public static void MakeStation(this TileIndex t, Owner o, StationID sid, StationType st, byte section,
                                       WaterClass wc = WaterClass.WATER_CLASS_INVALID)
        {
            TileMap.SetTileType(t, TileType.MP_STATION);
            TileMap.SetTileOwner(t, o);
            WaterMap.SetWaterClass(t, wc);
            Map._m[t].m2  = sid;
            Map._m[t].m3  = 0;
            Map._m[t].m4  = 0;
            Map._m[t].m5  = section;
            Map._me[t].m6 = BitMath.SB(Map._me[t].m6, 2, 1, 0);
            Map._me[t].m6 = BitMath.SB(Map._me[t].m6, 3, 3, st);
            Map._me[t].m7 = 0;
        }
Example #3
0
/**
 * Clean up unnecessary RoadBits of a planed tile.
 * @param tile current tile
 * @param org_rb planed RoadBits
 * @return optimised RoadBits
 */
        RoadBits CleanUpRoadBits(TileIndex tile, RoadBits org_rb)
        {
            if (!TileMap.IsValidTile(tile))
            {
                return(RoadBits.ROAD_NONE);
            }
            for (DiagDirection dir = DiagDirection.DIAGDIR_BEGIN; dir < DiagDirection.DIAGDIR_END; dir++)
            {
                TileIndex neighbor_tile = TileAddByDiagDir(tile, dir);

                /* Get the Roadbit pointing to the neighbor_tile */
                RoadBits target_rb = DiagDirToRoadBits(dir);

                /* If the roadbit is in the current plan */
                if (org_rb & target_rb)
                {
                    bool           connective  = false;
                    const RoadBits mirrored_rb = MirrorRoadBits(target_rb);

                    if (TileMap.IsValidTile(neighbor_tile))
                    {
                        switch (TileMap.GetTileType(neighbor_tile))
                        {
                        /* Always connective ones */
                        case TileType.MP_CLEAR:
                        case TileType.MP_TREES:
                            connective = true;
                            break;

                        /* The conditionally connective ones */
                        case TileType.MP_TUNNELBRIDGE:
                        case TileType.MP_STATION:
                        case TileType.MP_ROAD:
                            if (IsNormalRoadTile(neighbor_tile))
                            {
                                /* Always connective */
                                connective = true;
                            }
                            else
                            {
                                const RoadBits neighbor_rb =
                                    GetAnyRoadBits(neighbor_tile, RoadType.ROADTYPE_ROAD) |
                                    GetAnyRoadBits(neighbor_tile, RoadType.ROADTYPE_TRAM);

                                /* Accept only connective tiles */
                                connective = (neighbor_rb & mirrored_rb) != RoadBits.ROAD_NONE;
                            }
                            break;

                        case TileType.MP_RAILWAY:
                            connective = IsPossibleCrossing(neighbor_tile, DiagDirToAxis(dir));
                            break;

                        case TileType.MP_WATER:
                            /* Check for real water tile */
                            connective = !WaterMap.IsWater(neighbor_tile);
                            break;

                        /* The definitely not connective ones */
                        default: break;
                        }
                    }

                    /* If the neighbor tile is inconnective, remove the planed road connection to it */
                    if (!connective)
                    {
                        org_rb ^= target_rb;
                    }
                }
            }

            return(org_rb);
        }