Spawning special rooms

This commit is contained in:
Marco 2025-04-21 17:46:26 +02:00
commit 6e26eb21b1
17 changed files with 502 additions and 54 deletions

View file

@ -15,6 +15,10 @@ public partial class RogueliteRoom : Node2D
public Vector2I GridPosition { get; set; } // Set by dungeon manager
public Vector2I BottomLeft => GridPosition + new Vector2I(0, RoomResource.Size.Y - 1);
public Vector2I RandomBottomExit => BottomLeft - new Vector2I( GD.RandRange(0, RoomResource.Size.X - 1), 0);
[Export] public PackedScene DoorPrefab { get; private set; }
[Export] public PackedScene WallPrefab { get; private set; }
@ -208,4 +212,9 @@ public partial class RogueliteRoom : Node2D
{
if (area is not InteractionController player) return;
}
public override string ToString()
{
return $"{GridPosition} {RoomResource}";
}
}

View file

@ -96,16 +96,17 @@ public partial class RogueliteRoomManager : Node2D
var randomOffshootRoomsList = OffshootRooms.Shuffle(MaxBranchLength).ToList();
var currentPos = origin;
var currentPos = spawnedBeginRoom.RandomBottomExit;
_connections.Add(new RoomConnection(origin, currentPos + new Vector2I(0, 1)));
Vector2I nextPos;
var offshoots = new List<OffshootType>()
var offshoots = new List<RoomType>()
{
OffshootType.Item,
OffshootType.Secret,
OffshootType.Shop,
OffshootType.Key
RoomType.Treasure,
RoomType.Secret,
RoomType.Shop,
RoomType.Key,
RoomType.Regular
};
var shuffledOffshoots = offshoots.Shuffle().ToList();
@ -113,10 +114,11 @@ public partial class RogueliteRoomManager : Node2D
for (int i = 0; i < DungeonLength; i++)
{
GD.Print($"Dungeon room {i}");
nextPos = currentPos + new Vector2I(0, 1);
//var roomToSpawn = Rooms.Where(x => x.Type == RoomType.Regular).PickRandom();
var roomToSpawn = randomRoomsList[i];
var roomToSpawn = randomRoomsList[i % randomRoomsList.Count];
// We're already in the new room position, we do not care about previous anymore
var offset = 0;
@ -131,39 +133,40 @@ public partial class RogueliteRoomManager : Node2D
//var posWithOffset = nextPos + new Vector2I(offset, 0);
GD.Print($"Spawning room at {nextPos}");
if (!SpawnRoom(roomToSpawn, nextPos, out var spawnedRoom))
{
GD.PrintErr("Could not spawn room");
break;
GD.PrintErr($"Could not spawn room {roomToSpawn} at {nextPos}");
//DungeonLength += 1;
continue;
}
_mainPath.Add(nextPos);
// Place cursor at bottom of room
if (roomToSpawn.Size.Y > 1)
{
nextPos += new Vector2I(0, roomToSpawn.Size.Y - 1);
}
// Pick a random exit to continue
var exit = GD.RandRange(0, roomToSpawn.Size.X - 1);
if (exit < 0) exit = 0;
nextPos += new Vector2I(exit, 0);
nextPos = spawnedRoom.RandomBottomExit;
GD.Print($"Next pos is now: {nextPos}");
// nextPos is now the end of the room at the current exit
_connections.Add(new RoomConnection(nextPos, nextPos + new Vector2I(0, 1)));
currentPos = nextPos;
// Spawn offshoot here
var offshootTypeToSpawn = shuffledOffshoots[currentOffshoot % shuffledOffshoots.Count()];
if (offshootTypeToSpawn is RoomType.Regular)
{
currentOffshoot++;
continue;
}
int roomsInOffshot = GD.RandRange(0, MaxBranchLength);
var leftPosition = spawnedRoom.GridPosition;
// Roll whether to go left or right, if direction is full go the other, if both are full do not spawn
for (int j = 0; j < roomsInOffshot; j++)
@ -172,49 +175,49 @@ public partial class RogueliteRoomManager : Node2D
foreach (var shuffledOffshoot in shuffledOffshootRoomsList)
{
var offShootCoord = leftPosition - new Vector2I(shuffledOffshoot.Size.X, 0);
var offshootCoord = leftPosition - new Vector2I(shuffledOffshoot.Size.X, 0);
GD.Print("Spawning side room");
var spawned = SpawnRoom(shuffledOffshoot, offshootCoord, out var spawnedOffshoot);
if (!CanPlaceRoom(offShootCoord, shuffledOffshoot.Size))
if (!spawned)
{
GD.Print($"Could not place room {shuffledOffshoot.RoomName} {shuffledOffshoot.Size}");
GD.Print($"Could not place room {shuffledOffshoot} at {offshootCoord}");
// Try next in list
continue;
}
var offshootCoord = leftPosition - new Vector2I(shuffledOffshoot.Size.X, 0);
SpawnRoom(shuffledOffshoot, offshootCoord, out var spawnedOffshoot);
_connections.Add(new RoomConnection(leftPosition, offshootCoord + new Vector2I(shuffledOffshoot.Size.X -1, 0)));
leftPosition = offshootCoord;
// Stop because we spawned the room we needed to
currentOffshoot++;
break;
}
//var room = randomOffshootRoomsList.Shuffle().FirstOrDefault();
// Get a random room with the required doors
//var leftToRightRooms =
// Get a random door on right or left side
// spawn
// Add path
// Move cursor
// if last room generate final room
// Continue
// If it got here and couldn't spawn the offshoot, do not increase counter
}
// Offshoot over
currentPos = nextPos;
// Spawn final room
var finalRoomToSpawn = Rooms.Where(x => x.Type == offshootTypeToSpawn).PickRandom();
var finalRoomCoord = leftPosition - new Vector2I(finalRoomToSpawn.Size.X, 0);
SpawnRoom(finalRoomToSpawn, finalRoomCoord, out var spawnedFinalRoom);
_connections.Add(new RoomConnection(leftPosition, finalRoomCoord + new Vector2I(finalRoomToSpawn.Size.X -1, 0)));
leftPosition = finalRoomCoord;
// Done with last offshoot room
}
nextPos = currentPos + new Vector2I(0, 1);
GD.Print($"Final nextpos is {nextPos}");
var bossRoom = BossRooms.PickRandom();
@ -226,12 +229,12 @@ public partial class RogueliteRoomManager : Node2D
{
nextPos += new Vector2I(0, bossRoom.Size.Y - 1);
}
_connections.Add(new RoomConnection(currentPos, nextPos));
}
else
{
GD.PrintErr("Could not spawn boss room");
GD.PrintErr($"Could not spawn boss room {bossRoom} at {nextPos}");
}
foreach (var room in SpawnedRooms)
@ -289,6 +292,7 @@ public partial class RogueliteRoomManager : Node2D
if (!CanPlaceRoom(gridPos, room.Size))
{
spawnedRoom = null;
GD.Print($"{gridPos} size {room.Size} is occupied");
return false;
}
@ -299,10 +303,12 @@ public partial class RogueliteRoomManager : Node2D
spawnedScene.GridPosition = gridPos;
spawnedScene.Name = room.RoomName;
spawnedScene.Name = room.RoomName.ToString().Replace(" ", "_");
SpawnedRooms.Add(spawnedScene);
GD.Print($"Spawned room: {spawnedScene}");
// for reference
//SpawnRoom(room, origin + (room.Size * new Vector2(i, j) * tileSize));
spawnedScene.Spawn();