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.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

View file

@ -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);
} }
} }
} }