コード例 #1
0
        public void AddHall(IPermissiveRoomGen gen, ComponentCollection components, params RoomHallIndex[] attached)
        {
            // we expect that the hall has already been given a size...
            // check against colliding on other rooms (and not halls)
            foreach (var room in this.Rooms)
            {
                if (Collision.Collides(room.RoomGen.Draw, gen.Draw))
                {
                    throw new InvalidOperationException("Tried to add on top of an existing room!");
                }
            }

            // check against rooms that go out of bounds
            if (!this.DrawRect.Contains(gen.Draw))
            {
                throw new InvalidOperationException("Tried to add out of range!");
            }
            var plan = new FloorHallPlan(gen, components);

            // attach everything
            plan.Adjacents.AddRange(attached);
            foreach (RoomHallIndex fromRoom in attached)
            {
                IFloorRoomPlan fromPlan = this.GetRoomHall(fromRoom);
                fromPlan.Adjacents.Add(new RoomHallIndex(this.Halls.Count, true));
            }

            this.Halls.Add(plan);
        }
コード例 #2
0
        private static void InitFloorToContext(TestFloorPlan floorPlan, Rect rect, Rect[] rooms, Rect[] halls, Tuple <char, char>[] links)
        {
            floorPlan.InitRect(rect);

            // a quick way to set up rooms, halls, and connections
            // a list of rects for rooms, a list of rects for halls
            for (int ii = 0; ii < rooms.Length; ii++)
            {
                var gen = new TestFloorPlanGen((char)('A' + ii));
                gen.PrepareDraw(rooms[ii]);
                floorPlan.PublicRooms.Add(new FloorRoomPlan(gen, new ComponentCollection()));
            }

            for (int ii = 0; ii < halls.Length; ii++)
            {
                var gen = new TestFloorPlanGen((char)('a' + ii));
                gen.PrepareDraw(halls[ii]);
                floorPlan.PublicHalls.Add(new FloorHallPlan(gen, new ComponentCollection()));
            }

            // and finally a list of tuples that link rooms to rooms and halls to halls
            for (int ii = 0; ii < links.Length; ii++)
            {
                bool           hall1  = links[ii].Item1 >= 'a';
                int            index1 = hall1 ? links[ii].Item1 - 'a' : links[ii].Item1 - 'A';
                bool           hall2  = links[ii].Item2 >= 'a';
                int            index2 = hall2 ? links[ii].Item2 - 'a' : links[ii].Item2 - 'A';
                var            link1  = new RoomHallIndex(index1, hall1);
                var            link2  = new RoomHallIndex(index2, hall2);
                IFloorRoomPlan from1  = floorPlan.GetRoomHall(link1);
                IFloorRoomPlan from2  = floorPlan.GetRoomHall(link2);
                from1.Adjacents.Add(link2);
                from2.Adjacents.Add(link1);
            }
        }
コード例 #3
0
        public override void Apply(T map)
        {
            //Iterate every room/hall and coat the ones filtered
            List <RoomHallIndex>       spawningRooms = new List <RoomHallIndex>();
            Dictionary <Loc, SealType> sealList      = new Dictionary <Loc, SealType>();

            for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++)
            {
                if (!BaseRoomFilter.PassesAllFilters(map.RoomPlan.GetRoomPlan(ii), this.Filters))
                {
                    continue;
                }
                spawningRooms.Add(new RoomHallIndex(ii, false));
            }

            for (int ii = 0; ii < map.RoomPlan.HallCount; ii++)
            {
                if (!BaseRoomFilter.PassesAllFilters(map.RoomPlan.GetHallPlan(ii), this.Filters))
                {
                    continue;
                }
                spawningRooms.Add(new RoomHallIndex(ii, true));
            }

            if (spawningRooms.Count == 0)
            {
                return;
            }

            for (int ii = 0; ii < spawningRooms.Count; ii++)
            {
                IFloorRoomPlan plan = map.RoomPlan.GetRoomHall(spawningRooms[ii]);

                //seal the sides and note edge cases
                for (int xx = plan.RoomGen.Draw.X + 1; xx < plan.RoomGen.Draw.End.X - 1; xx++)
                {
                    sealBorderRay(map, sealList, plan, new LocRay8(xx, plan.RoomGen.Draw.Y, Dir8.Up), Dir8.Left, Dir8.Right);
                    sealBorderRay(map, sealList, plan, new LocRay8(xx, plan.RoomGen.Draw.End.Y - 1, Dir8.Down), Dir8.Left, Dir8.Right);
                }

                for (int yy = plan.RoomGen.Draw.Y + 1; yy < plan.RoomGen.Draw.End.Y - 1; yy++)
                {
                    sealBorderRay(map, sealList, plan, new LocRay8(plan.RoomGen.Draw.X, yy, Dir8.Left), Dir8.Up, Dir8.Down);
                    sealBorderRay(map, sealList, plan, new LocRay8(plan.RoomGen.Draw.End.X - 1, yy, Dir8.Right), Dir8.Up, Dir8.Down);
                }

                //seal edge cases
                sealCornerRay(map, sealList, plan, new LocRay8(plan.RoomGen.Draw.X, plan.RoomGen.Draw.Y, Dir8.UpLeft));
                sealCornerRay(map, sealList, plan, new LocRay8(plan.RoomGen.Draw.End.X - 1, plan.RoomGen.Draw.Y, Dir8.UpRight));
                sealCornerRay(map, sealList, plan, new LocRay8(plan.RoomGen.Draw.X, plan.RoomGen.Draw.End.Y - 1, Dir8.DownLeft));
                sealCornerRay(map, sealList, plan, new LocRay8(plan.RoomGen.Draw.End.X - 1, plan.RoomGen.Draw.End.Y - 1, Dir8.DownRight));
            }

            PlaceBorders(map, sealList);
        }
コード例 #4
0
        public override void DistributeSpawns(TGenContext map, List <TSpawnable> spawns)
        {
            // gather up all rooms and put in a spawn list
            // rooms that are farther from the start are more likely to have items
            var spawningRooms = new SpawnList <RoomHallIndex>();
            Dictionary <RoomHallIndex, int> roomWeights = new Dictionary <RoomHallIndex, int>();

            // get the start room
            int startRoom = 0;

            for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++)
            {
                FloorRoomPlan room = map.RoomPlan.GetRoomPlan(ii);
                if (Collision.InBounds(room.RoomGen.Draw, map.GetLoc(0)))
                {
                    startRoom = ii;
                    break;
                }
            }

            int maxVal = 1;

            void NodeAct(RoomHallIndex nodeIndex, int distance)
            {
                roomWeights[nodeIndex] = distance + 1;
                maxVal = Math.Max(maxVal, roomWeights[nodeIndex]);
            }

            Graph.TraverseBreadthFirst(new RoomHallIndex(startRoom, false), NodeAct, map.RoomPlan.GetAdjacents);

            int multFactor = int.MaxValue / maxVal / roomWeights.Count;

            foreach (RoomHallIndex idx in roomWeights.Keys)
            {
                IFloorRoomPlan room = map.RoomPlan.GetRoomHall(idx);
                if (idx.IsHall && !this.IncludeHalls)
                {
                    continue;
                }
                if (!BaseRoomFilter.PassesAllFilters(room, this.Filters))
                {
                    continue;
                }
                if (roomWeights[idx] == 0)
                {
                    continue;
                }
                spawningRooms.Add(idx, roomWeights[idx] * multFactor);
            }

            this.SpawnRandInCandRooms(map, spawningRooms, spawns, this.SuccessPercent);
        }
コード例 #5
0
        protected static SpawnList <ListPathTraversalNode> GetPossibleExpansions(FloorPlan floorPlan, List <RoomHallIndex> candList)
        {
            // get all probabilities.
            // the probability of an extension is the distance that the target room is from the start room, in rooms
            var expansions = new SpawnList <ListPathTraversalNode>();

            for (int nn = 0; nn < candList.Count; nn++)
            {
                // find the room to connect to
                // go through all sides of all rooms (randomly)
                RoomHallIndex  chosenFrom = candList[nn];
                IFloorRoomPlan planFrom   = floorPlan.GetRoomHall(chosenFrom);

                // exhausting all possible directions (randomly)
                foreach (Dir4 dir in DirExt.VALID_DIR4)
                {
                    bool forbidExtend = false;
                    foreach (RoomHallIndex adjacent in planFrom.Adjacents)
                    {
                        Rect adjRect = floorPlan.GetRoomHall(adjacent).RoomGen.Draw;
                        if (planFrom.RoomGen.Draw.GetScalar(dir) == adjRect.GetScalar(dir.Reverse()))
                        {
                            forbidExtend = true;
                            break;
                        }
                    }

                    if (!forbidExtend)
                    {
                        // find a rectangle to connect it with
                        ListPathTraversalNode?expandToResult = GetRoomToConnect(floorPlan, chosenFrom, dir);

                        if (expandToResult is ListPathTraversalNode expandTo)
                        {
                            int prb = floorPlan.GetDistance(expandTo.From, expandTo.To);
                            if (prb < 0)
                            {
                                expansions.Add(expandTo, 1);
                            }
                            else if (prb > 0)
                            {
                                expansions.Add(expandTo, prb);
                            }
                        }
                    }
                }
            }

            return(expansions);
        }
コード例 #6
0
        public void TransferBorderToAdjacents(RoomHallIndex from)
        {
            IFloorRoomPlan       basePlan  = this.GetRoomHall(from);
            IRoomGen             roomGen   = basePlan.RoomGen;
            List <RoomHallIndex> adjacents = basePlan.Adjacents;

            foreach (RoomHallIndex adjacent in adjacents)
            {
                // first determine if this adjacent should be receiving info
                if ((!from.IsHall && adjacent.IsHall) ||
                    (from.IsHall == adjacent.IsHall && from.Index < adjacent.Index))
                {
                    IRoomGen adjacentGen = this.GetRoomHall(adjacent).RoomGen;
                    adjacentGen.ReceiveOpenedBorder(roomGen, GetDirAdjacent(adjacentGen, roomGen));
                }
            }
        }
コード例 #7
0
        public void DrawOnMap(ITiledGenContext map)
        {
            GenContextDebug.StepIn("Main Rooms");
            for (int ii = 0; ii < this.Rooms.Count; ii++)
            {
                // take in the broad fulfillables from adjacent rooms that have not yet drawn
                IFloorRoomPlan plan = this.Rooms[ii];
                foreach (RoomHallIndex adj in plan.Adjacents)
                {
                    if (adj.IsHall || adj.Index > ii)
                    {
                        IRoomGen adjacentGen = this.GetRoomHall(adj).RoomGen;
                        plan.RoomGen.ReceiveFulfillableBorder(adjacentGen, GetDirAdjacent(plan.RoomGen, adjacentGen));
                    }
                }

                plan.RoomGen.DrawOnMap(map);
                this.TransferBorderToAdjacents(new RoomHallIndex(ii, false));
                GenContextDebug.DebugProgress("Draw Room");
            }

            GenContextDebug.StepOut();

            GenContextDebug.StepIn("Connecting Halls");
            for (int ii = 0; ii < this.Halls.Count; ii++)
            {
                // take in the broad fulfillables from adjacent rooms that have not yet drawn
                IFloorRoomPlan plan = this.Halls[ii];
                foreach (RoomHallIndex adj in plan.Adjacents)
                {
                    if (adj.IsHall && adj.Index > ii)
                    {
                        IRoomGen adjacentGen = this.GetRoomHall(adj).RoomGen;
                        plan.RoomGen.ReceiveFulfillableBorder(adjacentGen, GetDirAdjacent(plan.RoomGen, adjacentGen));
                    }
                }

                plan.RoomGen.DrawOnMap(map);
                this.TransferBorderToAdjacents(new RoomHallIndex(ii, true));
                GenContextDebug.DebugProgress("Draw Hall");
            }

            GenContextDebug.StepOut();
        }
コード例 #8
0
        private static Dictionary <Dir4, List <RoomHallIndex> > GetDirectionAdjacents(FloorPlan floorPlan, RoomHallIndex oldRoomHall)
        {
            var            adjacentsByDir = new Dictionary <Dir4, List <RoomHallIndex> >();
            IFloorRoomPlan oldPlan        = floorPlan.GetRoomHall(oldRoomHall);

            foreach (Dir4 dir in DirExt.VALID_DIR4)
            {
                adjacentsByDir[dir] = new List <RoomHallIndex>();
                foreach (RoomHallIndex adjacent in oldPlan.Adjacents)
                {
                    IFloorRoomPlan adjPlan = floorPlan.GetRoomHall(adjacent);
                    if (oldPlan.RoomGen.Draw.GetScalar(dir) ==
                        adjPlan.RoomGen.Draw.GetScalar(dir.Reverse()))
                    {
                        adjacentsByDir[dir].Add(adjacent);
                    }
                }
            }

            return(adjacentsByDir);
        }
コード例 #9
0
        public void AddRoom(IRoomGen gen, ComponentCollection components, params RoomHallIndex[] attached)
        {
            // check against colliding on other rooms (and not halls)
            foreach (var room in this.Rooms)
            {
                if (Collision.Collides(room.RoomGen.Draw, gen.Draw))
                {
                    throw new InvalidOperationException("Tried to add on top of an existing room!");
                }
            }

            foreach (var hall in this.Halls)
            {
                if (Collision.Collides(hall.RoomGen.Draw, gen.Draw))
                {
                    throw new InvalidOperationException("Tried to add on top of an existing hall!");
                }
            }

            // check against rooms that go out of bounds
            if (!this.DrawRect.Contains(gen.Draw))
            {
                throw new InvalidOperationException("Tried to add out of range!");
            }

            // we expect that the room has already been given a size
            // and that its fulfillables match up with its adjacent's fulfillables.
            var plan = new FloorRoomPlan(gen, components);

            // attach everything
            plan.Adjacents.AddRange(attached);
            foreach (RoomHallIndex fromRoom in attached)
            {
                IFloorRoomPlan fromPlan = this.GetRoomHall(fromRoom);
                fromPlan.Adjacents.Add(new RoomHallIndex(this.Rooms.Count, false));
            }

            this.Rooms.Add(plan);
        }
コード例 #10
0
        private void sealCornerRay(T map, Dictionary <Loc, SealType> sealList, IFloorRoomPlan plan, LocRay8 locRay)
        {
            DirH dirH;
            DirV dirV;

            locRay.Dir.Separate(out dirH, out dirV);

            bool outwardsH = sealBorderRay(map, sealList, plan, new LocRay8(locRay.Loc, dirH.ToDir8()), dirV.ToDir8().Reverse(), Dir8.None);
            bool outwardsV = sealBorderRay(map, sealList, plan, new LocRay8(locRay.Loc, dirV.ToDir8()), dirH.ToDir8().Reverse(), Dir8.None);


            //when two directions of a corner tile face inward, or outward, or a combination of inward and outward
            //-both inward: needs to not be redundant across the two sides - handled by hashset, no action needed
            //-one inward and one outward: can coexist - no action needed
            //-both outward: needs to check the outward diagonal to see if it forces inward
            // -if it doesnt force inward, do an outward operation
            // -if it does, do an inward operation

            if (outwardsH && outwardsV)
            {
                sealBorderRay(map, sealList, plan, locRay, Dir8.None, Dir8.None);
            }
        }
コード例 #11
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);
            }
        }
コード例 #12
0
        /// <summary>
        /// chooses and caegorizes the tile to be sealed
        /// </summary>
        /// <param name="map"></param>
        /// <param name="sealList"></param>
        /// <param name="plan"></param>
        /// <param name="loc"></param>
        /// <param name="dir"></param>
        /// <returns>Whether it affected the tile outwards or not</returns>
        private bool sealBorderRay(T map, Dictionary <Loc, SealType> sealList, IFloorRoomPlan plan, LocRay8 locRay, Dir8 side1, Dir8 side2)
        {
            Loc forthLoc = locRay.Loc + locRay.Dir.GetLoc();

            bool hasAdjacent  = false;
            bool hasCondition = false;

            for (int ii = 0; ii < plan.Adjacents.Count; ii++)
            {
                IFloorRoomPlan adjacentPlan = map.RoomPlan.GetRoomHall(plan.Adjacents[ii]);
                if (Collision.InBounds(adjacentPlan.RoomGen.Draw, forthLoc))
                {
                    hasAdjacent = true;
                    if (BaseRoomFilter.PassesAllFilters(adjacentPlan, this.Filters))
                    {
                        hasCondition = true;
                        break;
                    }
                }
            }

            if (!hasAdjacent)
            {
                //in the case where the extending tile is within no adjacents
                //  all normal walls shall be turned into impassables
                //  everything else is saved into the lock list
                sealBorderTile(map, sealList, SealType.Locked, forthLoc);

                return(true);
            }
            else if (!hasCondition)
            {
                //in the case where the extending tile is within an adjacent and that adjacent DOESNT pass filter
                //  all normal walls for the INWARD border shall be turned into impassables
                //  everything else for the INWARD border shall be saved into a key list

                if (map.Tiles[forthLoc.X][forthLoc.Y].TileEquivalent(map.RoomTerrain))
                {
                    sealBorderTile(map, sealList, SealType.Key, locRay.Loc);
                }
                else
                {
                    sealBorderTile(map, sealList, SealType.Locked, locRay.Loc);
                }

                //when transitioning between inward and outward
                //-when transitioning from outward to inward, the previous outward tile needs an inward check
                //-when transitioning from inward to outward, the current outward tile needs a inward check

                //in the interest of trading redundancy for simplicity, an inward block will just block the tiles to the sides
                //regardless of if they've already been blocked
                //redundancy will be handled by hashsets
                if (side1 != Dir8.None)
                {
                    Loc sideLoc = locRay.Loc + side1.GetLoc();
                    sealBorderTile(map, sealList, SealType.Locked, sideLoc);
                }
                if (side2 != Dir8.None)
                {
                    Loc sideLoc = locRay.Loc + side2.GetLoc();
                    sealBorderTile(map, sealList, SealType.Locked, sideLoc);
                }
                return(false);
            }
            else
            {
                //in the case where the extending tile is within an adjacent and that adjacent passes filter
                //  do nothing and skip these tiles
                return(true);
            }
        }
コード例 #13
0
        public bool IsChokePoint(RoomHallIndex room)
        {
            int roomsHit = 0;
            int hallsHit = 0;

            void NodeAct(RoomHallIndex nodeIndex, int distance)
            {
                if (!nodeIndex.IsHall)
                {
                    roomsHit++;
                }
                else
                {
                    hallsHit++;
                }
            }

            Graph.TraverseBreadthFirst(room, NodeAct, this.GetAdjacents);

            int totalRooms = roomsHit;
            int totalHalls = hallsHit;

            roomsHit = 0;
            hallsHit = 0;
            if (!room.IsHall)
            {
                roomsHit++;
            }
            else
            {
                hallsHit++;
            }

            List <RoomHallIndex> GetChokeAdjacents(RoomHallIndex nodeIndex)
            {
                List <RoomHallIndex> adjacents     = new List <RoomHallIndex>();
                List <RoomHallIndex> roomAdjacents = this.GetRoomHall(nodeIndex).Adjacents;

                // do not add adjacents if we arrive on a room
                // unless it's the first one.
                foreach (RoomHallIndex adjacentRoom in roomAdjacents)
                {
                    // do not count the origin room
                    if (adjacentRoom == room)
                    {
                        continue;
                    }
                    adjacents.Add(adjacentRoom);
                }

                return(adjacents);
            }

            IFloorRoomPlan plan = this.GetRoomHall(room);

            if (plan.Adjacents.Count > 0)
            {
                Graph.TraverseBreadthFirst(plan.Adjacents[0], NodeAct, GetChokeAdjacents);
            }

            return((roomsHit != totalRooms) || (hallsHit != totalHalls));
        }
コード例 #14
0
ファイル: FloorPlan.cs プロジェクト: ejbelt/RogueElements
        public bool IsChokePoint(RoomHallIndex room)
        {
            int roomsHit = 0;
            int hallsHit = 0;

            void NodeAct(int nodeIndex, int distance)
            {
                if (nodeIndex < this.Rooms.Count)
                {
                    roomsHit++;
                }
                else
                {
                    hallsHit++;
                }
            }

            int startIndex = room.Index + (room.IsHall ? this.Rooms.Count : 0);

            Graph.TraverseBreadthFirst(this.Rooms.Count + this.Halls.Count, startIndex, NodeAct, this.GetBreadthFirstAdjacents);

            int totalRooms = roomsHit;
            int totalHalls = hallsHit;

            roomsHit = 0;
            hallsHit = 0;
            if (!room.IsHall)
            {
                roomsHit++;
            }
            else
            {
                hallsHit++;
            }

            List <int> GetChokeAdjacents(int nodeIndex)
            {
                List <int>           adjacents     = new List <int>();
                List <RoomHallIndex> roomAdjacents = new List <RoomHallIndex>();

                // do not add adjacents if we arrive on a room
                // unless it's the first one.
                if (nodeIndex < this.Rooms.Count)
                {
                    roomAdjacents = this.Rooms[nodeIndex].Adjacents;
                }
                else
                {
                    roomAdjacents = this.Halls[nodeIndex - this.Rooms.Count].Adjacents;
                }

                foreach (RoomHallIndex adjacentRoom in roomAdjacents)
                {
                    // do not count the origin room
                    if (adjacentRoom == room)
                    {
                        continue;
                    }
                    if (adjacentRoom.IsHall)
                    {
                        adjacents.Add(adjacentRoom.Index + this.Rooms.Count);
                    }
                    else
                    {
                        adjacents.Add(adjacentRoom.Index);
                    }
                }

                return(adjacents);
            }

            IFloorRoomPlan plan = this.GetRoomHall(room);

            if (plan.Adjacents.Count > 0)
            {
                int adjIndex = plan.Adjacents[0].Index + (plan.Adjacents[0].IsHall ? this.Rooms.Count : 0);

                Graph.TraverseBreadthFirst(this.Rooms.Count + this.Halls.Count, adjIndex, NodeAct, GetChokeAdjacents);
            }

            return((roomsHit != totalRooms) || (hallsHit != totalHalls));
        }
コード例 #15
0
        public override void ApplyToPath(IRandom rand, FloorPlan floorPlan)
        {
            List <List <RoomHallIndex> > candBranchPoints = GetBranchArms(floorPlan);

            // remove the rooms that do not pass filter
            for (int xx = 0; xx < candBranchPoints.Count; xx++)
            {
                for (int yy = candBranchPoints[xx].Count - 1; yy >= 0; yy--)
                {
                    IFloorRoomPlan plan = floorPlan.GetRoomHall(candBranchPoints[xx][yy]);
                    if (!BaseRoomFilter.PassesAllFilters(plan, this.Filters))
                    {
                        candBranchPoints[xx].RemoveAt(yy);
                    }
                }
            }

            // compute a goal amount of branches 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 from
                int randIndex        = rand.Next(candBranchPoints.Count);
                var chosenDestResult = ChooseConnection(rand, floorPlan, candBranchPoints[randIndex]);

                if (chosenDestResult is ListPathTraversalNode chosenDest)
                {
                    // connect
                    PermissiveRoomGen <T> hall = (PermissiveRoomGen <T>) this.GenericHalls.Pick(rand).Copy();
                    hall.PrepareSize(rand, chosenDest.Connector.Size);
                    hall.SetLoc(chosenDest.Connector.Start);
                    floorPlan.AddHall(hall, this.Components.Clone(), chosenDest.From, chosenDest.To);
                    candBranchPoints.RemoveAt(randIndex);
                    connectionsLeft--;
                    GenContextDebug.DebugProgress("Added Connection");

                    // 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--)
                    {
                        for (int jj = 0; jj < candBranchPoints[ii].Count; jj++)
                        {
                            if (candBranchPoints[ii][jj] == chosenDest.To)
                            {
                                candBranchPoints.RemoveAt(ii);
                                connectionsLeft--;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    // remove the list anyway, but don't call it a success
                    candBranchPoints.RemoveAt(randIndex);
                }
            }
        }