Fixed connection room placement. It makes rooms but map printing needs to be improved to test fully.

This commit is contained in:
Max 2025-02-10 12:58:47 +01:00
parent 1c447ce510
commit 5c46281334
2 changed files with 75 additions and 35 deletions

View file

@ -4,6 +4,7 @@ using System.Linq;
using System.Numerics;
using System.Text;
using Unity.VisualScripting;
using Unity.VisualScripting.Dependencies.NCalc;
using Random = System.Random;
namespace DungeonGenerator
@ -56,7 +57,7 @@ namespace DungeonGenerator
rootRooms.Add(dungeon.GetBossRoom());
// 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());
nodeRoomsWithEntrances.AddRange(dungeon.GetEntranceRooms());
@ -66,13 +67,19 @@ namespace DungeonGenerator
foreach (var roomSideWithRoom in nodeRoomAndSideItIsOn)
{
Room closestSeenRoom = FindClosestSeenConnection(roomSideWithRoom.Value,
roomSideWithRoom.Key,
nodeRoomsWithEntrances,
rootRooms);
//Place rooms along the line until they are connected
dungeon.AddRooms(PlaceRoomsOrganicallyTowardRoom(roomSideWithRoom.Value, closestSeenRoom, RoomType.Normal,
dungeon.GetOccupiedPoints()));
foreach (Room room in roomSideWithRoom.Value)
{
Room closestSeenRoom = FindClosestSeenConnection(room,
roomSideWithRoom.Key,
nodeRoomsWithEntrances,
rootRooms);
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,
HashSet<Point> occupiedPoints)
HashSet<Point> occupiedPoints, HashSet<Point> unoccupiedPoints)
{
List<Room> placedRooms = new List<Room>();
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());
foreach (Point p in path)
bool roomPlaced = true;
while (currentRoom.GetCenterOfRoom().ManhattanDistance(targetRoom.GetCenterOfRoom()) >=
GetRoomSizeByType(type) && roomPlaced)
{
List<RoomSide> availableSides = sideToggle
? new List<RoomSide> { RoomSide.Left, RoomSide.Top }
: new List<RoomSide> { RoomSide.Right, RoomSide.Bottom };
Room newRoom;
// Get sides of room to try and place new room
(RoomSide primary, RoomSide secondary) =
GetSidesTowardsEndPoint(currentRoom.GetCenterOfRoom(), targetRoom.GetCenterOfRoom());
sideToggle = !sideToggle; // Alternate side for next placement.
foreach (RoomSide side in availableSides)
List<Point> availablePointsOnSide = GetUnoccupiedPointsOnSide(currentRoom, primary, unoccupiedPoints);
newRoom = CreateAdjacentRoom(type, availablePointsOnSide, primary, occupiedPoints);
// 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);
Room newRoom = CreateAdjacentRoom(RoomType.Normal, unoccupiedPointsOnSide, side, occupiedPoints);
if (newRoom != null)
{
placedRooms.Add(newRoom);
occupiedPoints.AddRange(newRoom.GetPointsInRoom());
currentRoom = newRoom;
break; // Move to the next room
}
availablePointsOnSide = GetUnoccupiedPointsOnSide(currentRoom, secondary, unoccupiedPoints);
newRoom = CreateAdjacentRoom(type, availablePointsOnSide, secondary, occupiedPoints);
}
if (newRoom != null)
{
placedRooms.Add(newRoom);
occupiedPoints.AddRange(newRoom.GetPointsInRoom());
currentRoom = newRoom;
}
else
{
roomPlaced = false;
}
if (currentRoom.GetCenterOfRoom().ManhattanDistance(targetRoom.GetCenterOfRoom()) <=
GetRoomSizeByType(type))
break;
}
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
} // Namespace

View file

@ -175,16 +175,20 @@ namespace DungeonGenerator
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 (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);
}
}
}