317 lines
11 KiB
C#
317 lines
11 KiB
C#
|
|
namespace GameJamDungeon;
|
|
|
|
using Chickensoft.AutoInject;
|
|
using Chickensoft.GodotNodeInterfaces;
|
|
using Chickensoft.Introspection;
|
|
using Godot;
|
|
|
|
public interface IGame : IProvide<IGameRepo>, IProvide<IGameEventDepot>, IProvide<IGame>, INode3D
|
|
{
|
|
event Game.StatRaisedAlertEventHandler StatRaisedAlert;
|
|
|
|
public IPlayer Player { get; }
|
|
|
|
public void DropItem(IInventoryItem item);
|
|
|
|
public void ThrowItem(IInventoryItem item);
|
|
|
|
public void HealHP(int amountToRaise);
|
|
public void RaiseHP(int amountToRaise);
|
|
|
|
public void HealVT(int amountToRaise);
|
|
public void RaiseVT(int amountToRaise);
|
|
}
|
|
|
|
[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!;
|
|
#endregion
|
|
|
|
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());
|
|
}
|
|
|
|
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.ReturnToHubWorld += ReturnToHubWorld;
|
|
FloorClearMenu.TransitionCompleted += FloorClearMenu_TransitionCompleted;
|
|
|
|
Player.InventoryButtonPressed += Player_InventoryButtonPressed;
|
|
Player.MinimapButtonHeld += Player_MinimapButtonHeld;
|
|
Player.PauseButtonPressed += Player_PauseButtonPressed;
|
|
|
|
GameEventDepot.EnemyDefeated += OnEnemyDefeated;
|
|
GameEventDepot.RestorativePickedUp += GameEventDepot_RestorativePickedUp;
|
|
}
|
|
|
|
private void Inventory_PickedUpItem(string pickedUpItemName)
|
|
{
|
|
InGameUI.PlayerInfoUI.DisplayPickedUpMessage(pickedUpItemName);
|
|
}
|
|
|
|
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)
|
|
{
|
|
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 ReturnToHubWorld()
|
|
{
|
|
// Implement a return to overworld state
|
|
// Don't carry over stats/equipment but we'll need to persist the overworld state
|
|
// Which may include rescued items and npc/questline state
|
|
GameLogic.Input(new GameLogic.Input.HideFloorClearMenu());
|
|
}
|
|
|
|
private void GameEventDepot_RestorativePickedUp(Restorative obj) => GameRepo.PlayerData.SetCurrentVT(GameRepo.PlayerData.CurrentVT.Value + obj.VTRestoreAmount);
|
|
|
|
private void Inventory_RaiseStatRequest(InventoryItemStats itemStats)
|
|
{
|
|
//if (itemStats.RaiseHPAmount > 0 && GameRepo.PlayerData.CurrentHP.Value.Equals(GameRepo.PlayerData.MaximumHP.Value))
|
|
// RaiseHP(itemStats.RaiseHPAmount);
|
|
//else if (itemStats.HealHPAmount > 0)
|
|
HealHP(itemStats.HealHPAmount);
|
|
HealVT(itemStats.HealVTAmount);
|
|
|
|
//if (itemStats.RaiseVTAmount > 0 && GameRepo.PlayerData.CurrentVT.Value.Equals(GameRepo.PlayerData.MaximumVT.Value))
|
|
// RaiseVT(itemStats.RaiseVTAmount);
|
|
//else if (itemStats.HealVTAmount > 0)
|
|
}
|
|
|
|
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 amountToRaise)
|
|
{
|
|
GameRepo.PlayerData.SetCurrentHP(GameRepo.PlayerData.CurrentHP.Value + amountToRaise);
|
|
var raiseString = amountToRaise == 1000 ? "MAX" : $"{amountToRaise}";
|
|
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 amountToRaise)
|
|
{
|
|
GameRepo.PlayerData.SetCurrentVT(GameRepo.PlayerData.CurrentVT.Value + amountToRaise);
|
|
var raiseString = amountToRaise == 1000 ? "MAX" : $"{amountToRaise}";
|
|
EmitSignal(SignalName.StatRaisedAlert, $"{raiseString}VT Restored.");
|
|
}
|
|
|
|
private void PlayerInventory_InventoryAtCapacity(string rejectedItem)
|
|
{
|
|
InGameUI.PlayerInfoUI.DisplayInventoryFullMessage(rejectedItem);
|
|
}
|
|
|
|
private void OnInventoryAtCapacity(string rejectedItemName) => InGameUI.PlayerInfoUI.DisplayInventoryFullMessage(rejectedItemName);
|
|
|
|
private void InventoryMenu_CloseInventory() => GameLogic.Input(new GameLogic.Input.CloseInventory());
|
|
|
|
private void Map_DungeonFinishedGenerating()
|
|
{
|
|
var transform = Map.GetPlayerSpawnPosition();
|
|
GameRepo.SetPlayerGlobalPosition(transform.Origin);
|
|
GameRepo.SetPlayerGlobalTransform(transform);
|
|
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());
|
|
}
|