Mapping and generation fixes

This commit is contained in:
Marco 2025-04-30 15:09:59 +02:00
commit 8c17738371
18 changed files with 628 additions and 53 deletions

View file

@ -2,6 +2,7 @@ using System;
using System.Collections;
using System.Threading.Tasks;
using Cirno.Scripts.Components.FSM;
using Cirno.Scripts.Enums;
using Cirno.Scripts.Resources;
using Godot;
@ -9,7 +10,7 @@ namespace Cirno.Scripts.Activables;
public partial class LevelTeleporter : Teleporter
{
[Export] public string LevelPath { get; private set; }
[Export] public string LevelPath { get; set; }
[Export] public MapResource Map { get; private set; }
[Export] public bool SaveInventory { get; private set; }
@ -38,6 +39,11 @@ public partial class LevelTeleporter : Teleporter
if (!string.IsNullOrWhiteSpace(LevelPath))
{
if (GlobalState.Instance.SessionSettings.GameMode is GameMode.Roguelite)
{
GlobalState.Instance.SessionSettings.LevelNumber += 1;
}
GlobalState.Instance.GotoScene(LevelPath);
}
else

View file

@ -41,9 +41,9 @@ public partial class TeleporterMarker : FeatureMarker
if (Engine.IsEditorHint()) return null;
if (_spawnedTeleporter is not null) return this;
_spawnedTeleporter = this.CreateSibling<Teleporter>(mapTheme.TeleporterPrefab);
_spawnedTeleporter = this.CreateSibling<Teleporter>(Type is TeleporterMarkerType.NextLevel ? mapTheme.LevelTeleporterPrefab : mapTheme.TeleporterPrefab);
if (Type is TeleporterMarkerType.Receiver or TeleporterMarkerType.Start)
if (Type is TeleporterMarkerType.Receiver or TeleporterMarkerType.Start or TeleporterMarkerType.NextLevel)
{
_spawnedTeleporter.IsEnabled = false;
}
@ -52,11 +52,16 @@ public partial class TeleporterMarker : FeatureMarker
_spawnedTeleporter.IsEnabled = true;
}
if (Type is TeleporterMarkerType.InvisibleReceiver)
if (Type is TeleporterMarkerType.InvisibleReceiver or TeleporterMarkerType.NextLevel)
{
_spawnedTeleporter.Invisible = true;
}
if (Type is TeleporterMarkerType.NextLevel && _spawnedTeleporter is LevelTeleporter levelTeleporter)
{
levelTeleporter.LevelPath = mapTheme.LevelTeleporterDestinationPath;
}
return this;
}
}

View file

@ -21,8 +21,8 @@ namespace Cirno.Scripts.Controllers;
public partial class RogueliteRoom : Node2D
{
[Export] public RogueliteRoomResource RoomResource { get; set; }
[Export] public Array<Node2D> RoomClearActivation { get; set; }
[Export] public Array<Node2D> RoomClearActivation { get; set; }
public RogueliteMapTheme MapTheme { get; set; }
@ -35,8 +35,9 @@ public partial class RogueliteRoom : Node2D
public Vector2 RoomSize => BaseRoomSize * RoomResource.Size;
[Signal] public delegate void RoomClearedEventHandler();
[Signal]
public delegate void RoomClearedEventHandler();
public Vector2I RandomBottomExit()
{
return BottomLeft + new Vector2I(GD.RandRange(0, RoomResource.Size.X - 1), 0);
@ -68,7 +69,7 @@ public partial class RogueliteRoom : Node2D
private List<EnemyFSMProxy> _enemies = [];
public List<TeleporterMarker> Teleporters { get; private set; } = [];
private Array<EnemyResource> SpawnableEnemies => RoomResource.SpawnableEnemies;
private BlackCover _shroud;
@ -224,15 +225,15 @@ public partial class RogueliteRoom : Node2D
// Move marker based on direction
var newMarkerPosition = marker.Direction switch
{
DoorDirections.East => marker.GlobalPosition + new Vector2(-4,0),
DoorDirections.West => marker.GlobalPosition + new Vector2(-12,0),
DoorDirections.North => marker.GlobalPosition + new Vector2(0,0),
DoorDirections.South => marker.GlobalPosition + new Vector2(0,-2),
DoorDirections.East => marker.GlobalPosition + new Vector2(-4, 0),
DoorDirections.West => marker.GlobalPosition + new Vector2(-12, 0),
DoorDirections.North => marker.GlobalPosition + new Vector2(0, 0),
DoorDirections.South => marker.GlobalPosition + new Vector2(0, -2),
_ => marker.GlobalPosition
};
marker.GlobalPosition = newMarkerPosition;
var wall = this.CreateChildOf<Node2D>(marker, marker.Direction switch
{
DoorDirections.North => MapTheme.HorizontalNorthWallPrefab,
@ -337,23 +338,22 @@ public partial class RogueliteRoom : Node2D
double chance = chestMarker.OverrideChance ? chestMarker.SpawnChance : MapTheme.ChestChance;
if (roll <= chance)
{
var hasLoot = MapTheme.ChestLootQueue.TryDequeue(out var loot);
if (!hasLoot)
{
GD.Print("Ran out of loot to spawn");
continue;
}
var chest = marker.CreateChild<Chest>(MapTheme.ChestPrefab);
chest.LootTable.Add(loot);
}
}
else if (markerNode is TeleporterMarker teleporterMarker)
{
var tp = teleporterMarker.Spawn(MapTheme);
MapTheme.TeleportersList.Add(tp);
Teleporters.Add(tp);
}
@ -368,10 +368,21 @@ public partial class RogueliteRoom : Node2D
if (_enemies.Count == 0)
{
OpenDoors();
EnableLevelExitTeleporter();
EmitSignalRoomCleared();
}
}
private void EnableLevelExitTeleporter()
{
var teleporter = Teleporters.FirstOrDefault(x => x.Type is TeleporterMarkerType.NextLevel);
if (teleporter is null) return;
teleporter.SpawnedTeleporter.IsEnabled = true;
teleporter.SpawnedTeleporter.Invisible = false;
}
public void OpenDoors()
{
foreach (var connection in _connections)
@ -421,6 +432,8 @@ public partial class RogueliteRoom : Node2D
if (_enemies.Count <= 0)
{
OpenDoors();
// TODO: Just for testing
EnableLevelExitTeleporter();
}
else
{

View file

@ -59,6 +59,7 @@ public partial class RogueliteRoomManager : Node2D
public void InitSpawning()
{
GlobalState.Instance.SessionSettings.GameMode = GameMode.Roguelite;
GenerateStraightLineDungeon();
}
@ -109,6 +110,7 @@ public partial class RogueliteRoomManager : Node2D
rng.Dispose();
}
GD.Seed(_seed);
GD.Print($"Seed: {_seed}");
}
@ -209,7 +211,7 @@ public partial class RogueliteRoomManager : Node2D
if (!offshootsQueue.TryDequeue(out var offshootTypeToSpawn))
{
GD.Print("Ran out of offshoot types, add more");
GD.Print("Ran out of offshoot types");
break;
}
@ -240,14 +242,20 @@ public partial class RogueliteRoomManager : Node2D
lockNext = true;
}
if (offshootTypeToSpawn is RoomType.Key &&
offshootsQueue.Peek() is RoomType.Key)
if (offshootTypeToSpawn is RoomType.Key)
{
bool hasNextRoom = offshootsQueue.TryPeek(out var nextRoom);
if (!hasNextRoom || nextRoom is RoomType.Key)
// Stop if next room is a key
break;
}
//break;
}
else
{
offshootsQueue.Enqueue(offshootTypeToSpawn);
}
}
// Add more dungeon if not enough rooms are generated

View file

@ -33,6 +33,8 @@ public partial class RogueliteMapTheme : Resource
[Export] public LootItem PointItemResource { get; set; }
[Export] public PackedScene TeleporterPrefab { get; set; }
[Export] public PackedScene LevelTeleporterPrefab { get; set; }
[Export] public StringName LevelTeleporterDestinationPath { get; set; }
[ExportGroup("Chances")]