Use queues for room generation

This commit is contained in:
Marco 2025-04-30 10:30:43 +02:00
commit 7482cfa496
3 changed files with 128 additions and 66 deletions

View file

@ -1,4 +1,4 @@
<Project Sdk="Godot.NET.Sdk/4.4.0"> <Project Sdk="Godot.NET.Sdk/4.4.1">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading> <EnableDynamicLoading>true</EnableDynamicLoading>

View file

@ -13,7 +13,7 @@ region = Rect2(0, 0, 64, 64)
script = ExtResource("9_vykx5") script = ExtResource("9_vykx5")
EnemyName = &"Boss 1" EnemyName = &"Boss 1"
EnemyKey = &"BOSS_1" EnemyKey = &"BOSS_1"
PrefabPath = &"uid://dt7i3x3g5ktbl" PrefabPath = &"uid://clyrne78j3f5a"
MaxHealth = 100.0 MaxHealth = 100.0
MovementSpeed = 40.0 MovementSpeed = 40.0
Weapon = ExtResource("8_w06jt") Weapon = ExtResource("8_w06jt")

View file

@ -108,6 +108,7 @@ public partial class RogueliteRoomManager : Node2D
_seed = rng.GetSeed(); _seed = rng.GetSeed();
rng.Dispose(); rng.Dispose();
} }
GD.Print($"Seed: {_seed}"); GD.Print($"Seed: {_seed}");
} }
@ -122,9 +123,13 @@ public partial class RogueliteRoomManager : Node2D
var starterRoom = MapTheme.Rooms.Where(r => r.Type == RoomType.Starter).PickRandom(); var starterRoom = MapTheme.Rooms.Where(r => r.Type == RoomType.Starter).PickRandom();
SpawnRoom(starterRoom, origin, out var spawnedBeginRoom); SpawnRoom(starterRoom, origin, out var spawnedBeginRoom);
var randomRoomsList = RegularRooms.Shuffle(MaxRooms * 4).ToList(); var randomRoomsList = RegularRooms.Shuffle().ToList();
var randomOffshootRoomsList = OffshootRooms.Shuffle(DungeonLength * 4).ToList(); var regularRoomsQueue = new Queue<RogueliteRoomResource>().EnqueueRange(randomRoomsList);
var randomOffshootRoomsList = OffshootRooms.Shuffle().ToList();
var offshootRoomsQueue = new Queue<RogueliteRoomResource>().EnqueueRange(randomOffshootRoomsList);
var currentPos = spawnedBeginRoom.RandomBottomExit(); var currentPos = spawnedBeginRoom.RandomBottomExit();
_connections.Add(new RoomConnection(origin, currentPos + new Vector2I(0, 1))); _connections.Add(new RoomConnection(origin, currentPos + new Vector2I(0, 1)));
@ -139,10 +144,8 @@ public partial class RogueliteRoomManager : Node2D
var shuffledOffshoots = offshoots.Shuffle().ToList(); var shuffledOffshoots = offshoots.Shuffle().ToList();
var offshootsQueue = new Queue<RoomType>();
offshootsQueue.EnqueueRange(shuffledOffshoots);
// var offshootsQueue = new Queue<RoomType>();
// offshootsQueue.EnqueueRange(shuffledOffshoots);
int currentOffshoot = 0; int currentOffshoot = 0;
@ -154,14 +157,27 @@ public partial class RogueliteRoomManager : Node2D
{ {
GD.Print($"Dungeon room {i}"); GD.Print($"Dungeon room {i}");
var randRoomStartIndex = SpawnedRooms.Count(x => x.RoomResource.Type is RoomType.Regular && x.RoomResource.HasDoors(DoorDirections.North | DoorDirections.South)); // if (!regularRoomsQueue.TryDequeue(out var roomToSpawn))
// {
// GD.Print("Ran out of regular rooms, add more");
// return;
// }
var spawnedRoom = TrySpawnRoom(randomRoomsList.Take(new Range(randRoomStartIndex, randomRoomsList.Count - 1)).ToList(), // var randRoomStartIndex = SpawnedRooms.Count(x =>
// x.RoomResource.Type is RoomType.Regular &&
// x.RoomResource.HasDoors(DoorDirections.North | DoorDirections.South));
// var spawnedRoom = TrySpawnRoom(
// randomRoomsList.Take(new Range(randRoomStartIndex, randomRoomsList.Count - 1)).ToList(),
// lastRoom, Direction.Down);
var spawnedRoom = TrySpawnRoom(regularRoomsQueue,
lastRoom, Direction.Down); lastRoom, Direction.Down);
if (spawnedRoom is null) if (spawnedRoom is null)
{ {
continue; GD.Print("Abort creation");
return;
} }
if (lockNext) if (lockNext)
@ -185,18 +201,31 @@ public partial class RogueliteRoomManager : Node2D
foreach (var direction in directions) foreach (var direction in directions)
{ {
var randOffshootStartIndex = SpawnedRooms.Count(x => x.RoomResource.Type is RoomType.Regular && x.RoomResource.HasDoors(DoorDirections.West | DoorDirections.East)); // var randOffshootStartIndex = SpawnedRooms.Count(x =>
// x.RoomResource.Type is RoomType.Regular &&
// x.RoomResource.HasDoors(DoorDirections.West | DoorDirections.East));
var offshootTypeToSpawn = shuffledOffshoots[currentOffshoot % shuffledOffshoots.Count()]; //var offshootTypeToSpawn = shuffledOffshoots[currentOffshoot % shuffledOffshoots.Count()];
if (!offshootsQueue.TryDequeue(out var offshootTypeToSpawn))
{
GD.Print("Ran out of offshoot types, add more");
break;
}
int roomsInOffshot = offshootTypeToSpawn is RoomType.Secret or RoomType.Shop int roomsInOffshot = offshootTypeToSpawn is RoomType.Secret or RoomType.Shop
? 0 ? 0
: GD.RandRange(0, MaxBranchLength); : GD.RandRange(0, MaxBranchLength);
var roomsForOffshoot = randomOffshootRoomsList // var roomsForOffshoot = randomOffshootRoomsList
.Take(new Range(randOffshootStartIndex, randomOffshootRoomsList.Count - 1)).ToList(); // .Take(new Range(randOffshootStartIndex, randomOffshootRoomsList.Count - 1)).ToList();
var res = SpawnOffshoot(lastRoom, direction, offshootTypeToSpawn, roomsInOffshot, roomsForOffshoot); // This one reshuffles improperly, good for now
var endRooms =
new Queue<RogueliteRoomResource>().EnqueueRange(MapTheme.Rooms
.Where(x => x.Type == offshootTypeToSpawn).ToList());
var res = SpawnOffshoot(lastRoom, direction, offshootTypeToSpawn, roomsInOffshot, offshootRoomsQueue, endRooms);
if (res) if (res)
{ {
@ -211,7 +240,8 @@ public partial class RogueliteRoomManager : Node2D
lockNext = true; lockNext = true;
} }
if (offshootTypeToSpawn is RoomType.Key && shuffledOffshoots[currentOffshoot % shuffledOffshoots.Count()] is RoomType.Key) if (offshootTypeToSpawn is RoomType.Key &&
offshootsQueue.Peek() is RoomType.Key)
{ {
// Stop if next room is a key // Stop if next room is a key
break; break;
@ -230,7 +260,9 @@ public partial class RogueliteRoomManager : Node2D
var bossRoom = BossRooms.PickRandom(); var bossRoom = BossRooms.PickRandom();
var spawnedBossRoom = TrySpawnRoom(BossRooms.ToList(), lastRoom, Direction.Down); var bossQueue = new Queue<RogueliteRoomResource>().EnqueueRange(BossRooms.Shuffle());
var spawnedBossRoom = TrySpawnRoom(bossQueue, lastRoom, Direction.Down);
if (spawnedBossRoom is null) if (spawnedBossRoom is null)
{ {
@ -281,7 +313,7 @@ public partial class RogueliteRoomManager : Node2D
} }
} }
private RogueliteRoom TrySpawnRoom(List<RogueliteRoomResource> roomsList, RogueliteRoom lastRoom, private RogueliteRoom TrySpawnRoom(Queue<RogueliteRoomResource> roomsList, RogueliteRoom lastRoom,
Direction direction) Direction direction)
{ {
//var nextPos = originPos + new Vector2I(0, 1); //var nextPos = originPos + new Vector2I(0, 1);
@ -297,16 +329,22 @@ public partial class RogueliteRoomManager : Node2D
_ => exitPosition _ => exitPosition
}; };
var rooms = roomsList; //.Shuffle().ToList(); //var rooms = roomsList; //.Shuffle().ToList();
int tries = 0;
for (int i = 0; i < rooms.Count(); i++) while (roomsList.Count > 0 && tries < 10)
{ {
var roomToSpawn = rooms[i % rooms.Count()]; if (!roomsList.TryDequeue(out var roomToSpawn))
{
GD.Print("Ran out of regular rooms, add more");
return null;
}
var spawnedRoom = TrySpawnRoom(roomToSpawn, nextPos, direction); var spawnedRoom = TrySpawnRoom(roomToSpawn, nextPos, direction);
if (spawnedRoom is null) if (spawnedRoom is null)
{ {
GD.PrintErr($"Could not spawn room {roomToSpawn} at {nextPos}"); GD.PrintErr($"Could not spawn room {roomToSpawn} at {nextPos}");
roomsList.Enqueue(roomToSpawn);
tries++;
continue; continue;
} }
@ -384,41 +422,65 @@ public partial class RogueliteRoomManager : Node2D
} }
private bool SpawnOffshoot(RogueliteRoom lastRoom, Direction direction, RoomType offshootTypeToSpawn, private bool SpawnOffshoot(RogueliteRoom lastRoom, Direction direction, RoomType offshootTypeToSpawn,
int roomsInOffshot, List<RogueliteRoomResource> randomOffshootRoomsList) int roomsInOffshot, Queue<RogueliteRoomResource> randomOffshootRoomsList, Queue<RogueliteRoomResource> endRoomsQueue)
{ {
RogueliteRoom lastSpawnedOffshootRoom = lastRoom; RogueliteRoom lastSpawnedOffshootRoom = lastRoom;
for (int j = 0; j < roomsInOffshot; j++)
int tries = 0;
int spawned = 0;
while (randomOffshootRoomsList.Count > 0 && tries < 10 && spawned < roomsInOffshot)
{ {
var shuffledOffshootRoomsList = randomOffshootRoomsList;//.Shuffle().ToList(); var spawnedRoom = TrySpawnRoom(randomOffshootRoomsList, lastSpawnedOffshootRoom, direction);
foreach (var shuffledOffshoot in shuffledOffshootRoomsList) if (spawnedRoom is null)
{ {
var spawnedRoom = TrySpawnRoom(shuffledOffshootRoomsList, lastSpawnedOffshootRoom, direction); // GD.Print($"Could not place offshoot {shuffledOffshoot}");
// Try next in list
if (spawnedRoom is null) tries++;
{ continue;
GD.Print($"Could not place offshoot {shuffledOffshoot}");
// Try next in list
continue;
}
lastSpawnedOffshootRoom = spawnedRoom;
break;
}
// Nope no offshoot
if (lastSpawnedOffshootRoom is null)
{
return false;
} }
lastSpawnedOffshootRoom = spawnedRoom;
//roomsInOffshot++;
spawned++;
} }
if (lastSpawnedOffshootRoom is null)
{
return false;
}
// for (int j = 0; j < roomsInOffshot; j++)
// {
// var shuffledOffshootRoomsList = randomOffshootRoomsList; //.Shuffle().ToList();
//
// foreach (var shuffledOffshoot in shuffledOffshootRoomsList)
// {
// var spawnedRoom = TrySpawnRoom(shuffledOffshootRoomsList, lastSpawnedOffshootRoom, direction);
//
// if (spawnedRoom is null)
// {
// GD.Print($"Could not place offshoot {shuffledOffshoot}");
// // Try next in list
// continue;
// }
//
// lastSpawnedOffshootRoom = spawnedRoom;
// break;
// }
//
// // Nope no offshoot
// if (lastSpawnedOffshootRoom is null)
// {
// return false;
// }
// }
// Offshoot over // Offshoot over
// Spawn final room // Spawn final room
// var finalRoomToSpawn = Rooms.Where(x => x.Type == offshootTypeToSpawn).PickRandom(); // var finalRoomToSpawn = Rooms.Where(x => x.Type == offshootTypeToSpawn).PickRandom();
var spawnedFinalRoom = TrySpawnRoom(MapTheme.Rooms.Where(x => x.Type == offshootTypeToSpawn).ToList(), var spawnedFinalRoom = TrySpawnRoom(endRoomsQueue,
lastSpawnedOffshootRoom, direction); lastSpawnedOffshootRoom, direction);
if (spawnedFinalRoom is null) if (spawnedFinalRoom is null)