Exemplo n.º 1
0
 private TileType ChooseInnerWall()
 {
     return(Rng.Item(new TileType[] { TileType.Wall, TileType.LowWall }));
 }
Exemplo n.º 2
0
        public bool MakeHall(Connector connector)
        {
            // create a random hall
            int length = Rng.Int(mWriter.Options.HallLengthMin, mWriter.Options.HallLengthMax);

            // check to see if we can place it
            Rect bounds = Rect.Empty;

            if (connector.Direction == Direction.N)
            {
                bounds = new Rect(connector.Position.X - 1, connector.Position.Y - length, 3, length + 1);
            }
            if (connector.Direction == Direction.S)
            {
                bounds = new Rect(connector.Position.X - 1, connector.Position.Y, 3, length + 1);
            }
            if (connector.Direction == Direction.E)
            {
                bounds = new Rect(connector.Position.X, connector.Position.Y - 1, length + 1, 3);
            }
            if (connector.Direction == Direction.W)
            {
                bounds = new Rect(connector.Position.X - length, connector.Position.Y - 1, length + 1, 3);
            }

            if (!mWriter.IsOpen(bounds, null))
            {
                return(false);
            }

            // make sure the end corners aren't open unless the position in front of the end is too
            // prevents cases like:
            Vec pos = connector.Position + (connector.Direction.Offset * (length + 1));

            if (!mWriter.Bounds.Contains(pos))
            {
                return(false);
            }
            if (!mWriter.Bounds.Contains(pos + connector.Direction.RotateLeft90))
            {
                return(false);
            }
            if (!mWriter.Bounds.Contains(pos + connector.Direction.RotateRight90))
            {
                return(false);
            }
            // ####..
            // ####..
            // ....## <- new hall ends at corner of room
            // ######
            if ((mWriter.GetTile(pos + connector.Direction.RotateLeft90) != TileType.Wall) &&
                (mWriter.GetTile(pos) == TileType.Wall))
            {
                return(false);
            }

            if ((mWriter.GetTile(pos + connector.Direction.RotateRight90) != TileType.Wall) &&
                (mWriter.GetTile(pos) == TileType.Wall))
            {
                return(false);
            }

            // place the hall
            pos = connector.Position;
            for (int i = 0; i <= length; i++)
            {
                mWriter.SetTile(pos, TileType.Floor);

                pos += connector.Direction;
            }

            PlaceDoor(connector.Position);
            PlaceDoor(connector.Position + (connector.Direction.Offset * length));

            // add the connectors
            mWriter.AddHallConnector(connector.Position + (connector.Direction.Offset * length),
                                     connector.Direction);

            Populate(bounds, 10, 10, mDepth);

            return(true);
        }
Exemplo n.º 3
0
        private Rect CreateRoom(Connector connector)
        {
            int width  = Rng.Int(6, 13);
            int height = Rng.Int(6, 13);

            Rect bounds = CreateRectRoom(connector, width, height);

            // bail if we failed
            if (bounds == Rect.Empty)
            {
                return(bounds);
            }

            // place the room
            foreach (Vec pos in bounds)
            {
                mWriter.SetTile(pos, TileType.Floor);
            }

            TileType decoration = ChooseInnerWall();

            RoomDecoration.Decorate(bounds, new FeatureFactory.RoomDecorator(this,
                                                                             pos => mWriter.Populate(pos, 60, 200, mDepth + Rng.Int(mDepth / 10))));

            mWriter.LightRect(bounds, mDepth);

            // place the connectors
            AddRoomConnectors(connector, bounds);

            Populate(bounds, 20, 20, mDepth);

            return(bounds);
        }
Exemplo n.º 4
0
        private bool MakePit(Connector connector)
        {
            // pits use room size right now
            int  width  = Rng.Int(mWriter.Options.RoomSizeMin, mWriter.Options.RoomSizeMax);
            int  height = Rng.Int(mWriter.Options.RoomSizeMin, mWriter.Options.RoomSizeMax);
            Rect bounds = CreateRectRoom(connector, width, height);

            // bail if we failed
            if (bounds == Rect.Empty)
            {
                return(false);
            }

            // light it
            mWriter.LightRect(bounds, mDepth);

            // choose a group
            IList <Race> races = mWriter.Content.Races.AllInGroup(Rng.Item(mWriter.Content.Races.Groups));

            // make sure we've got some races that aren't too out of depth
            races = new List <Race>(races.Where(race => race.Depth <= mDepth + 10));
            if (races.Count == 0)
            {
                return(false);
            }

            // place the room
            foreach (Vec pos in bounds)
            {
                mWriter.SetTile(pos, TileType.Floor);
            }

            RoomDecoration.DecorateInnerRoom(bounds, new RoomDecorator(this,
                                                                       pos => mWriter.AddEntity(new Monster(pos, Rng.Item(races)))));

            return(true);
        }
Exemplo n.º 5
0
        private bool MakeMaze(Connector connector)
        {
            // in maze units (i.e. thin walls), not tiles
            int width  = Rng.Int(mWriter.Options.MazeSizeMin, mWriter.Options.MazeSizeMax);
            int height = Rng.Int(mWriter.Options.MazeSizeMin, mWriter.Options.MazeSizeMax);

            int  tileWidth  = width * 2 + 3;
            int  tileHeight = height * 2 + 3;
            Rect bounds     = CreateRectRoom(connector, tileWidth, tileHeight);

            // bail if we failed
            if (bounds == Rect.Empty)
            {
                return(false);
            }

            // the hallway around the maze
            foreach (Vec pos in bounds.Trace())
            {
                mWriter.SetTile(pos, TileType.Floor);
            }

            // sometimes make the walls low
            if (Rng.OneIn(2))
            {
                foreach (Vec pos in bounds.Inflate(-1))
                {
                    mWriter.SetTile(pos, TileType.LowWall);
                }
            }

            // add an opening in one corner
            Vec doorway;

            switch (Rng.Int(8))
            {
            case 0: doorway = bounds.TopLeft.Offset(2, 1); break;

            case 1: doorway = bounds.TopLeft.Offset(1, 2); break;

            case 2: doorway = bounds.TopRight.Offset(-3, 1); break;

            case 3: doorway = bounds.TopRight.Offset(-2, 2); break;

            case 4: doorway = bounds.BottomRight.Offset(-3, -2); break;

            case 5: doorway = bounds.BottomRight.Offset(-2, -3); break;

            case 6: doorway = bounds.BottomLeft.Offset(2, -2); break;

            case 7: doorway = bounds.BottomLeft.Offset(1, -3); break;

            default: throw new Exception();
            }
            PlaceDoor(doorway);

            // carve the maze
            Maze maze = new Maze(width, height);

            maze.GrowTree();

            Vec offset = bounds.Position.Offset(1, 1);

            maze.Draw(pos => mWriter.SetTile(pos + offset, TileType.Floor));

            mWriter.LightRect(bounds, mDepth);

            // populate it
            int boostedDepth = mDepth + Rng.Int(mDepth / 5) + 2;

            Populate(bounds.Inflate(-2), 200, 300, boostedDepth);

            // place the connectors
            AddRoomConnectors(connector, bounds);

            return(true);
        }
Exemplo n.º 6
0
        private bool MakeJunction(Connector connector)
        {
            // create a random junction
            Vec center = connector.Position + connector.Direction;

            bool left     = false;
            bool right    = false;
            bool straight = false;

            int choice = Rng.Int(100);

            if (choice < mWriter.Options.ChanceOfTurn)
            {
                if (Rng.OneIn(2))
                {
                    left = true;
                }
                else
                {
                    right = true;
                }
            }
            else if (choice - mWriter.Options.ChanceOfTurn < mWriter.Options.ChanceOfFork)
            {
                if (Rng.OneIn(2))
                {
                    left = true;
                }
                else
                {
                    right = true;
                }
                straight = true;
            }
            else if (choice - mWriter.Options.ChanceOfTurn
                     - mWriter.Options.ChanceOfFork < mWriter.Options.ChanceOfTee)
            {
                left  = true;
                right = true;
            }
            else if (choice - mWriter.Options.ChanceOfTurn
                     - mWriter.Options.ChanceOfFork
                     - mWriter.Options.ChanceOfTee < mWriter.Options.ChanceOfFourWay)
            {
                left     = true;
                right    = true;
                straight = true;
            }
            else
            {
                straight = true;
            }

            // check to see if we can place it
            Rect rect = new Rect(center.Offset(-1, -1), 3, 3);

            if (!mWriter.IsOpen(rect, center + connector.Direction.Rotate180))
            {
                return(false);
            }

            // place the junction
            mWriter.SetTile(center, TileType.Floor);

            // add the connectors
            if (left)
            {
                mWriter.AddRoomConnector(center + connector.Direction.RotateLeft90, connector.Direction.RotateLeft90);
            }
            if (right)
            {
                mWriter.AddRoomConnector(center + connector.Direction.RotateRight90, connector.Direction.RotateRight90);
            }
            if (straight)
            {
                mWriter.AddRoomConnector(center + connector.Direction, connector.Direction);
            }

            return(true);
        }