Files
GameJamDungeon/src/game/Game.cs
2024-09-08 14:19:30 -07:00

148 lines
4.5 KiB
C#

namespace GameJamDungeon;
using Chickensoft.AutoInject;
using Chickensoft.GodotNodeInterfaces;
using Chickensoft.Introspection;
using Godot;
using System.Collections.Generic;
using System.Linq;
public interface IGame : IProvide<IGameRepo>, INode3D;
[Meta(typeof(IAutoNode))]
public partial class Game : Node3D, IGame
{
public override void _Notification(int what) => this.Notify(what);
IGameRepo IProvide<IGameRepo>.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<IAppRepo>();
[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<IDungeonFloor> 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<IDungeonFloor> { 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<Marker3D>();
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());
}