예제 #1
0
        private bool ValidateRoom(Rect2Int room)
        {
            if (room.xMax >= this.m_Size)
            {
                return(false);
            }

            if (room.x < 1)
            {
                return(false);
            }

            if (room.yMax >= this.m_Size)
            {
                return(false);
            }

            if (room.y < 1)
            {
                return(false);
            }

            if (room.width < MIN_ROOM_SIZE || room.width > MAX_ROOM_SIZE)
            {
                return(false);
            }

            if (room.height < MIN_ROOM_SIZE || room.height > MAX_ROOM_SIZE)
            {
                return(false);
            }

            return(true);
        }
예제 #2
0
        private void OpenRoom(Rect2Int room)
        {
            int doors = this.CalculateDoors(room);

            List <Vector2Int> validDoors = new List <Vector2Int>();

            for (int i = room.x; i < room.xMax + 1; i++)
            {
                for (int j = room.y; j < room.yMax + 1; j++)
                {
                    if (this.m_Tiles[i, j] != GeneratorTileType.Perimeter)
                    {
                        continue;
                    }

                    if (((i != room.x && i != room.xMax) || (j != room.y && j != room.yMax)) &&
                        i > 1 && i < this.m_Size - 1 && j > 1 && j < this.m_Size - 1)
                    {
                        validDoors.Add(new Vector2Int(i, j));
                    }
                }
            }

            for (int i = 0; i < doors; i++)
            {
                int index = this.Roller.Roll(0, validDoors.Count);

                Vector2Int point = new Vector2Int(validDoors[index].x, validDoors[index].y);

                if (this.m_Tiles[point.x - 1, point.y] == GeneratorTileType.Entrance)
                {
                    continue;
                }

                if (this.m_Tiles[point.x + 1, point.y] == GeneratorTileType.Entrance)
                {
                    continue;
                }

                if (this.m_Tiles[point.x, point.y - 1] == GeneratorTileType.Entrance)
                {
                    continue;
                }

                if (this.m_Tiles[point.x, point.y + 1] == GeneratorTileType.Entrance)
                {
                    continue;
                }

                if (this.m_Tiles[point.x, point.y] == GeneratorTileType.Perimeter)
                {
                    this.m_Tiles[point.x, point.y] = GeneratorTileType.Entrance;
                }
                else
                {
                    i -= 1;
                }
            }
        }
예제 #3
0
        private bool PlaceRoom(Vector2Int topLeft)
        {
            int loopCounter = 0;

            while (loopCounter < LOOP_BREAK)
            {
                loopCounter += 1;

                if (topLeft.x < 1 || topLeft.y < 1 || topLeft.x > this.m_Size - 1 || topLeft.y > this.m_Size - 1)
                {
                    return(false);
                }

                if (this.m_Tiles[topLeft.x, topLeft.y] == GeneratorTileType.Floor)
                {
                    return(false);
                }

                if (this.m_NumberOfRooms == this.m_NumberRoomsPlaced)
                {
                    return(false);
                }

                Vector2Int sizes = new Vector2Int(this.Roller.Roll(MIN_ROOM_SIZE, MAX_ROOM_SIZE), this.Roller.Roll(MIN_ROOM_SIZE, MAX_ROOM_SIZE));

                Rect2Int room = new Rect2Int(topLeft, sizes);

                if (!this.ValidateRoom(room))
                {
                    return(false);
                }

                if (this.CheckForRoom(room))
                {
                    return(false);
                }

                for (int i = room.x; i <= room.xMax; i++)
                {
                    for (int j = room.y; j <= room.yMax; j++)
                    {
                        if (i == room.x || i == room.xMax || j == room.y || j == room.yMax)
                        {
                            this.m_Tiles[i, j] = GeneratorTileType.Perimeter;
                        }
                        else
                        {
                            this.m_Tiles[i, j] = GeneratorTileType.Floor;
                        }
                    }
                }

                this.m_Rooms.Add(room);
                this.m_NumberRoomsPlaced += 1;
                return(true);
            }
            return(false);
        }
예제 #4
0
        private bool CheckForRoom(Rect2Int room)
        {
            for (int i = room.x; i <= room.xMax; i++)
            {
                for (int j = room.y; j <= room.yMax; j++)
                {
                    if (this.m_Tiles[i, j] != GeneratorTileType.None)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #5
0
        public virtual Rect2Int GetFullVisionRect(IEntity viewer)
        {
            Rect2Int visionRect = new Rect2Int(0, 0, viewer.MyWorld.Dimensions.x, viewer.MyWorld.Dimensions.y);

            return(visionRect);
        }
예제 #6
0
        public virtual Rect2Int GetVisionRect(IEntity viewer)
        {
            Rect2Int visionRect = new Rect2Int(viewer.WorldPosition, new Vector2Int(viewer.VisionMod * 2 + 1, viewer.VisionMod * 2 + 1));

            return(visionRect);
        }
예제 #7
0
        private int CalculateDoors(Rect2Int room)
        {
            int maxDoors = (int)Math.Sqrt(room.Area);

            return(this.Roller.Roll(1, maxDoors));
        }
예제 #8
0
        public Queue <Vector2Int> FindPath(Vector2Int fromPoint, Vector2Int toPoint, byte[,] grid, Rect2Int sizes)
        {
            Queue <Vector2Int> path = new Queue <Vector2Int>();

            sbyte[,] direction;
            if (this.Diagonals)
            {
                direction = new sbyte[8, 2] {
                    { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 }, { 1, -1 }, { 1, 1 }, { -1, 1 }, { -1, -1 }
                };
            }
            else
            {
                direction = new sbyte[4, 2] {
                    { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 }
                };
            }

            PathFinderNode parentNode = new PathFinderNode
            {
                G = 0,
                H = this.HeuristicEstimate
            };

            parentNode.F  = parentNode.G + parentNode.H;
            parentNode.X  = fromPoint.x;
            parentNode.Y  = fromPoint.y;
            parentNode.PX = parentNode.X;
            parentNode.PY = parentNode.Y;

            PriorityQueue <PathFinderNode> openList   = new PriorityQueue <PathFinderNode>(new PathfinderNodeComparer());
            List <PathFinderNode>          closedList = new List <PathFinderNode>();

            openList.Push(parentNode);

            bool found = false;

            int loopBreak = 0;

            while (openList.Count > 0 && loopBreak < this.SearchLimit)
            {
                parentNode = openList.Pop();

                if (parentNode.X == toPoint.x && parentNode.Y == toPoint.y)
                {
                    closedList.Add(parentNode);
                    found = true;
                    break;
                }

                if (closedList.Count > this.SearchLimit)
                {
                    return(null);
                }

                if (this.PunishChangeDirection)
                {
                    this.PunishmentValue = parentNode.X - parentNode.PX;
                }

                for (int i = 0; i < (this.Diagonals == true ? 8 : 4); i++)
                {
                    PathFinderNode newNode = new PathFinderNode
                    {
                        X = parentNode.X + direction[i, 0],
                        Y = parentNode.Y + direction[i, 1]
                    };

                    if (newNode.X < 0 || newNode.Y < 0 || newNode.X >= sizes.xMax || newNode.Y >= sizes.yMax)
                    {
                        continue;
                    }

                    //If it's impassible, skip
                    if (grid[newNode.X, newNode.Y] == byte.MaxValue)
                    {
                        continue;
                    }

                    int newG = parentNode.G + grid[newNode.X, newNode.Y];
                    if (this.HeavyDiagonals && i > 3)
                    {
                        newG += 2;
                    }

                    if (this.PunishChangeDirection)
                    {
                        if ((newNode.X - parentNode.X) != 0)
                        {
                            if (this.PunishmentValue == 0)
                            {
                                newG += this.PunishmentValue;
                            }
                        }
                        if ((newNode.Y - parentNode.Y) != 0)
                        {
                            if (this.PunishmentValue != 0)
                            {
                                newG += this.PunishmentValue;
                            }
                        }
                    }

                    int foundInOpenIndex = -1;
                    for (int j = 0; j < openList.Count; j++)
                    {
                        if (openList[j].X == newNode.X && openList[j].Y == newNode.Y)
                        {
                            foundInOpenIndex = j;
                            break;
                        }
                    }
                    if (foundInOpenIndex != -1 && openList[foundInOpenIndex].G <= newG)
                    {
                        continue;
                    }

                    int foundInCloseIndex = -1;
                    for (int j = 0; j < closedList.Count; j++)
                    {
                        if (closedList[j].X == newNode.X && closedList[j].Y == newNode.Y)
                        {
                            foundInCloseIndex = j;
                            break;
                        }
                    }
                    if (foundInCloseIndex != -1 && (this.ReopenCloseNodes || closedList[foundInCloseIndex].G <= newG))
                    {
                        continue;
                    }

                    newNode.PX = parentNode.X;
                    newNode.PY = parentNode.Y;
                    newNode.G  = newG;

                    int hDiagonal = Math.Min(Math.Abs(newNode.X - toPoint.x), Math.Abs(newNode.Y - toPoint.y));
                    int hStraight = Math.Abs(newNode.X - toPoint.x) + Math.Abs(newNode.Y - toPoint.y);
                    newNode.H = (this.HeuristicEstimate * 2) * hDiagonal + this.HeuristicEstimate * (hStraight - 2 * hDiagonal);

                    newNode.F = newNode.G + newNode.H;

                    openList.Push(newNode);
                }

                closedList.Add(parentNode);

                loopBreak++;
            }

            if (found)
            {
                PathFinderNode node = closedList[closedList.Count - 1];

                for (int i = closedList.Count - 1; i >= 0; i--)
                {
                    if (node.PX == closedList[i].X && node.PY == closedList[i].Y || i == closedList.Count - 1)
                    {
                        path.Enqueue(new Vector2Int(node.X, node.Y));
                        node = closedList[i];
                    }
                    else
                    {
                        closedList.RemoveAt(i);
                    }
                }
                //There's always a copy of the last node, so get rid of it
                path.Dequeue();
            }

            this.Stopped = true;
            Queue <Vector2Int> returnPath = new Queue <Vector2Int>(path.Reverse());

            return(returnPath);
        }
예제 #9
0
        public void GenerateChunks(bool print_debug = false)
        {
            Rect2Int chunk_rect = (map_tower_rect / Chunk.chunk_size).ExpandToInt();

            Vector2 top_left_corner = chunk_rect.min * Chunk.chunk_size;

            chunks = new Chunk [chunk_rect.w, chunk_rect.h];
            HashSet <Vector2Int> filled_chunks_temp = new HashSet <Vector2Int> ();

            for (int i = 0; i < chunk_rect.w; i++)
            {
                for (int j = 0; j < chunk_rect.h; j++)
                {
                    chunks [i, j] = new Chunk(new Vector2Int(i, j));
                }
            }

            // Put every tower into the correct chunk
            foreach (Tower tower in towers)
            {
                Vector2Int chunk_coord = ((tower.map_position - top_left_corner) / Chunk.chunk_size).floor;

                if (chunk_coord.x >= chunk_rect.w)
                {
                    chunk_coord.x--;
                }
                if (chunk_coord.y >= chunk_rect.h)
                {
                    chunk_coord.y--;
                }

                filled_chunks_temp.Add(chunk_coord);

                Chunk chunk = chunks [chunk_coord.x, chunk_coord.y];

                tower.chunk = chunk;
                chunk.towers.Add(tower);
            }

            // Populate chunk neighbours
            filled_chunks = filled_chunks_temp.ToArray();

            Vector2Int [] directions = new Vector2Int [] {
                new Vector2Int(-1, -1),
                new Vector2Int(0, -1),
                new Vector2Int(1, -1),
                new Vector2Int(-1, 0),
                new Vector2Int(1, 0),
                new Vector2Int(-1, 1),
                new Vector2Int(0, 1),
                new Vector2Int(1, 1)
            };

            foreach (Vector2Int coord in filled_chunks)
            {
                foreach (Vector2Int offset in directions)
                {
                    Vector2Int neighbour_coord = coord + offset;

                    if (filled_chunks_temp.Contains(neighbour_coord))
                    {
                        chunks [coord.x, coord.y].populated_neighbours.Add(chunks [neighbour_coord.x, neighbour_coord.y]);
                    }
                }
            }

            // Print out the chunk info
            if (print_debug)
            {
                Console.WriteLine(name + ": " + chunk_rect);

                for (int j = 0; j < chunk_rect.h; j++)
                {
                    for (int i = 0; i < chunk_rect.w; i++)
                    {
                        int c = chunks [i, j].populated_neighbours.Count;

                        string s = c.ToString();

                        if (chunks [i, j].towers.Count == 0)
                        {
                            s = "";
                        }

                        Console.Write(s + new string (' ', 3 - s.Length));
                    }

                    Console.Write("\n");
                }
            }
        }