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); return this; } 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 or RoomDirection.South => new Vector2I(marker.WallIndex, 0), RoomDirection.East or 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; bool connected = connectionChecker.Invoke(neighborPos); if (connected) { var door = this.CreateChild(DoorPrefab, marker.GlobalPosition); door.State = DoorState.Open; } else { var wall = this.CreateChild(WallPrefab, marker.GlobalPosition); } // 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); } } }