diff --git a/Zennysoft.Game.Ma.Implementation/Game/state/gamestates/GameState.State.FloorExitScreen.cs b/Zennysoft.Game.Ma.Implementation/Game/state/gamestates/GameState.State.FloorExitScreen.cs index 29f9a38d..6e32f871 100644 --- a/Zennysoft.Game.Ma.Implementation/Game/state/gamestates/GameState.State.FloorExitScreen.cs +++ b/Zennysoft.Game.Ma.Implementation/Game/state/gamestates/GameState.State.FloorExitScreen.cs @@ -13,6 +13,7 @@ public partial class GameState public FloorExitScreen() { OnAttach(() => Get().Pause()); + OnDetach(() => Get().Resume()); } public Transition On(in Input.LoadNextFloor input) diff --git a/Zennysoft.Game.Ma.Implementation/Map/IDungeonFloor.cs b/Zennysoft.Game.Ma.Implementation/Map/IDungeonFloor.cs index b65496db..368cb1af 100644 --- a/Zennysoft.Game.Ma.Implementation/Map/IDungeonFloor.cs +++ b/Zennysoft.Game.Ma.Implementation/Map/IDungeonFloor.cs @@ -11,5 +11,7 @@ public interface IDungeonFloor : INode3D public ImmutableList Rooms { get; } + public IDungeonRoom GetPlayersCurrentRoom(); + public bool FloorIsLoaded { get; set; } } diff --git a/Zennysoft.Game.Ma/src/enemy/behaviors/FleeBehavior.cs b/Zennysoft.Game.Ma/src/enemy/behaviors/FleeBehavior.cs index 92d5ef8a..14bcfb5c 100644 --- a/Zennysoft.Game.Ma/src/enemy/behaviors/FleeBehavior.cs +++ b/Zennysoft.Game.Ma/src/enemy/behaviors/FleeBehavior.cs @@ -35,7 +35,7 @@ public partial class FleeBehavior : Node3D, IBehavior public void StartFlee(NavigationAgent3D navigationAgent) { - var currentRoom = _map.GetPlayersCurrentRoom(); + var currentRoom = _map.CurrentFloor.GetPlayersCurrentRoom(); var rooms = _game.CurrentFloor.Rooms; var validRooms = new Godot.Collections.Array(rooms.OfType()); var randomRoom = validRooms.PickRandom(); diff --git a/Zennysoft.Game.Ma/src/game/Game.cs b/Zennysoft.Game.Ma/src/game/Game.cs index c3d4d694..09ab25be 100644 --- a/Zennysoft.Game.Ma/src/game/Game.cs +++ b/Zennysoft.Game.Ma/src/game/Game.cs @@ -185,12 +185,10 @@ public partial class Game : Node3D, IGame PauseContainer.AddChild((Map)_map); } - public async void OnResolved() + public void OnResolved() { LoadExistingGame(); - await InitializeGame(); - GameState.Set(GameRepo); GameState.Set(_player); GameState.Set(_map); @@ -200,13 +198,11 @@ public partial class Game : Node3D, IGame GameState.Start(); this.Provide(); + InitializeGame(); + InGameUI.UseTeleportPrompt.TeleportToNextFloor += UseTeleportPrompt_TeleportToNextFloor; InGameUI.UseTeleportPrompt.CloseTeleportPrompt += UseTeleportPrompt_CloseTeleportPrompt; - LoadNextLevel.GoToNextFloor += FloorClearMenu_GoToNextFloor; LoadNextLevel.Exit += FloorClearMenu_Exit; - LoadNextLevel.TransitionCompleted += FloorClearMenu_TransitionCompleted; - - OnLoadLevelRequest += LoadLevel; GameRepo.CloseInventoryEvent += ExitInventoryAction; @@ -250,12 +246,11 @@ public partial class Game : Node3D, IGame public void LoadExistingGame() => SaveFile.Load().ContinueWith((_) => CallDeferred(nameof(FinishedLoadingSaveFile))); - public async Task InitializeGame() + public void InitializeGame() { _player.ResetPlayerData(); - _map.InitializeMapData(); + _map.LoadFloor(_map.FloorRoute.First()); _effectService = new EffectService(this, _player, _map); - await _map.LoadFloor(); } public async Task Save() => await SaveFile.Save(); @@ -424,7 +419,6 @@ public partial class Game : Node3D, IGame }) .Handle((in GameState.Output.LoadNextFloor _) => { - EmitSignal(SignalName.OnLoadLevelRequest); var breakableItems = _player.Inventory.Items.Where(x => x.ItemTag == ItemTag.BreaksOnFloorExit).ToList(); foreach (IEquipableItem breakableItem in breakableItems) { @@ -433,11 +427,9 @@ public partial class Game : Node3D, IGame _player.Inventory.Remove(breakableItem); } Task.Run(() => Save()); - LoadNextLevel.FadeOut(); }) .Handle((in GameState.Output.ReturnToOverworld _) => { - LoadNextLevel.FadeOut(); Task.Run(() => Save()); InitializeGame(); }) @@ -464,13 +456,6 @@ public partial class Game : Node3D, IGame InGameUI.InventoryMenu.SetProcessInput(false); } - private async void LoadLevel() - { - await _map.LoadFloor(); - } - - private void FloorClearMenu_GoToNextFloor() => GameState.Input(new GameState.Input.LoadNextFloor()); - private void DropRestorative(Vector3 vector) { var restorativeScene = GD.Load("res://src/items/restorative/Restorative.tscn"); @@ -506,11 +491,6 @@ public partial class Game : Node3D, IGame private void PointUpFinished() => GameState.Input(new GameState.Input.UseTeleport()); - private void FloorClearMenu_TransitionCompleted() - { - GameRepo.Resume(); - } - private void IsPaused_Sync(bool isPaused) => GetTree().Paused = isPaused; private void FinishedLoadingSaveFile() => EmitSignal(SignalName.SaveFileLoaded); @@ -924,13 +904,13 @@ public partial class Game : Node3D, IGame private void OnFloorLoadFinished() { - LoadNextLevel.Hide(); GameLoaded?.Invoke(); - _map.FadeIn(); if (GameOverMenu.Visible) GameOverMenu.FadeOut(); - GameRepo.Resume(); _player.Activate(); + _map.ShowMap(); + GameState.Input(new GameState.Input.LoadNextFloor()); + Resume(); } private void RustStatusChanged(bool rustStatus) @@ -1001,9 +981,13 @@ public partial class Game : Node3D, IGame UnlockGalleryItem.Invoke("TrueEnd"); } + public void Pause() => GameRepo.Pause(); + + public void Resume() => GameRepo.Resume(); + private void OnQuit() => GameExitRequested?.Invoke(); - private void GameOverMenuAppeared() => _map.ClearFloor(); + private void GameOverMenuAppeared() => _map.EndCurrentGame(); private void OnResume() => GameState.Input(new GameState.Input.PauseButtonPressed()); @@ -1011,11 +995,7 @@ public partial class Game : Node3D, IGame { InGameUI.UseTeleportPrompt.TeleportToNextFloor -= UseTeleportPrompt_TeleportToNextFloor; InGameUI.UseTeleportPrompt.CloseTeleportPrompt -= UseTeleportPrompt_CloseTeleportPrompt; - LoadNextLevel.GoToNextFloor -= FloorClearMenu_GoToNextFloor; LoadNextLevel.Exit -= FloorClearMenu_Exit; - LoadNextLevel.TransitionCompleted -= FloorClearMenu_TransitionCompleted; - - OnLoadLevelRequest -= LoadLevel; GameRepo.CloseInventoryEvent -= ExitInventoryAction; diff --git a/Zennysoft.Game.Ma/src/game/IGame.cs b/Zennysoft.Game.Ma/src/game/IGame.cs index 15fc77b3..4508346f 100644 --- a/Zennysoft.Game.Ma/src/game/IGame.cs +++ b/Zennysoft.Game.Ma/src/game/IGame.cs @@ -52,6 +52,10 @@ public interface IGame : IProvide, IProvide, IProvide public Task OnReachTrueEnd(); + public void Pause(); + + public void Resume(); + public ItemRescueMenu ItemRescueMenu { get; } public QuestData QuestData { get; } diff --git a/Zennysoft.Game.Ma/src/items/EffectService.cs b/Zennysoft.Game.Ma/src/items/EffectService.cs index 166ae3bb..a4c1bc2a 100644 --- a/Zennysoft.Game.Ma/src/items/EffectService.cs +++ b/Zennysoft.Game.Ma/src/items/EffectService.cs @@ -22,7 +22,7 @@ public class EffectService public void TeleportEnemiesToCurrentRoom(List enemyList) { - var currentRoom = _map.GetPlayersCurrentRoom(); + var currentRoom = _map.CurrentFloor.GetPlayersCurrentRoom(); if (currentRoom is MonsterRoom currentMonsterRoom) { @@ -33,7 +33,7 @@ public class EffectService public void KillHalfEnemiesInRoom() { - var currentRoom = _map.GetPlayersCurrentRoom(); + var currentRoom = _map.CurrentFloor.GetPlayersCurrentRoom(); if (currentRoom is not MonsterRoom) return; @@ -46,7 +46,7 @@ public class EffectService public void TurnAllEnemiesInRoomIntoHealingItem() { - var currentRoom = _map.GetPlayersCurrentRoom(); + var currentRoom = _map.CurrentFloor.GetPlayersCurrentRoom(); if (currentRoom is not MonsterRoom) return; @@ -78,7 +78,7 @@ public class EffectService public void HealAllEnemiesAndPlayerInRoomToFull() { - var currentRoom = _map.GetPlayersCurrentRoom(); + var currentRoom = _map.CurrentFloor.GetPlayersCurrentRoom(); if (currentRoom is not MonsterRoom) return; @@ -91,7 +91,7 @@ public class EffectService public int AbsorbHPFromAllEnemiesInRoom() { - var currentRoom = _map.GetPlayersCurrentRoom(); + var currentRoom = _map.CurrentFloor.GetPlayersCurrentRoom(); if (currentRoom is not MonsterRoom) return 0; @@ -110,7 +110,7 @@ public class EffectService public void DealElementalDamageToAllEnemiesInRoom(ElementType elementType) { - var currentRoom = _map.GetPlayersCurrentRoom(); + var currentRoom = _map.CurrentFloor.GetPlayersCurrentRoom(); if (currentRoom is not MonsterRoom) return; diff --git a/Zennysoft.Game.Ma/src/map/DungeonFloorNode.cs b/Zennysoft.Game.Ma/src/map/DungeonFloorNode.cs deleted file mode 100644 index a301e7e4..00000000 --- a/Zennysoft.Game.Ma/src/map/DungeonFloorNode.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Godot; - -namespace Zennysoft.Game.Ma; - -public partial class DungeonFloorNode : FloorNode -{ - [ExportGroup("Floor Set")] - [Export] - public string FolderName { get; set; } - [Export] - public Godot.Collections.Array FloorOdds { get; set; } = []; - - - [ExportGroup("Spawn Rates")] - [Export] - public float Sproingy { get; set; } - [Export] - public float Michael { get; set; } - [Export] - public float FilthEater { get; set; } - [Export] - public float Sara { get; set; } - [Export] - public float Ballos { get; set; } - [Export] - public float Chinthe { get; set; } - [Export] - public float GreenAmbassador { get; set; } - [Export] - public float RedAmbassador { get; set; } - [Export] - public float SteelAmbassador { get; set; } - [Export] - public float AgniDemon { get; set; } - [Export] - public float AqueosDemon { get; set; } - [Export] - public float Palan { get; set; } - [Export] - public float ShieldOfHeaven { get; set; } - [Export] - public float GoldSproingy { get; set; } - - [ExportGroup("True Route Spawn Rates")] - [Export] - public float TrueSproingy { get; set; } - [Export] - public float TrueMichael { get; set; } - [Export] - public float TrueFilthEater { get; set; } - [Export] - public float TrueSara { get; set; } - [Export] - public float TrueBallos { get; set; } - [Export] - public float TrueChariot { get; set; } - [Export] - public float TrueChinthe { get; set; } - [Export] - public float TrueGreenAmbassador { get; set; } - [Export] - public float TrueRedAmbassador { get; set; } - [Export] - public float TrueSteelAmbassador { get; set; } - [Export] - public float TrueAgniDemon { get; set; } - [Export] - public float TrueAqueosDemon { get; set; } - [Export] - public float TruePalan { get; set; } - [Export] - public float TrueShieldOfHeaven { get; set; } - [Export] - public float TrueGoldSproingy { get; set; } -} diff --git a/Zennysoft.Game.Ma/src/map/EnemySpawnRate.cs b/Zennysoft.Game.Ma/src/map/EnemySpawnRate.cs new file mode 100644 index 00000000..2745571e --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/EnemySpawnRate.cs @@ -0,0 +1,13 @@ +using Godot; + +namespace Zennysoft.Game.Ma; + +[GlobalClass] +public partial class EnemySpawnRate : Resource +{ + [Export] + public EnemyType EnemyType { get; set; } + + [Export] + public float SpawnRate { get; set; } +} \ No newline at end of file diff --git a/Zennysoft.Game.Ma/src/map/EnemySpawnRate.cs.uid b/Zennysoft.Game.Ma/src/map/EnemySpawnRate.cs.uid new file mode 100644 index 00000000..7f166375 --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/EnemySpawnRate.cs.uid @@ -0,0 +1 @@ +uid://bjal67ir4k11d diff --git a/Zennysoft.Game.Ma/src/map/EnemySpawnTable.cs.uid b/Zennysoft.Game.Ma/src/map/EnemySpawnTable.cs.uid new file mode 100644 index 00000000..03898754 --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/EnemySpawnTable.cs.uid @@ -0,0 +1 @@ +uid://0xsxfrp5akmf diff --git a/Zennysoft.Game.Ma/src/map/FloorResourceType.cs b/Zennysoft.Game.Ma/src/map/FloorResourceType.cs deleted file mode 100644 index b9c3e454..00000000 --- a/Zennysoft.Game.Ma/src/map/FloorResourceType.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Godot; - -namespace Zennysoft.Game.Ma; - -[GlobalClass] -public partial class FloorResourceType : Resource -{ - [Export] public string FloorDisplayName { get; set; } - - [Export] public string FolderPath { get; set; } -} diff --git a/Zennysoft.Game.Ma/src/map/FloorScenePathConverter.cs b/Zennysoft.Game.Ma/src/map/FloorScenePathConverter.cs new file mode 100644 index 00000000..d2ffe55a --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/FloorScenePathConverter.cs @@ -0,0 +1,152 @@ +using Godot; +using Godot.Collections; +using System; +using System.Linq; + +namespace Zennysoft.Game.Ma; + +public static class FloorScenePathConverter +{ + public static string Convert(FloorScene sceneToConvert) + { + string filePath = @"res://src/map/dungeon/floors/"; + + switch (sceneToConvert.FloorType) + { + case FloorType.Overworld: + return filePath + @"Special Floors/Overworld.tscn"; + case FloorType.Altar: + return filePath + @"Special Floors/00. Altar.tscn"; + case FloorType.Floor01: + return PickRandomFromFolder(filePath + "Floor01/"); + case FloorType.Floor02: + return PickRandomFromFolder(filePath + "Floor02/"); + case FloorType.Floor03: + return PickRandomFromFolder(filePath + "Floor03/"); + case FloorType.Floor04: + return PickRandomFromFolder(filePath + "Floor04/"); + case FloorType.Floor05: + return PickRandomFromFolder(filePath + "Floor05/"); + case FloorType.Floor06: + return PickRandomFromFolder(filePath + "Floor06/"); + case FloorType.Floor07: + return PickRandomFromFolder(filePath + "Floor07/"); + case FloorType.BossFloorA: + return filePath + "Special Floors/Floor 08 Boss Floor A.tscn"; + case FloorType.Floor09: + return PickRandomFromFolder(filePath + "Floor09/"); + case FloorType.Floor10: + return PickRandomFromFolder(filePath + "Floor10/"); + case FloorType.Floor11: + return PickRandomFromFolder(filePath + "Floor11/"); + case FloorType.Floor12: + return PickRandomFromFolder(filePath + "Floor12/"); + case FloorType.Floor13: + return PickRandomFromFolder(filePath + "Floor13/"); + case FloorType.Floor14: + return PickRandomFromFolder(filePath + "Floor14/"); + case FloorType.Floor15: + return PickRandomFromFolder(filePath + "Floor15/"); + case FloorType.BossFloorB: + return filePath + "Special Floors/Floor 16 Boss Floor B.tscn"; + case FloorType.GoddessOfGuidance: + return filePath + "Special Floors/35. Goddess of Guidance's Room.tscn"; + case FloorType.FinalFloor: + return filePath + "Special Floors/36. Final Floor.tscn"; + case FloorType.Server: + return filePath + "Special Floors/Server.tscn"; + case FloorType.Cellular: + return filePath + "Special Floors/Cellular.tscn"; + case FloorType.Grassland: + return filePath + "Special Floors/Grassland.tscn"; + case FloorType.Platform: + return filePath + "Special Floors/Platform.tscn"; + case FloorType.River: + return filePath + "Special Floors/River.tscn"; + case FloorType.BadEnd: + return filePath + "Special Floors/BAD END.tscn"; + case FloorType.HeartOfAllThings: + break; + case FloorType.TrueGoddessOfGuidance: + return filePath + "Special Floors/40. Goddess of Guidance's Room - True Form.tscn"; + default: + throw new NotImplementedException("Floor not added yet."); + } + + return string.Empty; + } + + public static string ConvertFromSpecificLayout(FloorScene sceneToConvert, string layoutSceneName) + { + string filePath = @"res://src/map/dungeon/floors/"; + + switch (sceneToConvert.FloorType) + { + case FloorType.Overworld: + return filePath + @"Special Floors/Overworld.tscn"; + case FloorType.Altar: + return filePath + @"Special Floors/00. Altar.tscn"; + case FloorType.Floor01: + return filePath + "Floor01/" + layoutSceneName; + case FloorType.Floor02: + return filePath + "Floor02/" + layoutSceneName; + case FloorType.Floor03: + return filePath + "Floor03/" + layoutSceneName; + case FloorType.Floor04: + return filePath + "Floor04/" + layoutSceneName; + case FloorType.Floor05: + return filePath + "Floor05/" + layoutSceneName; + case FloorType.Floor06: + return filePath + "Floor06/" + layoutSceneName; + case FloorType.Floor07: + return filePath + "Floor07/" + layoutSceneName; + case FloorType.BossFloorA: + return filePath + "Special Floors/Floor 08 Boss Floor A.tscn"; + case FloorType.Floor09: + return filePath + "Floor09/" + layoutSceneName; + case FloorType.Floor10: + return filePath + "Floor10/" + layoutSceneName; + case FloorType.Floor11: + return filePath + "Floor11/" + layoutSceneName; + case FloorType.Floor12: + return filePath + "Floor12/" + layoutSceneName; + case FloorType.Floor13: + return filePath + "Floor13/" + layoutSceneName; + case FloorType.Floor14: + return filePath + "Floor14/" + layoutSceneName; + case FloorType.Floor15: + return filePath + "Floor15/" + layoutSceneName; + case FloorType.BossFloorB: + return filePath + "Special Floors/Floor 16 Boss Floor B.tscn"; + case FloorType.GoddessOfGuidance: + return filePath + "Special Floors/35. Goddess of Guidance's Room.tscn"; + case FloorType.FinalFloor: + return filePath + "Special Floors/36. Final Floor.tscn"; + case FloorType.Server: + return filePath + "Special Floors/Server.tscn"; + case FloorType.Cellular: + return filePath + "Special Floors/Cellular.tscn"; + case FloorType.Grassland: + return filePath + "Special Floors/Grassland.tscn"; + case FloorType.Platform: + return filePath + "Special Floors/Platform.tscn"; + case FloorType.TrueGoddessOfGuidance: + return filePath + "Special Floors/40. Goddess of Guidance's Room - True Form.tscn"; + case FloorType.River: + return filePath + "Special Floors/River.tscn"; + case FloorType.BadEnd: + return filePath + "Special Floors/BAD END.tscn"; + case FloorType.HeartOfAllThings: + break; + default: + throw new NotImplementedException("Floor not added yet."); + } + + return string.Empty; + } + private static string PickRandomFromFolder(string folder) + { + Array files = [.. DirAccess.GetFilesAt(folder).Where(x => x.EndsWith(".tscn"))]; + return folder + files.PickRandom(); + } +} \ No newline at end of file diff --git a/Zennysoft.Game.Ma/src/map/FloorScenePathConverter.cs.uid b/Zennysoft.Game.Ma/src/map/FloorScenePathConverter.cs.uid new file mode 100644 index 00000000..5999b0cb --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/FloorScenePathConverter.cs.uid @@ -0,0 +1 @@ +uid://bbabjp5tg27q2 diff --git a/Zennysoft.Game.Ma/src/map/FloorType.cs b/Zennysoft.Game.Ma/src/map/FloorType.cs new file mode 100644 index 00000000..0f1ff60c --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/FloorType.cs @@ -0,0 +1,33 @@ +namespace Zennysoft.Game.Ma; + +public enum FloorType +{ + Overworld, + Altar, + Floor01, + Floor02, + Floor03, + Floor04, + Floor05, + Floor06, + Floor07, + Floor09, + Floor10, + Floor11, + Floor12, + Floor13, + Floor14, + Floor15, + BossFloorA, + BossFloorB, + GoddessOfGuidance, + TrueGoddessOfGuidance, + Cellular, + Grassland, + Platform, + River, + Server, + FinalFloor, + BadEnd, + HeartOfAllThings +} diff --git a/Zennysoft.Game.Ma/src/map/FloorType.cs.uid b/Zennysoft.Game.Ma/src/map/FloorType.cs.uid new file mode 100644 index 00000000..af4bdc07 --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/FloorType.cs.uid @@ -0,0 +1 @@ +uid://bdyjlodn1pijf diff --git a/Zennysoft.Game.Ma/src/map/IMap.cs b/Zennysoft.Game.Ma/src/map/IMap.cs index a7eaf1bf..cd55036e 100644 --- a/Zennysoft.Game.Ma/src/map/IMap.cs +++ b/Zennysoft.Game.Ma/src/map/IMap.cs @@ -1,6 +1,7 @@ using Chickensoft.Collections; using Chickensoft.GodotNodeInterfaces; using Godot; +using Godot.Collections; using System; using System.Threading.Tasks; @@ -8,31 +9,29 @@ namespace Zennysoft.Game.Ma; public interface IMap : INode3D { - void ClearFloor(); - - Task LoadFloor(); - - Task LoadFloor(string sceneName); - IDungeonFloor CurrentFloor { get; } - (Vector3 Rotation, Vector3 Position) GetPlayerSpawnPosition(); + public AutoProp CurrentSelectedFloor { get; } - IDungeonRoom GetPlayersCurrentRoom(); - - void InitializeMapData(); - - public void FadeIn(); - - public void FadeOut(); - - public AutoProp CurrentFloorNumber { get; } - - AutoProp CurrentFloorDisplayString { get; } - - public string NextFloorDisplayString { get; } + public Array FloorRoute { get; } public event Action<(Vector3 Rotation, Vector3 Position)> SpawnPointCreated; public event Action FloorLoaded; + + public void ShowMap(); + + Task LoadFloor(FloorScene floorToLoad); + + Task LoadFloorByPath(string filePath); + + public void AddNormalRoute(); + + public void AddTrueRoute(); + + public void AddBadEndRoute(); + + public void ResetToBaseRoute(); + + public void EndCurrentGame(); } diff --git a/Zennysoft.Game.Ma/src/map/LayoutToScenePathConverter.cs b/Zennysoft.Game.Ma/src/map/LayoutToScenePathConverter.cs deleted file mode 100644 index fbff0586..00000000 --- a/Zennysoft.Game.Ma/src/map/LayoutToScenePathConverter.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Godot; -using System; -using System.Linq; - -namespace Zennysoft.Game.Ma; - -public static class LayoutToScenePathConverter -{ - private static readonly string _folderPath = "res://src/map/dungeon/floors"; - - public static string Convert(FloorNode floorNode) - { - if (floorNode is DungeonFloorNode dungeonFloorNode) - return RandomDungeonFloor(dungeonFloorNode); - else if (floorNode is SpecialFloorNode specialFloorNode) - return SpawnSpecialFloor(specialFloorNode.FloorName); - throw new NotImplementedException(); - } - - private static string SpawnSpecialFloor(SpecialFloorType floorType) - { - var path = $"{_folderPath}/Special Floors/"; - var files = DirAccess.GetFilesAt(path); - switch (floorType) - { - case SpecialFloorType.Overworld: - return path + files.Single(x => x.EndsWith("Overworld.tscn")); - case SpecialFloorType.Altar: - return path + files.Single(x => x.EndsWith("Altar.tscn")); - case SpecialFloorType.BossFloorA: - return path + files.Single(x => x.EndsWith("Boss Floor A.tscn")); - case SpecialFloorType.BossFloorB: - return path + files.Single(x => x.EndsWith("Boss Floor B.tscn")); - case SpecialFloorType.GoddessOfGuidanceFloor: - return path + files.Single(x => x.EndsWith("Goddess of Guidance's Room.tscn")); - case SpecialFloorType.TrueGoddessOfGuidanceFloor: - return path + files.Single(x => x.EndsWith("Goddess of Guidance's Room - True Form.tscn")); - case SpecialFloorType.FinalFloor: - return path + files.Single(x => x.EndsWith("Final Floor.tscn")); - default: - throw new NotImplementedException(); - } - } - - private static string RandomDungeonFloor(DungeonFloorNode floorNode) - { - var folderName = _folderPath + "/" + floorNode.FolderName; - var floorList = DirAccess.GetFilesAt(folderName).Where(x => x.EndsWith(".tscn")); - var rng = new RandomNumberGenerator(); - rng.Randomize(); - var index = (int)rng.RandWeighted([.. floorNode.FloorOdds]); - var result = floorList.ElementAt(index); - return folderName + "/" + result; - } -} diff --git a/Zennysoft.Game.Ma/src/map/LayoutToScenePathConverter.cs.uid b/Zennysoft.Game.Ma/src/map/LayoutToScenePathConverter.cs.uid deleted file mode 100644 index 1a33a31d..00000000 --- a/Zennysoft.Game.Ma/src/map/LayoutToScenePathConverter.cs.uid +++ /dev/null @@ -1 +0,0 @@ -uid://d0yn4yu7264c8 diff --git a/Zennysoft.Game.Ma/src/map/Map.cs b/Zennysoft.Game.Ma/src/map/Map.cs index 1dcc8927..58c88ead 100644 --- a/Zennysoft.Game.Ma/src/map/Map.cs +++ b/Zennysoft.Game.Ma/src/map/Map.cs @@ -18,30 +18,34 @@ public partial class Map : Node3D, IMap [Dependency] public IGame Game => this.DependOn(); - [Node] - public Node MapOrder { get; set; } = default!; - [Node] public AnimationPlayer AnimationPlayer { get; set; } = default!; public IDungeonFloor CurrentFloor { get; private set; } - public AutoProp CurrentFloorNumber { get; private set; } = new AutoProp(0); - - public AutoProp CurrentFloorDisplayString { get; private set; } = new AutoProp(string.Empty); - - public string NextFloorDisplayString => MapOrder.GetChildren().OfType().ElementAt(CurrentFloorNumber.Value + 1).DisplayedFloorNumber; - - private readonly string _floorFilePath = @"res://src/map/dungeon/floors/"; - public event Action<(Vector3 Rotation, Vector3 Position)> SpawnPointCreated; - [Export] - public Array FloorOrder { get; set; } = []; + public Array FloorRoute { get; private set; } + + [Export] public Array BaseRoute { get; set; } + + [Export] public Array NormalEndRoute { get; set; } + + [Export] public Array TrueEndRoute { get; set; } + + [Export] public Array BadEndRoute { get; set; } + + public AutoProp CurrentSelectedFloor { get; set; } public event Action FloorLoaded; - private string _sceneName; + private string _floorToLoad; + + public override void _EnterTree() + { + FloorRoute = [.. BaseRoute]; + CurrentSelectedFloor = new AutoProp(FloorRoute.First()); + } public void OnResolved() { @@ -52,47 +56,93 @@ public partial class Map : Node3D, IMap private async void AnimationPlayer_AnimationFinished(StringName animName) { if (animName == "fade_out") - { - await LoadNewFloor(); - FloorLoaded?.Invoke(); - } + await ContinueLoadingFloor(_floorToLoad); } - private async Task LoadNewFloor() + public void ShowMap() => FadeIn(); + + private void FadeIn() => AnimationPlayer.Play("fade_in"); + private void FadeOut() => AnimationPlayer.Play("fade_out"); + + public void EndCurrentGame() + { + CleanupCurrentFloor(); + ClearFloor(); + FloorRoute = [.. BaseRoute]; + } + + public async Task LoadFloor(FloorScene floorToLoad) + { + Game.Pause(); + // Clean up current floor + CleanupCurrentFloor(); + // Start loading new floor + var filePath = FloorScenePathConverter.Convert(floorToLoad); + _floorToLoad = filePath; + FadeOut(); + } + + public async Task LoadFloorByPath(string filePath) + { + Game.Pause(); + // Clean up current floor + CleanupCurrentFloor(); + // Start loading new floor + _floorToLoad = filePath; + FadeOut(); + } + + public void AddNormalRoute() + { + FloorRoute.AddRange(NormalEndRoute); + } + + public void AddTrueRoute() + { + FloorRoute.AddRange(TrueEndRoute); + } + + public void AddBadEndRoute() + { + FloorRoute.AddRange(BadEndRoute); + } + + public void ResetToBaseRoute() + { + FloorRoute = [.. BaseRoute]; + CurrentSelectedFloor = new AutoProp(FloorRoute.First()); + } + + private async Task ContinueLoadingFloor(string filePath) { SpawnPointCreated?.Invoke((Vector3.Forward, new Vector3(-999, -999, -999))); - var newFloor = await LoadNewFloor(_sceneName); + var newFloor = await LoadSceneFile(filePath); + + // New floor created, remove old floor ClearFloor(); + + // Setup new floor AddChild(newFloor); - InitializeFloor(newFloor); - var floor = MapOrder.GetChildren().OfType().ElementAt(CurrentFloorNumber.Value); - if (CurrentFloor is DungeonFloor dungeonFloor && floor is DungeonFloorNode dungeonFloorNode) - dungeonFloor.SpawnEnemies(dungeonFloorNode); - CurrentFloorDisplayString.OnNext(floor.DisplayedFloorNumber); + CurrentFloor = newFloor as IDungeonFloor; + CurrentFloor.InitializeDungeon(); + SpawnPointCreated?.Invoke(CurrentFloor.GetPlayerSpawnPoint()); + if (CurrentFloor is SpecialFloor) + Game.ShowMinimap(false); + else + Game.ShowMinimap(true); + SpawnEnemies(); + CurrentFloor.FloorIsLoaded = true; + FloorLoaded?.Invoke(); } - public void FadeIn() => AnimationPlayer.Play("fade_in"); - public void FadeOut() => AnimationPlayer.Play("fade_out"); - - public void InitializeMapData() + private void CleanupCurrentFloor() { - CurrentFloorNumber.OnNext(-1); + var dimmableAudio = GetTree().GetNodesInGroup("DimmableAudio").OfType(); + foreach (var node in dimmableAudio) + node.FadeOut(); } - public IDungeonRoom GetPlayersCurrentRoom() - { - var rooms = CurrentFloor.Rooms; - var playersRoom = rooms.SingleOrDefault(x => x.IsPlayerInRoom); - return playersRoom; - } - - public (Vector3 Rotation, Vector3 Position) GetPlayerSpawnPosition() - { - var spawnPoint = CurrentFloor.GetPlayerSpawnPoint(); - return (spawnPoint.Rotation, spawnPoint.Position); - } - - public void ClearFloor() + private void ClearFloor() { try { @@ -105,35 +155,7 @@ public partial class Map : Node3D, IMap } } - public async Task LoadFloor() - { - var floor = MapOrder.GetChildren().OfType().ElementAt(CurrentFloorNumber.Value + 1); - var sceneToLoad = LayoutToScenePathConverter.Convert(floor); - await LoadFloor(sceneToLoad); - } - - public async Task LoadFloor(string sceneName) - { - CallDeferred(MethodName.FadeOut); - _sceneName = sceneName; - var dimmableAudio = GetTree().GetNodesInGroup("DimmableAudio").OfType(); - foreach (var node in dimmableAudio) - node.FadeOut(); - } - - private void InitializeFloor(Node newFloor) - { - CurrentFloor = (IDungeonFloor)newFloor; - SetupDungeonFloor(); - CurrentFloor.FloorIsLoaded = true; - CurrentFloorNumber.OnNext(CurrentFloorNumber.Value + 1); - if (CurrentFloor is SpecialFloor) - Game.ShowMinimap(false); - else - Game.ShowMinimap(true); - } - - private async Task LoadNewFloor(string sceneName) + private async Task LoadSceneFile(string sceneName) { var sceneLoader = new SceneLoader(); AddChild(sceneLoader); @@ -144,10 +166,10 @@ public partial class Map : Node3D, IMap return result; } - private void SetupDungeonFloor() + private void SpawnEnemies() { - CurrentFloor.InitializeDungeon(); - var transform = GetPlayerSpawnPosition(); - SpawnPointCreated?.Invoke(transform); + var monsterRooms = CurrentFloor.Rooms.OfType(); + foreach (var room in monsterRooms) + room.SpawnEnemies(CurrentSelectedFloor.Value.EnemySpawnTable); } -} +} \ No newline at end of file diff --git a/Zennysoft.Game.Ma/src/map/Map.tscn b/Zennysoft.Game.Ma/src/map/Map.tscn index 75589910..3ab1247b 100644 --- a/Zennysoft.Game.Ma/src/map/Map.tscn +++ b/Zennysoft.Game.Ma/src/map/Map.tscn @@ -1,15 +1,202 @@ -[gd_scene load_steps=10 format=3 uid="uid://by67pn7fdsg1m"] +[gd_scene load_steps=36 format=3 uid="uid://by67pn7fdsg1m"] [ext_resource type="Script" uid="uid://14e8mu48ed4" path="res://src/map/Map.cs" id="1_bw70o"] -[ext_resource type="Script" uid="uid://bvacb3ih0qt6u" path="res://src/map/FloorResourceType.cs" id="2_0qcd2"] -[ext_resource type="Script" uid="uid://dbe3wf3ywtjqh" path="res://src/map/DungeonFloorNode.cs" id="2_00xd7"] -[ext_resource type="Script" uid="uid://dpj4qg0ip6yui" path="res://src/map/SpecialFloorNode.cs" id="3_v14r0"] +[ext_resource type="Script" uid="uid://bnxutyeas2ymm" path="res://src/map/dungeon/floors/FloorScene.cs" id="2_0qcd2"] +[ext_resource type="Script" uid="uid://bjal67ir4k11d" path="res://src/map/EnemySpawnRate.cs" id="2_s7lwc"] [sub_resource type="Resource" id="Resource_s7lwc"] script = ExtResource("2_0qcd2") -FloorDisplayName = "" -FolderPath = "" -metadata/_custom_type_script = "uid://bvacb3ih0qt6u" +FloorDisplayName = "Surface" +FloorType = 0 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_1ny7u"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "Altar" +FloorType = 1 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_v14r0"] +script = ExtResource("2_s7lwc") +EnemyType = 0 +SpawnRate = 0.5 +metadata/_custom_type_script = "uid://bjal67ir4k11d" + +[sub_resource type="Resource" id="Resource_0qcd2"] +script = ExtResource("2_s7lwc") +EnemyType = 1 +SpawnRate = 0.5 +metadata/_custom_type_script = "uid://bjal67ir4k11d" + +[sub_resource type="Resource" id="Resource_3olkd"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "01" +FloorType = 2 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([SubResource("Resource_v14r0"), SubResource("Resource_0qcd2")]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_55rmo"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "02" +FloorType = 3 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_f6kwn"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "03" +FloorType = 4 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_ne2vg"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "04" +FloorType = 5 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_abpbr"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "05" +FloorType = 6 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_caf7v"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "06" +FloorType = 7 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_y74f3"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "07" +FloorType = 8 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_dbqu2"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "08" +FloorType = 16 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_xcm54"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "09" +FloorType = 9 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_pvu0e"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "10" +FloorType = 10 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_1de7e"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "11" +FloorType = 11 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_5suoo"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "12" +FloorType = 12 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_t2vkt"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "13" +FloorType = 13 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_hi63v"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "14" +FloorType = 14 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_httk4"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "15" +FloorType = 15 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_ro62w"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "16" +FloorType = 18 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_q7oan"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "18" +FloorType = 25 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_3vg2e"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "192" +FloorType = 24 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_tx34j"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "7776" +FloorType = 20 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_8npfy"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "11,664" +FloorType = 23 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_pids3"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "117,000,000,000" +FloorType = 21 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_u3fsa"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "5.63 × 10^7" +FloorType = 22 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_io2ww"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "∞" +FloorType = 19 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" + +[sub_resource type="Resource" id="Resource_rb6u5"] +script = ExtResource("2_0qcd2") +FloorDisplayName = "-1" +FloorType = 26 +EnemySpawnTable = Array[ExtResource("2_s7lwc")]([]) +metadata/_custom_type_script = "uid://bnxutyeas2ymm" [sub_resource type="Animation" id="Animation_00xd7"] length = 0.001 @@ -64,8 +251,12 @@ _data = { } [node name="Map" type="Node3D"] +process_mode = 3 script = ExtResource("1_bw70o") -FloorOrder = Array[ExtResource("2_0qcd2")]([SubResource("Resource_s7lwc")]) +BaseRoute = Array[ExtResource("2_0qcd2")]([SubResource("Resource_s7lwc"), SubResource("Resource_1ny7u"), SubResource("Resource_3olkd"), SubResource("Resource_55rmo"), SubResource("Resource_f6kwn"), SubResource("Resource_ne2vg"), SubResource("Resource_abpbr"), SubResource("Resource_caf7v"), SubResource("Resource_y74f3"), SubResource("Resource_dbqu2"), SubResource("Resource_xcm54"), SubResource("Resource_pvu0e"), SubResource("Resource_1de7e"), SubResource("Resource_5suoo"), SubResource("Resource_t2vkt"), SubResource("Resource_hi63v"), SubResource("Resource_httk4"), SubResource("Resource_ro62w")]) +NormalEndRoute = Array[ExtResource("2_0qcd2")]([SubResource("Resource_q7oan")]) +TrueEndRoute = Array[ExtResource("2_0qcd2")]([SubResource("Resource_3vg2e"), SubResource("Resource_tx34j"), SubResource("Resource_8npfy"), SubResource("Resource_pids3"), SubResource("Resource_u3fsa"), SubResource("Resource_io2ww")]) +BadEndRoute = Array[Object]([SubResource("Resource_rb6u5")]) [node name="AnimationPlayer" type="AnimationPlayer" parent="."] unique_name_in_owner = true @@ -73,176 +264,6 @@ libraries = { &"": SubResource("AnimationLibrary_00xd7") } -[node name="MapOrder" type="Node" parent="."] -unique_name_in_owner = true - -[node name="Overworld" type="Node" parent="MapOrder"] -script = ExtResource("3_v14r0") -DisplayedFloorNumber = "Surface" - -[node name="Altar" type="Node" parent="MapOrder"] -script = ExtResource("3_v14r0") -FloorName = 1 -DisplayedFloorNumber = "Altar" - -[node name="Floor01" type="Node" parent="MapOrder"] -script = ExtResource("2_00xd7") -FolderName = "Floor01" -FloorOdds = Array[float]([0.33, 0.33, 0.33]) -Sproingy = 0.5 -Michael = 0.5 -DisplayedFloorNumber = "01" - -[node name="Floor02" type="Node" parent="MapOrder"] -script = ExtResource("2_00xd7") -FolderName = "Floor02" -FloorOdds = Array[float]([0.33, 0.33, 0.33]) -Sproingy = 0.5 -Michael = 0.5 -FilthEater = 0.1 -GoldSproingy = 0.05 -TrueRedAmbassador = 0.3 -DisplayedFloorNumber = "02" - -[node name="Floor03" type="Node" parent="MapOrder"] -script = ExtResource("2_00xd7") -FolderName = "Floor03" -FloorOdds = Array[float]([0.33, 0.33, 0.33]) -Sproingy = 0.25 -Michael = 0.5 -FilthEater = 0.3 -Sara = 0.1 -GoldSproingy = 0.05 -TrueRedAmbassador = 0.3 -DisplayedFloorNumber = "03" - -[node name="Floor04" type="Node" parent="MapOrder"] -script = ExtResource("2_00xd7") -FolderName = "Floor04" -FloorOdds = Array[float]([0.33, 0.33, 0.33]) -FilthEater = 0.5 -Sara = 0.3 -AgniDemon = 0.3 -GoldSproingy = 0.05 -DisplayedFloorNumber = "04" - -[node name="Floor05" type="Node" parent="MapOrder"] -script = ExtResource("2_00xd7") -FolderName = "Floor05" -FloorOdds = Array[float]([0.5, 0.5]) -FilthEater = 0.25 -Sara = 0.5 -Ballos = 0.4 -RedAmbassador = 0.3 -AgniDemon = 0.5 -GoldSproingy = 0.05 -DisplayedFloorNumber = "05" - -[node name="Floor06" type="Node" parent="MapOrder"] -script = ExtResource("2_00xd7") -FolderName = "Floor06" -FloorOdds = Array[float]([0.2, 0.8, 0.5, 0.1]) -Sara = 0.5 -Ballos = 0.5 -RedAmbassador = 0.3 -AgniDemon = 0.5 -GoldSproingy = 0.05 -DisplayedFloorNumber = "06" - -[node name="Floor07" type="Node" parent="MapOrder"] -script = ExtResource("2_00xd7") -FolderName = "Floor07" -FloorOdds = Array[float]([0.33, 0.33, 0.33]) -Sara = 0.1 -Ballos = 0.5 -RedAmbassador = 0.3 -AgniDemon = 0.4 -GoldSproingy = 0.05 -DisplayedFloorNumber = "07" - -[node name="Boss Floor 1" type="Node" parent="MapOrder"] -script = ExtResource("3_v14r0") -FloorName = 2 -DisplayedFloorNumber = "08" - -[node name="Floor09" type="Node" parent="MapOrder"] -script = ExtResource("2_00xd7") -FolderName = "Floor09" -FloorOdds = Array[float]([0.5, 0.5]) -Chinthe = 0.5 -GreenAmbassador = 0.1 -DisplayedFloorNumber = "09" - -[node name="Floor10" type="Node" parent="MapOrder"] -script = ExtResource("2_00xd7") -FolderName = "Floor10" -FloorOdds = Array[float]([0.5, 0.5]) -Chinthe = 0.5 -GreenAmbassador = 0.5 -ShieldOfHeaven = 0.1 -DisplayedFloorNumber = "10" - -[node name="Floor11" type="Node" parent="MapOrder"] -script = ExtResource("2_00xd7") -FolderName = "Floor11" -FloorOdds = Array[float]([0.5, 0.5]) -Chinthe = 0.5 -GreenAmbassador = 0.5 -ShieldOfHeaven = 0.5 -DisplayedFloorNumber = "11" - -[node name="Floor12" type="Node" parent="MapOrder"] -script = ExtResource("2_00xd7") -FolderName = "Floor12" -FloorOdds = Array[float]([0.5, 0.5]) -GreenAmbassador = 0.5 -SteelAmbassador = 0.05 -ShieldOfHeaven = 0.5 -DisplayedFloorNumber = "12" - -[node name="Floor13" type="Node" parent="MapOrder"] -script = ExtResource("2_00xd7") -FolderName = "Floor13" -FloorOdds = Array[float]([0.5, 0.5]) -Sproingy = 1.0 -GreenAmbassador = 0.25 -SteelAmbassador = 0.05 -Palan = 0.3 -ShieldOfHeaven = 0.5 -DisplayedFloorNumber = "13" - -[node name="Floor14" type="Node" parent="MapOrder"] -script = ExtResource("2_00xd7") -FolderName = "Floor14" -FloorOdds = Array[float]([0.5, 0.5]) -SteelAmbassador = 0.05 -Palan = 0.5 -ShieldOfHeaven = 0.5 -GoldSproingy = 0.05 -DisplayedFloorNumber = "14" - -[node name="Floor15" type="Node" parent="MapOrder"] -script = ExtResource("2_00xd7") -FolderName = "Floor15" -FloorOdds = Array[float]([1.0]) -Sproingy = 1.0 -DisplayedFloorNumber = "15" - -[node name="Boss Floor 2" type="Node" parent="MapOrder"] -script = ExtResource("3_v14r0") -FloorName = 3 -DisplayedFloorNumber = "16" - -[node name="Goddess of Guidance Floor" type="Node" parent="MapOrder"] -script = ExtResource("3_v14r0") -FloorName = 4 -DisplayedFloorNumber = "17" - -[node name="Final Floor" type="Node" parent="MapOrder"] -script = ExtResource("3_v14r0") -FloorName = 6 -DisplayedFloorNumber = "18" - [node name="ColorRect" type="ColorRect" parent="."] anchors_preset = 15 anchor_right = 1.0 diff --git a/Zennysoft.Game.Ma/src/map/SpecialFloorObject.cs b/Zennysoft.Game.Ma/src/map/SpecialFloorObject.cs deleted file mode 100644 index d8cbe0d1..00000000 --- a/Zennysoft.Game.Ma/src/map/SpecialFloorObject.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Godot; - -namespace Zennysoft.Game.Ma; - -[GlobalClass] -public partial class SpecialFloorObject : FloorResourceType -{ - //[Export] public SpecialFloorType specialFloorType { get; set; } -} diff --git a/Zennysoft.Game.Ma/src/map/dungeon/code/DungeonFloor.cs b/Zennysoft.Game.Ma/src/map/dungeon/code/DungeonFloor.cs index 9962638e..5dece833 100644 --- a/Zennysoft.Game.Ma/src/map/dungeon/code/DungeonFloor.cs +++ b/Zennysoft.Game.Ma/src/map/dungeon/code/DungeonFloor.cs @@ -30,30 +30,6 @@ public partial class DungeonFloor : Node3D, IDungeonFloor } - public void SpawnEnemies(DungeonFloorNode floorNode) - { - var enemyOdds = new Godot.Collections.Dictionary - { - { EnemyType.Sproingy, floorNode.Sproingy }, - { EnemyType.Michael, floorNode.Michael }, - { EnemyType.FilthEater, floorNode.FilthEater }, - { EnemyType.Sara, floorNode.Sara }, - { EnemyType.Ballos, floorNode.Ballos }, - { EnemyType.Chinthe, floorNode.Chinthe }, - { EnemyType.AmbassadorGreen, floorNode.GreenAmbassador }, - { EnemyType.AmbassadorRed, floorNode.RedAmbassador }, - { EnemyType.AmbassadorSteel, floorNode.SteelAmbassador }, - { EnemyType.AgniDemon, floorNode.AgniDemon }, - { EnemyType.AqueousDemon, floorNode.AqueosDemon }, - { EnemyType.Palan, floorNode.Palan }, - { EnemyType.ShieldOfHeaven, floorNode.ShieldOfHeaven }, - { EnemyType.GoldSproingy, floorNode.GoldSproingy }, - }; - var monsterRooms = Rooms.OfType(); - foreach (var room in monsterRooms) - room.SpawnEnemies(enemyOdds); - } - public (Vector3 Rotation, Vector3 Position) GetPlayerSpawnPoint() { return (_playerSpawnPoint.Rotation, new Vector3(_playerSpawnPoint.GlobalPosition.X, 0, _playerSpawnPoint.GlobalPosition.Z)); } @@ -80,4 +56,10 @@ public partial class DungeonFloor : Node3D, IDungeonFloor return FindAllDungeonRooms([.. nodesToSearch.SelectMany(x => x.GetChildren())], roomsFound); } + + public IDungeonRoom GetPlayersCurrentRoom() + { + var playersRoom = Rooms.SingleOrDefault(x => x.IsPlayerInRoom); + return playersRoom; + } } diff --git a/Zennysoft.Game.Ma/src/map/dungeon/code/MonsterRoom.cs b/Zennysoft.Game.Ma/src/map/dungeon/code/MonsterRoom.cs index 0d2e1032..5b85027c 100644 --- a/Zennysoft.Game.Ma/src/map/dungeon/code/MonsterRoom.cs +++ b/Zennysoft.Game.Ma/src/map/dungeon/code/MonsterRoom.cs @@ -1,6 +1,7 @@ using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; +using Godot.Collections; using System.Linq; namespace Zennysoft.Game.Ma; @@ -18,55 +19,55 @@ public partial class MonsterRoom : DungeonRoom public override void _Ready() { - SpawnItems(); + SpawnItems(); } - public void SpawnEnemies(Godot.Collections.Dictionary enemyInfo) + public void SpawnEnemies(Array spawnTable) { - if (enemyInfo == null || !enemyInfo.Any(x => x.Value > 0)) - return; + if (spawnTable.Count == 0) + return; - var rng = new RandomNumberGenerator(); - rng.Randomize(); - var enemySpawnPoints = EnemySpawnPoints.GetChildren(); - var numberOfEnemiesToSpawn = rng.RandiRange(1, enemySpawnPoints.Count); + var rng = new RandomNumberGenerator(); + rng.Randomize(); + var enemySpawnPoints = EnemySpawnPoints.GetChildren(); + var numberOfEnemiesToSpawn = rng.RandiRange(1, enemySpawnPoints.Count); - foreach (var spawnPoint in enemySpawnPoints.Cast()) - { - if (numberOfEnemiesToSpawn <= 0) - break; - numberOfEnemiesToSpawn--; + foreach (var spawnPoint in enemySpawnPoints.Cast()) + { + if (numberOfEnemiesToSpawn <= 0) + break; + numberOfEnemiesToSpawn--; - var index = rng.RandWeighted([.. enemyInfo.Values]); - var selectedEnemy = enemyInfo.ElementAt((int)index); - var instantiatedEnemy = EnemyTypeToEnemyConverter.Convert(selectedEnemy.Key); - AddChild(instantiatedEnemy); - instantiatedEnemy.GlobalPosition = new Vector3(spawnPoint.GlobalPosition.X, 0f, spawnPoint.GlobalPosition.Z); - ResetPhysicsInterpolation(); - } + var index = rng.RandWeighted([.. spawnTable.Select(x => x.SpawnRate)]); + var selectedEnemy = spawnTable.ElementAt((int)index); + var instantiatedEnemy = EnemyTypeToEnemyConverter.Convert(selectedEnemy.EnemyType); + AddChild(instantiatedEnemy); + instantiatedEnemy.GlobalPosition = new Vector3(spawnPoint.GlobalPosition.X, 0f, spawnPoint.GlobalPosition.Z); + ResetPhysicsInterpolation(); + } } private void SpawnItems() { - if (ItemSpawnPoints == null) - return; + if (ItemSpawnPoints == null) + return; - var itemSpawnPoints = ItemSpawnPoints.GetChildren(); - var rng = new RandomNumberGenerator(); - rng.Randomize(); - var numberOfItemsToSpawn = rng.RandiRange(1, itemSpawnPoints.Count); - itemSpawnPoints.Shuffle(); - var database = ItemDatabase.Instance; - foreach (var spawnPoint in itemSpawnPoints.Cast()) - { - if (numberOfItemsToSpawn <= 0) - break; - numberOfItemsToSpawn--; + var itemSpawnPoints = ItemSpawnPoints.GetChildren(); + var rng = new RandomNumberGenerator(); + rng.Randomize(); + var numberOfItemsToSpawn = rng.RandiRange(1, itemSpawnPoints.Count); + itemSpawnPoints.Shuffle(); + var database = ItemDatabase.Instance; + foreach (var spawnPoint in itemSpawnPoints.Cast()) + { + if (numberOfItemsToSpawn <= 0) + break; + numberOfItemsToSpawn--; - var selectedItem = database.PickItem() as Node3D; - var duplicated = selectedItem.Duplicate((int)DuplicateFlags.UseInstantiation) as Node3D; - AddChild(duplicated); - duplicated.Position = new Vector3(spawnPoint.Position.X, 0, spawnPoint.Position.Z); - } + var selectedItem = database.PickItem() as Node3D; + var duplicated = selectedItem.Duplicate((int)DuplicateFlags.UseInstantiation) as Node3D; + AddChild(duplicated); + duplicated.Position = new Vector3(spawnPoint.Position.X, 0, spawnPoint.Position.Z); + } } } diff --git a/Zennysoft.Game.Ma/src/map/dungeon/code/SpecialFloor.cs b/Zennysoft.Game.Ma/src/map/dungeon/code/SpecialFloor.cs index 2bcdc358..f5e52176 100644 --- a/Zennysoft.Game.Ma/src/map/dungeon/code/SpecialFloor.cs +++ b/Zennysoft.Game.Ma/src/map/dungeon/code/SpecialFloor.cs @@ -21,4 +21,6 @@ public partial class SpecialFloor : Node3D, IDungeonFloor public bool FloorIsLoaded { get; set; } public virtual (Vector3 Rotation, Vector3 Position) GetPlayerSpawnPoint() => (PlayerSpawnPoint.Rotation, new Vector3(PlayerSpawnPoint.Position.X, 0, PlayerSpawnPoint.Position.Z)); + + public IDungeonRoom GetPlayersCurrentRoom() => null; } \ No newline at end of file diff --git a/Zennysoft.Game.Ma/src/map/dungeon/floors/FloorScene.cs b/Zennysoft.Game.Ma/src/map/dungeon/floors/FloorScene.cs new file mode 100644 index 00000000..d04dfad8 --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/dungeon/floors/FloorScene.cs @@ -0,0 +1,14 @@ +using Godot; +using Godot.Collections; + +namespace Zennysoft.Game.Ma; + +[GlobalClass] +public partial class FloorScene : Resource +{ + [Export] public string FloorDisplayName { get; set; } + + [Export] public FloorType FloorType { get; set; } + + [Export] public Array EnemySpawnTable { get; set; } = []; +} diff --git a/Zennysoft.Game.Ma/src/map/dungeon/floors/FloorScene.cs.uid b/Zennysoft.Game.Ma/src/map/dungeon/floors/FloorScene.cs.uid new file mode 100644 index 00000000..edef484b --- /dev/null +++ b/Zennysoft.Game.Ma/src/map/dungeon/floors/FloorScene.cs.uid @@ -0,0 +1 @@ +uid://bnxutyeas2ymm diff --git a/Zennysoft.Game.Ma/src/menu/DebugMenu.tscn b/Zennysoft.Game.Ma/src/menu/DebugMenu.tscn index df1ff6f1..2885649a 100644 --- a/Zennysoft.Game.Ma/src/menu/DebugMenu.tscn +++ b/Zennysoft.Game.Ma/src/menu/DebugMenu.tscn @@ -63,6 +63,17 @@ layout_mode = 2 focus_neighbor_bottom = NodePath("../SpawnEnemyDropDown") theme_override_styles/normal = SubResource("StyleBoxFlat_1ctjd") +[node name="Layout Select" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer/VFlowContainer"] +layout_mode = 2 +text = "Layout Select:" +label_settings = ExtResource("2_a7f7f") + +[node name="LayoutSelectDropDown" type="OptionButton" parent="MarginContainer/VBoxContainer/HBoxContainer/VFlowContainer"] +unique_name_in_owner = true +layout_mode = 2 +focus_neighbor_bottom = NodePath("../SpawnEnemyDropDown") +theme_override_styles/normal = SubResource("StyleBoxFlat_1ctjd") + [node name="Label" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer/VFlowContainer"] layout_mode = 2 text = "Spawn Item:" @@ -167,3 +178,20 @@ text = "Rust" unique_name_in_owner = true layout_mode = 2 text = "Show Debug Info Overlay" + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/VBoxContainer/HBoxContainer/HBoxContainer"] +layout_mode = 2 +theme_override_constants/separation = 15 + +[node name="RouteSelect" type="Label" parent="MarginContainer/VBoxContainer/HBoxContainer/HBoxContainer/VBoxContainer"] +layout_mode = 2 +text = "Route Select:" +label_settings = ExtResource("2_a7f7f") + +[node name="RouteSelectDropDown" type="OptionButton" parent="MarginContainer/VBoxContainer/HBoxContainer/HBoxContainer/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +theme_override_styles/normal = SubResource("StyleBoxFlat_1ctjd") diff --git a/Zennysoft.Game.Ma/src/minimap/Minimap.cs b/Zennysoft.Game.Ma/src/minimap/Minimap.cs index 62456767..67bb19ae 100644 --- a/Zennysoft.Game.Ma/src/minimap/Minimap.cs +++ b/Zennysoft.Game.Ma/src/minimap/Minimap.cs @@ -21,7 +21,7 @@ public partial class Minimap : Control public void OnResolved() { - _map.CurrentFloorDisplayString.Sync += CurrentFloorNumber_Sync; + _map.CurrentSelectedFloor.Sync += CurrentFloorNumber_Sync; _ready = true; } @@ -31,13 +31,13 @@ public partial class Minimap : Control MinimapCamera.Position = new Vector3(_player.GlobalPosition.X, MinimapCamera.Position.Y, _player.GlobalPosition.Z); } - private void CurrentFloorNumber_Sync(string obj) + private void CurrentFloorNumber_Sync(FloorScene obj) { - LayerNumberText.Text = obj; + LayerNumberText.Text = obj.FloorDisplayName; } public void OnExitTree() { - _map.CurrentFloorDisplayString.Sync -= CurrentFloorNumber_Sync; + _map.CurrentSelectedFloor.Sync -= CurrentFloorNumber_Sync; } } diff --git a/Zennysoft.Game.Ma/src/minimap/Minimap.tscn b/Zennysoft.Game.Ma/src/minimap/Minimap.tscn index 54681899..b648d0c9 100644 --- a/Zennysoft.Game.Ma/src/minimap/Minimap.tscn +++ b/Zennysoft.Game.Ma/src/minimap/Minimap.tscn @@ -42,6 +42,7 @@ orientation = 1 [node name="Minimap" type="Control"] process_mode = 3 +visible = false light_mask = 2 visibility_layer = 2 layout_mode = 3 @@ -71,7 +72,7 @@ layout_mode = 2 transparent_bg = true handle_input_locally = false size = Vector2i(400, 350) -render_target_update_mode = 4 +render_target_update_mode = 0 [node name="MinimapCamera" type="Camera3D" parent="CenterContainer/SubViewportContainer/SubViewport"] unique_name_in_owner = true diff --git a/Zennysoft.Game.Ma/src/ui/load_next_level/IFloorClearMenu.cs b/Zennysoft.Game.Ma/src/ui/load_next_level/IFloorClearMenu.cs index e2a0f825..c3c3da96 100644 --- a/Zennysoft.Game.Ma/src/ui/load_next_level/IFloorClearMenu.cs +++ b/Zennysoft.Game.Ma/src/ui/load_next_level/IFloorClearMenu.cs @@ -5,8 +5,6 @@ namespace Zennysoft.Game.Ma; public interface IFloorClearMenu : IControl { - public event Action GoToNextFloor; - public event Action Exit; public event Action TransitionCompleted; diff --git a/Zennysoft.Game.Ma/src/ui/load_next_level/LoadNextLevel.cs b/Zennysoft.Game.Ma/src/ui/load_next_level/LoadNextLevel.cs index 76ebdeb0..5f80c922 100644 --- a/Zennysoft.Game.Ma/src/ui/load_next_level/LoadNextLevel.cs +++ b/Zennysoft.Game.Ma/src/ui/load_next_level/LoadNextLevel.cs @@ -33,8 +33,6 @@ public partial class LoadNextLevel : Control, IFloorClearMenu public void FadeOut() => AnimationPlayer.Play("fade_out"); - public event Action GoToNextFloor; - public event Action Exit; public event Action TransitionCompleted; @@ -49,9 +47,10 @@ public partial class LoadNextLevel : Control, IFloorClearMenu AnimationPlayer.AnimationStarted += AnimationPlayer_AnimationStarted; ContinueButton.Pressed += ContinueButton_Pressed; ExitButton.Pressed += ExitButton_Pressed; + _map.CurrentSelectedFloor.Changed += CurrentSelectedFloor_Changed; } - private void CurrentFloorNumber_Sync(int _) => FloorNumber.Text = _map.NextFloorDisplayString; + private void CurrentSelectedFloor_Changed(FloorScene obj) => FloorNumber.Text = obj.FloorDisplayName; private void EquipmentComponent_EquipmentChanged(IEquipableItem obj) { @@ -81,22 +80,24 @@ public partial class LoadNextLevel : Control, IFloorClearMenu ContinueButton.FocusMode = FocusModeEnum.None; ExitButton.FocusMode = FocusModeEnum.None; SfxDatabase.Instance.Play(SoundEffect.SelectUI); - GoToNextFloor?.Invoke(); + FadeOut(); } - private void AnimationPlayer_AnimationStarted(StringName animName) + private async void AnimationPlayer_AnimationStarted(StringName animName) { if (animName == "fade_in") { _fadingIn = true; ContinueButton.FocusMode = FocusModeEnum.None; ExitButton.FocusMode = FocusModeEnum.None; + _map.CurrentSelectedFloor.OnNext(_map.FloorRoute[_map.FloorRoute.IndexOf(_map.CurrentSelectedFloor.Value) + 1]); } if (animName == "fade_out") { DisableUISync(); _fadingIn = false; ContinueButton.CallDeferred(MethodName.ReleaseFocus); + await _map.LoadFloor(_map.CurrentSelectedFloor.Value); } } @@ -130,7 +131,7 @@ public partial class LoadNextLevel : Control, IFloorClearMenu _player.DefenseComponent.CurrentDefense.Sync += Defense_Sync; _player.DefenseComponent.MaximumDefense.Sync += Defense_Sync; _player.EquipmentComponent.EquipmentChanged += EquipmentComponent_EquipmentChanged; - _map.CurrentFloorNumber.Sync += CurrentFloorNumber_Sync; + _map.CurrentSelectedFloor.Changed += CurrentSelectedFloor_Changed; } private void DisableUISync() @@ -147,6 +148,6 @@ public partial class LoadNextLevel : Control, IFloorClearMenu _player.DefenseComponent.CurrentDefense.Sync -= Defense_Sync; _player.DefenseComponent.MaximumDefense.Sync -= Defense_Sync; _player.EquipmentComponent.EquipmentChanged -= EquipmentComponent_EquipmentChanged; - _map.CurrentFloorNumber.Sync -= CurrentFloorNumber_Sync; + _map.CurrentSelectedFloor.Changed -= CurrentSelectedFloor_Changed; } } diff --git a/Zennysoft.Game.Ma/src/ui/load_next_level/LoadNextLevel.tscn b/Zennysoft.Game.Ma/src/ui/load_next_level/LoadNextLevel.tscn index 19deb209..804a17b9 100644 --- a/Zennysoft.Game.Ma/src/ui/load_next_level/LoadNextLevel.tscn +++ b/Zennysoft.Game.Ma/src/ui/load_next_level/LoadNextLevel.tscn @@ -77,10 +77,22 @@ tracks/0/path = NodePath(".:modulate") tracks/0/interp = 1 tracks/0/loop_wrap = true tracks/0/keys = { +"times": PackedFloat32Array(0, 0.999, 1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 0, +"values": [Color(1, 1, 1, 1), Color(0, 0, 0, 1), Color(0, 0, 0, 1)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath(".:visible") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { "times": PackedFloat32Array(0, 1), "transitions": PackedFloat32Array(1, 1), -"update": 0, -"values": [Color(1, 1, 1, 1), Color(0, 0, 0, 1)] +"update": 1, +"values": [true, false] } [sub_resource type="AnimationLibrary" id="AnimationLibrary_7x216"] diff --git a/Zennysoft.Game.Ma/src/ui/pause_menu/PauseDebugMenu.cs b/Zennysoft.Game.Ma/src/ui/pause_menu/PauseDebugMenu.cs index 03796910..91ad65b7 100644 --- a/Zennysoft.Game.Ma/src/ui/pause_menu/PauseDebugMenu.cs +++ b/Zennysoft.Game.Ma/src/ui/pause_menu/PauseDebugMenu.cs @@ -1,6 +1,9 @@ using Chickensoft.AutoInject; +using Chickensoft.Collections; using Chickensoft.Introspection; +using Chickensoft.LogicBlocks; using Godot; +using Godot.Collections; using System.Collections.Immutable; using System.Linq; using Zennysoft.Ma; @@ -20,6 +23,9 @@ public partial class PauseDebugMenu : Control, IDebugMenu [Dependency] private IPlayer _player => this.DependOn(); [Node] public OptionButton FloorSelectDropDown { get; set; } = default!; + [Node] public OptionButton LayoutSelectDropDown { get; set; } = default!; + + [Node] public OptionButton RouteSelectDropDown { get; set; } = default!; [Node] public OptionButton SpawnItemDropDown { get; set; } = default; @@ -74,22 +80,30 @@ public partial class PauseDebugMenu : Control, IDebugMenu foreach (var item in _spawnableItems) SpawnItemDropDown.AddItem(item.ItemName); - var folders = DirAccess.GetDirectoriesAt(_floorFilePath); - - foreach (var folder in folders) - { - var files = DirAccess.GetFilesAt(_floorFilePath + folder).Where(x => x.EndsWith(".tscn")); - foreach (var file in files) - FloorSelectDropDown.AddItem(folder + "/" + file); - } - SigilDropDown.Select(0); + var dungeonFolders = DirAccess.GetDirectoriesAt(_floorFilePath).Except(["Special Floors"]); + foreach (var dungeonFolder in dungeonFolders) + { + var layouts = DirAccess.GetFilesAt(_floorFilePath + dungeonFolder).Where(x => x.EndsWith(".tscn")); + foreach (var layout in layouts) + LayoutSelectDropDown.AddItem(dungeonFolder + "/" + layout); + } + FloorSelectDropDown.AllowReselect = true; + LayoutSelectDropDown.AllowReselect = true; SpawnItemDropDown.AllowReselect = true; SpawnEnemyDropDown.AllowReselect = true; + RouteSelectDropDown.AddItem("Base"); + RouteSelectDropDown.AddItem("Normal"); + RouteSelectDropDown.AddItem("True"); + RouteSelectDropDown.AddItem("Bad"); + RouteSelectDropDown.Select(0); + RouteSelectDropDown.ItemSelected += RouteSelectDropDown_ItemSelected; + FloorSelectDropDown.ItemSelected += FloorSelectDropDown_ItemSelected; + LayoutSelectDropDown.ItemSelected += LayoutSelectDropDown_ItemSelected; SpawnItemDropDown.ItemSelected += SpawnItemDropDown_ItemSelected; SpawnEnemyDropDown.ItemSelected += SpawnEnemyDropDown_ItemSelected; @@ -98,6 +112,42 @@ public partial class PauseDebugMenu : Control, IDebugMenu DebugInfoCheckbox.Pressed += DebugInfoCheckbox_Pressed; } + private void RouteSelectDropDown_ItemSelected(long index) + { + _map.ResetToBaseRoute(); + var selectedItem = RouteSelectDropDown.GetItemText((int)index); + + if (selectedItem == "Normal") + _map.AddNormalRoute(); + else if (selectedItem == "True") + _map.AddTrueRoute(); + else if (selectedItem == "Bad") + _map.AddBadEndRoute(); + + SetFloorDropdownItems(); + LayoutSelectDropDown.Select(0); + FloorSelectDropDown_ItemSelected(0); + } + + private void SetFloorDropdownItems() + { + FloorSelectDropDown.Clear(); + foreach (var item in _map.FloorRoute) + FloorSelectDropDown.AddItem(item.FloorType.ToString()); + } + + private async void LayoutSelectDropDown_ItemSelected(long index) + { + var selection = LayoutSelectDropDown.GetItemText((int)index); + _map.CurrentSelectedFloor.OnNext(_map.FloorRoute.Single(x => selection.Contains(x.FloorDisplayName))); + await _map.LoadFloorByPath(_floorFilePath + selection); + } + + public void OnResolved() + { + SetFloorDropdownItems(); + } + private void SigilDropDown_ItemSelected(long index) { var sigilName = SigilDropDown.GetItemText((int)index); @@ -128,10 +178,12 @@ public partial class PauseDebugMenu : Control, IDebugMenu private void RustButton_Pressed() => _player.StatusEffectComponent.Rust.OnNext(true); - private void FloorSelectDropDown_ItemSelected(long index) + private async void FloorSelectDropDown_ItemSelected(long index) { - var sceneName = FloorSelectDropDown.GetItemText((int)index); - _map.LoadFloor(_floorFilePath + "/" + sceneName); + var selection = FloorSelectDropDown.GetItemText((int)index); + var selectedFloor = _map.FloorRoute[(int)index]; + _map.CurrentSelectedFloor.OnNext(selectedFloor); + await _map.LoadFloor(selectedFloor); } private void SpawnEnemyDropDown_ItemSelected(long index) @@ -152,6 +204,7 @@ public partial class PauseDebugMenu : Control, IDebugMenu private async void LoadNextFloorButton_Pressed() { - await _map.LoadFloor(); + _map.CurrentSelectedFloor.OnNext(_map.FloorRoute[_map.FloorRoute.IndexOf(_map.CurrentSelectedFloor.Value) + 1]); + await _map.LoadFloor(_map.CurrentSelectedFloor.Value); } } diff --git a/Zennysoft.Game.Ma/src/utils/SceneLoader.cs b/Zennysoft.Game.Ma/src/utils/SceneLoader.cs index 1c84004d..f59ceb0c 100644 --- a/Zennysoft.Game.Ma/src/utils/SceneLoader.cs +++ b/Zennysoft.Game.Ma/src/utils/SceneLoader.cs @@ -1,5 +1,4 @@ using Godot; -using System; using System.Linq; namespace Zennysoft.Game.Ma;