Files
GameJamDungeon/Zennysoft.Game.Ma/src/map/Map.cs
2026-02-06 17:07:38 -08:00

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);
}
}