using Chickensoft.AutoInject; using Chickensoft.Collections; using Chickensoft.Introspection; using Chickensoft.LogicBlocks; using Chickensoft.SaveFileBuilder; using Godot; using System.Collections.Generic; using System.Linq; using Zennysoft.Ma.Adapter; 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(); [Dependency] public IPlayer Player => this.DependOn(); #region Save public ISaveChunk MapChunk { get; set; } = default!; ISaveChunk IProvide>.Value() => MapChunk; [Dependency] public ISaveChunk GameChunk => this.DependOn>(); #endregion [Export] private Godot.Collections.Array _floors { get; set; } = default!; public List FloorScenes { get; private set; } = []; public IDungeonFloor CurrentFloor { get; private set; } public AutoProp CurrentFloorNumber { get; private set; } = new AutoProp(0); public void OnResolved() { MapChunk = new SaveChunk( onSave: (chunk) => new MapData() { FloorScenes = FloorScenes, }, onLoad: (chunk, data) => { FloorScenes = data.FloorScenes; } ); GameChunk.AddChunk(MapChunk); this.Provide(); InitializeMapData(); } public void InitializeMapData() { ClearMap(); FloorScenes = []; foreach (var floor in _floors) FloorScenes.Add(floor.ResourcePath); CurrentFloorNumber.OnNext(0); } public void LoadMap() { LoadFloor(); CurrentFloor.InitializeDungeon(); var transform = GetPlayerSpawnPosition(); Player.TeleportPlayer(transform); CurrentFloor.FloorIsLoaded = true; } private void ClearMap() { CurrentFloor?.CallDeferred(MethodName.QueueFree, []); } public void SpawnNextFloor() { ClearMap(); LoadFloor(); CurrentFloor.InitializeDungeon(); var transform = GetPlayerSpawnPosition(); Player.TeleportPlayer(transform); CurrentFloor.FloorIsLoaded = true; CurrentFloorNumber.OnNext(CurrentFloorNumber.Value + 1); } public IDungeonRoom GetPlayersCurrentRoom() { var rooms = CurrentFloor.Rooms; var playersRoom = rooms.SingleOrDefault(x => x.IsPlayerInRoom); return playersRoom; } public Transform3D GetPlayerSpawnPosition() => CurrentFloor.GetPlayerSpawnPoint(); public void LoadFloor() { ClearMap(); var currentFloorScene = FloorScenes.First(); var instantiator = new Instantiator(GetTree()); var loadedScene = instantiator.LoadAndInstantiate(currentFloorScene); AddChild(loadedScene); CurrentFloor = (IDungeonFloor)loadedScene; FloorScenes.Remove(currentFloorScene); var transform = GetPlayerSpawnPosition(); Player.TeleportPlayer(transform); } }