public Room(RoomTemplate template, IntRectangle bounds) { Template = template; Bounds = bounds; }
/// <summary> /// Generate a rectangular room /// </summary> /// <param name="iMin"></param> /// <param name="iMax"></param> /// <param name="jMin"></param> /// <param name="jMax"></param> /// <param name="template"></param> /// <param name="floorLevel"></param> /// <param name="slopeDirection"></param> /// <returns></returns> protected Room GenerateRoom(IntRectangle bounds, RoomTemplate template) { return(GenerateRoom(bounds.XMin, bounds.XMax, bounds.YMin, bounds.YMax, template)); }
public bool GrowRoom(int iDoor, int jDoor, RoomTemplate template, CompassDirection direction, bool createDoor, Room parent) { bool result = false; int doorSize = template.EntryWidth; var bounds = new IntRectangle(iDoor, jDoor); // Current room bounds bool iFrozen = false; // Is growth in the x-direction frozen? bool jFrozen = false; // Is growth in the y-direction frozen? //Generate target dimensions: var dimensions = new IntInterval( template.Dimension1.Random(_RNG), template.Dimension2.Random(_RNG)); //Create starting tiles in front of doorway: bounds.Move(direction, 1); if (direction == CompassDirection.North || direction == CompassDirection.South) { bounds.Grow(CompassDirection.East, doorSize - 1); } else { bounds.Grow(CompassDirection.North, doorSize - 1); } if (CheckAvailability(bounds)) { // Grow outwards, checking availability: CompassDirection growDirection = direction; int persistance = 5; //Failures before abort while (persistance > 0) { if (!(iFrozen && growDirection.IsHorizontal()) && !(jFrozen && growDirection.IsVertical())) { if (CheckAvailability(bounds.GrowZone(growDirection, 1))) { bounds.Grow(growDirection, 1); } else { persistance--; } } if (bounds.XSize + 1 >= dimensions.Max) { iFrozen = true; } if (bounds.XSize + 1 > dimensions.Min && bounds.YSize + 1 == dimensions.Min) { jFrozen = true; } if (bounds.YSize + 1 >= dimensions.Max) { jFrozen = true; } if (bounds.YSize + 1 > dimensions.Min && bounds.XSize + 1 == dimensions.Min) { iFrozen = true; } if (jFrozen && iFrozen) { persistance = 0; } else { growDirection = ExitDirection(template.ExitPlacement, direction); //TODO: ExitPlacement from RoomTemplate? } } if (template.RoomType == RoomType.Circulation && (!PreventParallelCorridors || IsParallelToCorridor(bounds))) { return(false); //Abort parallel corridors } if ((bounds.XSize + 1 >= template.Dimension1.Min && bounds.YSize + 1 >= template.Dimension2.Min || (bounds.XSize + 1 >= template.Dimension2.Min && bounds.YSize + 1 >= template.Dimension1.Min))) { // Reached target size - create room // Create doorway: if (createDoor) { GenerateDoorway(iDoor, jDoor, direction, doorSize); } // Create room: Room newRoom = GenerateRoom(bounds, template); //Take snapshot: TakeSnapshot(); if (template.RoomType == RoomType.Exit) { ExitPlaced = true; } //TODO: Store room & connections if (template.RoomType != RoomType.Circulation) { result = true; //Circulation rooms cannot validate chains } //Sprout new rooms: int tries = template.SproutTries; CompassDirection doorDirection = direction; int iNewDoor = 0; int jNewDoor = 0; bool symmetryLock = true; while (tries > 0 && (template.MaxConnections < 0 || newRoom.Connections.Count < template.MaxConnections)) { RoomTemplate nextRoom = NextRoom(template); if (nextRoom != null) { int newDoorWidth = nextRoom.EntryWidth; if (!symmetryLock && _RNG.NextDouble() < template.SymmetryChance) { symmetryLock = true; //Create door opposite last doorDirection = doorDirection.Reverse(); } else { symmetryLock = false; //Select random growth direction: doorDirection = ExitDirection(template.ExitPlacement, direction); } //Select door position for this try: bounds.RandomPointOnEdge(doorDirection, _RNG, newDoorWidth - 1, ref iNewDoor, ref jNewDoor); if (RecursiveGrowth(iNewDoor, jNewDoor, nextRoom, doorDirection, true, newRoom)) { result = true; } } tries -= 1; } if (result == false) { DeleteRoom(newRoom); } } } else { if (createDoor && AreAllType(bounds, CellGenerationType.Void) && AvailableForDoorway(iDoor, jDoor, direction, template.EntryWidth)) { // TODO: Check room connections GenerateDoorway(iDoor, jDoor, direction, template.EntryWidth); } } return(result); }
/// <summary> /// Generate a dungeon map /// </summary> /// <param name="iStart"></param> /// <param name="jStart"></param> /// <param name="startRoom">The room to start with</param> /// <param name="startDirection">The initial direction</param> /// <returns></returns> public bool Generate(int iStart, int jStart, RoomTemplate startRoom, CompassDirection startDirection) { //TODO: Generate negative space return(RecursiveGrowth(iStart, jStart, startRoom, startDirection, false, null)); }