Esempio n. 1
0
        /// <summary>
        /// Validates whether the neighbour of this isometric tile in the given direction satisfies the
        /// constraints of the tileset.
        /// </summary>
        /// <param name="dir">The direction of the neighbour to validate.</param>
        private void ValidateNeighbour(MapDirection dir)
        {
            IsoTile neighbour = this.neighbours[(int)dir];

            if (neighbour != null)
            {
                /// To simplify the algorithm, we use terrain combinations rotated to MapDirection.NorthEast.
                TerrainCombination thisCombRot  = MapHelper.RotateTerrainCombination(this.type.Combination, dir, MapDirection.NorthEast);
                TerrainCombination neighCombRot = MapHelper.RotateTerrainCombination(neighbour.type.Combination, dir, MapDirection.NorthEast);

                /// Generate the terrain-NESW array for this tile and the neighbour.
                ITerrainType[] thisNESWRot  = MapHelper.GetTerrainNESW(this.type.TerrainA, this.type.TerrainB, thisCombRot);
                ITerrainType[] neighNESWRot = MapHelper.GetTerrainNESW(neighbour.type.TerrainA, neighbour.type.TerrainB, neighCombRot);

                /// Check the generated terrain-NESW arrays.
                if (thisNESWRot[0] != neighNESWRot[3] || thisNESWRot[1] != neighNESWRot[2])
                {
                    throw new MapException(string.Format("Invalid neighbours at {0} and {1}!", this.mapCoords, neighbour.mapCoords));
                }

                /// Check whether the given direction satisfies the transition-length constraint.
                if (this.type.TerrainB != null && this.type.TerrainB.TransitionLength > 0 &&
                    thisNESWRot[0] == this.type.TerrainA && thisNESWRot[1] == this.type.TerrainA)
                {
                    int     remaining = this.type.TerrainB.TransitionLength;
                    IsoTile currTile  = neighbour;
                    while (currTile != null && remaining > 0)
                    {
                        /// Generate the terrain-NESW array of the currently checked tile.
                        TerrainCombination currCombRot = MapHelper.RotateTerrainCombination(currTile.type.Combination, dir, MapDirection.NorthEast);
                        ITerrainType[]     currNESWRot = MapHelper.GetTerrainNESW(currTile.type.TerrainA, currTile.type.TerrainB, currCombRot);

                        /// Check if the currently checked tile is part of the transition.
                        if (currNESWRot[0] != this.type.TerrainA || currNESWRot[1] != this.type.TerrainA ||
                            currNESWRot[2] != this.type.TerrainA || currNESWRot[3] != this.type.TerrainA)
                        {
                            /// No, it's not part of the transition. We have to check whether the upcoming terrain type
                            /// is another child of TerrainA or not.
                            if (currNESWRot[2] == this.type.TerrainA && currNESWRot[3] == this.type.TerrainA &&
                                (currNESWRot[0] == this.type.TerrainA || currNESWRot[0].Parent == this.type.TerrainA) &&
                                (currNESWRot[1] == this.type.TerrainA || currNESWRot[1].Parent == this.type.TerrainA))
                            {
                                /// It's another child of TerrainA, no contradiction with the tileset -> OK.
                                break;
                            }
                            else
                            {
                                /// It's not a child of TerrainA -> Error.
                                throw new MapException(string.Format("Invalid transition from {0} in direction {1}! Length must be at least {2}!", this.mapCoords, dir, this.type.TerrainB.TransitionLength));
                            }
                        }

                        /// Yes, it's part of the transition. We can switch to the next tile in the same direction.
                        currTile = currTile.neighbours[(int)dir];
                        remaining--;
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>This method is used to rotate the terrain combination of an isometric tile.</summary>
        /// <param name="combination">The original terrain combination to be rotated.</param>
        /// <param name="origDir">
        /// The original direction vector of the isometric tile.
        /// Can be one of the followings: MapDirection.NorthEast, MapDirection.SouthEast, MapDirection.SouthWest,
        /// MapDirection.NorthWest.
        /// </param>
        /// <param name="newDir">
        /// The new direction vector of the isometric tile.
        /// Can be one of the followings: MapDirection.NorthEast, MapDirection.SouthEast, MapDirection.SouthWest,
        /// MapDirection.NorthWest.
        /// </param>
        /// <returns>The rotated terrain combination of the tile.</returns>
        public static TerrainCombination RotateTerrainCombination(TerrainCombination combination, MapDirection origDir, MapDirection newDir)
        {
            /// No rotation has to be performed in case of simple terrain combination.
            if (combination == TerrainCombination.Simple)
            {
                return(combination);
            }

            if (newDir != MapDirection.NorthEast)
            {
                int modifiedOrigDir = ((int)MapDirection.NorthEast - (int)newDir + (int)origDir) % 8;
                return(MapHelper.RotateTerrainCombination(combination,
                                                          (MapDirection)(modifiedOrigDir >= 0 ? modifiedOrigDir : modifiedOrigDir + 8),
                                                          MapDirection.NorthEast));
            }

            if (origDir == MapDirection.NorthEast)
            {
                /// No rotation has to be performed as the direction vector already points to MapDirection.NorthEast.
                return(combination);
            }
            else if (origDir == MapDirection.SouthEast)
            {
                /// Rotate by +90 degrees.
                if (combination == TerrainCombination.AAAB)
                {
                    return(TerrainCombination.AABA);
                }
                if (combination == TerrainCombination.AABA)
                {
                    return(TerrainCombination.ABAA);
                }
                if (combination == TerrainCombination.AABB)
                {
                    return(TerrainCombination.ABBA);
                }
                if (combination == TerrainCombination.ABAA)
                {
                    return(TerrainCombination.BAAA);
                }
                if (combination == TerrainCombination.ABAB)
                {
                    return(TerrainCombination.BABA);
                }
                if (combination == TerrainCombination.ABBA)
                {
                    return(TerrainCombination.BBAA);
                }
                if (combination == TerrainCombination.ABBB)
                {
                    return(TerrainCombination.BBBA);
                }
                if (combination == TerrainCombination.BAAA)
                {
                    return(TerrainCombination.AAAB);
                }
                if (combination == TerrainCombination.BAAB)
                {
                    return(TerrainCombination.AABB);
                }
                if (combination == TerrainCombination.BABA)
                {
                    return(TerrainCombination.ABAB);
                }
                if (combination == TerrainCombination.BABB)
                {
                    return(TerrainCombination.ABBB);
                }
                if (combination == TerrainCombination.BBAA)
                {
                    return(TerrainCombination.BAAB);
                }
                if (combination == TerrainCombination.BBAB)
                {
                    return(TerrainCombination.BABB);
                }
                if (combination == TerrainCombination.BBBA)
                {
                    return(TerrainCombination.BBAB);
                }
                throw new ArgumentException("Invalid terrain combination!", "combination");
            }
            else if (origDir == MapDirection.SouthWest)
            {
                /// Rotate by +180 degrees.
                if (combination == TerrainCombination.AAAB)
                {
                    return(TerrainCombination.ABAA);
                }
                if (combination == TerrainCombination.AABA)
                {
                    return(TerrainCombination.BAAA);
                }
                if (combination == TerrainCombination.AABB)
                {
                    return(TerrainCombination.BBAA);
                }
                if (combination == TerrainCombination.ABAA)
                {
                    return(TerrainCombination.AAAB);
                }
                if (combination == TerrainCombination.ABAB)
                {
                    return(TerrainCombination.ABAB);
                }
                if (combination == TerrainCombination.ABBA)
                {
                    return(TerrainCombination.BAAB);
                }
                if (combination == TerrainCombination.ABBB)
                {
                    return(TerrainCombination.BBAB);
                }
                if (combination == TerrainCombination.BAAA)
                {
                    return(TerrainCombination.AABA);
                }
                if (combination == TerrainCombination.BAAB)
                {
                    return(TerrainCombination.ABBA);
                }
                if (combination == TerrainCombination.BABA)
                {
                    return(TerrainCombination.BABA);
                }
                if (combination == TerrainCombination.BABB)
                {
                    return(TerrainCombination.BBBA);
                }
                if (combination == TerrainCombination.BBAA)
                {
                    return(TerrainCombination.AABB);
                }
                if (combination == TerrainCombination.BBAB)
                {
                    return(TerrainCombination.ABBB);
                }
                if (combination == TerrainCombination.BBBA)
                {
                    return(TerrainCombination.BABB);
                }
                throw new ArgumentException("Invalid terrain combination!", "combination");
            }
            else if (origDir == MapDirection.NorthWest)
            {
                /// Rotate by +270 degrees.
                if (combination == TerrainCombination.AAAB)
                {
                    return(TerrainCombination.BAAA);
                }
                if (combination == TerrainCombination.AABA)
                {
                    return(TerrainCombination.AAAB);
                }
                if (combination == TerrainCombination.AABB)
                {
                    return(TerrainCombination.BAAB);
                }
                if (combination == TerrainCombination.ABAA)
                {
                    return(TerrainCombination.AABA);
                }
                if (combination == TerrainCombination.ABAB)
                {
                    return(TerrainCombination.BABA);
                }
                if (combination == TerrainCombination.ABBA)
                {
                    return(TerrainCombination.AABB);
                }
                if (combination == TerrainCombination.ABBB)
                {
                    return(TerrainCombination.BABB);
                }
                if (combination == TerrainCombination.BAAA)
                {
                    return(TerrainCombination.ABAA);
                }
                if (combination == TerrainCombination.BAAB)
                {
                    return(TerrainCombination.BBAA);
                }
                if (combination == TerrainCombination.BABA)
                {
                    return(TerrainCombination.ABAB);
                }
                if (combination == TerrainCombination.BABB)
                {
                    return(TerrainCombination.BBAB);
                }
                if (combination == TerrainCombination.BBAA)
                {
                    return(TerrainCombination.ABBA);
                }
                if (combination == TerrainCombination.BBAB)
                {
                    return(TerrainCombination.BBBA);
                }
                if (combination == TerrainCombination.BBBA)
                {
                    return(TerrainCombination.ABBB);
                }
                throw new ArgumentException("Invalid terrain combination!", "combination");
            }
            else
            {
                throw new ArgumentException("Invalid direction vector!", "direction");
            }
        }