From 4d2b58e234ac2a5766e5d1ebc5d3292da321ab73 Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 22 Apr 2025 13:50:26 +0200 Subject: [PATCH] Fix for x offsets --- Scenes/Maps/Roguelike.tscn | 1 + Scripts/Controllers/RogueliteRoom.cs | 5 +- Scripts/Controllers/RogueliteRoomManager.cs | 115 +++++++++++++----- .../Roguelite/RogueliteRoomResource.cs | 15 ++- 4 files changed, 103 insertions(+), 33 deletions(-) diff --git a/Scenes/Maps/Roguelike.tscn b/Scenes/Maps/Roguelike.tscn index 8b0de07d..5d797332 100644 --- a/Scenes/Maps/Roguelike.tscn +++ b/Scenes/Maps/Roguelike.tscn @@ -44,6 +44,7 @@ script = ExtResource("4_jtlua") Rooms = Array[Object]([ExtResource("5_gwtv6"), ExtResource("6_gwtv6"), ExtResource("7_wbqvu"), ExtResource("8_3fyis"), ExtResource("9_go1yg"), ExtResource("5_pfafs"), ExtResource("11_68lig"), ExtResource("12_83bvc"), ExtResource("13_y651a"), ExtResource("14_vhvs2"), ExtResource("15_6gk3e"), ExtResource("16_4gy5m"), ExtResource("17_td7hx"), ExtResource("18_2lxq3"), ExtResource("19_6ahuq"), ExtResource("20_xrp0h")]) DungeonLength = 6 MaxBranchLength = 2 +Seed = 4 [node name="CameraController" type="Camera2D" parent="."] process_mode = 1 diff --git a/Scripts/Controllers/RogueliteRoom.cs b/Scripts/Controllers/RogueliteRoom.cs index 2511612e..77217f8e 100644 --- a/Scripts/Controllers/RogueliteRoom.cs +++ b/Scripts/Controllers/RogueliteRoom.cs @@ -17,7 +17,10 @@ public partial class RogueliteRoom : Node2D 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); + public Vector2I RandomBottomExit() + { + return 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; } diff --git a/Scripts/Controllers/RogueliteRoomManager.cs b/Scripts/Controllers/RogueliteRoomManager.cs index 5fd0b5c1..4119547f 100644 --- a/Scripts/Controllers/RogueliteRoomManager.cs +++ b/Scripts/Controllers/RogueliteRoomManager.cs @@ -78,8 +78,7 @@ public partial class RogueliteRoomManager : Node2D x.Type is RoomType.Regular && x.HasDoors(DoorDirections.East | DoorDirections.West)); private IEnumerable BossRooms => Rooms.Where(x => x.Type is RoomType.Boss); - - private List _mainPath = new(); + private List _connections = new(); public List Connections => _connections; @@ -94,13 +93,12 @@ public partial class RogueliteRoomManager : Node2D Vector2I origin = Vector2I.Zero; var starterRoom = Rooms.Where(r => r.Type == RoomType.Starter).PickRandom(); SpawnRoom(starterRoom, origin, out var spawnedBeginRoom); - _mainPath.Add(origin); var randomRoomsList = RegularRooms.Shuffle(DungeonLength).ToList(); var randomOffshootRoomsList = OffshootRooms.Shuffle(MaxBranchLength).ToList(); - var currentPos = spawnedBeginRoom.RandomBottomExit; + var currentPos = spawnedBeginRoom.RandomBottomExit(); _connections.Add(new RoomConnection(origin, currentPos + new Vector2I(0, 1))); Vector2I nextPos; @@ -115,39 +113,55 @@ public partial class RogueliteRoomManager : Node2D var shuffledOffshoots = offshoots.Shuffle().ToList(); int currentOffshoot = 0; - + 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 % randomRoomsList.Count]; + var spawnedRoom = TrySpawnRoom(randomRoomsList, currentPos); - // We're already in the new room position, we do not care about previous anymore - var offset = 0; - - // Place it at a random X position - if (roomToSpawn.Size.X > 1) + if (spawnedRoom is null) { - offset -= GD.RandRange(0, roomToSpawn.Size.X - 1); - } - - nextPos += new Vector2I(offset, 0); - - //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 {roomToSpawn} at {nextPos}"); - //DungeonLength += 1; continue; } + + // + // nextPos = currentPos + new Vector2I(0, 1); + // + // var roomToSpawn = randomRoomsList[randRoomIndex % randomRoomsList.Count]; + // + // var spawnedRoom = TrySpawnRoom(roomToSpawn, nextPos); + // if (spawnedRoom is null) + // { + // // Failed, try another room + // DungeonLength += 1; + // randRoomIndex++; + // continue; + // } + // + // + // var offset = 0; + // + // // Place it at a random X position + // if (roomToSpawn.Size.X > 1) + // { + // offset -= GD.RandRange(0, roomToSpawn.Size.X - 1); + // } + // + // nextPos += new Vector2I(offset, 0); + // + // //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 {roomToSpawn} at {nextPos}"); + // //DungeonLength += 1; + // continue; + // } + - _mainPath.Add(nextPos); - - nextPos = spawnedRoom.RandomBottomExit; + nextPos = spawnedRoom.RandomBottomExit(); GD.Print($"Next pos is now: {nextPos}"); @@ -202,8 +216,7 @@ public partial class RogueliteRoomManager : Node2D currentOffshoot++; break; } - - // If it got here and couldn't spawn the offshoot, do not increase counter + } // Offshoot over @@ -229,7 +242,6 @@ public partial class RogueliteRoomManager : Node2D if (SpawnRoom(bossRoom, nextPos, out var spawnedBossRoom)) { - _mainPath.Add(nextPos); if (bossRoom.Size.Y > 1) { @@ -259,6 +271,47 @@ public partial class RogueliteRoomManager : Node2D //CallDeferred(MethodName.OpenStartDoorsDeferred, spawnedBeginRoom); } + private RogueliteRoom TrySpawnRoom(List roomsList, Vector2I originPos) + { + var nextPos = originPos + new Vector2I(0, 1); + var rooms = roomsList.Shuffle().ToList(); + + for (int i = 0; i < rooms.Count(); i++) + { + var roomToSpawn = rooms[i % rooms.Count()]; + + var spawnedRoom = TrySpawnRoom(roomToSpawn, nextPos); + if (spawnedRoom is null) + { + GD.PrintErr($"Could not spawn room {roomToSpawn} at {nextPos}"); + continue; + } + return spawnedRoom; + } + GD.PrintErr($"Could not spawn room at all at {nextPos}"); + return null; + } + + private RogueliteRoom TrySpawnRoom(RogueliteRoomResource roomToSpawn, Vector2I nextPos) + { + var offsets = roomToSpawn.GetTopRoomOffsets(nextPos).Shuffle(); + + foreach (var offset in offsets) + { + if (!SpawnRoom(roomToSpawn, offset, out var spawnedRoom)) + { + GD.PrintErr($"Could not spawn room {roomToSpawn} at {nextPos}"); + //DungeonLength += 1; + } + else + { + return spawnedRoom; + } + } + + return null; + } + private Vector2I GetNextPosition(Vector2I current, Vector2I target) { var possibleDirs = new List(); diff --git a/Scripts/Resources/Roguelite/RogueliteRoomResource.cs b/Scripts/Resources/Roguelite/RogueliteRoomResource.cs index 627e5253..7550bcf7 100644 --- a/Scripts/Resources/Roguelite/RogueliteRoomResource.cs +++ b/Scripts/Resources/Roguelite/RogueliteRoomResource.cs @@ -1,4 +1,5 @@ -using Cirno.Scripts.Enums; +using System.Collections.Generic; +using Cirno.Scripts.Enums; using Godot; using Godot.Collections; @@ -24,4 +25,16 @@ public partial class RogueliteRoomResource : Resource { return $"{RoomName} {Type} {Size.X}x{Size.Y}"; } + + public List GetTopRoomOffsets(Vector2I gridPosition) + { + List offsets = []; + + for (int i = 0; i < Size.X; i++) + { + offsets.Add(new Vector2I(gridPosition.X - i, gridPosition.Y)); + } + + return offsets; + } } \ No newline at end of file