Ejemplo n.º 1
0
 public void SetHall(GridHallPlan plan)
 {
     this.HallParts.Clear();
     if (plan != null)
     {
         this.HallParts.Add(plan);
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Sets the RoomGen found in the specified hall.
        /// </summary>
        /// <param name="locRay">The location of the room + the direction of the connecting hall relative to the room.</param>
        /// <param name="hallGen"></param>
        /// <param name="components">components to include in the hall</param>
        public void SetHall(LocRay4 locRay, IPermissiveRoomGen hallGen, ComponentCollection components)
        {
            if (locRay.Dir == Dir4.None)
            {
                throw new ArgumentException("Invalid direction.");
            }
            else if (!locRay.Dir.Validate())
            {
                throw new ArgumentOutOfRangeException("Invalid enum value.");
            }

            GridHallPlan plan = null;

            if (hallGen != null)
            {
                plan = new GridHallPlan((IPermissiveRoomGen)hallGen.Copy(), components);
            }

            switch (locRay.Dir)
            {
            case Dir4.Down:
                if (locRay.Loc.Y < this.GridHeight - 1)
                {
                    this.VHalls[locRay.Loc.X][locRay.Loc.Y].SetHall(plan);
                }
                break;

            case Dir4.Left:
                if (locRay.Loc.X > 0)
                {
                    this.HHalls[locRay.Loc.X - 1][locRay.Loc.Y].SetHall(plan);
                }
                break;

            case Dir4.Up:
                if (locRay.Loc.Y > 0)
                {
                    this.VHalls[locRay.Loc.X][locRay.Loc.Y - 1].SetHall(plan);
                }
                break;

            case Dir4.Right:
                if (locRay.Loc.X < this.GridWidth - 1)
                {
                    this.HHalls[locRay.Loc.X][locRay.Loc.Y].SetHall(plan);
                }
                break;

            case Dir4.None:
                throw new ArgumentException($"No hall for dir {nameof(Dir4.None)}");

            default:
                throw new ArgumentOutOfRangeException(nameof(locRay.Dir), "Invalid enum value.");
            }
        }
Ejemplo n.º 3
0
        public int GetRoomNum(LocRay4 locRay)
        {
            GridHallPlan hall = this.GetHall(locRay);

            if (hall != null)
            {
                Loc moveLoc = locRay.Traverse(1);
                return(this.Rooms[moveLoc.X][moveLoc.Y]);
            }

            return(-1);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Decides on the bounds for each hall.  Also writes to the adjacent rooms' SideReqs and tile permissions
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="vertical"></param>
        /// <param name="rand">todo: describe rand parameter on ChooseHallBounds</param>
        public void ChooseHallBounds(IRandom rand, int x, int y, bool vertical)
        {
            GridRoomPlan startRoom = this.GetRoomPlan(new Loc(x, y));
            GridRoomPlan endRoom   = this.GetRoomPlan(new Loc(x + (vertical ? 0 : 1), y + (vertical ? 1 : 0)));

            GridHallGroup hallGroup = vertical ? this.VHalls[x][y] : this.HHalls[x][y];

            if (hallGroup.MainHall != null)
            {
                // also sets the sidereqs
                int      tier          = vertical ? x : y;
                Dir4     dir           = vertical ? Dir4.Down : Dir4.Right;
                IntRange startRange    = this.GetHallTouchRange(startRoom.RoomGen, dir, tier);
                IntRange endRange      = this.GetHallTouchRange(endRoom.RoomGen, dir.Reverse(), tier);
                IntRange combinedRange = new IntRange(Math.Min(startRange.Min, endRange.Min), Math.Max(startRange.Max, endRange.Max));
                Loc      start         = startRoom.RoomGen.Draw.End;
                Loc      end           = endRoom.RoomGen.Draw.Start;

                Rect startCell = this.GetCellBounds(startRoom.Bounds);
                Rect endCell   = this.GetCellBounds(endRoom.Bounds);

                Rect bounds = vertical ? new Rect(combinedRange.Min, start.Y, combinedRange.Length, end.Y - start.Y)
                    : new Rect(start.X, combinedRange.Min, end.X - start.X, combinedRange.Length);

                // a side constitutes intruding bound when the rectangle moves forward enough to go to the other side
                // and the other side touched is outside of side B's bound (including borders)

                // startRange intrudes if startRange goes outside end's tier (borders included)
                bool startIntrude = !endCell.GetSide(dir.ToAxis()).Contains(startRange);

                // and end is greater than the edge (borders excluded)
                bool endTouch = bounds.GetScalar(dir) == endCell.GetScalar(dir.Reverse());

                bool endIntrude = !startCell.GetSide(dir.ToAxis()).Contains(endRange);

                // and end is greater than the edge (borders excluded)
                bool startTouch = bounds.GetScalar(dir.Reverse()) == startCell.GetScalar(dir);

                // neither side intrudes bound: use the computed rectangle
                if ((!startIntrude && !endIntrude) || (endTouch && startTouch) ||
                    (!(startIntrude && endIntrude) && ((startIntrude && endTouch) || (endIntrude && startTouch))))
                {
                    hallGroup.MainHall.RoomGen.PrepareSize(rand, bounds.Size);
                    hallGroup.MainHall.RoomGen.SetLoc(bounds.Start);
                }
                else
                {
                    int      divPoint      = startCell.GetScalar(dir) + 1;
                    IntRange startDivRange = startRange;
                    IntRange endDivRange   = endRange;
                    if (startIntrude && !endIntrude)
                    {
                        // side A intrudes bound, side B does not: divide A and B; doesn't matter who gets border
                        // side A touches border, side B does not: divide A and B; A gets border
                        //
                        // side A does not, side B touches border: A gets border; don't need B - this cannot happen
                        // side A touches border, side B touches border: A gets border; don't need B - this cannot happen
                        //
                        // in short, divide with start getting the border
                        // startDivRange needs to contain endRange
                        startDivRange = combinedRange;
                    }
                    else if (!startIntrude && endIntrude)
                    {
                        // side A does not, side B intrudes bound: divide A and B; doesn't matter who gets border
                        // side A does not, side B touches border: divide A and B; B gets border
                        //
                        // side A touches border, side B does not: B gets border; don't need A - this cannot happen
                        // side A touches border, side B touches border: B gets border; don't need B - this cannot happen
                        //
                        // in short, divide with end getting the border
                        // endDivRange needs to contain startRange
                        divPoint    = startCell.GetScalar(dir);
                        endDivRange = combinedRange;
                    }
                    else
                    {
                        // side A intrudes bound, side B intrudes bound: divide A and B; doesn't matter who gets border
                        if (startTouch)
                        {
                            // side A touches border, side B does not: divide A and B; A gets border
                        }

                        if (endTouch)
                        {
                            // side A does not, side B touches border: divide A and B; B gets border
                            divPoint = startCell.GetScalar(dir);
                        }

                        // side A touches border, side B touches border: A gets border; don't need B -  this cannot happen
                        // both sides need to cover the intersection of their cells
                        IntRange interCellSide = IntRange.Intersect(startCell.GetSide(dir.ToAxis()), endCell.GetSide(dir.ToAxis()));
                        startDivRange = IntRange.IncludeRange(startDivRange, interCellSide);
                        endDivRange   = IntRange.IncludeRange(endDivRange, interCellSide);
                    }

                    Rect startBox = vertical ? new Rect(startDivRange.Min, start.Y, startDivRange.Length, divPoint - start.Y)
                        : new Rect(start.X, startDivRange.Min, divPoint - start.X, startDivRange.Length);
                    Rect endBox = vertical ? new Rect(endDivRange.Min, divPoint, endDivRange.Length, end.Y - divPoint)
                        : new Rect(divPoint, endDivRange.Min, end.X - divPoint, endDivRange.Length);

                    GridHallPlan originalHall = hallGroup.MainHall;
                    hallGroup.HallParts.Add(new GridHallPlan((IPermissiveRoomGen)originalHall.RoomGen.Copy(), originalHall.Components));
                    hallGroup.HallParts[0].RoomGen.PrepareSize(rand, startBox.Size);
                    hallGroup.HallParts[0].RoomGen.SetLoc(startBox.Start);
                    hallGroup.HallParts[1].RoomGen.PrepareSize(rand, endBox.Size);
                    hallGroup.HallParts[1].RoomGen.SetLoc(endBox.Start);
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Generates the position and size of each room and hall, and places it in the specified IFloorPlanGenContext.
        /// </summary>
        /// <param name="map"></param>
        public void PlaceRoomsOnFloor(IFloorPlanGenContext map)
        {
            // decide on room sizes
            for (int ii = 0; ii < this.ArrayRooms.Count; ii++)
            {
                this.ChooseRoomBounds(map.Rand, ii);
            }

            // decide on halls; write to RoomSideReqs
            for (int xx = 0; xx < this.VHalls.Length; xx++)
            {
                for (int yy = 0; yy < this.VHalls[xx].Length; yy++)
                {
                    this.ChooseHallBounds(map.Rand, xx, yy, true);
                }
            }

            for (int xx = 0; xx < this.HHalls.Length; xx++)
            {
                for (int yy = 0; yy < this.HHalls[xx].Length; yy++)
                {
                    this.ChooseHallBounds(map.Rand, xx, yy, false);
                }
            }

            GenContextDebug.StepIn("Main Rooms");

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

            foreach (var plan in this.ArrayRooms)
            {
                if (plan.CountsAsHall())
                {
                    roomToHall.Add(new RoomHallIndex(map.RoomPlan.HallCount, true));
                    map.RoomPlan.AddHall((IPermissiveRoomGen)plan.RoomGen);
                    GenContextDebug.DebugProgress("Add Hall Room");
                }
                else
                {
                    roomToHall.Add(new RoomHallIndex(map.RoomPlan.RoomCount, false));
                    map.RoomPlan.AddRoom(plan.RoomGen, plan.Immutable);
                    GenContextDebug.DebugProgress("Added Room");
                }
            }

            GenContextDebug.StepOut();

            GenContextDebug.StepIn("Connecting Halls");

            for (int xx = 0; xx < this.VHalls.Length; xx++)
            {
                for (int yy = 0; yy < this.VHalls[xx].Length; yy++)
                {
                    GridHallPlan hall = this.VHalls[xx][yy];
                    if (hall.MainGen != null)
                    {
                        for (int ii = 0; ii < hall.Gens.Count; ii++)
                        {
                            List <RoomHallIndex> adj = new List <RoomHallIndex>();
                            if (ii == 0)
                            {
                                int upRoom = this.Rooms[xx][yy];
                                if (upRoom > -1)
                                {
                                    adj.Add(roomToHall[upRoom]);
                                }
                            }
                            else
                            {
                                adj.Add(new RoomHallIndex(map.RoomPlan.HallCount - 1, true));
                            }

                            if (ii == hall.Gens.Count - 1)
                            {
                                int downRoom = this.Rooms[xx][yy + 1];
                                if (downRoom > -1)
                                {
                                    adj.Add(roomToHall[downRoom]);
                                }
                            }

                            map.RoomPlan.AddHall(hall.Gens[ii], adj.ToArray());
                            GenContextDebug.DebugProgress("Add Hall");
                        }
                    }
                }
            }

            for (int xx = 0; xx < this.HHalls.Length; xx++)
            {
                for (int yy = 0; yy < this.HHalls[xx].Length; yy++)
                {
                    GridHallPlan hall = this.HHalls[xx][yy];
                    if (hall.MainGen != null)
                    {
                        for (int ii = 0; ii < hall.Gens.Count; ii++)
                        {
                            List <RoomHallIndex> adj = new List <RoomHallIndex>();
                            if (ii == 0)
                            {
                                int leftRoom = this.Rooms[xx][yy];
                                if (leftRoom > -1)
                                {
                                    adj.Add(roomToHall[leftRoom]);
                                }
                            }
                            else
                            {
                                adj.Add(new RoomHallIndex(map.RoomPlan.HallCount - 1, true));
                            }

                            if (ii == hall.Gens.Count - 1)
                            {
                                int rightRoom = this.Rooms[xx + 1][yy];
                                if (rightRoom > -1)
                                {
                                    adj.Add(roomToHall[rightRoom]);
                                }
                            }

                            map.RoomPlan.AddHall(hall.Gens[ii], adj.ToArray());
                            GenContextDebug.DebugProgress("Add Hall");
                        }
                    }
                }
            }

            GenContextDebug.StepOut();
        }