112 lines
3.1 KiB
C#
112 lines
3.1 KiB
C#
using Chickensoft.AutoInject;
|
|
using Chickensoft.Collections;
|
|
using Chickensoft.Introspection;
|
|
using Godot;
|
|
using System;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Zennysoft.Game.Ma;
|
|
|
|
[Meta(typeof(IAutoNode))]
|
|
public partial class Map : Node3D, IMap
|
|
{
|
|
public override void _Notification(int what) => this.Notify(what);
|
|
|
|
[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);
|
|
|
|
private readonly string _floorFilePath = @"res://src/map/dungeon/floors/";
|
|
|
|
public event Action<(Vector3 Rotation, Vector3 Position)> SpawnPointCreated;
|
|
|
|
public event Action FloorLoaded;
|
|
|
|
public void OnResolved()
|
|
{
|
|
this.Provide();
|
|
}
|
|
|
|
public void InitializeMapData()
|
|
{
|
|
CurrentFloorNumber.OnNext(-1);
|
|
}
|
|
|
|
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 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)
|
|
{
|
|
AnimationPlayer.CallDeferred(AnimationPlayer.MethodName.Play, "fade_out");
|
|
ClearMap();
|
|
var newFloor = await LoadNewFloor(sceneName);
|
|
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);
|
|
AnimationPlayer.CallDeferred(AnimationPlayer.MethodName.Play, ("fade_in"));
|
|
}
|
|
|
|
public void ClearMap()
|
|
{
|
|
AnimationPlayer.CallDeferred(AnimationPlayer.MethodName.Play, "fade_out");
|
|
CurrentFloor?.CallDeferred(MethodName.QueueFree, []);
|
|
SpawnPointCreated?.Invoke((Vector3.Forward, new Vector3(-999, -999, -999)));
|
|
}
|
|
|
|
private void InitializeFloor(Node newFloor)
|
|
{
|
|
CurrentFloor = (IDungeonFloor)newFloor;
|
|
SetupDungeonFloor();
|
|
CurrentFloor.FloorIsLoaded = true;
|
|
CurrentFloorNumber.OnNext(CurrentFloorNumber.Value + 1);
|
|
FloorLoaded?.Invoke();
|
|
}
|
|
|
|
private async Task<Node> LoadNewFloor(string sceneName)
|
|
{
|
|
var sceneLoader = new SceneLoader();
|
|
AddChild(sceneLoader);
|
|
sceneLoader.LoadSceneRequest(sceneName);
|
|
await ToSignal(sceneLoader, SceneLoader.SignalName.SceneLoaded);
|
|
var result = sceneLoader.LoadedScene;
|
|
sceneLoader.QueueFree();
|
|
return result;
|
|
}
|
|
|
|
private void SetupDungeonFloor()
|
|
{
|
|
CurrentFloor.InitializeDungeon();
|
|
var transform = GetPlayerSpawnPosition();
|
|
SpawnPointCreated?.Invoke(transform);
|
|
}
|
|
}
|