Files
GameJamDungeon/src/game/Game.cs

292 lines
9.5 KiB
C#

namespace GameJamDungeon;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System;
using static GameJamDungeon.GameLogic.State;
[Meta(typeof(IAutoNode))]
public partial class Game : Node3D, IGame
{
public override void _Notification(int what) => this.Notify(what);
IGameRepo IProvide<IGameRepo>.Value() => GameRepo;
IGame IProvide<IGame>.Value() => this;
IPlayer IProvide<IPlayer>.Value() => Player;
IGameEventDepot IProvide<IGameEventDepot>.Value() => GameEventDepot;
public IInstantiator Instantiator { get; set; } = default!;
public IGameLogic GameLogic { get; set; } = default!;
public IGameEventDepot GameEventDepot { get; set; } = default!;
public IGameRepo GameRepo { get; set; } = default!;
public GameLogic.IBinding GameBinding { get; set; } = default!;
[Signal]
public delegate void StatRaisedAlertEventHandler(string statRaisedAlert);
[Dependency] public IAppRepo AppRepo => this.DependOn<IAppRepo>();
#region Nodes
[Node] private IMap Map { get; set; } = default!;
[Node] private InGameUI InGameUI { get; set; } = default!;
[Node] private IFloorClearMenu FloorClearMenu { get; set; } = default!;
[Node] private DeathMenu DeathMenu { get; set; } = default!;
[Node] private IPauseMenu PauseMenu { get; set; } = default!;
[Node] private InGameAudio InGameAudio { get; set; } = default!;
[Node] private Timer DoubleEXPTimer { get; set; } = default!;
[Node] private IPlayer Player { get; set; } = default!;
#endregion
public RescuedItemDatabase RescuedItems { get; set; } = default!;
public void Setup()
{
GameRepo = new GameRepo();
GameLogic = new GameLogic();
GameEventDepot = new GameEventDepot();
GameLogic.Set(GameRepo);
GameLogic.Set(AppRepo);
GameLogic.Set(GameEventDepot);
GameLogic.Set(Player);
Instantiator = new Instantiator(GetTree());
RescuedItems = new RescuedItemDatabase();
}
public void OnResolved()
{
GameBinding = GameLogic.Bind();
GameBinding
.Handle((in GameLogic.Output.StartGame _) =>
{
InGameUI.Show();
})
.Handle((in GameLogic.Output.GoToOverworld _) =>
{
GameEventDepot.OnOverworldEntered();
})
.Handle((in GameLogic.Output.SetPauseMode output) => CallDeferred(nameof(SetPauseMode), output.IsPaused))
.Handle((in GameLogic.Output.ShowPauseMenu _) =>
{
PauseMenu.Show();
PauseMenu.FadeIn();
Input.MouseMode = Input.MouseModeEnum.Visible;
PauseMenu.SetProcessUnhandledInput(true);
})
.Handle((in GameLogic.Output.LoadNextFloor _) =>
{
Map.SpawnNextFloor();
})
.Handle((in GameLogic.Output.HidePauseMenu _) => { PauseMenu.Hide(); })
.Handle((in GameLogic.Output.ExitPauseMenu _) => { PauseMenu.FadeOut(); Input.MouseMode = Input.MouseModeEnum.Visible; PauseMenu.SetProcessUnhandledInput(false); })
.Handle((in GameLogic.Output.ShowFloorClearMenu _) => { FloorClearMenu.Show(); FloorClearMenu.FadeIn(); })
.Handle((in GameLogic.Output.ExitFloorClearMenu _) => { FloorClearMenu.FadeOut(); })
.Handle((in GameLogic.Output.OpenInventory _) => { InGameUI.ShowInventoryScreen(); InGameUI.InventoryMenu.SetProcessInput(true); })
.Handle((in GameLogic.Output.HideInventory _) => { InGameUI.HideInventoryScreen(); InGameUI.InventoryMenu.SetProcessInput(false); })
.Handle((in GameLogic.Output.ShowMiniMap _) => { InGameUI.ShowMiniMap(); })
.Handle((in GameLogic.Output.HideMiniMap _) => { InGameUI.HideMiniMap(); })
.Handle((in GameLogic.Output.ShowAskForTeleport _) => { GameRepo.Pause(); InGameUI.UseTeleportPrompt.FadeIn(); InGameUI.SetProcessInput(true); })
.Handle((in GameLogic.Output.HideAskForTeleport _) => { GameRepo.Resume(); InGameUI.UseTeleportPrompt.FadeOut(); InGameUI.SetProcessInput(false); })
.Handle((in GameLogic.Output.ShowLostScreen _) => { DeathMenu.Show(); DeathMenu.FadeIn(); })
.Handle((in GameLogic.Output.ExitLostScreen _) => { DeathMenu.FadeOut(); });
GameLogic.Start();
GameLogic.Input(new GameLogic.Input.Initialize());
this.Provide();
PauseMenu.TransitionCompleted += OnPauseMenuTransitioned;
PauseMenu.UnpauseButtonPressed += PauseMenu_UnpauseButtonPressed;
InGameUI.InventoryMenu.ClosedMenu += InventoryMenu_CloseInventory;
InGameUI.MinimapButtonReleased += Player_MinimapButtonReleased;
InGameUI.UseTeleportPrompt.TeleportToNextFloor += UseTeleportPrompt_TeleportToNextFloor;
InGameUI.UseTeleportPrompt.CloseTeleportPrompt += UseTeleportPrompt_CloseTeleportPrompt;
Player.Inventory.InventoryAtCapacity += PlayerInventory_InventoryAtCapacity;
Player.Inventory.PickedUpItem += Inventory_PickedUpItem;
FloorClearMenu.GoToNextFloor += FloorClearMenu_GoToNextFloor;
FloorClearMenu.SaveAndExit += FloorClearMenu_SaveAndExit;
FloorClearMenu.TransitionCompleted += FloorClearMenu_TransitionCompleted;
GameEventDepot.RestorativePickedUp += GameEventDepot_RestorativePickedUp;
DoubleEXPTimer.Timeout += DoubleEXPTimer_Timeout;
}
public void ToggleInventory()
{
if (GameLogic.Value is InventoryOpened)
GameLogic.Input(new GameLogic.Input.CloseInventory());
else
GameLogic.Input(new GameLogic.Input.OpenInventory());
}
public void ToggleMinimap()
{
GameLogic.Input(new GameLogic.Input.MiniMapButtonPressed());
}
public void FloorExitReached()
{
GameLogic.Input(new GameLogic.Input.AskForTeleport());
GameEventDepot.OnTeleportEntered();
}
private void Inventory_PickedUpItem(string pickedUpItemName)
{
InGameUI.PlayerInfoUI.DisplayMessage($"{pickedUpItemName} picked up.");
}
public void DropItem(IInventoryItem item)
{
var droppedScene = GD.Load<PackedScene>("res://src/items/dropped/DroppedItem.tscn");
var dropped = droppedScene.Instantiate<DroppedItem>();
dropped.Item = item;
AddChild(dropped);
dropped.Drop();
}
public void ThrowItem(IInventoryItem item)
{
var thrownScene = GD.Load<PackedScene>("res://src/items/thrown/ThrownItem.tscn");
var thrown = thrownScene.Instantiate<ThrownItem>();
thrown.ItemThatIsThrown = item;
AddChild(thrown);
thrown.Position += new Vector3(-0.5f, 1.5f, -0.5f);
thrown.Throw();
}
public void AnnounceMessageOnInventoryScreen(string message)
{
InGameUI.InventoryMenu.ShowMessage(message);
}
public void AnnounceMessageOnMainScreen(string message)
{
InGameUI.PlayerInfoUI.DisplayMessage(message);
}
public IDungeonFloor CurrentFloor => Map.CurrentFloor;
public void EnemyDefeated(Vector3 defeatedLocation, EnemyStatResource resource)
{
Player.GainExp(resource.ExpFromDefeat * GameRepo.EXPRate);
}
private void DropRestorative(Vector3 vector)
{
var restorativeScene = GD.Load<PackedScene>("res://src/items/restorative/Restorative.tscn");
var restorative = restorativeScene.Instantiate<Restorative>();
AddChild(restorative);
restorative.GlobalPosition = vector;
}
private void UseTeleportPrompt_CloseTeleportPrompt()
{
GameLogic.Input(new GameLogic.Input.HideAskForTeleport());
}
private void UseTeleportPrompt_TeleportToNextFloor()
{
GameLogic.Input(new GameLogic.Input.FloorExitReached());
GameEventDepot.OnDungeonAThemeAreaEntered();
}
private void PauseMenu_UnpauseButtonPressed()
{
GameLogic.Input(new GameLogic.Input.UnpauseGame());
}
private void Player_PauseButtonPressed()
{
GameLogic.Input(new GameLogic.Input.PauseGame());
}
private void Player_MinimapButtonReleased()
{
GameLogic.Input(new GameLogic.Input.MiniMapButtonReleased());
}
private void FloorClearMenu_TransitionCompleted()
{
GameRepo.Resume();
if (Player.EquippedWeapon.Value.ItemTags.Contains(ItemTag.BreaksOnChange))
Player.Unequip(Player.EquippedWeapon.Value);
if (Player.EquippedArmor.Value.ItemTags.Contains(ItemTag.BreaksOnChange))
Player.Unequip(Player.EquippedArmor.Value);
if (Player.EquippedAccessory.Value.ItemTags.Contains(ItemTag.BreaksOnChange))
Player.Unequip(Player.EquippedAccessory.Value);
}
private void FloorClearMenu_GoToNextFloor()
{
GameLogic.Input(new GameLogic.Input.GoToNextFloor());
}
private void FloorClearMenu_SaveAndExit()
{
// Save
GameLogic.Input(new GameLogic.Input.HideFloorClearMenu());
GameLogic.Input(new GameLogic.Input.SaveGame());
}
private void GameEventDepot_RestorativePickedUp(Restorative obj)
=> Player.Stats.SetCurrentVT(Player.Stats.CurrentVT.Value + obj.VTRestoreAmount);
private void SetPauseMode(bool isPaused)
{
if (GetTree() != null)
GetTree().Paused = isPaused;
}
public async void DoubleEXP(TimeSpan lengthOfEffect)
{
ToggleInventory();
InGameUI.PlayerInfoUI.DisplayMessage("Experience points temporarily doubled.");
DoubleEXPTimer.Start(lengthOfEffect.Seconds);
GameRepo.EXPRate = 2;
}
private void DoubleEXPTimer_Timeout()
{
DoubleEXPTimer.Stop();
GameRepo.EXPRate = 1;
InGameUI.PlayerInfoUI.DisplayMessage("Experience points effect wore off.");
}
private void PlayerInventory_InventoryAtCapacity(string rejectedItem)
{
InGameUI.PlayerInfoUI.DisplayMessage($"Could not pick up {rejectedItem}.");
}
private void InventoryMenu_CloseInventory() => GameLogic.Input(new GameLogic.Input.CloseInventory());
public void NextFloorLoaded()
{
GameLogic.Input(new GameLogic.Input.HideFloorClearMenu());
}
private void OnPauseMenuTransitioned()
{
GameLogic.Input(new GameLogic.Input.PauseMenuTransitioned());
}
public void OnStart() => GameLogic.Input(new GameLogic.Input.StartGame());
}