예제 #1
0
        public override void ApplyToPath(IRandom rand, GridPlan floorPlan)
        {
            List <int> candidates = new List <int>();

            for (int ii = 0; ii < floorPlan.RoomCount; ii++)
            {
                if (!floorPlan.GetRoomPlan(ii).Immutable)
                {
                    List <int> adjacents = floorPlan.GetAdjacentRooms(ii);
                    if (adjacents.Count > 1)
                    {
                        candidates.Add(ii);
                    }
                }
            }

            // our candidates are all rooms except immutables and terminals
            int amountToDefault = this.DefaultRatio.Pick(rand) * candidates.Count / 100;

            for (int ii = 0; ii < amountToDefault; ii++)
            {
                int          randIndex = rand.Next(candidates.Count);
                GridRoomPlan plan      = floorPlan.GetRoomPlan(candidates[randIndex]);
                plan.RoomGen    = new RoomGenDefault <T>();
                plan.PreferHall = true;
                candidates.RemoveAt(randIndex);
                GenContextDebug.DebugProgress("Defaulted Room");
            }
        }
        public override void ApplyToPath(IRandom rand, GridPlan floorPlan)
        {
            // choose certain rooms in the list to be special rooms
            // special rooms are required; so make sure they don't overlap
            List <int> room_indices = new List <int>();

            for (int ii = 0; ii < floorPlan.RoomCount; ii++)
            {
                GridRoomPlan plan = floorPlan.GetRoomPlan(ii);
                if (!plan.Immutable && !plan.CountsAsHall())
                {
                    room_indices.Add(ii);
                }
            }

            if (room_indices.Count > 0)
            {
                int          ind  = rand.Next(room_indices.Count);
                GridRoomPlan plan = floorPlan.GetRoomPlan(room_indices[ind]);
                plan.RoomGen   = this.Rooms.Pick(rand).Copy();
                plan.Immutable = true;
                room_indices.RemoveAt(ind);
                GenContextDebug.DebugProgress("Set Special Room");
            }
        }
예제 #3
0
        private static Loc GetBoundsSize(GridPlan floorPlan, GridRoomPlan plan)
        {
            Loc cellSize     = new Loc(plan.Bounds.Width * floorPlan.WidthPerCell, plan.Bounds.Height * floorPlan.HeightPerCell);
            Loc cellWallSize = new Loc((plan.Bounds.Width - 1) * floorPlan.CellWall, (plan.Bounds.Height - 1) * floorPlan.CellWall);

            return(cellSize + cellWallSize);
        }
예제 #4
0
        public override void Apply(T map)
        {
            // initialize grid
            var floorPlan = new GridPlan();

            floorPlan.InitSize(this.CellX, this.CellY, this.CellWidth, this.CellHeight, this.CellWall);

            map.InitGrid(floorPlan);
        }
예제 #5
0
 public static void UnsafeAddHall(LocRay4 locRay, GridPlan floorPlan, IPermissiveRoomGen hallGen, ComponentCollection components)
 {
     floorPlan.SetHall(locRay, hallGen, components.Clone());
     GenContextDebug.DebugProgress("Hall");
     if (floorPlan.GetRoomPlan(locRay.Loc) == null || floorPlan.GetRoomPlan(locRay.Traverse(1)) == null)
     {
         floorPlan.Clear();
         throw new InvalidOperationException("Can't create a hall without rooms to connect!");
     }
 }
예제 #6
0
 private void RollOpenRoom(IRandom rand, GridPlan floorPlan, Loc loc, ref int roomOpen, ref int maxRooms)
 {
     if (RollRatio(rand, ref roomOpen, ref maxRooms))
     {
         floorPlan.AddRoom(loc, this.GenericRooms.Pick(rand), this.RoomComponents.Clone());
     }
     else
     {
         floorPlan.AddRoom(loc, this.GetDefaultGen(), this.HallComponents.Clone(), true);
     }
 }
예제 #7
0
 /// <summary>
 /// Gets the directions a room can expand in.
 /// </summary>
 /// <param name="floorPlan"></param>
 /// <param name="loc"></param>
 /// <returns></returns>
 private static IEnumerable <Dir4> GetRoomExpandDirs(GridPlan floorPlan, Loc loc)
 {
     foreach (Dir4 dir in DirExt.VALID_DIR4)
     {
         Loc endLoc = loc + dir.GetLoc();
         if (Collision.InBounds(floorPlan.GridWidth, floorPlan.GridHeight, endLoc) &&
             floorPlan.GetRoomPlan(endLoc) == null)
         {
             yield return(dir);
         }
     }
 }
예제 #8
0
        public virtual LocRay4 ChooseRoomExpansion(IRandom rand, GridPlan floorPlan, bool branch)
        {
            List <LocRay4> availableRays = GetPossibleExpansions(floorPlan, branch);

            if (availableRays.Count == 0)
            {
                return(new LocRay4(Dir4.None));
            }

            LocRay4 chosenRay = availableRays[rand.Next(availableRays.Count)];

            return(chosenRay);
        }
예제 #9
0
        protected bool ExpandPath(IRandom rand, GridPlan floorPlan, bool branch)
        {
            LocRay4 chosenRay = this.ChooseRoomExpansion(rand, floorPlan, branch);

            if (chosenRay.Dir == Dir4.None)
            {
                return(false);
            }
            floorPlan.SetHall(chosenRay, this.GenericHalls.Pick(rand));
            floorPlan.AddRoom(chosenRay.Traverse(1), this.GenericRooms.Pick(rand));

            GenContextDebug.DebugProgress(branch ? "Branched Path" : "Extended Path");
            return(true);
        }
예제 #10
0
        public static void SafeAddHall(LocRay4 locRay, GridPlan floorPlan, IPermissiveRoomGen hallGen, IRoomGen roomGen, bool preferHall = false)
        {
            floorPlan.SetHall(locRay, hallGen);
            if (floorPlan.GetRoomPlan(locRay.Loc) == null)
            {
                floorPlan.AddRoom(locRay.Loc, roomGen, false, preferHall);
            }
            Loc dest = locRay.Traverse(1);

            if (floorPlan.GetRoomPlan(dest) == null)
            {
                floorPlan.AddRoom(dest, roomGen, false, preferHall);
            }
        }
예제 #11
0
        public static void SafeAddHall(LocRay4 locRay, GridPlan floorPlan, IPermissiveRoomGen hallGen, IRoomGen roomGen, ComponentCollection roomComponents, ComponentCollection hallComponents, bool preferHall = false)
        {
            floorPlan.SetHall(locRay, hallGen, hallComponents.Clone());
            ComponentCollection collection = preferHall ? hallComponents : roomComponents;

            if (floorPlan.GetRoomPlan(locRay.Loc) == null)
            {
                floorPlan.AddRoom(locRay.Loc, roomGen, collection.Clone(), preferHall);
            }
            Loc dest = locRay.Traverse(1);

            if (floorPlan.GetRoomPlan(dest) == null)
            {
                floorPlan.AddRoom(dest, roomGen, collection.Clone(), preferHall);
            }
        }
예제 #12
0
        public static List <LocRay4> GetPossibleExpansions(GridPlan floorPlan, bool branch)
        {
            List <LocRay4> availableRays = new List <LocRay4>();

            for (int ii = 0; ii < floorPlan.RoomCount; ii++)
            {
                List <int> adjacents = floorPlan.GetAdjacentRooms(ii);
                if ((adjacents.Count <= 1) != branch)
                {
                    foreach (Dir4 dir in GetRoomExpandDirs(floorPlan, floorPlan.GetRoomPlan(ii).Bounds.Start))
                    {
                        availableRays.Add(new LocRay4(floorPlan.GetRoomPlan(ii).Bounds.Start, dir));
                    }
                }
            }

            return(availableRays);
        }
예제 #13
0
        public override void ApplyToPath(IRandom rand, GridPlan floorPlan)
        {
            IRoomGen newGen = this.Rooms.Pick(rand).Copy();
            Loc      size   = newGen.ProposeSize(rand);

            // choose certain rooms in the list to be special rooms
            // special rooms are required; so make sure they don't overlap
            List <int> room_indices = new List <int>();

            for (int ii = 0; ii < floorPlan.RoomCount; ii++)
            {
                GridRoomPlan plan = floorPlan.GetRoomPlan(ii);
                if (!BaseRoomFilter.PassesAllFilters(plan, this.Filters))
                {
                    continue;
                }
                if (plan.PreferHall)
                {
                    continue;
                }
                Loc boundsSize = GetBoundsSize(floorPlan, plan);
                if (boundsSize.X >= size.X && boundsSize.Y >= size.Y)
                {
                    room_indices.Add(ii);
                }
            }

            if (room_indices.Count > 0)
            {
                int          ind  = rand.Next(room_indices.Count);
                GridRoomPlan plan = floorPlan.GetRoomPlan(room_indices[ind]);
                plan.RoomGen = newGen;
                foreach (RoomComponent component in this.RoomComponents)
                {
                    plan.Components.Set(component.Clone());
                }
                room_indices.RemoveAt(ind);
                GenContextDebug.DebugProgress("Set Special Room");
            }
        }
예제 #14
0
        public override void ApplyToPath(IRandom rand, GridPlan floorPlan)
        {
            if (floorPlan.GridWidth != this.SpecificVHalls.Length ||
                floorPlan.GridWidth - 1 != this.SpecificHHalls.Length ||
                floorPlan.GridHeight - 1 != this.SpecificVHalls[0].Length ||
                floorPlan.GridHeight != this.SpecificHHalls[0].Length)
            {
                throw new InvalidOperationException("Incorrect hall path sizes.");
            }

            foreach (var chosenRoom in this.SpecificRooms)
            {
                floorPlan.AddRoom(chosenRoom.Bounds, chosenRoom.RoomGen, chosenRoom.Components.Clone(), chosenRoom.PreferHall);
                GenContextDebug.DebugProgress("Room");
            }

            // place halls
            for (int x = 0; x < this.SpecificVHalls.Length; x++)
            {
                for (int y = 0; y < this.SpecificHHalls[0].Length; y++)
                {
                    if (x > 0)
                    {
                        if (this.SpecificHHalls[x - 1][y] != null)
                        {
                            UnsafeAddHall(new LocRay4(new Loc(x, y), Dir4.Left), floorPlan, this.SpecificHHalls[x - 1][y], this.HallComponents);
                        }
                    }

                    if (y > 0)
                    {
                        if (this.SpecificVHalls[x][y - 1] != null)
                        {
                            UnsafeAddHall(new LocRay4(new Loc(x, y), Dir4.Up), floorPlan, this.SpecificVHalls[x][y - 1], this.HallComponents);
                        }
                    }
                }
            }
        }
예제 #15
0
        public override void ApplyToPath(IRandom rand, GridPlan floorPlan)
        {
            if (floorPlan.GridWidth < 3 || floorPlan.GridHeight < 3)
            {
                throw new InvalidOperationException("Not enough room to create path.");
            }

            int maxRooms = (2 * floorPlan.GridWidth) + (2 * floorPlan.GridHeight) - 4;
            int roomOpen = maxRooms * this.CircleRoomRatio.Pick(rand) / 100;
            int paths    = this.Paths.Pick(rand);

            if (roomOpen < 1 && paths < 1)
            {
                roomOpen = 1;
            }

            GenContextDebug.StepIn("Outer Circle");

            // draw the top and bottom
            for (int xx = 0; xx < floorPlan.GridWidth; xx++)
            {
                this.RollOpenRoom(rand, floorPlan, new Loc(xx, 0), ref roomOpen, ref maxRooms);
                GenContextDebug.DebugProgress("Room");
                this.RollOpenRoom(rand, floorPlan, new Loc(xx, floorPlan.GridHeight - 1), ref roomOpen, ref maxRooms);
                GenContextDebug.DebugProgress("Room");
                if (xx > 0)
                {
                    floorPlan.SetHall(new LocRay4(new Loc(xx, 0), Dir4.Left), this.GenericHalls.Pick(rand), this.HallComponents.Clone());
                    GenContextDebug.DebugProgress("Hall");
                    floorPlan.SetHall(new LocRay4(new Loc(xx, floorPlan.GridHeight - 1), Dir4.Left), this.GenericHalls.Pick(rand), this.HallComponents.Clone());
                    GenContextDebug.DebugProgress("Hall");
                }
            }

            // draw the left and right (excluding the top and bottom)
            for (int yy = 0; yy < floorPlan.GridHeight; yy++)
            {
                // exclude the top and bottom
                if (yy > 0 && yy < floorPlan.GridHeight - 1)
                {
                    this.RollOpenRoom(rand, floorPlan, new Loc(0, yy), ref roomOpen, ref maxRooms);
                    GenContextDebug.DebugProgress("Room");
                    this.RollOpenRoom(rand, floorPlan, new Loc(floorPlan.GridWidth - 1, yy), ref roomOpen, ref maxRooms);
                    GenContextDebug.DebugProgress("Room");
                }

                if (yy > 0)
                {
                    floorPlan.SetHall(new LocRay4(new Loc(0, yy), Dir4.Up), this.GenericHalls.Pick(rand), this.HallComponents.Clone());
                    GenContextDebug.DebugProgress("Hall");
                    floorPlan.SetHall(new LocRay4(new Loc(floorPlan.GridWidth - 1, yy), Dir4.Up), this.GenericHalls.Pick(rand), this.HallComponents.Clone());
                    GenContextDebug.DebugProgress("Hall");
                }
            }

            GenContextDebug.StepOut();

            GenContextDebug.StepIn("Inner Paths");

            Rect innerRect = new Rect(1, 1, floorPlan.GridWidth - 2, floorPlan.GridHeight - 2);

            // create inner paths
            for (int pathsMade = 0; pathsMade < paths; pathsMade++)
            {
                GenContextDebug.StepIn($"Path {pathsMade}");

                Dir4 startDir = DirExt.VALID_DIR4.ElementAt(rand.Next(DirExt.DIR4_COUNT));
                int  x        = rand.Next(innerRect.Start.X, innerRect.End.X);
                int  y        = rand.Next(innerRect.Start.Y, innerRect.End.Y);
                switch (startDir)
                {
                case Dir4.Down:
                    y = 0;
                    break;

                case Dir4.Left:
                    x = floorPlan.GridWidth - 1;
                    break;

                case Dir4.Up:
                    y = floorPlan.GridHeight - 1;
                    break;

                case Dir4.Right:
                    x = 0;
                    break;

                case Dir4.None:
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(startDir), "Invalid enum value.");
                }

                Loc  wanderer   = new Loc(x, y);
                Dir4 prevDir    = Dir4.None; // direction of movement
                int  pathLength = (startDir.ToAxis() == Axis4.Vert) ? innerRect.Height : innerRect.Width;
                for (int currentLength = 0; currentLength < pathLength; currentLength++)
                {
                    Dir4 chosenDir = startDir;

                    // avoid this block the first time
                    if (currentLength > 0)
                    {
                        List <Dir4> dirs = new List <Dir4>();
                        foreach (Dir4 dir in DirExt.VALID_DIR4)
                        {
                            // do not backtrack
                            if (dir == prevDir)
                            {
                                continue;
                            }

                            // do not hit edge
                            if (!Collision.InBounds(innerRect, wanderer + dir.GetLoc()))
                            {
                                continue;
                            }
                            dirs.Add(dir);
                        }

                        chosenDir = dirs[rand.Next(dirs.Count)];
                    }

                    Loc dest = wanderer + chosenDir.GetLoc();

                    GridRoomPlan existingRoom = floorPlan.GetRoomPlan(dest);
                    if (existingRoom == null)
                    {
                        if (currentLength == pathLength - 1) // only the end room can be a non-hall
                        {
                            floorPlan.AddRoom(dest, this.GenericRooms.Pick(rand), this.RoomComponents.Clone());
                        }
                        else
                        {
                            floorPlan.AddRoom(dest, this.GetDefaultGen(), this.HallComponents.Clone(), true);
                        }
                        GenContextDebug.DebugProgress("Room");
                    }
                    else if (existingRoom.PreferHall)
                    {
                        if (currentLength == pathLength - 1)
                        {
                            // override the hall room
                            existingRoom.RoomGen    = this.GenericRooms.Pick(rand).Copy();
                            existingRoom.PreferHall = false;
                        }
                    }

                    floorPlan.SetHall(new LocRay4(wanderer, chosenDir), this.GenericHalls.Pick(rand), this.HallComponents.Clone());
                    GenContextDebug.DebugProgress("Hall");

                    wanderer = dest;
                    prevDir  = chosenDir.Reverse();
                }

                GenContextDebug.StepOut();
            }

            GenContextDebug.StepOut();
        }
예제 #16
0
        public override void ApplyToPath(IRandom rand, GridPlan floorPlan)
        {
            if (floorPlan.GridWidth < 3 || floorPlan.GridHeight < 3)
            {
                throw new InvalidOperationException("Not enough room to create path.");
            }

            int roomMax  = (2 * (floorPlan.GridWidth - 2)) + (2 * (floorPlan.GridHeight - 2));
            int roomOpen = roomMax * this.RoomRatio / 100;

            if (roomOpen < 1)
            {
                roomOpen = 1;
            }

            GenContextDebug.StepIn("Inner Grid");

            // set hallrooms in middle of grid and open hallways between them
            for (int x = 1; x < floorPlan.GridWidth - 1; x++)
            {
                for (int y = 1; y < floorPlan.GridHeight - 1; y++)
                {
                    floorPlan.AddRoom(new Loc(x, y), this.GetDefaultGen(), false, true);

                    if (x > 1)
                    {
                        floorPlan.SetHall(new LocRay4(new Loc(x, y), Dir4.Left), this.GenericHalls.Pick(rand));
                    }
                    if (y > 1)
                    {
                        floorPlan.SetHall(new LocRay4(new Loc(x, y), Dir4.Up), this.GenericHalls.Pick(rand));
                    }

                    GenContextDebug.DebugProgress("Room");
                }
            }

            GenContextDebug.StepOut();

            GenContextDebug.StepIn("Outer Rooms");

            // open random rooms on all sides
            for (int x = 1; x < floorPlan.GridWidth - 1; x++)
            {
                if (RollRatio(rand, ref roomOpen, ref roomMax))
                {
                    floorPlan.AddRoom(new Loc(x, 0), this.GenericRooms.Pick(rand));
                    floorPlan.SetHall(new LocRay4(new Loc(x, 0), Dir4.Down), this.GenericHalls.Pick(rand));
                    GenContextDebug.DebugProgress("Room");
                }

                if (RollRatio(rand, ref roomOpen, ref roomMax))
                {
                    floorPlan.AddRoom(new Loc(x, floorPlan.GridHeight - 1), this.GenericRooms.Pick(rand));
                    floorPlan.SetHall(new LocRay4(new Loc(x, floorPlan.GridHeight - 1), Dir4.Up), this.GenericHalls.Pick(rand));
                    GenContextDebug.DebugProgress("Room");
                }
            }

            for (int y = 1; y < floorPlan.GridHeight - 1; y++)
            {
                if (RollRatio(rand, ref roomOpen, ref roomMax))
                {
                    floorPlan.AddRoom(new Loc(0, y), this.GenericRooms.Pick(rand));
                    floorPlan.SetHall(new LocRay4(new Loc(0, y), Dir4.Right), this.GenericHalls.Pick(rand));
                    GenContextDebug.DebugProgress("Room");
                }

                if (RollRatio(rand, ref roomOpen, ref roomMax))
                {
                    floorPlan.AddRoom(new Loc(floorPlan.GridWidth - 1, y), this.GenericRooms.Pick(rand));
                    floorPlan.SetHall(new LocRay4(new Loc(floorPlan.GridWidth - 1, y), Dir4.Left), this.GenericHalls.Pick(rand));
                    GenContextDebug.DebugProgress("Room");
                }
            }

            GenContextDebug.StepOut();

            GenContextDebug.StepIn("Extra Halls");

            // get all halls eligible to be opened
            List <Loc> hHallSites = new List <Loc>();
            List <Loc> vHallSites = new List <Loc>();

            for (int x = 1; x < floorPlan.GridWidth; x++)
            {
                if (floorPlan.GetRoomPlan(new Loc(x, 0)) != null || floorPlan.GetRoomPlan(new Loc(x - 1, 0)) != null)
                {
                    hHallSites.Add(new Loc(x, 0));
                }
                if (floorPlan.GetRoomPlan(new Loc(x, floorPlan.GridHeight - 1)) != null || floorPlan.GetRoomPlan(new Loc(x - 1, floorPlan.GridHeight - 1)) != null)
                {
                    hHallSites.Add(new Loc(x, floorPlan.GridHeight - 1));
                }
            }

            for (int y = 1; y < floorPlan.GridHeight; y++)
            {
                if (floorPlan.GetRoomPlan(new Loc(0, y)) != null || floorPlan.GetRoomPlan(new Loc(0, y - 1)) != null)
                {
                    vHallSites.Add(new Loc(0, y));
                }
                if (floorPlan.GetRoomPlan(new Loc(floorPlan.GridWidth - 1, y)) != null || floorPlan.GetRoomPlan(new Loc(floorPlan.GridWidth - 1, y - 1)) != null)
                {
                    vHallSites.Add(new Loc(floorPlan.GridWidth - 1, y));
                }
            }

            int halls       = hHallSites.Count + vHallSites.Count;
            int placedHalls = halls * this.HallRatio / 100;

            // place the halls
            for (int ii = 0; ii < hHallSites.Count; ii++)
            {
                if (rand.Next() % halls < placedHalls)
                {
                    SafeAddHall(new LocRay4(hHallSites[ii], Dir4.Left), floorPlan, this.GenericHalls.Pick(rand), this.GenericRooms.Pick(rand));
                    GenContextDebug.DebugProgress("Hall");
                    placedHalls--;
                }

                halls--;
            }

            for (int ii = 0; ii < vHallSites.Count; ii++)
            {
                if (rand.Next() % halls < placedHalls)
                {
                    SafeAddHall(new LocRay4(vHallSites[ii], Dir4.Up), floorPlan, this.GenericHalls.Pick(rand), this.GenericRooms.Pick(rand));
                    GenContextDebug.DebugProgress("Hall");
                    placedHalls--;
                }

                halls--;
            }

            GenContextDebug.StepOut();
        }
예제 #17
0
 public abstract void ApplyToPath(IRandom rand, GridPlan floorPlan);
예제 #18
0
        public override void ApplyToPath(IRandom rand, GridPlan floorPlan)
        {
            for (int ii = 0; ii < 10; ii++)
            {
                // always clear before trying
                floorPlan.Clear();

                int roomsToOpen = floorPlan.GridWidth * floorPlan.GridHeight * this.RoomRatio.Pick(rand) / 100;
                if (roomsToOpen < 1)
                {
                    roomsToOpen = 1;
                }
                int addBranch = this.BranchRatio.Pick(rand);
                int roomsLeft = roomsToOpen;

                Loc sourceRoom = new Loc(rand.Next(floorPlan.GridWidth), rand.Next(floorPlan.GridHeight)); // randomly determine start room
                floorPlan.AddRoom(sourceRoom, this.GenericRooms.Pick(rand));

                GenContextDebug.DebugProgress("Start Room");

                roomsLeft--;
                int pendingBranch = 0;
                while (roomsLeft > 0)
                {
                    bool terminalSuccess = this.ExpandPath(rand, floorPlan, false);
                    bool branchSuccess   = false;
                    if (terminalSuccess)
                    {
                        roomsLeft--;
                        if (floorPlan.RoomCount > 2)
                        {
                            pendingBranch += addBranch;
                        }
                    }
                    else if (this.NoForcedBranches)
                    {
                        break;
                    }
                    else
                    {
                        pendingBranch = 100;
                    }

                    while (pendingBranch >= 100 && roomsLeft > 0)
                    {
                        branchSuccess = this.ExpandPath(rand, floorPlan, true);
                        if (!branchSuccess)
                        {
                            break;
                        }
                        pendingBranch -= 100;
                        roomsLeft--;
                    }

                    if (!terminalSuccess && !branchSuccess)
                    {
                        break;
                    }
                }

                if (roomsLeft <= 0)
                {
                    break;
                }
            }
        }
예제 #19
0
        public override void ApplyToPath(IRandom rand, GridPlan floorPlan)
        {
            List <LocRay4> endBranches = new List <LocRay4>();

            for (int ii = 0; ii < floorPlan.RoomCount; ii++)
            {
                GridRoomPlan roomPlan = floorPlan.GetRoomPlan(ii);

                if (!BaseRoomFilter.PassesAllFilters(roomPlan, this.Filters))
                {
                    continue;
                }

                if (roomPlan.Bounds.Size == new Loc(1))
                {
                    List <int> adjacents = floorPlan.GetAdjacentRooms(ii);
                    if (adjacents.Count == 1)
                    {
                        endBranches.Add(new LocRay4(roomPlan.Bounds.Start));
                    }
                }
            }

            List <List <LocRay4> > candBranchPoints = new List <List <LocRay4> >();

            for (int nn = 0; nn < endBranches.Count; nn++)
            {
                LocRay4 chosenBranch = endBranches[nn];

                while (chosenBranch.Loc != new Loc(-1))
                {
                    List <LocRay4> connectors = new List <LocRay4>();
                    List <LocRay4> candBonds  = new List <LocRay4>();
                    foreach (Dir4 dir in DirExt.VALID_DIR4)
                    {
                        if (dir != chosenBranch.Dir)
                        {
                            if (floorPlan.GetHall(new LocRay4(chosenBranch.Loc, dir)) != null)
                            {
                                connectors.Add(new LocRay4(chosenBranch.Loc, dir));
                            }
                            else
                            {
                                Loc loc = chosenBranch.Loc + dir.GetLoc();
                                if (Collision.InBounds(floorPlan.GridWidth, floorPlan.GridHeight, loc) &&
                                    floorPlan.GetRoomIndex(loc) > -1)
                                {
                                    candBonds.Add(new LocRay4(chosenBranch.Loc, dir));
                                }
                            }
                        }
                    }

                    if (connectors.Count == 1)
                    {
                        if (candBonds.Count > 0)
                        {
                            candBranchPoints.Add(candBonds);
                            chosenBranch = new LocRay4(new Loc(-1));
                        }
                        else
                        {
                            chosenBranch = new LocRay4(connectors[0].Traverse(1), connectors[0].Dir.Reverse());
                        }
                    }
                    else
                    {
                        chosenBranch = new LocRay4(new Loc(-1));
                    }
                }
            }

            // compute a goal amount of terminals to connect
            // this computation ignores the fact that some terminals may be impossible
            var randBin         = new RandBinomial(candBranchPoints.Count, this.ConnectPercent);
            int connectionsLeft = randBin.Pick(rand);

            while (candBranchPoints.Count > 0 && connectionsLeft > 0)
            {
                // choose random point to connect
                int            randIndex = rand.Next(candBranchPoints.Count);
                List <LocRay4> candBonds = candBranchPoints[randIndex];
                LocRay4        chosenDir = candBonds[rand.Next(candBonds.Count)];

                // connect
                floorPlan.SetHall(chosenDir, this.GenericHalls.Pick(rand), this.HallComponents);
                candBranchPoints.RemoveAt(randIndex);
                GenContextDebug.DebugProgress("Connected Branch");
                connectionsLeft--;

                // check to see if connection destination was also a candidate,
                // counting this as a double if so
                for (int ii = candBranchPoints.Count - 1; ii >= 0; ii--)
                {
                    if (candBranchPoints[ii][0].Loc == chosenDir.Traverse(1))
                    {
                        candBranchPoints.RemoveAt(ii);
                        connectionsLeft--;
                    }
                }
            }
        }
예제 #20
0
        public override void ApplyToPath(IRandom rand, GridPlan floorPlan)
        {
            // open rooms on both sides
            Loc gridSize = new Loc(floorPlan.GridWidth, floorPlan.GridHeight);
            int scalar   = gridSize.GetScalar(this.GapAxis);
            int orth     = gridSize.GetScalar(this.GapAxis.Orth());

            if (scalar < 2 || orth < 1)
            {
                throw new InvalidOperationException("Not enough room to create path.");
            }

            GenContextDebug.StepIn("Initial Rooms");

            for (int ii = 0; ii < orth; ii++)
            {
                // place the rooms at the edge
                floorPlan.AddRoom(this.GapAxis.CreateLoc(0, ii), this.GenericRooms.Pick(rand), this.RoomComponents.Clone());
                GenContextDebug.DebugProgress("Room");
                floorPlan.AddRoom(this.GapAxis.CreateLoc(scalar - 1, ii), this.GenericRooms.Pick(rand), this.RoomComponents.Clone());
                GenContextDebug.DebugProgress("Room");

                if (scalar > 2)
                {
                    // place hall rooms
                    Loc loc  = this.GapAxis.CreateLoc(1, ii);
                    Loc size = this.GapAxis.CreateLoc(scalar - 2, 1);
                    floorPlan.AddRoom(new Rect(loc, size), this.GetDefaultGen(), this.HallComponents.Clone(), true);
                    GenContextDebug.DebugProgress("Mid Room");
                }
            }

            GenContextDebug.StepOut();

            GenContextDebug.StepIn("Connecting Sides");

            // halls connecting two tiers of the same side
            bool[][] connections = new bool[orth - 1][];
            for (int ii = 0; ii < orth - 1; ii++)
            {
                connections[ii] = new bool[2];
            }

            // add crosses
            for (int ii = 0; ii < orth - 1; ii++)
            {
                if (rand.Next(2) == 0)
                {
                    connections[ii][0] = true;
                }
                else
                {
                    connections[ii][1] = true;
                }
            }

            // paint hallways
            for (int ii = 0; ii < orth; ii++)
            {
                // place the halls at the sides
                if (ii < orth - 1)
                {
                    if (connections[ii][0])
                    {
                        this.PlaceOrientedHall(this.GapAxis.Orth(), 0, ii, 1, floorPlan, this.GenericHalls.Pick(rand));
                        GenContextDebug.DebugProgress("Side Connection");
                    }

                    if (connections[ii][1])
                    {
                        this.PlaceOrientedHall(this.GapAxis.Orth(), scalar - 1, ii, 1, floorPlan, this.GenericHalls.Pick(rand));
                        GenContextDebug.DebugProgress("Side Connection");
                    }
                }

                // place halls to bridge the gap
                this.PlaceOrientedHall(this.GapAxis, 0, ii, 1, floorPlan, this.GenericHalls.Pick(rand));
                if (scalar > 2)
                {
                    this.PlaceOrientedHall(this.GapAxis, scalar - 1, ii, -1, floorPlan, this.GenericHalls.Pick(rand));
                }
                GenContextDebug.DebugProgress("Bridge");
            }

            GenContextDebug.StepOut();
        }
예제 #21
0
 public virtual void CreateErrorPath(IRandom rand, GridPlan floorPlan)
 {
     floorPlan.Clear();
     floorPlan.AddRoom(new Loc(0, 0), this.GetDefaultGen());
 }
예제 #22
0
        public void PlaceOrientedHall(Axis4 axis, int scalar, int orth, int scalarDiff, GridPlan floorPlan, PermissiveRoomGen <T> hallGen)
        {
            Loc loc = this.GapAxis.CreateLoc(scalar, orth);

            floorPlan.SetHall(new LocRay4(loc, axis.GetDir(scalarDiff)), hallGen, this.HallComponents.Clone());
        }