diff --git a/Resources/BossPhases/Roguelite/Roguelite_Boss_1.tres b/Resources/BossPhases/Roguelite/Roguelite_Boss_1.tres index 605bfdee..c8a20d0e 100644 --- a/Resources/BossPhases/Roguelite/Roguelite_Boss_1.tres +++ b/Resources/BossPhases/Roguelite/Roguelite_Boss_1.tres @@ -110,7 +110,7 @@ Controllable = false Freezable = true Grazeable = true GrazeValue = 1.0 -TimeModifiers = null +TimeModifiers = [] metadata/_custom_type_script = "uid://dslyrfcej3g2n" [sub_resource type="Resource" id="Resource_we0cr"] diff --git a/Resources/RogueliteMaps/Factory_Theme.tres b/Resources/RogueliteMaps/Factory_Theme.tres index 07368f31..f7de1c6c 100644 --- a/Resources/RogueliteMaps/Factory_Theme.tres +++ b/Resources/RogueliteMaps/Factory_Theme.tres @@ -1,4 +1,4 @@ -[gd_resource type="Resource" script_class="RogueliteMapTheme" load_steps=55 format=3 uid="uid://cw6868vuvuynh"] +[gd_resource type="Resource" script_class="RogueliteMapTheme" load_steps=56 format=3 uid="uid://cw6868vuvuynh"] [ext_resource type="Script" uid="uid://bwtif3if3ea0u" path="res://Scripts/Resources/RogueliteMapTheme.cs" id="1_2rtdw"] [ext_resource type="Resource" uid="uid://cltxhkrqp055v" path="res://Resources/Items/Money_Pickup.tres" id="1_ae3bb"] @@ -46,6 +46,7 @@ [ext_resource type="Resource" uid="uid://bdpbekqhuuq4l" path="res://Resources/Items/Shield_Extend_Pickup.tres" id="41_tsgja"] [ext_resource type="Resource" uid="uid://ciybnocjfpshh" path="res://Resources/Items/Heart_Extend_Pickup.tres" id="42_qo6vk"] [ext_resource type="PackedScene" uid="uid://c21m7w5ahpsd0" path="res://Scenes/Activable/Shroud.tscn" id="43_3kwn2"] +[ext_resource type="PackedScene" uid="uid://byms2dhliyux0" path="res://Scenes/Actors/teleporter.tscn" id="43_to7mi"] [ext_resource type="Resource" uid="uid://bgcgeg187vg1h" path="res://Resources/Items/IcicleRepeater.tres" id="45_f7mru"] [ext_resource type="Resource" uid="uid://dau0s8ob7qnpc" path="res://Resources/Items/IceShotgun.tres" id="46_3kwn2"] [ext_resource type="Resource" uid="uid://brsukcuyoq364" path="res://Resources/Items/NuclearGunPickup.tres" id="47_to7mi"] @@ -87,6 +88,7 @@ VendingMachinePrefab = ExtResource("30_exyjy") KeyCardsPrefabs = Array[PackedScene]([ExtResource("5_0lwa1"), ExtResource("6_03ih2"), ExtResource("7_modrh"), ExtResource("8_exyjy")]) ShroudPrefab = ExtResource("43_3kwn2") PointItemResource = ExtResource("5_ga54h") +TeleporterPrefab = ExtResource("43_to7mi") ChestChance = 15.0 EnemyDropChance = 40.0 ChestLootTable = SubResource("Resource_nnvxo") diff --git a/Scenes/Maps/RogueliteMaps/Beginner1.tscn b/Scenes/Maps/RogueliteMaps/Beginner1.tscn index b86f029d..22d789a4 100644 --- a/Scenes/Maps/RogueliteMaps/Beginner1.tscn +++ b/Scenes/Maps/RogueliteMaps/Beginner1.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=13 format=4 uid="uid://24wh7h2dbljf"] +[gd_scene load_steps=17 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"] @@ -11,10 +11,17 @@ [ext_resource type="Resource" uid="uid://cltxhkrqp055v" path="res://Resources/Items/Money_Pickup.tres" id="9_5yebg"] [ext_resource type="PackedScene" uid="uid://dt7i3x3g5ktbl" path="res://Scenes/Actors/Roguelite_Boss_1.tscn" id="10_kublc"] [ext_resource type="PackedScene" uid="uid://crph24e6e0v0q" path="res://Scenes/Interactable/Control_Pad.tscn" id="11_dbn5e"] +[ext_resource type="Script" uid="uid://g6oraxgd87ij" path="res://Scripts/Actors/TeleporterMarker.cs" id="12_f3e1d"] +[ext_resource type="Texture2D" uid="uid://d3e762pxublbt" path="res://Sprites/teleporter.png" id="13_c0yr1"] +[ext_resource type="LabelSettings" uid="uid://buk3e7bbwmnv1" path="res://Resources/Styles/Hud_Text_Style.tres" id="14_c0yr1"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_u3c1h"] size = Vector2(272, 85) +[sub_resource type="AtlasTexture" id="AtlasTexture_5rt6n"] +atlas = ExtResource("13_c0yr1") +region = Rect2(0, 0, 16, 16) + [node name="Tilemaps" type="Node2D" node_paths=PackedStringArray("RoomClearActivation")] process_mode = 1 script = ExtResource("1_vhsym") @@ -73,4 +80,20 @@ collision_mask = 2 position = Vector2(162, 94.5) shape = SubResource("RectangleShape2D_u3c1h") +[node name="Features" type="Node2D" parent="."] + +[node name="Teleporter" type="Marker2D" parent="Features"] +position = Vector2(40, 56) +script = ExtResource("12_f3e1d") +Type = 4 +MarkerTexture = SubResource("AtlasTexture_5rt6n") + +[node name="Label" type="Label" parent="Features/Teleporter"] +offset_left = -20.0 +offset_top = -22.0 +offset_right = 32.0 +offset_bottom = 1.0 +text = "Boss Debug" +label_settings = ExtResource("14_c0yr1") + [connection signal="area_entered" from="PlayerEnterDetector" to="." method="OnRoomEntered"] diff --git a/Scenes/Maps/RogueliteMaps/Boss1.tscn b/Scenes/Maps/RogueliteMaps/Boss1.tscn index f073ee1a..b219114e 100644 --- a/Scenes/Maps/RogueliteMaps/Boss1.tscn +++ b/Scenes/Maps/RogueliteMaps/Boss1.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=7 format=4 uid="uid://brytwc48xpj78"] +[gd_scene load_steps=10 format=4 uid="uid://brytwc48xpj78"] [ext_resource type="Script" uid="uid://b2j00riayxkit" path="res://Scripts/Controllers/RogueliteRoom.cs" id="1_vm1u7"] [ext_resource type="Resource" uid="uid://cgac12krx7vbf" path="res://Resources/RogueliteMaps/Boss1.tres" id="2_vm1u7"] @@ -6,6 +6,12 @@ [ext_resource type="Script" uid="uid://krean0uywtms" path="res://Scripts/TilemapAvoidance.cs" id="4_vo7cb"] [ext_resource type="PackedScene" uid="uid://dt7i3x3g5ktbl" path="res://Scenes/Actors/Roguelite_Boss_1.tscn" id="5_wmvx8"] [ext_resource type="PackedScene" uid="uid://crph24e6e0v0q" path="res://Scenes/Interactable/Control_Pad.tscn" id="6_vo7cb"] +[ext_resource type="Script" uid="uid://g6oraxgd87ij" path="res://Scripts/Actors/TeleporterMarker.cs" id="7_5nx6x"] +[ext_resource type="Texture2D" uid="uid://d3e762pxublbt" path="res://Sprites/teleporter.png" id="8_6d01x"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_gh1se"] +atlas = ExtResource("8_6d01x") +region = Rect2(0, 0, 16, 16) [node name="Tilemaps" type="Node2D" node_paths=PackedStringArray("RoomClearActivation")] process_mode = 1 @@ -44,3 +50,11 @@ position = Vector2(118, 37) ActivationType = 1 [node name="EnemySpawners" type="Node2D" parent="."] + +[node name="Features" type="Node2D" parent="."] + +[node name="Teleporter" type="Marker2D" parent="Features"] +position = Vector2(160, 61) +script = ExtResource("7_5nx6x") +Type = 1 +MarkerTexture = SubResource("AtlasTexture_gh1se") diff --git a/Scripts/Activables/Teleporter.cs b/Scripts/Activables/Teleporter.cs index ce293169..c1060fb0 100644 --- a/Scripts/Activables/Teleporter.cs +++ b/Scripts/Activables/Teleporter.cs @@ -15,7 +15,7 @@ public partial class Teleporter : Activable public bool IsEnabled { get; set; } [Export] - public bool Invisible { get; private set; } = false; + public bool Invisible { get; set; } = false; public bool IsPrimed { get; private set; } diff --git a/Scripts/Actors/TeleporterMarker.cs b/Scripts/Actors/TeleporterMarker.cs new file mode 100644 index 00000000..fc3eaac6 --- /dev/null +++ b/Scripts/Actors/TeleporterMarker.cs @@ -0,0 +1,72 @@ +using Cirno.Scripts.Activables; +using Cirno.Scripts.Resources; +using Godot; + +namespace Cirno.Scripts.Actors; + +[Tool] +public partial class TeleporterMarker : FeatureMarker +{ + private Texture2D _markerTexture; + private Teleporter _spawnedTeleporter; + public Teleporter SpawnedTeleporter => _spawnedTeleporter; + + [Export] + public TeleporterMarkerType Type { get; set; } + + [Export] + public Texture2D MarkerTexture + { + get => _markerTexture; + set + { + _markerTexture = value; + if (Engine.IsEditorHint()) + { + QueueRedraw(); + } + } + } + + public override void _Draw() + { + if (!Engine.IsEditorHint()) return; + if (MarkerTexture is null) return; + + DrawTexture(MarkerTexture, -new Vector2(MarkerTexture.GetWidth() / 2f, MarkerTexture.GetHeight() / 2f)); + } + + public TeleporterMarker Spawn(RogueliteMapTheme mapTheme) + { + if (Engine.IsEditorHint()) return null; + if (_spawnedTeleporter is not null) return this; + + _spawnedTeleporter = this.CreateSibling(mapTheme.TeleporterPrefab); + + if (Type is TeleporterMarkerType.Receiver or TeleporterMarkerType.Start) + { + _spawnedTeleporter.IsEnabled = false; + } + else + { + _spawnedTeleporter.IsEnabled = true; + } + + if (Type is TeleporterMarkerType.InvisibleReceiver) + { + _spawnedTeleporter.Invisible = true; + } + + return this; + } +} + +public enum TeleporterMarkerType +{ + Receiver, + InvisibleReceiver, + Start, + BranchReturn, + Boss, + NextLevel +} \ No newline at end of file diff --git a/Scripts/Actors/TeleporterMarker.cs.uid b/Scripts/Actors/TeleporterMarker.cs.uid new file mode 100644 index 00000000..0f9f894c --- /dev/null +++ b/Scripts/Actors/TeleporterMarker.cs.uid @@ -0,0 +1 @@ +uid://g6oraxgd87ij diff --git a/Scripts/Controllers/RogueliteRoom.cs b/Scripts/Controllers/RogueliteRoom.cs index 8b77af36..e78f91a1 100644 --- a/Scripts/Controllers/RogueliteRoom.cs +++ b/Scripts/Controllers/RogueliteRoom.cs @@ -67,6 +67,8 @@ public partial class RogueliteRoom : Node2D private List _connections = []; private List _enemies = []; + public List Teleporters { get; private set; } = []; + private Array SpawnableEnemies => RoomResource.SpawnableEnemies; private BlackCover _shroud; @@ -340,7 +342,7 @@ public partial class RogueliteRoom : Node2D if (!hasLoot) { GD.Print("Ran out of loot to spawn"); - return; + continue; } var chest = marker.CreateChild(MapTheme.ChestPrefab); @@ -348,8 +350,13 @@ public partial class RogueliteRoom : Node2D chest.LootTable.Add(loot); } } - - + else if (markerNode is TeleporterMarker teleporterMarker) + { + var tp = teleporterMarker.Spawn(MapTheme); + + MapTheme.TeleportersList.Add(tp); + Teleporters.Add(tp); + } } } diff --git a/Scripts/Controllers/RogueliteRoomManager.cs b/Scripts/Controllers/RogueliteRoomManager.cs index 0fcf4f03..5a03bb22 100644 --- a/Scripts/Controllers/RogueliteRoomManager.cs +++ b/Scripts/Controllers/RogueliteRoomManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Cirno.Scripts.Actors; using Cirno.Scripts.Enums; using Cirno.Scripts.Resources; using Cirno.Scripts.Resources.Roguelite; @@ -41,8 +42,10 @@ public partial class RogueliteRoomManager : Node2D [Export] public int MaxTreasures = 2; [Export] public int MinShops = 1; [Export] public int MaxShops = 1; - [Export] public ulong Seed = 0; + [Export] public string ManualSeed { get; private set; } + private ulong _seed; + [Export] public Vector2I TileSize { get; set; } = new Vector2I(16, 16); [Export] public Vector2I RoomSizeInTiles { get; set; } = new Vector2I(20, 10); @@ -93,12 +96,27 @@ public partial class RogueliteRoomManager : Node2D public List Connections => _connections; + private void SetSeed() + { + if (!string.IsNullOrWhiteSpace(ManualSeed) && ulong.TryParse(ManualSeed, out var seed)) + { + _seed = seed; + } + else + { + var rng = new RandomNumberGenerator(); + _seed = rng.GetSeed(); + rng.Dispose(); + } + GD.Print($"Seed: {_seed}"); + } + private void GenerateStraightLineDungeon() { - if (Seed > 0) - { - GD.Seed(Seed); - } + SetSeed(); + + MapTheme.MakeChestLootQueue(); + MapTheme.TeleportersList = []; Vector2I origin = Vector2I.Zero; var starterRoom = MapTheme.Rooms.Where(r => r.Type == RoomType.Starter).PickRandom(); @@ -121,7 +139,7 @@ public partial class RogueliteRoomManager : Node2D var shuffledOffshoots = offshoots.Shuffle().ToList(); - MapTheme.MakeChestLootQueue(); + // var offshootsQueue = new Queue(); // offshootsQueue.EnqueueRange(shuffledOffshoots); @@ -235,12 +253,34 @@ public partial class RogueliteRoomManager : Node2D //return _roomGrid.ContainsKey(neighborPos); }); } + + // Debug teleporter matching + MatchBossTeleporter(); EmitSignalMapCreated(); //CallDeferred(MethodName.OpenStartDoorsDeferred, spawnedBeginRoom); } + private void MatchBossTeleporter() + { + var bossTeleporters = MapTheme.TeleportersList.Where(x => x.Type is TeleporterMarkerType.Boss); + + foreach (var teleporterMarker in bossTeleporters) + { + var bossRoom = SpawnedRooms.FirstOrDefault(x => x.RoomResource.Type is RoomType.Boss); + + if (bossRoom is null) return; + + var teleporter = bossRoom.Teleporters.FirstOrDefault(x => + x.Type is TeleporterMarkerType.Receiver or TeleporterMarkerType.InvisibleReceiver); + + if (teleporter is null) return; + + teleporterMarker.SpawnedTeleporter.Target = teleporter.SpawnedTeleporter; + } + } + private RogueliteRoom TrySpawnRoom(List roomsList, RogueliteRoom lastRoom, Direction direction) { diff --git a/Scripts/Resources/RogueliteMapTheme.cs b/Scripts/Resources/RogueliteMapTheme.cs index 24847e96..f25b3b56 100644 --- a/Scripts/Resources/RogueliteMapTheme.cs +++ b/Scripts/Resources/RogueliteMapTheme.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using Cirno.Scripts.Activables; +using Cirno.Scripts.Actors; using Cirno.Scripts.Resources.Loot; using Cirno.Scripts.Resources.Roguelite; using Cirno.Scripts.Utils; @@ -31,6 +32,8 @@ public partial class RogueliteMapTheme : Resource [Export] public PackedScene ShroudPrefab { get; set; } [Export] public LootItem PointItemResource { get; set; } + [Export] public PackedScene TeleporterPrefab { get; set; } + [ExportGroup("Chances")] [Export] public double ChestChance { get; set; } @@ -53,4 +56,7 @@ public partial class RogueliteMapTheme : Resource return ChestLootQueue; } + + public List TeleportersList { get; set; } = []; + } \ No newline at end of file