Пример #1
0
        private void GenRoom(TCODBsp bsp, ref Map map)
        {
            if (bsp.isLeaf())
            {
                float propX1 = _rand.getInt(0, 33);
                float propX2 = _rand.getInt(0, 33);
                float propY1 = _rand.getInt(0, 33);
                float propY2 = _rand.getInt(0, 33);

                int x = bsp.x + (int)(propX1 / 100f * bsp.w);
                int w = bsp.w - (x - bsp.x) - (int)(propX2 / 100f * bsp.w);
                int y = bsp.y + (int)(propY1 / 100f * bsp.h);
                int h = bsp.h - (y - bsp.y) - (int)(propY2 / 100f * bsp.h);

                for (int i = x; i < x + w; i++)
                {
                    for (int j = y; j < y + h; j++)
                    {
                        map[i, j] = false;
                    }
                }
            }
            else
            {
                TCODBsp left  = bsp.getLeft();
                TCODBsp right = bsp.getRight();

                GenRoom(left, ref map);
                GenRoom(right, ref map);

                if (bsp.horizontal)
                {
                    int midx = (left.x + left.x + left.w) / 2;
                    int midL = (left.y + left.y + left.h) / 2;
                    int midR = (right.y + right.y + right.h) / 2;
                    for (int y = midL; y < midR; y++)
                    {
                        map[midx, y] = false;
                    }
                }
                else
                {
                    int midy = (left.y + left.y + left.h) / 2;
                    int midL = (left.x + left.x + left.w) / 2;
                    int midR = (right.x + right.x + right.w) / 2;
                    for (int x = midL; x < midR; x++)
                    {
                        map[x, midy] = false;
                    }
                }
            }
        }
Пример #2
0
        private void GenRoom(TCODBsp bsp, ref Map map)
        {
            if (bsp.isLeaf())
            {
                float propX1 = _rand.getInt(0, 33);
                float propX2 = _rand.getInt(0, 33);
                float propY1 = _rand.getInt(0, 33);
                float propY2 = _rand.getInt(0, 33);

                int x = bsp.x + (int)(propX1 / 100f * bsp.w);
                int w = bsp.w - (x - bsp.x) - (int)(propX2 / 100f * bsp.w);
                int y = bsp.y + (int)(propY1 / 100f * bsp.h);
                int h = bsp.h - (y - bsp.y) - (int)(propY2 / 100f * bsp.h);

                for (int i = x; i < x + w; i++)
                    for (int j = y; j < y + h; j++)
                    {
                        map[i, j] = false;
                    }
            }
            else
            {
                TCODBsp left = bsp.getLeft();
                TCODBsp right = bsp.getRight();

                GenRoom(left, ref map);
                GenRoom(right, ref map);

                if (bsp.horizontal)
                {
                    int midx = (left.x + left.x + left.w) / 2;
                    int midL = (left.y + left.y + left.h) / 2;
                    int midR = (right.y + right.y + right.h) / 2;
                    for (int y = midL; y < midR; y++)
                    {
                        map[midx, y] = false;
                    }
                }
                else
                {
                    int midy = (left.y + left.y + left.h) / 2;
                    int midL = (left.x + left.x + left.w) / 2;
                    int midR = (right.x + right.x + right.w) / 2;
                    for (int x = midL; x < midR; x++)
                    {
                        map[x, midy] = false;
                    }
                }
            }
        }
Пример #3
0
            public override bool visitNode(TCODBsp node)
            {
                if (!node.isLeaf())
                {
                    return(true);
                }

                int w = rng.getInt(MIN_ROOM_SIZE, node.w - 2);
                int h = rng.getInt(MIN_ROOM_SIZE, node.h - 2);
                int x = rng.getInt(node.x + 1, node.x + node.w - w - 1);
                int y = rng.getInt(node.y + 1, node.y + node.h - h - 1);

                Rect rect = new Rect(x, y, w, h);

                rooms.Add(new DungeonRoom(rect));
                return(true);
            }
Пример #4
0
 public void Generate(int level, out Map map, Game game)
 {
     map = new Map(game);
     TCODBsp root = new TCODBsp(1, 1, Map.MAP_WIDTH - 2, Map.MAP_HEIGHT - 2);
     root.splitRecursive(_rand, level, 3, 3, 1.5f, 1.5f);
     //map = new Map(80, 50, new TCODConsole(5, 5));
     GenRoom(root, ref map);
     int x;
     int y;
     FindOpenSpot(out x, out y, map);
     map.SetStartPos(x, y);
     FindOpenSpot(out x, out y, map);
     map.Stair = new Stairs(x, y);
     for (int i = 0; i < 20; i++)
     {
         PlaceRandomItem(map);
     }
 }
Пример #5
0
        public void Generate(int level, out Map map, Game game)
        {
            map = new Map(game);
            TCODBsp root = new TCODBsp(1, 1, Map.MAP_WIDTH - 2, Map.MAP_HEIGHT - 2);

            root.splitRecursive(_rand, level, 3, 3, 1.5f, 1.5f);
            //map = new Map(80, 50, new TCODConsole(5, 5));
            GenRoom(root, ref map);
            int x;
            int y;

            FindOpenSpot(out x, out y, map);
            map.SetStartPos(x, y);
            FindOpenSpot(out x, out y, map);
            map.Stair = new Stairs(x, y);
            for (int i = 0; i < 20; i++)
            {
                PlaceRandomItem(map);
            }
        }
Пример #6
0
        void render_bsp(bool first, TCODKey key)
        {
            int x, y;

            if (generate || refresh)
            {
                // dungeon generation
                if (bsp == null)
                {
                    // create the bsp
                    bsp = new TCODBsp(0, 0, SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT);
                }
                else
                {
                    // restore the nodes size
                    bsp.resize(0, 0, SAMPLE_SCREEN_WIDTH, SAMPLE_SCREEN_HEIGHT);
                }

                for (int x1 = 0; x1 < SAMPLE_SCREEN_WIDTH; x1++)
                    for (int y1 = 0; y1 < SAMPLE_SCREEN_HEIGHT; y1++)
                        bsp_map[x1, y1] = '#';

                if (generate)
                {
                    // build a new random bsp tree
                    bsp.removeSons();
                    bsp.splitRecursive(null, bspDepth, minRoomSize + (roomWalls ? 1 : 0), minRoomSize + (roomWalls ? 1 : 0), 1.5f, 1.5f);
                }
                // create the dungeon from the bsp
                bsp.traverseInvertedLevelOrder(new TraverseNode());
                generate = false;
                refresh = false;
            }

            sampleConsole.clear();
            sampleConsole.setForegroundColor(TCODColor.white);
            sampleConsole.printEx(1, 1, TCODBackgroundFlag.None, TCODAlignment.LeftAlignment, "ENTER : rebuild bsp\nSPACE : rebuild dungeon\n+-: bsp depth " + bspDepth + "\n*/: room size " + minRoomSize + "\n1 : random room size " + (randomRoom ? "ON" : "OFF"));

            if (randomRoom)
                sampleConsole.printEx(1, 6, TCODBackgroundFlag.None, TCODAlignment.LeftAlignment, "2 : room walls " + (roomWalls ? "ON" : "OFF"));

            // render the level
            for (y = 0; y < SAMPLE_SCREEN_HEIGHT; y++)
            {
                for (x = 0; x < SAMPLE_SCREEN_WIDTH; x++)
                {
                    bool wall = (bsp_map[x,y] == '#');
                    sampleConsole.setCharBackground(x, y, (wall ? darkWall : darkGround), TCODBackgroundFlag.Set);
                }
            }

            if (key.KeyCode == TCODKeyCode.Enter || key.KeyCode == TCODKeyCode.KeypadEnter)
            {
                generate = true;
            }
            else if (key.Character == ' ')
            {
                refresh = true;
            }
            else if (key.Character == '+')
            {
                bspDepth++;
                generate = true;
            }
            else if (key.Character == '-' && bspDepth > 1)
            {
                bspDepth--;
                generate = true;
            }
            else if (key.Character == '*')
            {
                minRoomSize++;
                generate = true;
            }
            else if (key.Character == '/' && minRoomSize > 2)
            {
                minRoomSize--;
                generate = true;
            }
            else if (key.Character == '1' || key.KeyCode == TCODKeyCode.One || key.KeyCode == TCODKeyCode.KeypadOne)
            {
                randomRoom = !randomRoom;
                if (!randomRoom) roomWalls = true;
                refresh = true;
            }
            else if (key.Character == '2' || key.KeyCode == TCODKeyCode.Two || key.KeyCode == TCODKeyCode.KeypadTwo)
            {
                roomWalls = !roomWalls;
                refresh = true;
            }
        }
Пример #7
0
            public override bool visitNode(TCODBsp node)
            {
                TCODRandom rnd = new TCODRandom();

                if (node.isLeaf())
                {
                    // calculate the room size
                    int minx = node.x + 1;
                    int maxx = node.x + node.w - 1;
                    int miny = node.y + 1;
                    int maxy = node.y + node.h - 1;
                    int x, y;
                    if (!roomWalls)
                    {
                        if (minx > 1) minx--;
                        if (miny > 1) miny--;
                    }
                    if (maxx == SAMPLE_SCREEN_WIDTH - 1) maxx--;
                    if (maxy == SAMPLE_SCREEN_HEIGHT - 1) maxy--;
                    if (randomRoom)
                    {
                        minx = rnd.getInt(minx, maxx - minRoomSize + 1);
                        miny = rnd.getInt(miny, maxy - minRoomSize + 1);
                        maxx = rnd.getInt(minx + minRoomSize - 1, maxx);
                        maxy = rnd.getInt(miny + minRoomSize - 1, maxy);
                    }
                    // resize the node to fit the room
                    //	printf("node %dx%d %dx%d => room %dx%d %dx%d\n",node->x,node->y,node->w,node->h,minx,miny,maxx-minx+1,maxy-miny+1);
                    node.x = minx;
                    node.y = miny;
                    node.w = maxx - minx + 1;
                    node.h = maxy - miny + 1;
                    // dig the room
                    for (x = minx; x <= maxx; x++)
                    {
                        for (y = miny; y <= maxy; y++)
                        {
                            bsp_map[x, y] = ' ';
                        }
                    }
                }
                else
                {
                    //	printf("lvl %d %dx%d %dx%d\n",node->level, node->x,node->y,node->w,node->h);
                    // resize the node to fit its sons
                    TCODBsp left = node.getLeft();
                    TCODBsp right = node.getRight();

                    node.x = System.Math.Min(left.x, right.x);
                    node.y = System.Math.Min(left.y, right.y);
                    node.w = System.Math.Max(left.x + left.w, right.x + right.w) - node.x;
                    node.h = System.Math.Max(left.y + left.h, right.y + right.h) - node.y;
                    // create a corridor between the two lower nodes
                    if (node.horizontal)
                    {
                        // vertical corridor
                        if (left.x + left.w - 1 < right.x || right.x + right.w - 1 < left.x)
                        {
                            // no overlapping zone. we need a Z shaped corridor
                            int x1 = rnd.getInt(left.x, left.x + left.w - 1);
                            int x2 = rnd.getInt(right.x, right.x + right.w - 1);
                            int y = rnd.getInt(left.y + left.h, right.y);
                            vline_up(bsp_map, x1, y - 1);
                            hline(bsp_map, x1, y, x2);
                            vline_down(bsp_map, x2, y + 1);
                        }
                        else
                        {
                            // straight vertical corridor
                            int minx = System.Math.Max(left.x, right.x);
                            int maxx = System.Math.Min(left.x + left.w - 1, right.x + right.w - 1);
                            int x = rnd.getInt(minx, maxx);
                            vline_down(bsp_map, x, right.y);
                            vline_up(bsp_map, x, right.y - 1);
                        }
                    }
                    else
                    {
                        // horizontal corridor
                        if (left.y + left.h - 1 < right.y || right.y + right.h - 1 < left.y)
                        {
                            // no overlapping zone. we need a Z shaped corridor
                            int y1 = rnd.getInt(left.y, left.y + left.h - 1);
                            int y2 = rnd.getInt(right.y, right.y + right.h - 1);
                            int x = rnd.getInt(left.x + left.w, right.x);
                            hline_left(bsp_map, x - 1, y1);
                            vline(bsp_map, x, y1, y2);
                            hline_right(bsp_map, x + 1, y2);
                        }
                        else
                        {
                            // straight horizontal corridor
                            int miny = System.Math.Max(left.y, right.y);
                            int maxy = System.Math.Min(left.y + left.h - 1, right.y + right.h - 1);
                            int y = rnd.getInt(miny, maxy);
                            hline_left(bsp_map, right.x - 1, y);
                            hline_right(bsp_map, right.x, y);
                        }
                    }
                }
                return true;
            }
Пример #8
0
        public override void GenerateMap(AreaMap.Tile[] tiles, int width, int height)
        {
            this.width  = width;
            this.height = height;

            objectSpawns = new List <ObjectSpawn>();

            // generate a binary tree of rooms that subdivides the space, suignthe TCODBsp module
            TCODBsp       bsp           = new TCODBsp(0, 0, width, height);
            RoomGenerator roomGenerator = new RoomGenerator(rng);

            bsp.splitRecursive(rng, NUM_SUBDIVISIONS, MAX_ROOM_SIZE, MAX_ROOM_SIZE, MAX_SIDE_RATIO, MAX_SIDE_RATIO);
            bsp.traverseInvertedLevelOrder(roomGenerator);

            // dig out the generated rooms
            foreach (DungeonRoom room in roomGenerator.rooms)
            {
                DigArea(tiles, room.data.x, room.data.y, room.data.x + room.data.w - 1, room.data.y + room.data.h - 1);
            }

            // generate a sparsely connected graph of the created rooms, so that all rooms are connected
            CreateSparseRoomGraph(roomGenerator.rooms);

            // follow the connections in the graph and generate a tunnel b/w the rooms that are connected
            foreach (DungeonRoom room in roomGenerator.rooms)
            {
                // dig a hallway to each neighboring room
                foreach (DungeonRoom neighbor in room.neighbors)
                {
                    Rect roomData = room.data;
                    Rect nextData = neighbor.data;

                    ConnectRooms(tiles, roomData, nextData);
                }
            }

            // decide where the player should spawn
            int         playerRoomIdx = rng.getInt(0, roomGenerator.rooms.Count - 1);
            DungeonRoom playerRoom    = roomGenerator.rooms[playerRoomIdx];

            Vector2 playerLoc = RandomSpawnInRoom(playerRoom);

            objectSpawns.Add(new ObjectSpawn(playerLoc, ENTRANCE_ENTITY));
            objectSpawns.Add(new ObjectSpawn(playerLoc, "Player"));

            // place doors between rooms where appropriate, and spawn other entities and obejcts as well
            int numChests = 0;

            foreach (DungeonRoom room in roomGenerator.rooms)
            {
                GetDoors(tiles, room.data);

                // decide if any mobs should go in this room: defs not if its the start room
                if (room == playerRoom)
                {
                    continue;
                }

                SpawnContainers(room, mapInfo, ref numChests);
                SpawnMobs(room, mapInfo);
            }

            // spawn a key for each chest
            for (int i = 0; i < numChests; i++)
            {
                Vector2 loc = RandomSpawn(roomGenerator.rooms);
                objectSpawns.Add(new ObjectSpawn(loc, KEY_ENTITY));
            }

            // and add exit somewhere else
            Vector2 exitLoc = RandomSpawn(roomGenerator.rooms);

            objectSpawns.Add(new ObjectSpawn(exitLoc, EXIT_ENTITY));
        }