Пример #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);
        }
Пример #2
0
        /**
         * Find file information of a file by its name from the file list.
         * @param file The filename to return information about. Can be the actual name
         *             or a numbered entry into the filename list.
         * @return The information on the file, or \c NULL if the file is not available.
         */
        public FiosItem FindItem(string file)
        {
            foreach (var item in files)
            {
                if (file == item.name || file == item.title)
                {
                    return(item);
                }
            }

            /* If no name matches, try to parse it as number */
            if (int.TryParse(file, out var i) && MathFuncs.IsInsideMM(i, 0, (uint)this.files.Count))
            {
                return(this[i]);
            }

            /* As a last effort assume it is an OpenTTD savegame and
             * that the ".sav" part was not given. */
            var long_file = file + ".sav";

            foreach (var item in files)
            {
                if (long_file == item.name || long_file == item.title)
                {
                    return(item);
                }
            }

            return(null);
        }
Пример #3
0
        /**
         * Add the rail types that are to be introduced at the given date.
         * @param current The currently available railtypes.
         * @param date    The date for the introduction comparisons.
         * @return The rail types that should be available when date
         *         introduced rail types are taken into account as well.
         */
        public RailTypes AddDateIntroducedRailTypes(RailTypes current, Date date)
        {
            RailTypes rts = current;

            for (RailType rt = RailType.RAILTYPE_BEGIN; rt != RailType.RAILTYPE_END; rt++)
            {
                RailtypeInfo rti = GetRailTypeInfo(rt);
                /* Unused rail type. */
                if (rti.label == 0)
                {
                    continue;
                }

                /* Not date introduced. */
                if (!MathFuncs.IsInsideMM(rti.introduction_date, 0, MAX_DAY))
                {
                    continue;
                }

                /* Not yet introduced at this date. */
                if (rti.introduction_date > date)
                {
                    continue;
                }

                /* Have we introduced all required railtypes? */
                RailTypes required = rti.introduction_required_railtypes;
                if ((rts & required) != required)
                {
                    continue;
                }

                rts |= rti.introduces_railtypes;
            }

            /* When we added railtypes we need to run this method again; the added
             * railtypes might enable more rail types to become introduced. */
            return(rts == current ? rts : AddDateIntroducedRailTypes(rts, date));
        }
Пример #4
0
        /**
         * (Re)allocates a map with the given dimension
         * @param size_x the width of the map along the NE/SW edge
         * @param size_y the 'height' of the map along the SE/NW edge
         */

        public static void AllocateMap(uint size_x, uint size_y)
        {
            /* Make sure that the map size is within the limits and that
             * size of both axes is a power of 2. */
            if (!MathFuncs.IsInsideMM((int)size_x, TileConstants.MIN_MAP_SIZE, TileConstants.MAX_MAP_SIZE + 1) ||
                !MathFuncs.IsInsideMM((int)size_y, TileConstants.MIN_MAP_SIZE, TileConstants.MAX_MAP_SIZE + 1) ||
                (size_x & (size_x - 1)) != 0 ||
                (size_y & (size_y - 1)) != 0)
            {
                throw new Exception("Invalid map size");
            }

            Log.Error($"Allocating map of size {size_x}x{size_y}");

            _map_log_x     = BitMath.FindFirstBit(size_x);
            _map_log_y     = BitMath.FindFirstBit(size_y);
            _map_size_x    = size_x;
            _map_size_y    = size_y;
            _map_size      = size_x * size_y;
            _map_tile_mask = _map_size - 1;

            _m  = new Tile[_map_size];
            _me = new TileExtended[_map_size];
        }