Fixed connection room placement. It makes rooms but map printing needs to be improved to test fully.
This commit is contained in:
parent
1c447ce510
commit
5c46281334
2 changed files with 75 additions and 35 deletions
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Unity.VisualScripting;
|
using Unity.VisualScripting;
|
||||||
|
using Unity.VisualScripting.Dependencies.NCalc;
|
||||||
using Random = System.Random;
|
using Random = System.Random;
|
||||||
|
|
||||||
namespace DungeonGenerator
|
namespace DungeonGenerator
|
||||||
|
|
@ -56,7 +57,7 @@ namespace DungeonGenerator
|
||||||
rootRooms.Add(dungeon.GetBossRoom());
|
rootRooms.Add(dungeon.GetBossRoom());
|
||||||
|
|
||||||
// Create list of connection rooms
|
// Create list of connection rooms
|
||||||
Dictionary<RoomSide, Room> nodeRoomAndSideItIsOn = new Dictionary<RoomSide, Room>();
|
Dictionary<RoomSide, List<Room>> nodeRoomAndSideItIsOn = dungeon.GetNodesWithSides();
|
||||||
|
|
||||||
List<Room> nodeRoomsWithEntrances = new List<Room>(dungeon.GetNodeRooms());
|
List<Room> nodeRoomsWithEntrances = new List<Room>(dungeon.GetNodeRooms());
|
||||||
nodeRoomsWithEntrances.AddRange(dungeon.GetEntranceRooms());
|
nodeRoomsWithEntrances.AddRange(dungeon.GetEntranceRooms());
|
||||||
|
|
@ -66,13 +67,19 @@ namespace DungeonGenerator
|
||||||
|
|
||||||
foreach (var roomSideWithRoom in nodeRoomAndSideItIsOn)
|
foreach (var roomSideWithRoom in nodeRoomAndSideItIsOn)
|
||||||
{
|
{
|
||||||
Room closestSeenRoom = FindClosestSeenConnection(roomSideWithRoom.Value,
|
foreach (Room room in roomSideWithRoom.Value)
|
||||||
roomSideWithRoom.Key,
|
{
|
||||||
nodeRoomsWithEntrances,
|
Room closestSeenRoom = FindClosestSeenConnection(room,
|
||||||
rootRooms);
|
roomSideWithRoom.Key,
|
||||||
//Place rooms along the line until they are connected
|
nodeRoomsWithEntrances,
|
||||||
dungeon.AddRooms(PlaceRoomsOrganicallyTowardRoom(roomSideWithRoom.Value, closestSeenRoom, RoomType.Normal,
|
rootRooms);
|
||||||
dungeon.GetOccupiedPoints()));
|
if (closestSeenRoom != null)
|
||||||
|
{
|
||||||
|
//Place rooms along the line until they are connected
|
||||||
|
dungeon.AddRooms(PlaceRoomsOrganicallyTowardRoom(room, closestSeenRoom, RoomType.Normal,
|
||||||
|
dungeon.GetOccupiedPoints(), dungeon.GetUnoccupiedPoints()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -529,43 +536,72 @@ namespace DungeonGenerator
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Room> PlaceRoomsOrganicallyTowardRoom(Room startingRoom, Room targetRoom, RoomType type,
|
private List<Room> PlaceRoomsOrganicallyTowardRoom(Room startingRoom, Room targetRoom, RoomType type,
|
||||||
HashSet<Point> occupiedPoints)
|
HashSet<Point> occupiedPoints, HashSet<Point> unoccupiedPoints)
|
||||||
{
|
{
|
||||||
List<Room> placedRooms = new List<Room>();
|
List<Room> placedRooms = new List<Room>();
|
||||||
Room currentRoom = startingRoom;
|
Room currentRoom = startingRoom;
|
||||||
bool sideToggle = true; // Start with left placement first
|
|
||||||
|
|
||||||
|
// TODO I don't think I actually need this
|
||||||
List<Point> path = GetPointsOnLine(startingRoom.GetCenterOfRoom(), targetRoom.GetCenterOfRoom());
|
List<Point> path = GetPointsOnLine(startingRoom.GetCenterOfRoom(), targetRoom.GetCenterOfRoom());
|
||||||
|
|
||||||
foreach (Point p in path)
|
bool roomPlaced = true;
|
||||||
|
while (currentRoom.GetCenterOfRoom().ManhattanDistance(targetRoom.GetCenterOfRoom()) >=
|
||||||
|
GetRoomSizeByType(type) && roomPlaced)
|
||||||
{
|
{
|
||||||
List<RoomSide> availableSides = sideToggle
|
Room newRoom;
|
||||||
? new List<RoomSide> { RoomSide.Left, RoomSide.Top }
|
// Get sides of room to try and place new room
|
||||||
: new List<RoomSide> { RoomSide.Right, RoomSide.Bottom };
|
(RoomSide primary, RoomSide secondary) =
|
||||||
|
GetSidesTowardsEndPoint(currentRoom.GetCenterOfRoom(), targetRoom.GetCenterOfRoom());
|
||||||
|
|
||||||
sideToggle = !sideToggle; // Alternate side for next placement.
|
List<Point> availablePointsOnSide = GetUnoccupiedPointsOnSide(currentRoom, primary, unoccupiedPoints);
|
||||||
|
newRoom = CreateAdjacentRoom(type, availablePointsOnSide, primary, occupiedPoints);
|
||||||
foreach (RoomSide side in availableSides)
|
// If the primary side doesn't have room for a new room the try secondary
|
||||||
|
if (newRoom == null)
|
||||||
{
|
{
|
||||||
List<Point> unoccupiedPointsOnSide = GetUnoccupiedPointsOnSide(currentRoom, side, occupiedPoints);
|
availablePointsOnSide = GetUnoccupiedPointsOnSide(currentRoom, secondary, unoccupiedPoints);
|
||||||
Room newRoom = CreateAdjacentRoom(RoomType.Normal, unoccupiedPointsOnSide, side, occupiedPoints);
|
newRoom = CreateAdjacentRoom(type, availablePointsOnSide, secondary, occupiedPoints);
|
||||||
|
}
|
||||||
if (newRoom != null)
|
|
||||||
{
|
if (newRoom != null)
|
||||||
placedRooms.Add(newRoom);
|
{
|
||||||
occupiedPoints.AddRange(newRoom.GetPointsInRoom());
|
placedRooms.Add(newRoom);
|
||||||
currentRoom = newRoom;
|
occupiedPoints.AddRange(newRoom.GetPointsInRoom());
|
||||||
break; // Move to the next room
|
currentRoom = newRoom;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
roomPlaced = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentRoom.GetCenterOfRoom().ManhattanDistance(targetRoom.GetCenterOfRoom()) <=
|
|
||||||
GetRoomSizeByType(type))
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return placedRooms;
|
return placedRooms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public (RoomSide primarySide, RoomSide secondarySide) GetSidesTowardsEndPoint(Point start, Point end)
|
||||||
|
{
|
||||||
|
// Calculate the differences in X and Y
|
||||||
|
int deltaX = end.X - start.X;
|
||||||
|
int deltaY = end.Y - start.Y;
|
||||||
|
|
||||||
|
// Determine the primary side
|
||||||
|
RoomSide primarySide;
|
||||||
|
RoomSide secondarySide;
|
||||||
|
|
||||||
|
if (Math.Abs(deltaX) > Math.Abs(deltaY))
|
||||||
|
{
|
||||||
|
// If horizontal movement is greater, primary side is horizontal
|
||||||
|
primarySide = deltaX > 0 ? RoomSide.Right : RoomSide.Left;
|
||||||
|
secondarySide = deltaY > 0 ? RoomSide.Bottom : RoomSide.Top;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If vertical movement is greater, primary side is vertical
|
||||||
|
primarySide = deltaY > 0 ? RoomSide.Bottom : RoomSide.Top;
|
||||||
|
secondarySide = deltaX > 0 ? RoomSide.Right : RoomSide.Left;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (primarySide, secondarySide);
|
||||||
|
}
|
||||||
|
|
||||||
} // Class
|
} // Class
|
||||||
} // Namespace
|
} // Namespace
|
||||||
|
|
@ -175,16 +175,20 @@ namespace DungeonGenerator
|
||||||
return nodeRooms;
|
return nodeRooms;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<RoomSide, Room> GetNodesWithSides()
|
public Dictionary<RoomSide, List<Room>> GetNodesWithSides()
|
||||||
{
|
{
|
||||||
Dictionary<RoomSide, Room> nodesWithSides = new Dictionary<RoomSide, Room>();
|
Dictionary<RoomSide, List<Room>> nodesWithSides = new Dictionary<RoomSide, List<Room>>();
|
||||||
foreach (Room room in _monsterRooms)
|
foreach (Room room in _monsterRooms)
|
||||||
{
|
{
|
||||||
foreach (var kvp in room.GetAdjacentRoomsDict())
|
foreach (var kvp in room.GetAdjacentRoomsDict())
|
||||||
{
|
{
|
||||||
foreach (Room adjacentRoom in kvp.Value)
|
if (!nodesWithSides.ContainsKey(kvp.Key))
|
||||||
{
|
{
|
||||||
nodesWithSides[kvp.Key] = room;
|
nodesWithSides[kvp.Key] = new List<Room>(kvp.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nodesWithSides[kvp.Key].AddRange(kvp.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue