cirnogodot/Scripts/Controllers/RogueliteRoom.cs

99 lines
3.2 KiB
C#
Raw Normal View History

2025-04-11 18:39:39 +02:00
using System;
using System.Linq;
2025-04-11 15:53:59 +02:00
using Cirno.Scripts.Resources;
using Cirno.Scripts.Resources.Roguelite;
2025-04-10 19:04:06 +02:00
using Godot;
2025-04-11 15:53:59 +02:00
using Godot.Collections;
2025-04-10 19:04:06 +02:00
namespace Cirno.Scripts.Controllers;
public partial class RogueliteRoom : Node2D
{
[Export] public RogueliteRoomResource RoomResource { get; set; }
2025-04-14 16:50:58 +02:00
2025-04-11 18:39:39 +02:00
public Vector2I GridPosition { get; set; } // Set by dungeon manager
2025-04-14 16:50:58 +02:00
2025-04-11 18:39:39 +02:00
[Export] public PackedScene DoorPrefab { get; private set; }
2025-04-14 16:50:58 +02:00
[Export] public PackedScene WallPrefab { get; private set; }
2025-04-11 18:39:39 +02:00
private static readonly Dictionary<string, Vector2I> DirectionMap = new()
{
{ "North", new Vector2I(0, -1) },
{ "South", new Vector2I(0, 1) },
2025-04-14 16:50:58 +02:00
{ "East", new Vector2I(1, 0) },
{ "West", new Vector2I(-1, 0) },
2025-04-11 18:39:39 +02:00
};
2025-04-11 15:53:59 +02:00
2025-04-14 16:50:58 +02:00
private Array<EnemyResource> SpawnableEnemies => RoomResource.SpawnableEnemies;
2025-04-11 15:53:59 +02:00
2025-04-14 16:50:58 +02:00
public RogueliteRoom Spawn()
2025-04-11 18:39:39 +02:00
{
SpawnEnemies();
2025-04-14 16:50:58 +02:00
//HandleDoors(connectionChecker);
2025-04-11 18:39:39 +02:00
return this;
}
2025-04-14 16:50:58 +02:00
public void HandleDoors(Func<Vector2I, bool> connectionChecker)
2025-04-11 18:39:39 +02:00
{
if (!HasNode("Doors")) return;
var doorsNode = GetNode("Doors");
foreach (Node child in doorsNode.GetChildren())
{
if (child is not DoorMarker marker) continue;
2025-04-14 16:50:58 +02:00
2025-04-11 18:39:39 +02:00
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);
2025-04-14 16:50:58 +02:00
if (connected)
{
var door = this.CreateChild<Door>(DoorPrefab, marker.GlobalPosition);
2025-04-11 18:39:39 +02:00
2025-04-14 16:50:58 +02:00
door.State = DoorState.Open;
}
else
{
var wall = this.CreateChild<Node2D>(WallPrefab, marker.GlobalPosition);
}
2025-04-11 18:39:39 +02:00
// PackedScene prefab = hasConnection
// ? GD.Load<PackedScene>("res://Prefabs/Door.tscn")
// : GD.Load<PackedScene>("res://Prefabs/Wall.tscn");
//
// var instance = prefab.Instantiate<Node2D>();
// AddChild(instance);
// instance.GlobalPosition = ((Node2D)child).GlobalPosition;
// instance.Rotation = ((Node2D)child).GlobalRotation;
}
}
private void SpawnEnemies()
2025-04-11 15:53:59 +02:00
{
2025-04-11 18:39:39 +02:00
if (SpawnableEnemies is null || !SpawnableEnemies.Any()) return;
2025-04-14 16:50:58 +02:00
2025-04-11 15:53:59 +02:00
var enemySpawners = this.GetNode("EnemySpawners").GetChildren().Cast<Marker2D>();
foreach (var spawner in enemySpawners)
{
var index = GD.RandRange(0, SpawnableEnemies.Count - 1);
2025-04-14 16:50:58 +02:00
2025-04-11 15:53:59 +02:00
var e = SpawnableEnemies[index];
2025-04-14 16:50:58 +02:00
2025-04-11 15:53:59 +02:00
var enemyScene = GD.Load<PackedScene>(e.PrefabPath);
var spawnedEnemy = spawner.CreateChild<Node2D>(enemyScene);
}
}
2025-04-10 19:04:06 +02:00
}