mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 11:15:33 +00:00
Use queues for room generation
This commit is contained in:
parent
4705fca148
commit
7482cfa496
3 changed files with 128 additions and 66 deletions
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Godot.NET.Sdk/4.4.0">
|
||||
<Project Sdk="Godot.NET.Sdk/4.4.1">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ region = Rect2(0, 0, 64, 64)
|
|||
script = ExtResource("9_vykx5")
|
||||
EnemyName = &"Boss 1"
|
||||
EnemyKey = &"BOSS_1"
|
||||
PrefabPath = &"uid://dt7i3x3g5ktbl"
|
||||
PrefabPath = &"uid://clyrne78j3f5a"
|
||||
MaxHealth = 100.0
|
||||
MovementSpeed = 40.0
|
||||
Weapon = ExtResource("8_w06jt")
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace Cirno.Scripts.Controllers;
|
|||
public partial class RogueliteRoomManager : Node2D
|
||||
{
|
||||
//[Export] public Array<RogueliteRoomResource> Rooms { get; set; }
|
||||
|
||||
|
||||
[Export] public RogueliteMapTheme MapTheme { get; set; }
|
||||
|
||||
//private Godot.Collections.Dictionary<Vector2I, RogueliteRoomResource> _grid = new();
|
||||
|
|
@ -44,8 +44,8 @@ public partial class RogueliteRoomManager : Node2D
|
|||
[Export] public int MaxShops = 1;
|
||||
[Export] public string ManualSeed { get; private set; }
|
||||
|
||||
private ulong _seed;
|
||||
|
||||
private ulong _seed;
|
||||
|
||||
[Export] public Vector2I TileSize { get; set; } = new Vector2I(16, 16);
|
||||
[Export] public Vector2I RoomSizeInTiles { get; set; } = new Vector2I(20, 10);
|
||||
|
||||
|
|
@ -108,13 +108,14 @@ public partial class RogueliteRoomManager : Node2D
|
|||
_seed = rng.GetSeed();
|
||||
rng.Dispose();
|
||||
}
|
||||
|
||||
GD.Print($"Seed: {_seed}");
|
||||
}
|
||||
|
||||
|
||||
private void GenerateStraightLineDungeon()
|
||||
{
|
||||
SetSeed();
|
||||
|
||||
|
||||
MapTheme.MakeChestLootQueue();
|
||||
MapTheme.TeleportersList = [];
|
||||
|
||||
|
|
@ -122,9 +123,13 @@ public partial class RogueliteRoomManager : Node2D
|
|||
var starterRoom = MapTheme.Rooms.Where(r => r.Type == RoomType.Starter).PickRandom();
|
||||
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();
|
||||
_connections.Add(new RoomConnection(origin, currentPos + new Vector2I(0, 1)));
|
||||
|
|
@ -139,29 +144,40 @@ public partial class RogueliteRoomManager : Node2D
|
|||
|
||||
var shuffledOffshoots = offshoots.Shuffle().ToList();
|
||||
|
||||
|
||||
|
||||
// var offshootsQueue = new Queue<RoomType>();
|
||||
// offshootsQueue.EnqueueRange(shuffledOffshoots);
|
||||
|
||||
var offshootsQueue = new Queue<RoomType>();
|
||||
offshootsQueue.EnqueueRange(shuffledOffshoots);
|
||||
|
||||
int currentOffshoot = 0;
|
||||
|
||||
RogueliteRoom lastRoom = spawnedBeginRoom;
|
||||
|
||||
bool lockNext = false;
|
||||
|
||||
|
||||
for (int i = 0; i < DungeonLength; 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);
|
||||
|
||||
if (spawnedRoom is null)
|
||||
{
|
||||
continue;
|
||||
GD.Print("Abort creation");
|
||||
return;
|
||||
}
|
||||
|
||||
if (lockNext)
|
||||
|
|
@ -171,9 +187,9 @@ public partial class RogueliteRoomManager : Node2D
|
|||
}
|
||||
|
||||
lastRoom = spawnedRoom;
|
||||
|
||||
|
||||
// Spawn offshoot here
|
||||
|
||||
|
||||
// Roll whether to go left or right, if direction is full go the other, if both are full do not spawn
|
||||
|
||||
var directions = new List<Direction>();
|
||||
|
|
@ -182,27 +198,40 @@ public partial class RogueliteRoomManager : Node2D
|
|||
if (lastRoom.RoomResource.DoorDirections.HasFlag(DoorDirections.West)) directions.Add(Direction.Left);
|
||||
|
||||
directions = directions.Shuffle().ToList();
|
||||
|
||||
|
||||
foreach (var direction in directions)
|
||||
{
|
||||
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 randOffshootStartIndex = SpawnedRooms.Count(x =>
|
||||
// x.RoomResource.Type is RoomType.Regular &&
|
||||
// x.RoomResource.HasDoors(DoorDirections.West | DoorDirections.East));
|
||||
|
||||
//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
|
||||
? 0
|
||||
: GD.RandRange(0, MaxBranchLength);
|
||||
|
||||
var roomsForOffshoot = randomOffshootRoomsList
|
||||
.Take(new Range(randOffshootStartIndex, randomOffshootRoomsList.Count - 1)).ToList();
|
||||
// var roomsForOffshoot = randomOffshootRoomsList
|
||||
// .Take(new Range(randOffshootStartIndex, randomOffshootRoomsList.Count - 1)).ToList();
|
||||
|
||||
// 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, roomsForOffshoot);
|
||||
var res = SpawnOffshoot(lastRoom, direction, offshootTypeToSpawn, roomsInOffshot, offshootRoomsQueue, endRooms);
|
||||
|
||||
if (res)
|
||||
{
|
||||
currentOffshoot++;
|
||||
// Try to spawn one the other direction too
|
||||
|
||||
|
||||
// If key, lock the last connection
|
||||
if (offshootTypeToSpawn is RoomType.Key)
|
||||
{
|
||||
|
|
@ -210,8 +239,9 @@ public partial class RogueliteRoomManager : Node2D
|
|||
// Need to lock the next connection
|
||||
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
|
||||
break;
|
||||
|
|
@ -230,13 +260,15 @@ public partial class RogueliteRoomManager : Node2D
|
|||
|
||||
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)
|
||||
{
|
||||
GD.PrintErr($"Could not spawn boss room {bossRoom}");
|
||||
}
|
||||
|
||||
|
||||
if (lockNext)
|
||||
{
|
||||
_connections.Last().IsLocked = true;
|
||||
|
|
@ -253,7 +285,7 @@ public partial class RogueliteRoomManager : Node2D
|
|||
//return _roomGrid.ContainsKey(neighborPos);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Debug teleporter matching
|
||||
MatchBossTeleporter();
|
||||
|
||||
|
|
@ -265,13 +297,13 @@ public partial class RogueliteRoomManager : Node2D
|
|||
private void MatchBossTeleporter()
|
||||
{
|
||||
var bossTeleporters = MapTheme.TeleportersList.Where(x => x.Type is TeleporterMarkerType.Boss);
|
||||
|
||||
|
||||
foreach (var teleporterMarker in bossTeleporters)
|
||||
{
|
||||
var bossRoom = SpawnedRooms.FirstOrDefault(x => x.RoomResource.Type is RoomType.Boss);
|
||||
|
||||
if (bossRoom is null) return;
|
||||
|
||||
|
||||
var teleporter = bossRoom.Teleporters.FirstOrDefault(x =>
|
||||
x.Type is TeleporterMarkerType.Receiver or TeleporterMarkerType.InvisibleReceiver);
|
||||
|
||||
|
|
@ -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)
|
||||
{
|
||||
//var nextPos = originPos + new Vector2I(0, 1);
|
||||
|
|
@ -297,16 +329,22 @@ public partial class RogueliteRoomManager : Node2D
|
|||
_ => exitPosition
|
||||
};
|
||||
|
||||
var rooms = roomsList; //.Shuffle().ToList();
|
||||
|
||||
for (int i = 0; i < rooms.Count(); i++)
|
||||
//var rooms = roomsList; //.Shuffle().ToList();
|
||||
int tries = 0;
|
||||
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);
|
||||
if (spawnedRoom is null)
|
||||
{
|
||||
GD.PrintErr($"Could not spawn room {roomToSpawn} at {nextPos}");
|
||||
roomsList.Enqueue(roomToSpawn);
|
||||
tries++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -384,41 +422,65 @@ public partial class RogueliteRoomManager : Node2D
|
|||
}
|
||||
|
||||
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;
|
||||
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();
|
||||
|
||||
foreach (var shuffledOffshoot in shuffledOffshootRoomsList)
|
||||
var spawnedRoom = TrySpawnRoom(randomOffshootRoomsList, lastSpawnedOffshootRoom, direction);
|
||||
|
||||
if (spawnedRoom is null)
|
||||
{
|
||||
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;
|
||||
// GD.Print($"Could not place offshoot {shuffledOffshoot}");
|
||||
// Try next in list
|
||||
tries++;
|
||||
continue;
|
||||
}
|
||||
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
|
||||
|
||||
// Spawn final room
|
||||
// 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);
|
||||
|
||||
if (spawnedFinalRoom is null)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue