Files
GameJamDungeon/src/game/Game.cs

328 lines
11 KiB
C#

namespace GameJamDungeon;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using GameJamDungeon.src.item_rescue;
using Godot;
using System;
[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;
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] public IMap Map { get; set; } = default!;
[Node] public IPlayer Player { get; set; } = default!;
[Node] public InGameUI InGameUI { get; set; } = default!;
[Node] public IFloorClearMenu FloorClearMenu { get; set; } = default!;
[Node] public DeathMenu DeathMenu { get; set; } = default!;
[Node] public IPauseMenu PauseMenu { get; set; } = default!;
[Node] public InGameAudio InGameAudio { get; set; } = default!;
[Node] public Timer DoubleEXPTimer { 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);
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;
GameEventDepot.TeleportEntered += Map_TeleportReached;
Map.DungeonFinishedGenerating += Map_DungeonFinishedGenerating;
InGameUI.InventoryMenu.ClosedMenu += InventoryMenu_CloseInventory;
InGameUI.MinimapButtonReleased += Player_MinimapButtonReleased;
InGameUI.UseTeleportPrompt.TeleportToNextFloor += UseTeleportPrompt_TeleportToNextFloor;
InGameUI.UseTeleportPrompt.CloseTeleportPrompt += UseTeleportPrompt_CloseTeleportPrompt;
GameRepo.PlayerData.Inventory.InventoryAtCapacity += PlayerInventory_InventoryAtCapacity;
GameRepo.PlayerData.Inventory.PickedUpItem += Inventory_PickedUpItem;
GameRepo.PlayerData.Inventory.RaiseStatRequest += Inventory_RaiseStatRequest;
FloorClearMenu.GoToNextFloor += FloorClearMenu_GoToNextFloor;
FloorClearMenu.SaveAndExit += FloorClearMenu_SaveAndExit;
FloorClearMenu.TransitionCompleted += FloorClearMenu_TransitionCompleted;
Player.InventoryButtonPressed += Player_InventoryButtonPressed;
Player.MinimapButtonHeld += Player_MinimapButtonHeld;
Player.PauseButtonPressed += Player_PauseButtonPressed;
GameRepo.PlayerData.CurrentHP.Sync += CurrentHP_Sync;
GameEventDepot.EnemyDefeated += OnEnemyDefeated;
GameEventDepot.RestorativePickedUp += GameEventDepot_RestorativePickedUp;
DoubleEXPTimer.Timeout += DoubleEXPTimer_Timeout;
}
private void CurrentHP_Sync(int currentHP)
{
if (currentHP <= 0)
GameLogic.Input(new GameLogic.Input.GameOver());
}
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.ThrownItemStats = item.Info;
AddChild(thrown);
thrown.Throw();
}
private void OnEnemyDefeated(Vector3 vector, EnemyStatResource resource)
{
GameRepo.PlayerData.SetCurrentExp(GameRepo.PlayerData.CurrentExp.Value + (resource.ExpFromDefeat * GameRepo.EXPRate));
DropRestorative(vector);
}
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 Player_MinimapButtonHeld()
{
GameLogic.Input(new GameLogic.Input.MiniMapButtonPressed());
}
private void Player_InventoryButtonPressed()
{
GameLogic.Input(new GameLogic.Input.OpenInventory());
}
private void FloorClearMenu_TransitionCompleted()
{
GameRepo.Resume();
if (GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.WeaponTags.Contains(WeaponTag.BreaksOnChange))
GameRepo.PlayerData.Inventory.Unequip(GameRepo.PlayerData.Inventory.EquippedWeapon.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)
=> GameRepo.PlayerData.SetCurrentVT(GameRepo.PlayerData.CurrentVT.Value + obj.VTRestoreAmount);
private void Inventory_RaiseStatRequest(InventoryItemStats itemStats)
{
HealHP(itemStats.HealHPAmount);
HealVT(itemStats.HealVTAmount);
}
private void SetPauseMode(bool isPaused)
{
if (GetTree() != null)
GetTree().Paused = isPaused;
}
public void RaiseHP(int amountToRaise)
{
if (GameRepo.PlayerData.CurrentHP.Value == GameRepo.PlayerData.MaximumHP.Value)
{
GameRepo.PlayerData.SetMaximumHP(GameRepo.PlayerData.MaximumHP.Value + amountToRaise);
GameRepo.PlayerData.SetCurrentHP(GameRepo.PlayerData.MaximumHP.Value);
EmitSignal(SignalName.StatRaisedAlert, $"{amountToRaise}MAXHP Up.");
}
}
public void HealHP(int amountToRestore)
{
GameRepo.PlayerData.SetCurrentHP(GameRepo.PlayerData.CurrentHP.Value + amountToRestore);
var raiseString = amountToRestore == 1000 ? "MAX" : $"{amountToRestore}";
EmitSignal(SignalName.StatRaisedAlert, $"{raiseString}HP Restored.");
}
public void RaiseVT(int amountToRaise)
{
if (GameRepo.PlayerData.CurrentVT.Value == GameRepo.PlayerData.MaximumVT.Value)
{
GameRepo.PlayerData.SetMaximumVT(GameRepo.PlayerData.MaximumVT.Value + amountToRaise);
GameRepo.PlayerData.SetCurrentVT(GameRepo.PlayerData.MaximumVT.Value);
EmitSignal(SignalName.StatRaisedAlert, $"{amountToRaise}MAXVT Up.");
}
}
public void HealVT(int amountToRestore)
{
GameRepo.PlayerData.SetCurrentVT(GameRepo.PlayerData.CurrentVT.Value + amountToRestore);
var raiseString = amountToRestore == 1000 ? "MAX" : $"{amountToRestore}";
EmitSignal(SignalName.StatRaisedAlert, $"{raiseString}VT Restored.");
}
public async void DoubleEXP(TimeSpan lengthOfEffect)
{
InventoryMenu_CloseInventory();
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());
private void Map_DungeonFinishedGenerating()
{
var transform = Map.GetPlayerSpawnPosition();
GameRepo.SetPlayerGlobalTransform(transform);
GameRepo.SetPlayerGlobalPosition(new Vector3(transform.Origin.X, -2, transform.Origin.Z));
GameLogic.Input(new GameLogic.Input.HideFloorClearMenu());
}
private void Map_TeleportReached()
{
GameLogic.Input(new GameLogic.Input.AskForTeleport());
}
private void OnPauseMenuTransitioned()
{
GameLogic.Input(new GameLogic.Input.PauseMenuTransitioned());
}
public void OnStart() => GameLogic.Input(new GameLogic.Input.StartGame());
}