예제 #1
0
        public List <RoomHallIndex> CheckCollision(Rect rect)
        {
            // gets all rooms/halls colliding with the rectangle
            List <RoomHallIndex> results = new List <RoomHallIndex>();

            for (int ii = 0; ii < this.Rooms.Count; ii++)
            {
                FloorRoomPlan room = this.Rooms[ii];
                if (Collision.Collides(room.RoomGen.Draw, rect))
                {
                    results.Add(new RoomHallIndex(ii, false));
                }
            }

            for (int ii = 0; ii < this.Halls.Count; ii++)
            {
                FloorHallPlan hall = this.Halls[ii];
                if (Collision.Collides(hall.RoomGen.Draw, rect))
                {
                    results.Add(new RoomHallIndex(ii, true));
                }
            }

            return(results);
        }
예제 #2
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);
        }
예제 #3
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);
        }
예제 #4
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);
            }
        }
예제 #5
0
        private protected static List <List <RoomHallIndex> > GetBranchArms(FloorPlan floorPlan)
        {
            List <ListPathTraversalNode> endBranches = new List <ListPathTraversalNode>();

            for (int ii = 0; ii < floorPlan.RoomCount; ii++)
            {
                FloorRoomPlan roomPlan = floorPlan.GetRoomPlan(ii);
                if (roomPlan.Adjacents.Count == 1)
                {
                    endBranches.Add(new ListPathTraversalNode(new RoomHallIndex(-1, false), new RoomHallIndex(ii, false)));
                }
            }

            List <List <RoomHallIndex> > branchArms = new List <List <RoomHallIndex> >();

            for (int nn = 0; nn < endBranches.Count; nn++)
            {
                ListPathTraversalNode chosenBranch = endBranches[nn];
                List <RoomHallIndex>  arm          = new List <RoomHallIndex>();

                while (true)
                {
                    List <RoomHallIndex> connectors = new List <RoomHallIndex>();
                    List <RoomHallIndex> adjacents  = floorPlan.GetRoomHall(chosenBranch.To).Adjacents;
                    foreach (RoomHallIndex dest in adjacents)
                    {
                        if (dest != chosenBranch.From)
                        {
                            connectors.Add(dest);
                        }
                    }

                    if (connectors.Count == 1)
                    {
                        arm.Add(chosenBranch.To);
                        chosenBranch = new ListPathTraversalNode(chosenBranch.To, connectors[0]);
                    }
                    else if (connectors.Count == 0)
                    {
                        // we've reached the other side of a single line; add
                        arm.Add(chosenBranch.To);

                        // but also find the other pending arm and remove it
                        for (int ii = endBranches.Count - 1; ii > nn; ii--)
                        {
                            ListPathTraversalNode otherBranch = endBranches[ii];
                            if (chosenBranch.To == otherBranch.To)
                            {
                                endBranches.RemoveAt(ii);
                            }
                        }

                        // end the loop
                        break;
                    }
                    else
                    {
                        break;
                    }
                }

                branchArms.Add(arm);
            }

            return(branchArms);
        }