Revamp map route stuff
This commit is contained in:
+1
@@ -13,6 +13,7 @@ public partial class GameState
|
||||
public FloorExitScreen()
|
||||
{
|
||||
OnAttach(() => Get<IGameRepo>().Pause());
|
||||
OnDetach(() => Get<IGameRepo>().Resume());
|
||||
}
|
||||
|
||||
public Transition On(in Input.LoadNextFloor input)
|
||||
|
||||
@@ -11,5 +11,7 @@ public interface IDungeonFloor : INode3D
|
||||
|
||||
public ImmutableList<IDungeonRoom> Rooms { get; }
|
||||
|
||||
public IDungeonRoom GetPlayersCurrentRoom();
|
||||
|
||||
public bool FloorIsLoaded { get; set; }
|
||||
}
|
||||
|
||||
@@ -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<MonsterRoom>(rooms.OfType<MonsterRoom>());
|
||||
var randomRoom = validRooms.PickRandom();
|
||||
|
||||
@@ -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<PackedScene>("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;
|
||||
|
||||
|
||||
@@ -52,6 +52,10 @@ public interface IGame : IProvide<IGame>, IProvide<IGameRepo>, IProvide<IPlayer>
|
||||
|
||||
public Task OnReachTrueEnd();
|
||||
|
||||
public void Pause();
|
||||
|
||||
public void Resume();
|
||||
|
||||
public ItemRescueMenu ItemRescueMenu { get; }
|
||||
|
||||
public QuestData QuestData { get; }
|
||||
|
||||
@@ -22,7 +22,7 @@ public class EffectService
|
||||
|
||||
public void TeleportEnemiesToCurrentRoom(List<IEnemy> 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;
|
||||
|
||||
@@ -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<float> 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; }
|
||||
}
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://bjal67ir4k11d
|
||||
@@ -0,0 +1 @@
|
||||
uid://0xsxfrp5akmf
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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<string> files = [.. DirAccess.GetFilesAt(folder).Where(x => x.EndsWith(".tscn"))];
|
||||
return folder + files.PickRandom();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://bbabjp5tg27q2
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://bdyjlodn1pijf
|
||||
@@ -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<FloorScene> CurrentSelectedFloor { get; }
|
||||
|
||||
IDungeonRoom GetPlayersCurrentRoom();
|
||||
|
||||
void InitializeMapData();
|
||||
|
||||
public void FadeIn();
|
||||
|
||||
public void FadeOut();
|
||||
|
||||
public AutoProp<int> CurrentFloorNumber { get; }
|
||||
|
||||
AutoProp<string> CurrentFloorDisplayString { get; }
|
||||
|
||||
public string NextFloorDisplayString { get; }
|
||||
public Array<FloorScene> 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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
uid://d0yn4yu7264c8
|
||||
@@ -18,30 +18,34 @@ public partial class Map : Node3D, IMap
|
||||
[Dependency]
|
||||
public IGame Game => this.DependOn<IGame>();
|
||||
|
||||
[Node]
|
||||
public Node MapOrder { get; set; } = default!;
|
||||
|
||||
[Node]
|
||||
public AnimationPlayer AnimationPlayer { get; set; } = default!;
|
||||
|
||||
public IDungeonFloor CurrentFloor { get; private set; }
|
||||
|
||||
public AutoProp<int> CurrentFloorNumber { get; private set; } = new AutoProp<int>(0);
|
||||
|
||||
public AutoProp<string> CurrentFloorDisplayString { get; private set; } = new AutoProp<string>(string.Empty);
|
||||
|
||||
public string NextFloorDisplayString => MapOrder.GetChildren().OfType<FloorNode>().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<FloorResourceType> FloorOrder { get; set; } = [];
|
||||
public Array<FloorScene> FloorRoute { get; private set; }
|
||||
|
||||
[Export] public Array<FloorScene> BaseRoute { get; set; }
|
||||
|
||||
[Export] public Array<FloorScene> NormalEndRoute { get; set; }
|
||||
|
||||
[Export] public Array<FloorScene> TrueEndRoute { get; set; }
|
||||
|
||||
[Export] public Array<FloorScene> BadEndRoute { get; set; }
|
||||
|
||||
public AutoProp<FloorScene> CurrentSelectedFloor { get; set; }
|
||||
|
||||
public event Action FloorLoaded;
|
||||
|
||||
private string _sceneName;
|
||||
private string _floorToLoad;
|
||||
|
||||
public override void _EnterTree()
|
||||
{
|
||||
FloorRoute = [.. BaseRoute];
|
||||
CurrentSelectedFloor = new AutoProp<FloorScene>(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<FloorScene>(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<FloorNode>().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<IDimmableAudioStreamPlayer>();
|
||||
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<FloorNode>().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<IDimmableAudioStreamPlayer>();
|
||||
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<Node> LoadNewFloor(string sceneName)
|
||||
private async Task<Node> 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<MonsterRoom>();
|
||||
foreach (var room in monsterRooms)
|
||||
room.SpawnEnemies(CurrentSelectedFloor.Value.EnemySpawnTable);
|
||||
}
|
||||
}
|
||||
}
|
||||
+199
-178
@@ -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
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
using Godot;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class SpecialFloorObject : FloorResourceType
|
||||
{
|
||||
//[Export] public SpecialFloorType specialFloorType { get; set; }
|
||||
}
|
||||
@@ -30,30 +30,6 @@ public partial class DungeonFloor : Node3D, IDungeonFloor
|
||||
|
||||
}
|
||||
|
||||
public void SpawnEnemies(DungeonFloorNode floorNode)
|
||||
{
|
||||
var enemyOdds = new Godot.Collections.Dictionary<EnemyType, float>
|
||||
{
|
||||
{ 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<MonsterRoom>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<EnemyType, float> enemyInfo)
|
||||
public void SpawnEnemies(Array<EnemySpawnRate> 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<Marker3D>())
|
||||
{
|
||||
if (numberOfEnemiesToSpawn <= 0)
|
||||
break;
|
||||
numberOfEnemiesToSpawn--;
|
||||
foreach (var spawnPoint in enemySpawnPoints.Cast<Marker3D>())
|
||||
{
|
||||
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<Marker3D>())
|
||||
{
|
||||
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<Marker3D>())
|
||||
{
|
||||
if (numberOfItemsToSpawn <= 0)
|
||||
break;
|
||||
numberOfItemsToSpawn--;
|
||||
|
||||
var selectedItem = database.PickItem<IBaseInventoryItem>() 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<IBaseInventoryItem>() as Node3D;
|
||||
var duplicated = selectedItem.Duplicate((int)DuplicateFlags.UseInstantiation) as Node3D;
|
||||
AddChild(duplicated);
|
||||
duplicated.Position = new Vector3(spawnPoint.Position.X, 0, spawnPoint.Position.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<EnemySpawnRate> EnemySpawnTable { get; set; } = [];
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://bnxutyeas2ymm
|
||||
@@ -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")
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -5,8 +5,6 @@ namespace Zennysoft.Game.Ma;
|
||||
|
||||
public interface IFloorClearMenu : IControl
|
||||
{
|
||||
public event Action GoToNextFloor;
|
||||
|
||||
public event Action Exit;
|
||||
|
||||
public event Action TransitionCompleted;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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<IPlayer>();
|
||||
|
||||
[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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
Reference in New Issue
Block a user