Locked Doors

This commit is contained in:
Marco 2025-04-24 16:40:51 +02:00
commit e25da0fe16
20 changed files with 318 additions and 61 deletions

View file

@ -64,7 +64,7 @@ public partial class ActivationProvider : Area2D
_errorSound?.Play();
return true;
};
bool success = selected.Activate();
bool success = selected.Activate(ActivationType.Use);
if (success)
{

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using Cirno.Scripts.Components.FSM.Enemy;
using Cirno.Scripts.Enums;
using Cirno.Scripts.Interactables;
using Cirno.Scripts.Resources;
using Cirno.Scripts.Resources.Roguelite;
using Godot;
@ -14,6 +15,8 @@ namespace Cirno.Scripts.Controllers;
public partial class RogueliteRoom : Node2D
{
[Export] public RogueliteRoomResource RoomResource { get; set; }
public RogueliteMapTheme MapTheme { get; set; }
public Vector2I GridPosition { get; set; } // Set by dungeon manager
@ -39,11 +42,6 @@ public partial class RogueliteRoom : Node2D
};
}
[Export] public PackedScene DoorPrefab { get; private set; }
[Export] public PackedScene VerticalDoorPrefab { get; private set; }
[Export] public PackedScene WallPrefab { get; private set; }
private static readonly Godot.Collections.Dictionary<string, Vector2I> DirectionMap = new()
{
{ "North", new Vector2I(0, -1) },
@ -157,14 +155,16 @@ public partial class RogueliteRoom : Node2D
var door = this.CreateChildOf<Door>(marker, marker.Direction switch
{
DoorDirections.North => DoorPrefab,
DoorDirections.South => DoorPrefab,
DoorDirections.East => VerticalDoorPrefab,
DoorDirections.West => VerticalDoorPrefab,
DoorDirections.North => MapTheme.HorizontalDoorPrefab,
DoorDirections.South => MapTheme.HorizontalDoorPrefab,
DoorDirections.East => MapTheme.VerticalDoorPrefab,
DoorDirections.West => MapTheme.VerticalDoorPrefab,
_ => throw new ArgumentOutOfRangeException()
}, marker.GlobalPosition);
door.State = DoorState.Closed;
door.Close();
// door.State = DoorState.Closed;
if (connected)
{
_doors.Add(door);
@ -172,6 +172,21 @@ public partial class RogueliteRoom : Node2D
if (doorEdge == connection.From)
{
connection.FromDoor = door;
// Spawn lock if locked
if (connection.IsLocked)
{
var doorLock = door.CreateChild<RogueliteDoorLock>(MapTheme.DoorLockPrefab);
doorLock.Connection = connection;
doorLock.ZIndex += 2;
//doorLock.Targets.Add(door);
//doorLock.Targets.Add(connection.ToDoor);
doorLock.ActivationType = ActivationType.Open;
}
}
else if (doorEdge == connection.To)
{
@ -184,6 +199,9 @@ public partial class RogueliteRoom : Node2D
}
_connections.Add(connection);
}
else
{
@ -229,8 +247,14 @@ public partial class RogueliteRoom : Node2D
{
foreach (var connection in _connections)
{
connection.FromDoor?.Open();
connection.ToDoor?.Open();
if(!connection.IsLocked)
{
connection.FromDoor?.Open();
}
if(!connection.IsLocked)
{
connection.ToDoor?.Open();
}
}
}
@ -238,8 +262,14 @@ public partial class RogueliteRoom : Node2D
{
foreach (var connection in _connections)
{
connection.FromDoor?.Close();
connection.ToDoor?.Close();
if(!connection.IsLocked)
{
connection.FromDoor?.Close();
}
if(!connection.IsLocked)
{
connection.ToDoor?.Close();
}
}
}

View file

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using Cirno.Scripts.Enums;
using Cirno.Scripts.Resources;
using Cirno.Scripts.Resources.Roguelite;
using Cirno.Scripts.Utils;
using Godot;
@ -12,9 +13,9 @@ namespace Cirno.Scripts.Controllers;
public partial class RogueliteRoomManager : Node2D
{
[Export] public Array<RogueliteRoomResource> Rooms { get; set; }
[Export] public Node2D SceneContainer { get; set; }
//[Export] public Array<RogueliteRoomResource> Rooms { get; set; }
[Export] public RogueliteMapTheme MapTheme { get; set; }
//private Godot.Collections.Dictionary<Vector2I, RogueliteRoomResource> _grid = new();
private Godot.Collections.Dictionary<Vector2I, RogueliteRoom> _roomGrid = new();
@ -69,8 +70,8 @@ public partial class RogueliteRoomManager : Node2D
{
for (int j = 0; j < 10; j++)
{
var roomIndex = GD.RandRange(0, Rooms.Count - 1);
var room = Rooms[roomIndex];
var roomIndex = GD.RandRange(0, MapTheme.Rooms.Count - 1);
var room = MapTheme.Rooms[roomIndex];
//SpawnRoom(room, origin + (room.Size * new Vector2(i, j) * tileSize));
}
}
@ -78,15 +79,15 @@ public partial class RogueliteRoomManager : Node2D
//CallDeferred(MethodName.RebakeNavigationDeferred);
}
private IEnumerable<RogueliteRoomResource> StarterRooms => Rooms.Where(x => x.Type is RoomType.Starter);
private IEnumerable<RogueliteRoomResource> StarterRooms => MapTheme.Rooms.Where(x => x.Type is RoomType.Starter);
private IEnumerable<RogueliteRoomResource> RegularRooms => Rooms.Where(x =>
private IEnumerable<RogueliteRoomResource> RegularRooms => MapTheme.Rooms.Where(x =>
x.Type is RoomType.Regular && x.HasDoors(DoorDirections.North | DoorDirections.South));
private IEnumerable<RogueliteRoomResource> OffshootRooms => Rooms.Where(x =>
private IEnumerable<RogueliteRoomResource> OffshootRooms => MapTheme.Rooms.Where(x =>
x.Type is RoomType.Regular && x.HasDoors(DoorDirections.East | DoorDirections.West));
private IEnumerable<RogueliteRoomResource> BossRooms => Rooms.Where(x => x.Type is RoomType.Boss);
private IEnumerable<RogueliteRoomResource> BossRooms => MapTheme.Rooms.Where(x => x.Type is RoomType.Boss);
private List<RoomConnection> _connections = new();
@ -100,7 +101,7 @@ public partial class RogueliteRoomManager : Node2D
}
Vector2I origin = Vector2I.Zero;
var starterRoom = Rooms.Where(r => r.Type == RoomType.Starter).PickRandom();
var starterRoom = MapTheme.Rooms.Where(r => r.Type == RoomType.Starter).PickRandom();
SpawnRoom(starterRoom, origin, out var spawnedBeginRoom);
var randomRoomsList = RegularRooms.Shuffle(MaxRooms * 4).ToList();
@ -372,7 +373,7 @@ public partial class RogueliteRoomManager : Node2D
// Spawn final room
// var finalRoomToSpawn = Rooms.Where(x => x.Type == offshootTypeToSpawn).PickRandom();
var spawnedFinalRoom = TrySpawnRoom(Rooms.Where(x => x.Type == offshootTypeToSpawn).ToList(),
var spawnedFinalRoom = TrySpawnRoom(MapTheme.Rooms.Where(x => x.Type == offshootTypeToSpawn).ToList(),
lastSpawnedOffshootRoom, direction);
if (spawnedFinalRoom is null)
@ -406,6 +407,7 @@ public partial class RogueliteRoomManager : Node2D
var roomScene = GD.Load<PackedScene>(room.ScenePath);
var spawnedScene = this.CreateChild<RogueliteRoom>(roomScene, position);
spawnedScene.MapTheme = MapTheme;
spawnedScene.GridPosition = gridPos;
spawnedScene.Name = room.RoomName.ToString().Replace(" ", "_");

View file

@ -44,6 +44,7 @@ public partial class Door : Activable
public virtual void Open()
{
if (State == DoorState.Open) return;
// _animatedSprite.Play("Opening");
State = DoorState.Open;
CallDeferred(MethodName.DeferredDisableCollision, true);
@ -55,6 +56,7 @@ public partial class Door : Activable
public virtual void Close()
{
if (State == DoorState.Closed) return;
// _animatedSprite.Play("Closing");
State = DoorState.Closed;
CallDeferred(MethodName.DeferredDisableCollision, false);

View file

@ -0,0 +1,24 @@
using Cirno.Scripts.Controllers;
namespace Cirno.Scripts.Interactables;
public partial class RogueliteDoorLock : Switch
{
public RoomConnection Connection { get; set; }
public override bool Activate(ActivationType activationType = ActivationType.Toggle)
{
base.Activate(activationType);
if (!MeetsRequirements()) return false;
Connection.FromDoor.Activate(activationType);
Connection.ToDoor.Activate(activationType);
InventoryManager.Instance.RemoveItem("GRAY_KEY", 1);
this.QueueFree();
return true;
}
}

View file

@ -0,0 +1 @@
uid://6n7duf35c52l

View file

@ -25,15 +25,25 @@ public partial class Switch : Interactable
public override bool Activate(ActivationType activationType = ActivationType.Toggle)
{
ActivationType activationTypeToUse;
if (activationType is ActivationType.Use)
{
activationTypeToUse = ActivationType;
}
else
{
activationTypeToUse = activationType;
}
if (!MeetsRequirements()) return false;
_activationSound?.Play();
EmitSignal(SignalName.OnActivated, (int)activationType);
EmitSignal(SignalName.OnActivated, (int)activationTypeToUse);
// Compatibility for old single system
bool success = ActivateTarget(Target, activationType);
bool success = ActivateTarget(Target, activationTypeToUse);
return Targets.Aggregate(success, (current, target) => ActivateTarget(target, activationType) | success);
return Targets.Aggregate(success, (current, target) => ActivateTarget(target, activationTypeToUse) | success);
}
private bool ActivateTarget(Node2D target, ActivationType activationType = ActivationType.Toggle)

View file

@ -0,0 +1,18 @@
using Cirno.Scripts.Resources.Roguelite;
using Godot;
using Godot.Collections;
namespace Cirno.Scripts.Resources;
[GlobalClass]
public partial class RogueliteMapTheme : Resource
{
[Export] public PackedScene HorizontalDoorPrefab { get; set; }
[Export] public PackedScene HorizontalWallPrefab { get; set; }
[Export] public PackedScene VerticalDoorPrefab { get; set; }
[Export] public PackedScene VerticalWallPrefab { get; set; }
[Export] public PackedScene DoorLockPrefab { get; set; }
[Export] public PackedScene KeyCardPrefab { get; set; }
[Export] public Array<RogueliteRoomResource> Rooms { get; set; }
}

View file

@ -0,0 +1 @@
uid://bwtif3if3ea0u