示例#1
0
        /// <summary>
        /// Transforms regular AutoTile input data into an output format that is optimized for
        /// efficient reading and updating operations.
        /// </summary>
        /// <param name="autoTileIndex"></param>
        /// <param name="autoTileInput"></param>
        /// <param name="tileData"></param>
        /// <param name="sourceTileCount"></param>
        /// <returns></returns>
        private TilesetAutoTileInfo TransformAutoTileData(int autoTileIndex, TilesetAutoTileInput autoTileInput, RawList <TileInfo> tileData, int sourceTileCount)
        {
            int[] stateToTileMap = new int[(int)TileConnection.All + 1];
            TilesetAutoTileItem[] autoTileInfo = new TilesetAutoTileItem[sourceTileCount];
            int baseTile = MathF.Clamp(autoTileInput.BaseTileIndex, 0, sourceTileCount - 1);

            // Initialize the tile mapping for all potential connection states with the base tile
            for (int conIndex = 0; conIndex < stateToTileMap.Length; conIndex++)
            {
                stateToTileMap[conIndex] = baseTile;
            }

            // Use the directly applicable tile mapping as-is
            int autoTileSourceTileCount = MathF.Min(autoTileInput.TileInput.Count, sourceTileCount);

            bool[] isStateAvailable = new bool[stateToTileMap.Length + 1];
            for (int tileIndex = autoTileSourceTileCount - 1; tileIndex >= 0; tileIndex--)
            {
                TilesetAutoTileItem tileInput = autoTileInput.TileInput[tileIndex];
                autoTileInfo[tileIndex] = tileInput;

                if (tileInput.IsAutoTile)
                {
                    isStateAvailable[(int)tileInput.Neighbours] = true;
                    stateToTileMap[(int)tileInput.Neighbours]   = tileIndex;
                    autoTileInfo[tileIndex].ConnectsToAutoTile  = true;

                    // Apply base tile information to the main tile dataset
                    tileData.Count = Math.Max(tileData.Count, tileIndex + 1);
                    tileData.Data[tileIndex].AutoTileLayer = autoTileIndex + 1;
                }
            }

            // Fill up unavailable state mappings with the closest available match
            for (int stateIndex = 0; stateIndex < isStateAvailable.Length; stateIndex++)
            {
                if (isStateAvailable[stateIndex])
                {
                    continue;
                }

                IReadOnlyList <TileConnection> fallbacks = AutoTileFallbackMap.GetFallback((TileConnection)stateIndex);
                for (int i = 0; i < fallbacks.Count; i++)
                {
                    int fallbackStateIndex = (int)fallbacks[i];
                    if (isStateAvailable[fallbackStateIndex])
                    {
                        stateToTileMap[stateIndex] = stateToTileMap[fallbackStateIndex];
                        break;
                    }
                }
            }

            // Add the complete AutoTile info / mapping to the result data
            return(new TilesetAutoTileInfo(
                       baseTile,
                       stateToTileMap,
                       autoTileInfo));
        }
示例#2
0
        /// <summary>
        /// Transforms the intermediate AutoTile data into an output format that is optimized for
        /// efficient reading and updating operations.
        ///
        /// Requires the total number of output tiles, including generated ones, to be known.
        /// </summary>
        private void TransformAutoTileData(List <TilesetAutoTileInfo> outputData)
        {
            for (int autoTileIndex = 0; autoTileIndex < this.autoTiles.Count; autoTileIndex++)
            {
                AutoTileData data = this.autoTiles[autoTileIndex];

                TilesetAutoTileItem[] tileInfo = new TilesetAutoTileItem[this.outputTileCount];
                data.TileInfo.CopyTo(tileInfo, 0);

                outputData.Add(new TilesetAutoTileInfo(
                                   data.BaseTile,
                                   data.StateToTile,
                                   tileInfo));
            }
        }
        public EditTilesetAutoTileItemAction(Tileset tileset, TilesetAutoTileInput autoTile, int tileIndex, TilesetAutoTileItem tileInput)
        {
            if (tileset == null) throw new ArgumentNullException("tileset");
            if (autoTile == null) throw new ArgumentNullException("autoTile");

            this.tileset = tileset;
            this.autoTile = autoTile;

            this.tileInput = new RawList<TilesetAutoTileItem>(tileIndex + 1);
            this.tileInput.Count = tileIndex + 1;
            this.tileInput.Data[tileIndex] = tileInput;

            this.tileInputMask = new RawList<bool>(tileIndex + 1);
            this.tileInputMask.Count = tileIndex + 1;
            this.tileInputMask.Data[tileIndex] = true;
        }
示例#4
0
        /// <summary>
        /// Creates a new <see cref="TilesetAutoTileInfo"/> based on prepared data.
        /// </summary>
        /// <param name="baseTile">The tile index of the base tile for this AutoTile.</param>
        /// <param name="stateToTile">
        /// An array where the item at a <see cref="TileConnection"/> index represents the tile index
        /// of the border tile to use in this connectivity setup. This array is not copied. If you plan
        /// to re-use it, pass a copy as a parameter.
        /// </param>
        public TilesetAutoTileInfo(int baseTile, int[] stateToTile, TilesetAutoTileItem[] tileInfo)
        {
            if (stateToTile == null) throw new ArgumentNullException("stateToTile");
            if (tileInfo == null) throw new ArgumentNullException("tileInfo");
            if (stateToTile.Length != (int)TileConnection.All + 1)
            {
                throw new ArgumentException(
                    string.Format(
                        "Invalid number of border tile mappings. It always has to equal {0}.",
                        (int)TileConnection.All + 1),
                    "borderTiles");
            }

            this.baseTile = baseTile;
            this.stateToTile = stateToTile;
            this.tileInfo = tileInfo;
        }
示例#5
0
        /// <summary>
        /// Transforms regular AutoTile input data into an output format that is optimized for 
        /// efficient reading and updating operations.
        /// </summary>
        /// <param name="autoTileIndex"></param>
        /// <param name="autoTileInput"></param>
        /// <param name="tileData"></param>
        /// <param name="sourceTileCount"></param>
        /// <returns></returns>
        private TilesetAutoTileInfo TransformAutoTileData(int autoTileIndex, TilesetAutoTileInput autoTileInput, RawList<TileInfo> tileData, int sourceTileCount)
        {
            int[] stateToTileMap = new int[(int)TileConnection.All + 1];
            TilesetAutoTileItem[] autoTileInfo = new TilesetAutoTileItem[sourceTileCount];
            int baseTile = MathF.Clamp(autoTileInput.BaseTileIndex, 0, sourceTileCount - 1);

            // Initialize the tile mapping for all potential connection states with the base tile
            for (int conIndex = 0; conIndex < stateToTileMap.Length; conIndex++)
            {
                stateToTileMap[conIndex] = baseTile;
            }

            // Use the directly applicable tile mapping as-is
            int autoTileSourceTileCount = MathF.Min(autoTileInput.TileInput.Count, sourceTileCount);
            bool[] isStateAvailable = new bool[stateToTileMap.Length + 1];
            for (int tileIndex = autoTileSourceTileCount - 1; tileIndex >= 0; tileIndex--)
            {
                TilesetAutoTileItem tileInput = autoTileInput.TileInput[tileIndex];
                autoTileInfo[tileIndex] = tileInput;

                if (tileInput.IsAutoTile)
                {
                    isStateAvailable[(int)tileInput.Neighbours] = true;
                    stateToTileMap[(int)tileInput.Neighbours] = tileIndex;
                    autoTileInfo[tileIndex].ConnectsToAutoTile = true;

                    // Apply base tile information to the main tile dataset
                    tileData.Count = Math.Max(tileData.Count, tileIndex + 1);
                    tileData.Data[tileIndex].AutoTileLayer = autoTileIndex + 1;
                }
            }

            // Fill up unavailable state mappings with the closest available match
            for (int stateIndex = 0; stateIndex < isStateAvailable.Length; stateIndex++)
            {
                if (isStateAvailable[stateIndex]) continue;

                IReadOnlyList<TileConnection> fallbacks = AutoTileFallbackMap.GetFallback((TileConnection)stateIndex);
                for (int i = 0; i < fallbacks.Count; i++)
                {
                    int fallbackStateIndex = (int)fallbacks[i];
                    if (isStateAvailable[fallbackStateIndex])
                    {
                        stateToTileMap[stateIndex] = stateToTileMap[fallbackStateIndex];
                        break;
                    }
                }
            }

            // Add the complete AutoTile info / mapping to the result data
            return new TilesetAutoTileInfo(
                baseTile,
                stateToTileMap,
                autoTileInfo);
        }
示例#6
0
        /// <summary>
        /// Gathers and processes AutoTile input data into an easily modifyable intermediate format,
        /// while also collecting information on generated tiles and connectivity state mappings.
        /// </summary>
        /// <param name="autoTileConfig"></param>
        private void GatherAutoTileData(IReadOnlyList <TilesetAutoTileInput> autoTileConfig)
        {
            for (int autoTileIndex = 0; autoTileIndex < autoTileConfig.Count; autoTileIndex++)
            {
                TilesetAutoTileInput autoTileInput = autoTileConfig[autoTileIndex];
                AutoTileData         autoTile      = new AutoTileData
                {
                    BaseTile         = MathF.Clamp(autoTileInput.BaseTileIndex, 0, this.inputTileCount - 1),
                    TileInfo         = this.autoTileItemPool.Rent(this.inputTileCount),
                    StateToTile      = new int[(int)TileConnection.All + 1],
                    IsStateAvailable = new bool[(int)TileConnection.All + 1]
                };
                autoTile.TileInfo.Count = this.inputTileCount;

                // Initialize the tile mapping for all potential connection states with the base tile
                for (int conIndex = 0; conIndex < autoTile.StateToTile.Length; conIndex++)
                {
                    autoTile.StateToTile[conIndex] = autoTile.BaseTile;
                }

                // Use the directly applicable tile mapping as-is
                int autoTileSourceTileCount = MathF.Min(autoTileInput.TileInput.Count, this.inputTileCount);
                for (int tileIndex = autoTileSourceTileCount - 1; tileIndex >= 0; tileIndex--)
                {
                    TilesetAutoTileItem tileInput = autoTileInput.TileInput[tileIndex];
                    autoTile.TileInfo[tileIndex] = tileInput;

                    if (tileInput.IsAutoTile)
                    {
                        autoTile.IsStateAvailable[(int)tileInput.Neighbours] = true;
                        autoTile.StateToTile[(int)tileInput.Neighbours]      = tileIndex;
                        autoTile.TileInfo.Data[tileIndex].ConnectsToAutoTile = true;

                        // Apply base tile information to the main tile dataset
                        this.tiles.Data[tileIndex].AutoTileLayer = autoTileIndex + 1;
                    }
                }

                // Attempt to construct missing tiles of the minimum required base set from existing tiles
                // by using their sub-tile quadrants individually. Use a buffer for availability checks, so
                // we don't base generated tiles on previously generated tiles.
                autoTile.IsStateAvailable.CopyTo(this.autoTileStateBuffer, 0);
                for (int i = 0; i < AutoTileFallbackMap.BaseConnectivityTiles.Count; i++)
                {
                    TileConnection connectivity = AutoTileFallbackMap.BaseConnectivityTiles[i];
                    if (this.autoTileStateBuffer[(int)connectivity])
                    {
                        continue;
                    }

                    TileConnection topLeft     = FindGeneratedAutoTileBase(TileQuadrant.TopLeft, connectivity, this.autoTileStateBuffer);
                    TileConnection topRight    = FindGeneratedAutoTileBase(TileQuadrant.TopRight, connectivity, this.autoTileStateBuffer);
                    TileConnection bottomRight = FindGeneratedAutoTileBase(TileQuadrant.BottomRight, connectivity, this.autoTileStateBuffer);
                    TileConnection bottomLeft  = FindGeneratedAutoTileBase(TileQuadrant.BottomLeft, connectivity, this.autoTileStateBuffer);

                    // Skip cases where we can't construct a full tile
                    if (topLeft == TileConnection.None)
                    {
                        continue;
                    }
                    if (topRight == TileConnection.None)
                    {
                        continue;
                    }
                    if (bottomRight == TileConnection.None)
                    {
                        continue;
                    }
                    if (bottomLeft == TileConnection.None)
                    {
                        continue;
                    }

                    int generatedIndex = this.ScheduleGenerateTile(
                        autoTile.BaseTile,
                        autoTile.StateToTile[(int)topLeft],
                        autoTile.StateToTile[(int)topRight],
                        autoTile.StateToTile[(int)bottomRight],
                        autoTile.StateToTile[(int)bottomLeft]);

                    autoTile.IsStateAvailable[(int)connectivity] = true;
                    autoTile.StateToTile[(int)connectivity]      = generatedIndex;
                    autoTile.TileInfo.Count = MathF.Max(autoTile.TileInfo.Count, generatedIndex + 1);
                    autoTile.TileInfo.Data[generatedIndex] = autoTileInput.TileInput[autoTile.BaseTile];
                    autoTile.TileInfo[generatedIndex]      = new TilesetAutoTileItem
                    {
                        IsAutoTile         = true,
                        ConnectsToAutoTile = true,
                        Neighbours         = connectivity
                    };
                }

                // Fill up unavailable state mappings with the closest available match
                for (int stateIndex = 0; stateIndex < autoTile.IsStateAvailable.Length; stateIndex++)
                {
                    if (autoTile.IsStateAvailable[stateIndex])
                    {
                        continue;
                    }

                    IReadOnlyList <TileConnection> fallbacks = AutoTileFallbackMap.GetFallback((TileConnection)stateIndex);
                    for (int i = 0; i < fallbacks.Count; i++)
                    {
                        int fallbackStateIndex = (int)fallbacks[i];
                        if (autoTile.IsStateAvailable[fallbackStateIndex])
                        {
                            autoTile.StateToTile[stateIndex] = autoTile.StateToTile[fallbackStateIndex];
                            break;
                        }
                    }
                }

                // Add the gathered info to our local working data
                this.autoTiles.Add(autoTile);
            }
        }