mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 10:45:33 +00:00
Door connections
This commit is contained in:
parent
cae1f99949
commit
700be1e207
11 changed files with 127 additions and 149 deletions
|
|
@ -43,7 +43,7 @@ metadata/_custom_type_script = "uid://cq65aed620ijo"
|
|||
script = ExtResource("8_241b0")
|
||||
EnemyName = &"Fairy"
|
||||
EnemyKey = &"FAIRY_BASE"
|
||||
PrefabPath = &"res://Scenes/Actors/Fairy_New.tscn"
|
||||
PrefabPath = &"uid://clieeuln36a7a"
|
||||
MaxHealth = 8.0
|
||||
MovementSpeed = 30.0
|
||||
Weapon = ExtResource("7_xkg5o")
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ metadata/_custom_type_script = "uid://cq65aed620ijo"
|
|||
script = ExtResource("8_8fxhl")
|
||||
EnemyName = &"Special Fairy"
|
||||
EnemyKey = &"FAIRY_BASE_SPECIAL"
|
||||
PrefabPath = &"res://Scenes/Actors/Fairy_Special_FSM.tscn"
|
||||
PrefabPath = &"uid://bq4r28ikbmn0r"
|
||||
MaxHealth = 12.0
|
||||
MovementSpeed = 30.0
|
||||
Weapon = ExtResource("7_tf7s2")
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ metadata/_custom_type_script = "uid://cq65aed620ijo"
|
|||
script = ExtResource("1_p31tv")
|
||||
EnemyName = &"Fairy Guard"
|
||||
EnemyKey = &"FAIRY_GUARD"
|
||||
PrefabPath = &"res://Scenes/Actors/FairyGuard_New.tscn"
|
||||
PrefabPath = &"uid://bb32f4p5e671j"
|
||||
MaxHealth = 10.0
|
||||
MovementSpeed = 40.0
|
||||
Weapon = ExtResource("7_xlxdc")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
[gd_resource type="Resource" script_class="EnemyResource" load_steps=4 format=3 uid="uid://cfdvg162u65sr"]
|
||||
[gd_resource type="Resource" script_class="EnemyResource" load_steps=3 format=3 uid="uid://cfdvg162u65sr"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cq65aed620ijo" path="res://Scripts/Resources/Loot/LootDrop.cs" id="1_f3huq"]
|
||||
[ext_resource type="Resource" uid="uid://cdfmedtgp2rcn" path="res://Resources/Weapons/EnemyWeapon.tres" id="7_filx8"]
|
||||
[ext_resource type="Script" uid="uid://cd5o0ceb50jki" path="res://Scripts/Resources/EnemyResource.cs" id="8_x8scf"]
|
||||
|
||||
|
|
@ -8,11 +7,11 @@
|
|||
script = ExtResource("8_x8scf")
|
||||
EnemyName = &"Robot 1"
|
||||
EnemyKey = &"ROBOT_1"
|
||||
PrefabPath = &"res://Scenes/Actors/Thermathron.tscn"
|
||||
PrefabPath = &"uid://dky13otbks8cm"
|
||||
MaxHealth = 16.0
|
||||
MovementSpeed = 38.0
|
||||
Weapon = ExtResource("7_filx8")
|
||||
LootDrops = Array[ExtResource("1_f3huq")]([])
|
||||
LootDrops = []
|
||||
MotivationReward = 4.0
|
||||
PlayerDetectionRange = 90.0
|
||||
ViewRange = 120.0
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ process_mode = 1
|
|||
script = ExtResource("4_jtlua")
|
||||
Rooms = Array[Object]([ExtResource("5_gwtv6"), ExtResource("6_gwtv6"), ExtResource("7_wbqvu"), ExtResource("8_3fyis"), ExtResource("9_go1yg"), ExtResource("5_pfafs"), ExtResource("11_68lig"), ExtResource("12_83bvc"), ExtResource("13_y651a")])
|
||||
DungeonLength = 12
|
||||
Seed = 1
|
||||
|
||||
[node name="CameraController" type="Camera2D" parent="."]
|
||||
process_mode = 1
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=7 format=4 uid="uid://24wh7h2dbljf"]
|
||||
[gd_scene load_steps=8 format=4 uid="uid://24wh7h2dbljf"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b2j00riayxkit" path="res://Scripts/Controllers/RogueliteRoom.cs" id="1_vhsym"]
|
||||
[ext_resource type="Resource" uid="uid://dn3ai56rrxfnk" path="res://Resources/RogueliteMaps/Beginner1.tres" id="2_vhsym"]
|
||||
|
|
@ -7,6 +7,9 @@
|
|||
[ext_resource type="Script" uid="uid://krean0uywtms" path="res://Scripts/TilemapAvoidance.cs" id="4_pys6w"]
|
||||
[ext_resource type="Script" uid="uid://ddry5kjj3fr6c" path="res://Scripts/Controllers/DoorMarker.cs" id="5_mqiea"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_u3c1h"]
|
||||
size = Vector2(272, 85)
|
||||
|
||||
[node name="Tilemaps" type="Node2D"]
|
||||
process_mode = 1
|
||||
script = ExtResource("1_vhsym")
|
||||
|
|
@ -57,3 +60,13 @@ Direction = 2
|
|||
position = Vector2(8.1806, 87.7693)
|
||||
script = ExtResource("5_mqiea")
|
||||
Direction = 3
|
||||
|
||||
[node name="PlayerEnterDetector" type="Area2D" parent="."]
|
||||
collision_layer = 0
|
||||
collision_mask = 2
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerEnterDetector"]
|
||||
position = Vector2(162, 94.5)
|
||||
shape = SubResource("RectangleShape2D_u3c1h")
|
||||
|
||||
[connection signal="area_entered" from="PlayerEnterDetector" to="." method="OnRoomEntered"]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_scene load_steps=9 format=4 uid="uid://dcxrdhq1yw5c7"]
|
||||
[gd_scene load_steps=10 format=4 uid="uid://dcxrdhq1yw5c7"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://b2j00riayxkit" path="res://Scripts/Controllers/RogueliteRoom.cs" id="1_cak6m"]
|
||||
[ext_resource type="Resource" uid="uid://ly8l7asedjpx" path="res://Resources/RogueliteMaps/TestRGMap2.tres" id="2_cak6m"]
|
||||
|
|
@ -15,6 +15,9 @@ outlines = Array[PackedVector2Array]([PackedVector2Array(17, 36, 14, 12, 47, 15,
|
|||
parsed_collision_mask = 353
|
||||
source_geometry_mode = 1
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_wtdf1"]
|
||||
size = Vector2(272, 85)
|
||||
|
||||
[node name="Map" type="Node2D"]
|
||||
process_mode = 1
|
||||
script = ExtResource("1_cak6m")
|
||||
|
|
@ -81,3 +84,13 @@ Direction = 3
|
|||
|
||||
[node name="NavigationRegion2D" type="NavigationRegion2D" parent="."]
|
||||
navigation_polygon = SubResource("NavigationPolygon_f7qjl")
|
||||
|
||||
[node name="PlayerEnterDetector" type="Area2D" parent="."]
|
||||
collision_layer = 0
|
||||
collision_mask = 2
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="PlayerEnterDetector"]
|
||||
position = Vector2(162, 94.5)
|
||||
shape = SubResource("RectangleShape2D_wtdf1")
|
||||
|
||||
[connection signal="area_entered" from="PlayerEnterDetector" to="." method="OnRoomEntered"]
|
||||
|
|
|
|||
|
|
@ -23,6 +23,13 @@ public partial class EnemyFSMProxy : CharacterBody2D, IActivable
|
|||
|
||||
[Export] public ActivationType ActivationType { get; private set; } = ActivationType.Toggle;
|
||||
|
||||
[Signal] public delegate void DeathEventHandler(EnemyFSMProxy enemy);
|
||||
|
||||
public void TriggerDeath()
|
||||
{
|
||||
EmitSignalDeath(this);
|
||||
}
|
||||
|
||||
public bool Activate(ActivationType activationType = ActivationType.Toggle)
|
||||
{
|
||||
switch (activationType)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -101,14 +116,6 @@ 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,7 +87,7 @@ 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();
|
||||
|
|
@ -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