Пример #1
0
        public void GetHallTouchRangeLargeRoom(Dir4 dir, int tier, int rangeMin, int rangeMax)
        {
            // a room that takes up multiple cells
            string[] inGrid =
            {
                "A.A.0.0",
                ". . . .",
                "A.A.0.0",
                ". . . .",
                "A.A.0.0",
                ". . . .",
                "0.0.0.0",
            };

            TestGridFloorPlan floorPlan = TestGridFloorPlan.InitGridToContext(inGrid, 6, 4);
            Mock <IRandom>    testRand  = new Mock <IRandom>(MockBehavior.Strict);
            IRoomGen          testGen   = floorPlan.PublicArrayRooms[0].RoomGen;

            testGen.PrepareSize(testRand.Object, new Loc(5, 10));
            testGen.SetLoc(new Loc(1, 2));
            IntRange bounds        = floorPlan.GetHallTouchRange(testGen, dir, tier);
            IntRange compareBounds = new IntRange(rangeMin, rangeMax);

            Assert.That(bounds, Is.EqualTo(compareBounds));
        }
Пример #2
0
        public override void ApplyToPath(IRandom rand, FloorPlan floorPlan)
        {
            // choose certain rooms in the list to be special rooms
            // special rooms are required; so make sure they don't overlap
            IRoomGen newGen = this.Rooms.Pick(rand).Copy();
            Loc      size   = newGen.ProposeSize(rand);

            newGen.PrepareSize(rand, size);
            int factor = floorPlan.DrawRect.Area / newGen.Draw.Area;

            // TODO: accept smaller rooms to replace
            // bulldozing the surrounding rooms to get the space
            var room_indices = new SpawnList <RoomHallIndex>();

            for (int ii = 0; ii < floorPlan.RoomCount; ii++)
            {
                FloorRoomPlan plan = floorPlan.GetRoomPlan(ii);
                if (!plan.Immutable &&
                    plan.RoomGen.Draw.Width >= newGen.Draw.Width &&
                    plan.RoomGen.Draw.Height >= newGen.Draw.Height)
                {
                    room_indices.Add(new RoomHallIndex(ii, false), ComputeRoomChance(factor, plan.RoomGen.Draw, newGen.Draw));
                }
            }

            for (int ii = 0; ii < floorPlan.HallCount; ii++)
            {
                var            roomHall = new RoomHallIndex(ii, true);
                IFloorRoomPlan plan     = floorPlan.GetRoomHall(roomHall);
                if (plan.RoomGen.Draw.Width >= newGen.Draw.Width &&
                    plan.RoomGen.Draw.Height >= newGen.Draw.Height)
                {
                    room_indices.Add(roomHall, ComputeRoomChance(factor, plan.RoomGen.Draw, newGen.Draw));
                }
            }

            while (room_indices.Count > 0)
            {
                int           ind         = room_indices.PickIndex(rand);
                RoomHallIndex oldRoomHall = room_indices.GetSpawn(ind);
                Dictionary <Dir4, List <RoomHallIndex> > adjacentIndicesByDir = GetDirectionAdjacents(floorPlan, oldRoomHall);
                var adjacentsByDir = new Dictionary <Dir4, List <IRoomGen> >();
                foreach (Dir4 dir in DirExt.VALID_DIR4)
                {
                    adjacentsByDir[dir] = new List <IRoomGen>();
                    foreach (RoomHallIndex adj in adjacentIndicesByDir[dir])
                    {
                        adjacentsByDir[dir].Add(floorPlan.GetRoomHall(adj).RoomGen);
                    }
                }

                Loc placement = this.FindPlacement(rand, adjacentsByDir, newGen, floorPlan.GetRoomHall(oldRoomHall).RoomGen);
                if (placement != new Loc(-1))
                {
                    newGen.SetLoc(placement);
                    this.PlaceRoom(rand, floorPlan, newGen, oldRoomHall);
                    GenContextDebug.DebugProgress("Set Special Room");
                    return;
                }

                room_indices.RemoveAt(ind);
            }
        }
Пример #3
0
        public override void ApplyToPath(IRandom rand, FloorPlan floorPlan)
        {
            for (int ii = 0; ii < 10; ii++)
            {
                // always clear before trying
                floorPlan.Clear();

                int tilesToOpen = floorPlan.DrawRect.Area * this.FillPercent.Pick(rand) / 100;
                if (tilesToOpen < 1)
                {
                    tilesToOpen = 1;
                }
                int addBranch = this.BranchRatio.Pick(rand);
                int tilesLeft = tilesToOpen;

                // choose a room
                IRoomGen room = this.PrepareRoom(rand, floorPlan, false);

                // place in a random location
                room.SetLoc(new Loc(
                                rand.Next(floorPlan.DrawRect.Left, floorPlan.DrawRect.Right - room.Draw.Width + 1),
                                rand.Next(floorPlan.DrawRect.Top, floorPlan.DrawRect.Bottom - room.Draw.Height + 1)));
                floorPlan.AddRoom(room, this.RoomComponents.Clone());
                GenContextDebug.DebugProgress("Start Room");

                tilesLeft -= room.Draw.Area;

                // repeat this process until the requisite room amount is met
                int pendingBranch = 0;
                while (tilesLeft > 0)
                {
                    (int area, int rooms)terminalResult = this.ExpandPath(rand, floorPlan, false);
                    (int area, int rooms)branchResult   = (0, 0);
                    if (terminalResult.area > 0)
                    {
                        tilesLeft -= terminalResult.area;

                        // add branch PER ROOM when we add over the min threshold
                        for (int jj = 0; jj < terminalResult.rooms; jj++)
                        {
                            if (floorPlan.RoomCount + floorPlan.HallCount - terminalResult.rooms + jj + 1 > 2)
                            {
                                pendingBranch += addBranch;
                            }
                        }
                    }
                    else if (this.NoForcedBranches)
                    {
                        break;
                    }
                    else
                    {
                        pendingBranch = 100;
                    }

                    while (pendingBranch >= 100 && tilesLeft > 0)
                    {
                        branchResult = this.ExpandPath(rand, floorPlan, true);
                        if (branchResult.area == 0)
                        {
                            break;
                        }
                        pendingBranch -= 100;

                        // if we add any more than one room, that also counts as a branchable node
                        pendingBranch += (branchResult.rooms - 1) * addBranch;
                        tilesLeft     -= branchResult.area;
                    }

                    if (terminalResult.area == 0 && branchResult.area == 0)
                    {
                        break;
                    }
                }

                if (tilesLeft <= 0)
                {
                    break;
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Chooses a node to expand the path from based on the specified branch setting.
        /// </summary>
        /// <param name="availableExpansions">todo: describe availableExpansions parameter on ChooseRoomExpansion</param>
        /// <param name="prepareRoom">todo: describe prepareRoom parameter on ChooseRoomExpansion</param>
        /// <param name="hallPercent">todo: describe hallPercent parameter on ChooseRoomExpansion</param>
        /// <param name="rand"></param>
        /// <param name="floorPlan"></param>
        /// <returns>A set of instructions on how to expand the path.</returns>
        public static ListPathBranchExpansion?ChooseRoomExpansion(RoomPrep prepareRoom, int hallPercent, IRandom rand, FloorPlan floorPlan, List <RoomHallIndex> availableExpansions)
        {
            if (availableExpansions.Count == 0)
            {
                return(null);
            }

            for (int ii = 0; ii < 30; ii++)
            {
                // choose the next room to add to
                RoomHallIndex firstExpandFrom = availableExpansions[rand.Next(availableExpansions.Count)];
                RoomHallIndex expandFrom      = firstExpandFrom;
                IRoomGen      roomFrom        = floorPlan.GetRoomHall(firstExpandFrom).RoomGen;

                // choose the next room to add
                // choose room size/fulfillables
                // note: by allowing halls to be picked as extensions, we run the risk of adding dead-end halls
                // halls should always terminate at rooms?
                // this means... doubling up with hall+room?
                bool     addHall = rand.Next(100) < hallPercent;
                IRoomGen hall    = null;
                if (addHall)
                {
                    hall = prepareRoom(rand, floorPlan, true);

                    // randomly choose a perimeter to assign this to
                    SpawnList <Loc> possibleHallPlacements = new SpawnList <Loc>();
                    foreach (Dir4 dir in DirExt.VALID_DIR4)
                    {
                        AddLegalPlacements(possibleHallPlacements, floorPlan, expandFrom, roomFrom, hall, dir);
                    }

                    // at this point, all possible factors for whether a placement is legal or not is accounted for
                    // therefor just pick one
                    if (possibleHallPlacements.Count == 0)
                    {
                        continue;
                    }

                    // randomly choose one
                    Loc hallCandLoc = possibleHallPlacements.Pick(rand);

                    // set location
                    hall.SetLoc(hallCandLoc);

                    // change the roomfrom for the upcoming room
                    expandFrom = new RoomHallIndex(-1, false);
                    roomFrom   = hall;
                }

                IRoomGen room = prepareRoom(rand, floorPlan, false);

                // randomly choose a perimeter to assign this to
                SpawnList <Loc> possiblePlacements = new SpawnList <Loc>();
                foreach (Dir4 dir in DirExt.VALID_DIR4)
                {
                    AddLegalPlacements(possiblePlacements, floorPlan, expandFrom, roomFrom, room, dir);
                }

                // at this point, all possible factors for whether a placement is legal or not is accounted for
                // therefore just pick one
                if (possiblePlacements.Count > 0)
                {
                    // randomly choose one
                    Loc candLoc = possiblePlacements.Pick(rand);

                    // set location
                    room.SetLoc(candLoc);
                    return(new ListPathBranchExpansion(firstExpandFrom, room, (IPermissiveRoomGen)hall));
                }
            }

            return(null);
        }