mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 11:15:33 +00:00
Door connections
This commit is contained in:
parent
cae1f99949
commit
700be1e207
11 changed files with 127 additions and 149 deletions
|
|
@ -1,5 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Cirno.Scripts.Components.FSM.Enemy;
|
||||
using Cirno.Scripts.Resources;
|
||||
using Cirno.Scripts.Resources.Roguelite;
|
||||
using Godot;
|
||||
|
|
@ -16,7 +18,7 @@ public partial class RogueliteRoom : Node2D
|
|||
[Export] public PackedScene DoorPrefab { get; private set; }
|
||||
[Export] public PackedScene WallPrefab { get; private set; }
|
||||
|
||||
private static readonly Dictionary<string, Vector2I> DirectionMap = new()
|
||||
private static readonly Godot.Collections.Dictionary<string, Vector2I> DirectionMap = new()
|
||||
{
|
||||
{ "North", new Vector2I(0, -1) },
|
||||
{ "South", new Vector2I(0, 1) },
|
||||
|
|
@ -24,6 +26,10 @@ public partial class RogueliteRoom : Node2D
|
|||
{ "West", new Vector2I(-1, 0) },
|
||||
};
|
||||
|
||||
private List<Door> _doors = [];
|
||||
private List<RoomConnection> _connections = [];
|
||||
private List<EnemyFSMProxy> _enemies = [];
|
||||
|
||||
private Array<EnemyResource> SpawnableEnemies => RoomResource.SpawnableEnemies;
|
||||
|
||||
public RogueliteRoom Spawn()
|
||||
|
|
@ -84,6 +90,15 @@ public partial class RogueliteRoom : Node2D
|
|||
|
||||
door.State = DoorState.Closed;
|
||||
|
||||
_doors.Add(door);
|
||||
|
||||
if (connection.FromDoor is null) connection.FromDoor = door;
|
||||
else if (connection.ToDoor is null) connection.ToDoor = door;
|
||||
else
|
||||
GD.Print("Door connection was full");
|
||||
|
||||
_connections.Add(connection);
|
||||
|
||||
// var label = new Label();
|
||||
// label.Text = $"Door Edge: {doorEdge}, {connection}";
|
||||
// label.ZIndex = 10;
|
||||
|
|
@ -100,15 +115,7 @@ public partial class RogueliteRoom : Node2D
|
|||
//
|
||||
// marker.AddChild(label);
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +132,59 @@ public partial class RogueliteRoom : Node2D
|
|||
var e = SpawnableEnemies[index];
|
||||
|
||||
var enemyScene = GD.Load<PackedScene>(e.PrefabPath);
|
||||
var spawnedEnemy = spawner.CreateChild<Node2D>(enemyScene);
|
||||
var spawnedEnemy = spawner.CreateChild<EnemyFSMProxy>(enemyScene);
|
||||
|
||||
_enemies.Add(spawnedEnemy);
|
||||
|
||||
spawnedEnemy.Death += SpawnedEnemyOnDeath;
|
||||
}
|
||||
}
|
||||
|
||||
private void SpawnedEnemyOnDeath(EnemyFSMProxy enemy)
|
||||
{
|
||||
enemy.Death -= SpawnedEnemyOnDeath;
|
||||
_enemies.Remove(enemy);
|
||||
|
||||
if (_enemies.Count == 0)
|
||||
{
|
||||
OpenDoors();
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenDoors()
|
||||
{
|
||||
foreach (var connection in _connections)
|
||||
{
|
||||
connection.FromDoor?.Activate(ActivationType.Open);
|
||||
connection.ToDoor?.Activate(ActivationType.Open);
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseDoors()
|
||||
{
|
||||
foreach (var connection in _connections)
|
||||
{
|
||||
connection.FromDoor?.Activate(ActivationType.Close);
|
||||
connection.ToDoor?.Activate(ActivationType.Close);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRoomEntered(Area2D area)
|
||||
{
|
||||
if (area is not InteractionController player) return;
|
||||
|
||||
if (_enemies.Count <= 0)
|
||||
{
|
||||
OpenDoors();
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseDoors();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRoomExited(Area2D area)
|
||||
{
|
||||
if (area is not InteractionController player) return;
|
||||
}
|
||||
}
|
||||
|
|
@ -87,9 +87,9 @@ public partial class RogueliteRoomManager : Node2D
|
|||
|
||||
Vector2I origin = Vector2I.Zero;
|
||||
var starterRoom = Rooms.Where(r => r.Type == RoomType.Starter).PickRandom();
|
||||
SpawnRoom(starterRoom, origin);
|
||||
SpawnRoom(starterRoom, origin, out var spawnedBeginRoom);
|
||||
_mainPath.Add(origin);
|
||||
|
||||
|
||||
var randomRoomsList = RegularRooms.Shuffle(DungeonLength).ToList();
|
||||
|
||||
var currentPos = origin;
|
||||
|
|
@ -120,7 +120,7 @@ public partial class RogueliteRoomManager : Node2D
|
|||
|
||||
//var posWithOffset = nextPos + new Vector2I(offset, 0);
|
||||
|
||||
if (!SpawnRoom(roomToSpawn, nextPos))
|
||||
if (!SpawnRoom(roomToSpawn, nextPos, out var spawnedRoom))
|
||||
{
|
||||
GD.PrintErr("Could not spawn room");
|
||||
break;
|
||||
|
|
@ -153,7 +153,7 @@ public partial class RogueliteRoomManager : Node2D
|
|||
|
||||
var bossRoom = BossRooms.PickRandom();
|
||||
|
||||
if (SpawnRoom(bossRoom, nextPos))
|
||||
if (SpawnRoom(bossRoom, nextPos, out var spawnedBossRoom))
|
||||
{
|
||||
_mainPath.Add(nextPos);
|
||||
|
||||
|
|
@ -175,136 +175,17 @@ public partial class RogueliteRoomManager : Node2D
|
|||
room.HandleDoors((doorEdge, pos) =>
|
||||
{
|
||||
//var neighborPos = room.GridPosition + pos;
|
||||
return _connections.FirstOrDefault(x => (x.From == doorEdge && x.To == pos) || (x.From == pos && x.To == doorEdge));
|
||||
return _connections.FirstOrDefault(x =>
|
||||
(x.From == doorEdge && x.To == pos) || (x.From == pos && x.To == doorEdge));
|
||||
//return _roomGrid.ContainsKey(neighborPos);
|
||||
});
|
||||
}
|
||||
|
||||
EmitSignalMapCreated();
|
||||
|
||||
//CallDeferred(MethodName.OpenStartDoorsDeferred, spawnedBeginRoom);
|
||||
}
|
||||
|
||||
private void GenerateDungeon()
|
||||
{
|
||||
Vector2I origin = Vector2I.Zero;
|
||||
var starterRoom = Rooms.Where(r => r.Type == RoomType.Starter).PickRandom();
|
||||
SpawnRoom(starterRoom, origin);
|
||||
_mainPath.Add(origin);
|
||||
|
||||
var currentPos = origin;
|
||||
|
||||
// 🔐 Reserve boss room position
|
||||
var bossRoom = BossRooms.FirstOrDefault();
|
||||
Vector2I? bossTargetPos = FindValidBossRoomLocation(currentPos);
|
||||
|
||||
if (bossRoom == null || bossTargetPos == null)
|
||||
{
|
||||
GD.PrintErr("Failed to place boss room!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate path to boss room
|
||||
while (currentPos != bossTargetPos.Value)
|
||||
{
|
||||
var nextPos = GetNextPosition(currentPos, bossTargetPos.Value);
|
||||
if (!SpawnRoom(Rooms.Where(x => x.Type == RoomType.Regular).PickRandom(), nextPos)) break;
|
||||
|
||||
_mainPath.Add(nextPos);
|
||||
_connections.Add(new RoomConnection(currentPos, nextPos));
|
||||
currentPos = nextPos;
|
||||
}
|
||||
|
||||
// Place the boss room
|
||||
if (SpawnRoom(bossRoom, bossTargetPos.Value))
|
||||
{
|
||||
_mainPath.Add(bossTargetPos.Value);
|
||||
_connections.Add(new RoomConnection(currentPos, bossTargetPos.Value));
|
||||
}
|
||||
}
|
||||
|
||||
// private void SpawnRoomsBinaryTree()
|
||||
// {
|
||||
// var directions = new List<Vector2I>
|
||||
// {
|
||||
// new Vector2I(0, -1), // North
|
||||
// new Vector2I(0, 1), // South
|
||||
// new Vector2I(1, 0), // East
|
||||
// new Vector2I(-1, 0), // West
|
||||
// };
|
||||
//
|
||||
// //var origin = Vector2I.Zero;
|
||||
// var tileSize = new Vector2(16, 16);
|
||||
// var gridRoomSizeInTiles = new Vector2(20, 10);
|
||||
//
|
||||
// var starterRooms = StarterRooms.ToList();
|
||||
// var regularRooms = RegularRooms.ToList();
|
||||
// var bossRooms = BossRooms.ToList();
|
||||
// var starterRoom = starterRooms[GD.RandRange(0, starterRooms.Count - 1)];
|
||||
//
|
||||
// var spawnedStartRoom = SpawnRoom(starterRoom, SpawnOrigin);
|
||||
//
|
||||
// Vector2I currentPos = SpawnOrigin;
|
||||
//
|
||||
// //MarkRoom(SpawnOrigin, starterRoom.Size, starterRoom);
|
||||
//
|
||||
// for (int i = 0; i < DungeonLength - 2; i++)
|
||||
// {
|
||||
// var nextPos = GetNextPosition(currentPos);
|
||||
// if (nextPos == currentPos) break;
|
||||
//
|
||||
// var room = regularRooms[GD.RandRange(0, regularRooms.Count - 1)];
|
||||
// if (!SpawnRoom(room, nextPos)) break; // Skip on overlap
|
||||
//
|
||||
// _mainPath.Add(nextPos);
|
||||
// _connections.Add(new RoomConnection(currentPos, nextPos));
|
||||
// currentPos = nextPos;
|
||||
// }
|
||||
//
|
||||
// // Place Boss Room
|
||||
//
|
||||
// var bossRoom = bossRooms[GD.RandRange(0, bossRooms.Count - 1)];
|
||||
// var bossPos = GetNextPosition(currentPos);
|
||||
// if (!SpawnRoom(bossRoom, bossPos)) break; // Skip on overlap
|
||||
// SpawnRoom(bossRoom, bossPos);
|
||||
// _mainPath.Add(bossPos);
|
||||
// _connections.Add(new RoomConnection(currentPos, bossPos));
|
||||
//
|
||||
// // Place Shop and Secret Rooms
|
||||
// //PlaceSpecialRoom(RoomType.Shop);
|
||||
// //PlaceSpecialRoom(RoomType.Secret);
|
||||
//
|
||||
// // Optionally, add branches
|
||||
// for (int i = 0; i < MaxBranches; i++)
|
||||
// {
|
||||
// var branchStart = _mainPath[GD.RandRange(0, _mainPath.Count -1)];
|
||||
// var branchLength = GD.RandRange(1, MaxBranchLength);
|
||||
// //_random.Next(1, MaxBranchLength + 1);
|
||||
// var branchPos = branchStart;
|
||||
//
|
||||
// for (int j = 0; j < branchLength; j++)
|
||||
// {
|
||||
// var nextPos = GetNextPosition(branchPos);
|
||||
// if (_roomGrid.ContainsKey(nextPos)) break;
|
||||
//
|
||||
// var room = regularRooms[GD.RandRange(0,regularRooms.Count -1)];
|
||||
//
|
||||
// SpawnRoom(room, nextPos);
|
||||
// _connections.Add(new RoomConnection(branchPos, nextPos));
|
||||
// branchPos = nextPos;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // Spawn doors and walls
|
||||
// foreach (var roomEntry in _roomGrid)
|
||||
// {
|
||||
// var room = roomEntry.Value;
|
||||
// room.HandleDoors(pos =>
|
||||
// {
|
||||
// var neighborPos = room.GridPosition + pos;
|
||||
// return _roomGrid.ContainsKey(neighborPos);
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
private Vector2I? FindValidBossRoomLocation(Vector2I from, int maxSteps = 10)
|
||||
{
|
||||
var directions = new List<Vector2I> { Vector2I.Right, Vector2I.Left, Vector2I.Up, Vector2I.Down };
|
||||
|
|
@ -361,10 +242,13 @@ public partial class RogueliteRoomManager : Node2D
|
|||
GameManager.Instance.RebakeNavigation();
|
||||
}
|
||||
|
||||
private bool SpawnRoom(RogueliteRoomResource room, Vector2I gridPos)
|
||||
private bool SpawnRoom(RogueliteRoomResource room, Vector2I gridPos, out RogueliteRoom spawnedRoom)
|
||||
{
|
||||
if (!CanPlaceRoom(gridPos, room.Size))
|
||||
{
|
||||
spawnedRoom = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
var position = gridPos * TileSize * RoomSizeInTiles;
|
||||
|
||||
|
|
@ -379,6 +263,7 @@ public partial class RogueliteRoomManager : Node2D
|
|||
//SpawnRoom(room, origin + (room.Size * new Vector2(i, j) * tileSize));
|
||||
spawnedScene.Spawn();
|
||||
MarkRoom(gridPos, room.Size, spawnedScene);
|
||||
spawnedRoom = spawnedScene;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ public class RoomConnection
|
|||
public bool IsLocked;
|
||||
public bool IsSecret;
|
||||
|
||||
public Door FromDoor { get; set; }
|
||||
public Door ToDoor { get; set; }
|
||||
|
||||
public RoomConnection(Vector2I from, Vector2I to, bool isLocked = false, bool isSecret = false)
|
||||
{
|
||||
From = from;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue