Example #1
0
        void AddStairs()
        {
            var        downStairs = Tower.StairsDownNextToGenerate(width, height);
            List <int> upPositions;

            if (downStairs >= 0)
            {
                SetTileType(downStairs, TileType.StairsDown);
                if (GetNeighbourIndices(downStairs, TileType.Walkable, tileTypeMap, width).Count == 0)
                {
                    EatWallFromFirstFound(new List <int>(new int[] { downStairs }), TileType.Walkable);
                }
                upPositions = RoomSearch.GetPositionsAtDistance(tileTypeMap, downStairs, new Range(minDistanceBetweenStairs), TileType.Wall, true, width);
            }
            else
            {
                upPositions = RoomSearch.GetNonCornerPerimiterPositions(width, height);
            }

            if (upPositions.Count == 0)
            {
                Debug.LogError("No valid up stairs position");
            }

            var upStairs = upPositions[Random.Range(0, upPositions.Count)];

            SetTileType(upStairs, TileType.StairsUp);
            if (GetNeighbourIndices(upStairs, TileType.Walkable, tileTypeMap, width).Count == 0)
            {
                EatWallFromFirstFound(new List <int>(new int[] { upStairs }), TileType.Walkable);
            }
        }
Example #2
0
        int CountPathsToTargets(Coordinate origin, out Coordinate lastDeadEnd, params Coordinate[] targets)
        {
            int paths = 0;

            lastDeadEnd = origin;
            foreach (var neighbour in origin.Neighbours())
            {
                if (!PassableTile(neighbour, false, TileType.Walkable, TileType.SpikeTrap))
                {
                    continue;
                }
                for (int i = 0; i < targets.Length; i++)
                {
                    var pathsBefore = paths;
                    if (RoomSearch.FindShortestPath(this, neighbour, targets[i], false, TileType.SpikeTrap, TileType.Walkable).Length > 1)
                    {
                        paths++;
                        break;
                    }
                    if (pathsBefore == paths)
                    {
                        lastDeadEnd = neighbour;
                    }
                }
            }
            return(paths);
        }
Example #3
0
        void RigDoorAndTreasure()
        {
            var candidates = RoomSearch.GetTileIndicesWithType(TileType.Walkable, tileTypeMap).ToArray();

            if (candidates.Length > 1)
            {
                candidates = ShuffleArray <int> .Shuffle(candidates);
            }

            var upStairs   = Coordinate.FromPosition(RoomSearch.GetFirstOccurance(tileTypeMap, TileType.StairsUp), width);
            var downStairs = Coordinate.FromPosition(RoomSearch.GetFirstOccurance(tileTypeMap, TileType.StairsDown), width);

            for (int i = 0; i < candidates.Length; i++)
            {
                var coord = Coordinate.FromPosition(candidates[i], width);
                if (PermissableDoorPosition(coord))
                {
                    var path = RoomSearch.FindShortestPath(this, upStairs, downStairs, false, TileType.Walkable, TileType.SpikeTrap, TileType.StairsUp, TileType.StairsDown);
                    if (path.Length > 0 && !System.Array.Exists <Coordinate>(path, e => e == coord))
                    {
                        SetTileType(coord, TileType.Door);
                        Coordinate deadEnd;
                        if (CountPathsToTargets(coord, out deadEnd, upStairs, downStairs) == 1)
                        {
                            if (deadEnd != coord)
                            {
                                PlaceCoins(deadEnd);
                            }
                            return;
                        }
                    }
                }
            }
        }
Example #4
0
        void JoinWalkableAreas()
        {
            var  undecided      = RoomSearch.GetTileIndicesWithType(TileType.None, tileTypeMap);
            bool firstIteration = true;
            int  iterations     = 0;

            while (RoomSearch.HasAnyOfType(TileType.None, tileTypeMap))
            {
                if (firstIteration)
                {
                    var floodOrigin = undecided[Random.Range(0, undecided.Count)];
                    FloodFillAs(floodOrigin, TileType.None, TileType.Walkable);
                    firstIteration = false;
                }

                if (!RoomSearch.HasAnyOfType(TileType.None, tileTypeMap))
                {
                    break;
                }

                //Mapping the through wall distance
                EatWallFromFirstFound(GetTilesBorderingWalls(), TileType.None);

                iterations++;
                if (iterations > width * height)
                {
                    return;
                }
            }
        }
Example #5
0
        void FindPath()
        {
            var newPath = RoomSearch.FindShortestPath(Tower.ActiveRoom, Tower.Player.position, lastTile.position, true, TileType.Door, TileType.Walkable, TileType.StairsUp, TileType.SpikeTrap);

            SmartJoinPaths(newPath);
            GrowTrailWhileNeeded(path);
            UpdateTrail(path);
        }
Example #6
0
        void FloodFillAs(int floodOrigin, TileType selector, TileType fillType)
        {
            var filling = RoomSearch.FloodSearch(tileTypeMap, width, floodOrigin, selector);

            for (int i = 0, l = filling.Count; i < l; i++)
            {
                SetTileType(filling[i], fillType);
            }
        }
Example #7
0
        public static int GetCorrespondingPosition(RoomData data, TileType tileType, int roomWidth, int roomHeight, bool stayOnEdge)
        {
            var pos = RoomSearch.GetFirstOccurance(data.tileTypeMap, tileType);

            if (pos < 0)
            {
                return(pos);
            }

            return(GetCorrespondingPosition(data, pos, roomWidth, roomHeight, stayOnEdge));
        }
Example #8
0
        public static void LaySpikeTraps(Room room, RoomData data, int parts)
        {
            var selectedCoordinates = new List <Coordinate>();
            var potentialSources    = RoomSearch.GetTileIndicesWithType(TileType.Walkable, data.tileTypeMap);
            var position            = potentialSources[Random.Range(0, potentialSources.Count)];

            selectedCoordinates.Add(Coordinate.FromPosition(position, data.width));
            parts--;
            room.SetTileType(position, TileType.SpikeTrap);
            data.tileTypeMap[position] = (int)TileType.SpikeTrap;

            while (parts > 0)
            {
                var prevCoordIndex = selectedCoordinates.Count - 1;
                var nextCandidates = RoomSearch.GetPositionsAtDistance(
                    data.tileTypeMap,
                    selectedCoordinates[prevCoordIndex].ToPosition(data.width, data.height),
                    new Range(1, 2), TileType.Walkable,
                    false,
                    data.width);

                if (nextCandidates.Count == 0)
                {
                    return;
                }
                else if (selectedCoordinates.Count == 1)
                {
                    position = nextCandidates[Random.Range(0, nextCandidates.Count)];
                }
                else
                {
                    var offset = selectedCoordinates[prevCoordIndex] - selectedCoordinates[prevCoordIndex - 1];
                    position = (offset + selectedCoordinates[prevCoordIndex]).ToPosition(data.width, data.height);
                    if (!nextCandidates.Contains(position))
                    {
                        position = (offset.Rotated90CCW() + selectedCoordinates[prevCoordIndex]).ToPosition(data.width, data.height);
                        if (!nextCandidates.Contains(position))
                        {
                            position = (offset.Rotated90CW() + selectedCoordinates[prevCoordIndex]).ToPosition(data.width, data.height);
                            if (!nextCandidates.Contains(position))
                            {
                                return;
                            }
                        }
                    }
                }

                selectedCoordinates.Add(Coordinate.FromPosition(position, data.width));
                parts--;
                room.SetTileType(position, TileType.SpikeTrap);
                data.tileTypeMap[position] = (int)TileType.SpikeTrap;
            }
        }
Example #9
0
        void EatWallFromFirstFound(List <int> edge, TileType searchType)
        {
            var distanceToEdge = new int[tileTypeMap.Length];
            int distance       = 0;
            int wall           = -1;

            //Find nearest connectable area
            while (true)
            {
                distance++;
                edge = GetNonPerimeterNeighbourIndices(edge, TileType.Wall, distanceToEdge, 0);
                for (int i = 0, l = edge.Count; i < l; i++)
                {
                    distanceToEdge[edge[i]] = distance;
                }

                var bordersToUndecieded = RoomSearch.GetNonPerimeterTilesThatBorderToType(tileTypeMap, edge, searchType, width);
                if (bordersToUndecieded.Count > 0)
                {
                    wall = bordersToUndecieded[Random.Range(0, bordersToUndecieded.Count)];
                    break;
                }
                if (distance > width + height)
                {
                    break;
                }
            }

            //Digging a connection between walkable areas
            while (wall >= 0)
            {
                SetTileType(wall, TileType.None);
                distance--;

                if (distance <= 0)
                {
                    break;
                }
                var neighbours = GetNeighbourIndices(wall, TileType.Wall, distanceToEdge, distance);
                if (neighbours.Count > 0)
                {
                    wall = neighbours[Random.Range(0, neighbours.Count)];
                }
            }

            if (wall > 0)
            {
                FloodFillAs(wall, TileType.None, TileType.Walkable);
            }
        }
Example #10
0
        List <int> GetNeighbourIndices(int index, TileType neighbourType, int[] selector, int selectionValue)
        {
            var neighbours     = new List <int>();
            var tileNeighbours = RoomSearch.GetNeighbourIndices(tileTypeMap, width, index, neighbourType);

            for (int i = 0, l = tileNeighbours.Count; i < l; i++)
            {
                if (selector[tileNeighbours[i]] == selectionValue)
                {
                    neighbours.Add(tileNeighbours[i]);
                }
            }

            return(neighbours);
        }
Example #11
0
        List <int> GetNeighbourIndices(List <int> indices, TileType neighbourType)
        {
            var neighbours = new HashSet <int>();

            for (int i = 0, j = indices.Count; i < j; i++)
            {
                var tileNeighbours = RoomSearch.GetNeighbourIndices(tileTypeMap, width, indices[i], neighbourType);
                for (int k = 0, l = tileNeighbours.Count; k < l; k++)
                {
                    neighbours.Add(tileNeighbours[k]);
                }
            }

            return(new List <int>(neighbours));
        }
Example #12
0
        List <int> GetTilesBorderingWalls()
        {
            var matchingByType = RoomSearch.GetTileIndicesWithType(TileType.Walkable, tileTypeMap);
            var edge           = new List <int>();

            for (int i = 0, l = matchingByType.Count; i < l; i++)
            {
                var tileNeighbours = RoomSearch.GetNeighbourIndices(tileTypeMap, width, matchingByType[i], TileType.Wall);
                if (tileNeighbours.Count > 0)
                {
                    edge.Add(matchingByType[i]);
                }
            }
            return(edge);
        }
Example #13
0
        int PlayerSpawnPosition(RoomData data)
        {
            if (RoomSearch.HasAnyOfType(TileType.StairsDown, data.tileTypeMap))
            {
                return(RoomSearch.GetFirstOccurance(data.tileTypeMap, TileType.StairsDown));
            }
            else
            {
                var candidates = RoomSearch.GetPositionsAtDistance(data.tileTypeMap,
                                                                   RoomSearch.GetFirstOccurance(data.tileTypeMap, TileType.StairsUp),
                                                                   new Range(minDistanceSpawnInFirstLevel), TileType.Walkable, false, data.width);

                return(candidates[Random.Range(0, candidates.Count)]);
            }
        }
Example #14
0
        public Coordinate GetRandomFreeTileCoordinate(Coordinate referencePosition, int minDistance)
        {
            var distances = RoomSearch.GetDistanceMap(this, referencePosition);

            //Count all valid positions and set them to value 1
            var validPositions  = 0;
            var invalidDistance = Height + Width;

            for (int x = 0, lX = distances.GetLength(0); x < lX; x++)
            {
                for (int y = 0, lY = distances.GetLength(1); y < lY; y++)
                {
                    if (distances[x, y] >= minDistance && distances[x, y] < invalidDistance)
                    {
                        distances[x, y] = 1;
                        validPositions++;
                    }
                    else
                    {
                        distances[x, y] = 0;
                    }
                }
            }

            //Select position based on count and iterate until found it
            int selectedPosition = Random.Range(0, validPositions);

            for (int x = 0, lX = distances.GetLength(0); x < lX; x++)
            {
                for (int y = 0, lY = distances.GetLength(1); y < lY; y++)
                {
                    if (distances[x, y] == 1)
                    {
                        if (selectedPosition < 1)
                        {
                            return(new Coordinate(x, y));
                        }
                        else
                        {
                            selectedPosition--;
                        }
                    }
                }
            }
            Debug.LogWarning("No valid position found");
            return(Coordinate.InvalidPlacement);
        }
Example #15
0
        int[] GenerateWallIsands()
        {
            var undecidedTiles  = RoomSearch.GetTileIndicesWithType(TileType.None, tileTypeMap);
            var islandsToCreate = Random.Range(minWallIslands, maxWallIslands);
            var islands         = new int[Mathf.Max(islandsToCreate, 0)];

            while (islandsToCreate > 0)
            {
                var tileIndex = undecidedTiles[Random.Range(0, undecidedTiles.Count)];
                undecidedTiles.Remove(tileIndex);
                SetTileType(tileIndex, TileType.Wall);
                islands[islandsToCreate - 1] = tileIndex;
                islandsToCreate--;
            }

            return(islands);
        }
Example #16
0
        List <int> GetNonPerimeterNeighbourIndices(List <int> indices, TileType neighbourType, int[] selector, int selectionValue)
        {
            var neighbours = new HashSet <int>();

            for (int i = 0, j = indices.Count; i < j; i++)
            {
                var tileNeighbours = RoomSearch.GetNeighbourIndices(tileTypeMap, width, indices[i], neighbourType);
                for (int k = 0, l = tileNeighbours.Count; k < l; k++)
                {
                    if (selector[tileNeighbours[k]] == selectionValue && !RoomMath.IndexOnPerimeter(tileNeighbours[k], width, height))
                    {
                        neighbours.Add(tileNeighbours[k]);
                    }
                }
            }

            return(new List <int>(neighbours));
        }
Example #17
0
        public static List <int> FloodSearch(int[] tileTypeMap, int width, int source, params TileType[] selectors)
        {
            var fillingIndex = 0;
            var filling      = new List <int>();

            filling.Add(source);

            while (fillingIndex < filling.Count)
            {
                var neighbourUndecided = RoomSearch.GetNeighbourIndices(tileTypeMap, width, filling[fillingIndex], selectors);
                for (int i = 0, l = neighbourUndecided.Count; i < l; i++)
                {
                    if (!filling.Contains(neighbourUndecided[i]))
                    {
                        filling.AddRange(neighbourUndecided);
                    }
                }
                fillingIndex++;
            }
            return(filling);
        }
Example #18
0
        void PlaceCoins(Coordinate deadEnd)
        {
            var treasurePositions = RoomSearch.FloodSearch(tileTypeMap, width, deadEnd.ToPosition(width, height), TileType.Walkable, TileType.SpikeTrap);

            TreasureChest.Spawn(treasurePositions, width);
        }
Example #19
0
        void GrowWalls(int iterations)
        {
            var walls = RoomSearch.GetTileIndicesWithType(TileType.Wall, tileTypeMap);

            GrowWallIslands(walls.ToArray(), iterations);
        }
Example #20
0
 void NewWaveSource()
 {
     waveSource = waveSource == TileType.StairsUp ? (RoomSearch.HasAnyOfType(TileType.StairsDown, tileTypeMap) ? TileType.StairsDown : TileType.StairsUp) : TileType.StairsUp;
     SetDistanceMap(RoomSearch.GetFirstOccurance(tileTypeMap, waveSource));
     wavePeak = 0;
 }