namespace GameJamDungeon; using Chickensoft.AutoInject; using Chickensoft.GodotNodeInterfaces; using Chickensoft.Introspection; using Godot; using System.Collections.Generic; using System.Linq; public interface IGame : IProvide, INode3D; [Meta(typeof(IAutoNode))] public partial class Game : Node3D, IGame { public override void _Notification(int what) => this.Notify(what); IGameRepo IProvide.Value() => GameRepo; public IInstantiator Instantiator { get; set; } = default!; public IGameLogic GameLogic { get; set; } = default!; public IGameRepo GameRepo { get; set; } = default!; public GameLogic.IBinding GameBinding { get; set; } = default!; [Dependency] public IAppRepo AppRepo => this.DependOn(); [Node] public IInventoryMenu InventoryMenu { get; set; } = default!; [Node] public Control MiniMap { get; set; } = default!; [Node] public Area3D Teleport { get; set; } = default!; [Node] public IDungeonFloor Overworld { get; set; } = default!; [Node] public IDungeonFloor Floor1 { get; set; } = default!; [Node] public IDungeonFloor Floor2 { get; set; } = default!; [Node] public IDungeonFloor Floor3 { get; set; } = default!; [Node] public AnimationPlayer AnimationPlayer { get; set; } = default!; private List Floors; private int _currentFloor = -1; public void Setup() { GameRepo = new GameRepo(); GameLogic = new GameLogic(); GameLogic.Set(GameRepo); GameLogic.Set(AppRepo); Instantiator = new Instantiator(GetTree()); Floors = new List { Overworld, Floor1, Floor2, Floor3 }; Teleport.BodyEntered += OnTeleportEntered; } private void OnTeleportEntered(Node3D body) { GameLogic.Input(new GameLogic.Input.LoadNextFloor()); } public void OnResolved() { GameBinding = GameLogic.Bind(); GameBinding .Handle((in GameLogic.Output.StartGame _) => { }) .Handle((in GameLogic.Output.LoadNextFloor _) => { AnimationPlayer.Play("wait_and_load"); var currentFloor = Floors.ElementAt(_currentFloor); currentFloor.CallDeferred(MethodName.QueueFree, []); if (GameRepo.EquippedWeapon.Info != null && ((WeaponInfo)GameRepo.EquippedWeapon.Info).WeaponTags.Contains(WeaponTag.BreaksOnChange)) { GameRepo.InventoryItems.Value.Remove(GameRepo.EquippedWeapon); GameRepo.OnWeaponEquipped(new Weapon()); } }) .Handle((in GameLogic.Output.SetPauseMode output) => { CallDeferred(nameof(SetPauseMode), output.IsPaused); }) .Handle((in GameLogic.Output.SetInventoryMode _) => { InventoryMenu.PopulateItems(_.Inventory); InventoryMenu.Show(); }) .Handle((in GameLogic.Output.HideInventory _) => { InventoryMenu.Hide(); InventoryMenu.ClearItems(); }) .Handle((in GameLogic.Output.ShowMiniMap _) => { MiniMap.Show(); }) .Handle((in GameLogic.Output.HideMiniMap _) => { MiniMap.Hide(); }) .Handle((in GameLogic.Output.GameOver _) => { AppRepo.OnGameOver(); }); GameLogic.Start(); GameLogic.Input(new GameLogic.Input.Initialize()); AnimationPlayer.AnimationStarted += AnimationPlayer_AnimationStarted; AnimationPlayer.AnimationFinished += AnimationPlayer_AnimationFinished; AnimationPlayer.Play("wait_and_load"); this.Provide(); } private void AnimationPlayer_AnimationStarted(StringName animName) { var newFloor = Floors.ElementAt(_currentFloor + 1); newFloor.CallDeferred(nameof(newFloor.InitializeDungeon), []); newFloor.Show(); } private void AnimationPlayer_AnimationFinished(StringName animName) { var spawnPoints = GetTree().GetNodesInGroup("Exit").OfType(); Teleport.GlobalPosition = spawnPoints.Last().GlobalPosition; _currentFloor++; } public override void _Process(double delta) { if (Input.IsActionJustPressed(GameInputs.Inventory)) { GD.Print("Inventory button pressed"); GameLogic.Input(new GameLogic.Input.InventoryMenuButtonPressed()); } if (Input.IsActionJustPressed(GameInputs.MiniMap)) { GD.Print("MiniMap button pressed"); GameLogic.Input(new GameLogic.Input.MiniMapButtonPressed()); } if (Input.IsActionJustReleased(GameInputs.MiniMap)) { GD.Print("MiniMap button released"); GameLogic.Input(new GameLogic.Input.MiniMapButtonReleased()); } } private void SetPauseMode(bool isPaused) { if (GetTree() != null) GetTree().Paused = isPaused; } public void OnStart() => GameLogic.Input(new GameLogic.Input.Start()); }