示例#1
0
        /// <summary>
        /// Fills up the layers from the base layer up to the target layer.
        /// </summary>
        /// <param name="center">The center of the draw operation.</param>
        /// <param name="targetTerrain">The target terrain of the draw operation.</param>
        /// <param name="baseTerrain">The base layer of the draw operation.</param>
        public void FillLayers(IMapAccess map, IIsoTile center, ITerrainType targetTerrain, ITerrainType baseTerrain)
        {
            /// Find the biggest flood area to be filled.
            FloodArea areaToFill = new FloodArea();

            ITerrainType[] layersToFill = targetTerrain.FindRoute(baseTerrain);
            for (int routeIdx = 0; routeIdx < layersToFill.Length; routeIdx++)
            {
                ITerrainType prevTerrain = routeIdx - 1 >= 0 ? layersToFill[routeIdx - 1] : null;
                if (prevTerrain != null)
                {
                    areaToFill.Enlarge(prevTerrain.TransitionLength + 1);
                }
            }

            /// Fill the appropriate layers
            for (int routeIdx = layersToFill.Length - 1; routeIdx >= 0; routeIdx--)
            {
                /// Fill the current layer at the appropriate area.
                ITerrainType currLayer = layersToFill[routeIdx];
                foreach (FloodItem floodItem in areaToFill)
                {
                    IIsoTile filledTile = map.GetIsoTile(center.MapCoords + floodItem.Coordinates);
                    if (filledTile != null)
                    {
                        if (filledTile.Type.Combination != TerrainCombination.Simple)
                        {
                            /// Mixed tile.
                            if (filledTile.Type.TerrainB == currLayer)
                            {
                                int newCombInt             = (int)filledTile.Type.Combination | (floodItem.Combination != TerrainCombination.Simple ? (int)floodItem.Combination : 0xF);
                                TerrainCombination newComb = newCombInt != 0xF ? (TerrainCombination)newCombInt : TerrainCombination.Simple;
                                if (newComb != filledTile.Type.Combination)
                                {
                                    filledTile.ExchangeType(
                                        newComb == TerrainCombination.Simple ?
                                        map.Tileset.GetIsoTileType(filledTile.Type.TerrainB.Name) :
                                        map.Tileset.GetIsoTileType(filledTile.Type.TerrainA.Name, filledTile.Type.TerrainB.Name, newComb));
                                }
                            }
                            else if (currLayer.IsDescendantOf(filledTile.Type.TerrainB))
                            {
                                throw new MapException("Filling over the topmost layer is not possible!");
                            }
                        }
                        else
                        {
                            /// Simple tile.
                            if (filledTile.Type.TerrainA == currLayer.Parent)
                            {
                                filledTile.ExchangeType(
                                    floodItem.Combination == TerrainCombination.Simple ?
                                    map.Tileset.GetIsoTileType(currLayer.Name) :
                                    map.Tileset.GetIsoTileType(filledTile.Type.TerrainA.Name, currLayer.Name, floodItem.Combination));
                            }
                            else if (currLayer.IsDescendantOf(filledTile.Type.TerrainA))
                            {
                                throw new MapException("Filling over the topmost layer is not possible!");
                            }
                        }
                    }
                }

                if (routeIdx > 0)
                {
                    areaToFill.Reduce();
                }
            }
        }
示例#2
0
        /// <summary>
        /// Clears the given layers for a draw operation.
        /// </summary>
        /// <param name="map">Reference to the map.</param>
        /// <param name="center">The center of the draw operation.</param>
        /// <param name="targetTerrain">The target terrain of the draw operation.</param>
        /// <param name="baseTerrain">The base layer of the draw operation.</param>
        /// <param name="layersToClear">The route from the target terrain up to a topmost layer in the terrain tree.</param>
        private void ClearLayers(IMapAccess map, IIsoTile center, ITerrainType targetTerrain, ITerrainType baseTerrain, ITerrainType[] layersToClear)
        {
            /// Find the biggest flood area to be cleared.
            FloodArea    areaToClear        = new FloodArea();
            ITerrainType lastUninjuredLayer = null;

            for (int routeIdx = 0; routeIdx < layersToClear.Length; routeIdx++)
            {
                ITerrainType currTerrain = layersToClear[routeIdx];
                if (lastUninjuredLayer == null)
                {
                    /// We are going downstairs.
                    ITerrainType nextTerrain = layersToClear[routeIdx + 1];
                    if (nextTerrain.Parent == currTerrain)
                    {
                        /// Last uninjured layer found, from now we go upstairs.
                        lastUninjuredLayer = currTerrain;

                        /// Enlarge the clear area by 1 if there was a previous layer along the way downstairs.
                        ITerrainType prevTerrain = routeIdx - 1 >= 0 ? layersToClear[routeIdx - 1] : null;
                        if (prevTerrain != null)
                        {
                            areaToClear.Enlarge(1);
                        }
                    }
                    else
                    {
                        /// Enlarge the clear area by the transition length of the previous layer if there
                        /// was a previous layer along the way downstairs.
                        ITerrainType prevTerrain = routeIdx - 1 >= 0 ? layersToClear[routeIdx - 1] : null;
                        if (prevTerrain != null)
                        {
                            areaToClear.Enlarge(prevTerrain.TransitionLength + 1);
                        }
                    }
                }
                else
                {
                    /// We are going upstairs.
                    ITerrainType prevTerrain = layersToClear[routeIdx - 1];
                    if (prevTerrain != lastUninjuredLayer)
                    {
                        areaToClear.Enlarge(currTerrain.TransitionLength + 1);
                    }
                }
            }

            /// Clear the appropriate layers.
            if (lastUninjuredLayer == null)
            {
                throw new MapException("Last uninjured layer not found for draw terrain operation!");
            }
            for (int routeIdx = layersToClear.Length - 1; routeIdx >= 0; routeIdx--)
            {
                ITerrainType currLayer = layersToClear[routeIdx];
                if (currLayer == lastUninjuredLayer)
                {
                    break;
                }

                /// Clear the current layer at the appropriate area.
                foreach (FloodItem floodItem in areaToClear)
                {
                    IIsoTile clearedTile = map.GetIsoTile(center.MapCoords + floodItem.Coordinates);
                    if (clearedTile != null)
                    {
                        if (clearedTile.Type.Combination != TerrainCombination.Simple)
                        {
                            /// Mixed tile.
                            if (clearedTile.Type.TerrainB.IsDescendantOf(currLayer))
                            {
                                /// Check whether TerrainB will be cleared by another branch or this is an error.
                                if (!layersToClear.Contains(clearedTile.Type.TerrainB))
                                {
                                    continue;
                                }
                                else
                                {
                                    throw new MapException("Clearing non-topmost layer is not possible!");
                                }
                            }
                            if (clearedTile.Type.TerrainB == currLayer)
                            {
                                TerrainCombination newComb = (TerrainCombination)((int)clearedTile.Type.Combination & ~(floodItem.Combination != TerrainCombination.Simple ? (int)floodItem.Combination : 0xF));
                                if (newComb != clearedTile.Type.Combination)
                                {
                                    clearedTile.ExchangeType(
                                        newComb == TerrainCombination.Simple ?
                                        map.Tileset.GetIsoTileType(clearedTile.Type.TerrainA.Name) :
                                        map.Tileset.GetIsoTileType(clearedTile.Type.TerrainA.Name, clearedTile.Type.TerrainB.Name, newComb));
                                }
                            }
                        }
                        else
                        {
                            /// Simple tile.
                            if (clearedTile.Type.TerrainA.IsDescendantOf(currLayer))
                            {
                                /// Check whether TerrainA will be cleared by another branch or this is an error.
                                if (!layersToClear.Contains(clearedTile.Type.TerrainA))
                                {
                                    continue;
                                }
                                else
                                {
                                    throw new MapException("Clearing non-topmost layer is not possible!");
                                }
                            }
                            if (clearedTile.Type.TerrainA == currLayer)
                            {
                                TerrainCombination newComb = (TerrainCombination)(0xF & ~(floodItem.Combination != TerrainCombination.Simple ? (int)floodItem.Combination : 0xF));
                                clearedTile.ExchangeType(
                                    newComb == TerrainCombination.Simple ?
                                    map.Tileset.GetIsoTileType(clearedTile.Type.TerrainA.Parent.Name) :
                                    map.Tileset.GetIsoTileType(clearedTile.Type.TerrainA.Parent.Name, clearedTile.Type.TerrainA.Name, newComb));
                            }
                        }
                    }
                }

                if (routeIdx > 1)
                {
                    areaToClear.Reduce();
                }
            }
        }