using System; using System.Linq; using Cirno.Scripts.Resources; using Cirno.Scripts.Resources.Roguelite; using Godot; using Godot.Collections; namespace Cirno.Scripts.Controllers; public partial class RogueliteRoom : Node2D { [Export] public RogueliteRoomResource RoomResource { get; set; } public Vector2I GridPosition { get; set; } // Set by dungeon manager [Export] public PackedScene DoorPrefab { get; private set; } [Export] public PackedScene WallPrefab { get; private set; } private static readonly Dictionary DirectionMap = new() { { "North", new Vector2I(0, -1) }, { "South", new Vector2I(0, 1) }, { "East", new Vector2I(1, 0) }, { "West", new Vector2I(-1, 0) }, }; private Array SpawnableEnemies => RoomResource.SpawnableEnemies; public RogueliteRoom Spawn() { SpawnEnemies(); //HandleDoors(connectionChecker); AddDebugLabel(); return this; } private void AddDebugLabel() { for (int i = 0; i < RoomResource.Size.X; i++) { for (int j = 0; j < RoomResource.Size.Y; j++) { var label = new Label(); label.Text = $"{GridPosition + new Vector2I(i, j)}"; label.ZIndex = 11; label.Position = (new Vector2(i, j) * new Vector2(320, 160)) + new Vector2(160, 80); this.AddChild(label); } } } public void HandleDoors(Func connectionChecker) { if (!HasNode("Doors")) return; var doorsNode = GetNode("Doors"); foreach (Node child in doorsNode.GetChildren()) { if (child is not DoorMarker marker) continue; var baseDir = marker.GetWorldDirection(); // WallIndex determines the offset *along* the edge of the room Vector2I offset = marker.Direction switch { RoomDirection.North => new Vector2I(marker.WallIndex, 0), RoomDirection.South => new Vector2I(marker.WallIndex, RoomResource.Size.Y - 1), RoomDirection.East => new Vector2I(RoomResource.Size.X - 1, marker.WallIndex), RoomDirection.West => new Vector2I(0, marker.WallIndex), _ => Vector2I.Zero }; // Combine GridPosition + offset to locate where this door aligns Vector2I doorEdge = GridPosition + offset; Vector2I neighborPos = doorEdge + baseDir; var connection = connectionChecker.Invoke(doorEdge, neighborPos); var connected = connection is not null; if (connected) { var door = this.CreateChild(DoorPrefab, marker.GlobalPosition); door.State = DoorState.Closed; // var label = new Label(); // label.Text = $"Door Edge: {doorEdge}, {connection}"; // label.ZIndex = 10; // // door.AddChild(label); } else { var wall = this.CreateChild(WallPrefab, marker.GlobalPosition); // var label = new Label(); // label.Text = $"Door Edge: {doorEdge}, Neighbor: {neighborPos}"; // label.ZIndex = 10; // // marker.AddChild(label); } // PackedScene prefab = hasConnection // ? GD.Load("res://Prefabs/Door.tscn") // : GD.Load("res://Prefabs/Wall.tscn"); // // var instance = prefab.Instantiate(); // AddChild(instance); // instance.GlobalPosition = ((Node2D)child).GlobalPosition; // instance.Rotation = ((Node2D)child).GlobalRotation; } } private void SpawnEnemies() { if (SpawnableEnemies is null || !SpawnableEnemies.Any()) return; var enemySpawners = this.GetNode("EnemySpawners").GetChildren().Cast(); foreach (var spawner in enemySpawners) { var index = GD.RandRange(0, SpawnableEnemies.Count - 1); var e = SpawnableEnemies[index]; var enemyScene = GD.Load(e.PrefabPath); var spawnedEnemy = spawner.CreateChild(enemyScene); } } }