More inventory menu improvements

This commit is contained in:
2024-09-13 16:43:10 -07:00
parent f0e75703f6
commit 1d7d70e033
41 changed files with 995 additions and 275 deletions

View File

@@ -4,7 +4,9 @@ namespace GameJamDungeon;
using Chickensoft.AutoInject;
using Chickensoft.GodotNodeInterfaces;
using Chickensoft.Introspection;
using DialogueManagerRuntime;
using Godot;
using System;
public interface IGame : IProvide<IGameRepo>, IProvide<IGame>, INode3D
{
@@ -36,9 +38,11 @@ public partial class Game : Node3D, IGame
#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 FloorClearMenu FloorClearMenu { get; set; } = default!;
[Node] public IFloorClearMenu FloorClearMenu { get; set; } = default!;
[Node] public DeathMenu DeathMenu { get; set; } = default!;
@@ -54,40 +58,6 @@ public partial class Game : Node3D, IGame
Instantiator = new Instantiator(GetTree());
}
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.InventoryMenuToggle());
private void Map_DungeonFinishedGenerating()
{
GameRepo.SetPlayerGlobalPosition(Map.GetPlayerSpawnPosition());
}
private void Map_DialogueChoiceMade()
{
GameRepo.Resume();
}
private void Map_TeleportReached()
{
GameRepo.Pause();
}
private void OnFloorClearTransitionCompleted()
{
GameLogic.Input(new GameLogic.Input.FloorClearTransitioned());
}
private void OnPauseMenuTransitioned()
{
GameLogic.Input(new GameLogic.Input.PauseMenuTransitioned());
}
public void OnResolved()
{
GameBinding = GameLogic.Bind();
@@ -101,13 +71,19 @@ public partial class Game : Node3D, IGame
{
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(); })
.Handle((in GameLogic.Output.ExitPauseMenu _) => { PauseMenu.FadeOut(); Input.MouseMode = Input.MouseModeEnum.Captured; PauseMenu.SetProcessUnhandledInput(false); })
.Handle((in GameLogic.Output.ShowFloorClearMenu _) => { FloorClearMenu.Show(); FloorClearMenu.FadeIn(); })
.Handle((in GameLogic.Output.ExitFloorClearMenu _) => { FloorClearMenu.FadeOut(); })
.Handle((in GameLogic.Output.SetInventoryMode _) => { InGameUI.ShowInventoryScreen(); })
.Handle((in GameLogic.Output.HideInventory _) => { InGameUI.HideInventoryScreen(); })
.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.ShowLostScreen _) => { DeathMenu.Show(); DeathMenu.FadeIn(); })
@@ -118,14 +94,69 @@ public partial class Game : Node3D, IGame
this.Provide();
FloorClearMenu.TransitionCompleted += OnFloorClearTransitionCompleted;
PauseMenu.TransitionCompleted += OnPauseMenuTransitioned;
PauseMenu.UnpauseButtonPressed += PauseMenu_UnpauseButtonPressed;
Map.TeleportReached += Map_TeleportReached;
Map.DialogueDecisionMade += Map_DialogueChoiceMade;
Map.DungeonFinishedGenerating += Map_DungeonFinishedGenerating;
InGameUI.InventoryMenu.ClosedMenu += InventoryMenu_CloseInventory;
InGameUI.MinimapButtonReleased += Player_MinimapButtonReleased;
GameRepo.PlayerData.Inventory.InventoryAtCapacity += PlayerInventory_InventoryAtCapacity;
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;
}
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();
}
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());
}
public void GoToNextFloor()
{
GameLogic.Input(new GameLogic.Input.FloorExitReached());
}
private void Inventory_RaiseStatRequest(ConsumableItemStats consumableItemStats)
@@ -143,7 +174,7 @@ public partial class Game : Node3D, IGame
private void RaiseHP(int amountToRaise)
{
if (GameRepo.PlayerData.CurrentHP == GameRepo.PlayerData.MaximumHP)
if (GameRepo.PlayerData.CurrentHP.Value == GameRepo.PlayerData.MaximumHP.Value)
{
GameRepo.PlayerData.SetMaximumHP(GameRepo.PlayerData.MaximumHP.Value + amountToRaise);
GameRepo.PlayerData.SetCurrentHP(GameRepo.PlayerData.MaximumHP.Value);
@@ -151,38 +182,6 @@ public partial class Game : Node3D, IGame
}
}
public void ToggleInventory()
{
GameLogic.Input(new GameLogic.Input.InventoryMenuToggle());
}
public override void _UnhandledInput(InputEvent @event)
{
if (@event.IsActionPressed(GameInputs.Inventory))
{
GD.Print("Inventory button pressed");
GameLogic.Input(new GameLogic.Input.InventoryMenuToggle());
}
if (@event.IsActionPressed(GameInputs.MiniMap))
{
GD.Print("MiniMap button pressed");
GameLogic.Input(new GameLogic.Input.MiniMapButtonPressed());
}
if (@event.IsActionReleased(GameInputs.MiniMap))
{
GD.Print("MiniMap button released");
GameLogic.Input(new GameLogic.Input.MiniMapButtonReleased());
}
if (@event.IsActionPressed(GameInputs.Pause))
{
GD.Print("Pause button pressed");
GameLogic.Input(new GameLogic.Input.PauseButtonPressed());
}
}
private void SetPauseMode(bool isPaused)
{
if (GetTree() != null)
@@ -197,7 +196,7 @@ public partial class Game : Node3D, IGame
private void RaiseVT(int amountToRaise)
{
if (GameRepo.PlayerData.CurrentVT == GameRepo.PlayerData.MaximumVT)
if (GameRepo.PlayerData.CurrentVT.Value == GameRepo.PlayerData.MaximumVT.Value)
{
GameRepo.PlayerData.SetMaximumVT(GameRepo.PlayerData.MaximumVT.Value + amountToRaise);
GameRepo.PlayerData.SetCurrentVT(GameRepo.PlayerData.MaximumVT.Value);
@@ -211,5 +210,33 @@ public partial class Game : Node3D, IGame
EmitSignal(SignalName.StatRaisedAlert, $"{amountToRaise}VT Up.");
}
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()
{
GameRepo.SetPlayerGlobalPosition(Map.GetPlayerSpawnPosition());
GameLogic.Input(new GameLogic.Input.HideFloorClearMenu());
}
private void Map_TeleportReached()
{
GameRepo.Pause();
DialogueManager.GetCurrentScene = (() => this);
var dialogueResource = GD.Load<Resource>("res://src/ui/dialogue/FloorExit.dialogue");
DialogueController.ShowDialogue(dialogueResource, "floor_exit");
}
private void OnPauseMenuTransitioned()
{
GameLogic.Input(new GameLogic.Input.PauseMenuTransitioned());
}
public void OnStart() => GameLogic.Input(new GameLogic.Input.StartGame());
}

View File

@@ -27,6 +27,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2.74459, 1.22144)
[node name="Map" parent="PauseContainer" instance=ExtResource("3_d8awv")]
unique_name_in_owner = true
process_mode = 1
script = ExtResource("4_f5pye")
[node name="InGameUI" parent="." instance=ExtResource("5_lxtnp")]
@@ -46,7 +47,6 @@ visible = false
[node name="FloorClearMenu" parent="." instance=ExtResource("11_rya1n")]
unique_name_in_owner = true
visible = false
modulate = Color(1, 1, 1, 1)
[node name="PauseMenu" parent="." instance=ExtResource("12_yev8k")]
unique_name_in_owner = true

View File

@@ -8,21 +8,24 @@
public readonly record struct Initialize;
public readonly record struct InventoryMenuToggle;
public readonly record struct OpenInventory;
public readonly record struct CloseInventory;
public readonly record struct MiniMapButtonPressed;
public readonly record struct MiniMapButtonReleased;
public readonly record struct GameOver;
public readonly record struct FloorExitReached;
public readonly record struct HideFloorClearMenu;
public readonly record struct FloorClearTransitioned;
public readonly record struct GameOver;
public readonly record struct GoToNextFloor;
public readonly record struct PauseButtonPressed;
public readonly record struct PauseGame;
public readonly record struct UnpauseGame;
public readonly record struct PauseMenuTransitioned;
}

View File

@@ -14,7 +14,7 @@ namespace GameJamDungeon
public readonly record struct ExitPauseMenu;
public readonly record struct SetInventoryMode();
public readonly record struct OpenInventory();
public readonly record struct HideInventory;

View File

@@ -1,37 +1,33 @@
@startuml GameLogic
state "GameLogic State" as GameJamDungeon_GameLogic_State {
state "FloorCleared" as GameJamDungeon_GameLogic_State_FloorCleared
state "GameStarted" as GameJamDungeon_GameLogic_State_GameStarted
state "InventoryOpened" as GameJamDungeon_GameLogic_State_InventoryOpened
state "MenuBackdrop" as GameJamDungeon_GameLogic_State_MenuBackdrop
state "MinimapOpen" as GameJamDungeon_GameLogic_State_MinimapOpen
state "Paused" as GameJamDungeon_GameLogic_State_Paused
state "Playing" as GameJamDungeon_GameLogic_State_Playing
state "Playing" as GameJamDungeon_GameLogic_State_Playing {
state "FloorClearedDecisionState" as GameJamDungeon_GameLogic_State_FloorClearedDecisionState
state "InventoryOpened" as GameJamDungeon_GameLogic_State_InventoryOpened
state "MinimapOpen" as GameJamDungeon_GameLogic_State_MinimapOpen
state "Paused" as GameJamDungeon_GameLogic_State_Paused
state "Resuming" as GameJamDungeon_GameLogic_State_Resuming
}
state "Quit" as GameJamDungeon_GameLogic_State_Quit
state "Resuming" as GameJamDungeon_GameLogic_State_Resuming
}
GameJamDungeon_GameLogic_State_FloorCleared --> GameJamDungeon_GameLogic_State_FloorCleared : GoToNextFloor
GameJamDungeon_GameLogic_State_FloorClearedDecisionState --> GameJamDungeon_GameLogic_State_FloorClearedDecisionState : GoToNextFloor
GameJamDungeon_GameLogic_State_FloorClearedDecisionState --> GameJamDungeon_GameLogic_State_Playing : HideFloorClearMenu
GameJamDungeon_GameLogic_State_GameStarted --> GameJamDungeon_GameLogic_State_Playing : Initialize
GameJamDungeon_GameLogic_State_InventoryOpened --> GameJamDungeon_GameLogic_State_Playing : InventoryMenuToggle
GameJamDungeon_GameLogic_State_MenuBackdrop --> GameJamDungeon_GameLogic_State_MenuBackdrop : Initialize
GameJamDungeon_GameLogic_State_MenuBackdrop --> GameJamDungeon_GameLogic_State_Playing : StartGame
GameJamDungeon_GameLogic_State_InventoryOpened --> GameJamDungeon_GameLogic_State_Playing : CloseInventory
GameJamDungeon_GameLogic_State_MinimapOpen --> GameJamDungeon_GameLogic_State_Playing : MiniMapButtonReleased
GameJamDungeon_GameLogic_State_Paused --> GameJamDungeon_GameLogic_State_Resuming : PauseButtonPressed
GameJamDungeon_GameLogic_State_Playing --> GameJamDungeon_GameLogic_State_FloorCleared : FloorExitReached
GameJamDungeon_GameLogic_State_Playing --> GameJamDungeon_GameLogic_State_InventoryOpened : InventoryMenuToggle
GameJamDungeon_GameLogic_State_Paused --> GameJamDungeon_GameLogic_State_Resuming : UnpauseGame
GameJamDungeon_GameLogic_State_Playing --> GameJamDungeon_GameLogic_State_FloorClearedDecisionState : FloorExitReached
GameJamDungeon_GameLogic_State_Playing --> GameJamDungeon_GameLogic_State_InventoryOpened : OpenInventory
GameJamDungeon_GameLogic_State_Playing --> GameJamDungeon_GameLogic_State_MinimapOpen : MiniMapButtonPressed
GameJamDungeon_GameLogic_State_Playing --> GameJamDungeon_GameLogic_State_Paused : PauseButtonPressed
GameJamDungeon_GameLogic_State_Playing --> GameJamDungeon_GameLogic_State_Paused : PauseGame
GameJamDungeon_GameLogic_State_Playing --> GameJamDungeon_GameLogic_State_Quit : GameOver
GameJamDungeon_GameLogic_State_Resuming --> GameJamDungeon_GameLogic_State_Playing : PauseMenuTransitioned
GameJamDungeon_GameLogic_State : OnIsPaused() → SetPauseMode
GameJamDungeon_GameLogic_State_FloorCleared : OnEnter → ShowFloorClearMenu
GameJamDungeon_GameLogic_State_FloorCleared : OnExit → ExitFloorClearMenu
GameJamDungeon_GameLogic_State_GameStarted : OnEnter → ShowFloorClearMenu
GameJamDungeon_GameLogic_State_GameStarted : OnExit → ExitFloorClearMenu
GameJamDungeon_GameLogic_State_FloorClearedDecisionState : OnGoToNextFloor → LoadNextFloor
GameJamDungeon_GameLogic_State_GameStarted : OnInitialize → StartGame
GameJamDungeon_GameLogic_State_InventoryOpened : OnEnter → SetInventoryMode
GameJamDungeon_GameLogic_State_InventoryOpened : OnEnter → OpenInventory
GameJamDungeon_GameLogic_State_InventoryOpened : OnExit → HideInventory
GameJamDungeon_GameLogic_State_MinimapOpen : OnEnter → ShowMiniMap
GameJamDungeon_GameLogic_State_MinimapOpen : OnExit → HideMiniMap

View File

@@ -8,18 +8,24 @@ namespace GameJamDungeon
public partial record State
{
[Meta]
public partial record FloorCleared : State, IGet<Input.GoToNextFloor>
public partial record FloorClearedDecisionState : Playing, IGet<Input.GoToNextFloor>, IGet<Input.HideFloorClearMenu>
{
public FloorCleared()
public FloorClearedDecisionState()
{
this.OnEnter(() => { Get<IGameRepo>().Pause(); Output(new Output.ShowFloorClearMenu()); });
this.OnExit(() => { Output(new Output.ExitFloorClearMenu()); });
this.OnAttach(() => { Get<IGameRepo>().Pause(); Output(new Output.ShowFloorClearMenu()); });
this.OnDetach(() => { Output(new Output.ExitFloorClearMenu()); });
}
public Transition On(in Input.GoToNextFloor input)
{
Output(new Output.LoadNextFloor());
return ToSelf();
}
public Transition On(in Input.HideFloorClearMenu input)
{
return To<Playing>();
}
}
}
}

View File

@@ -12,8 +12,8 @@ namespace GameJamDungeon
{
public GameStarted()
{
this.OnEnter(() => { Get<IGameRepo>().Pause(); Output(new Output.ShowFloorClearMenu()); });
this.OnExit(() => { Output(new Output.ExitFloorClearMenu()); });
this.OnEnter(() => { Get<IGameRepo>().Pause(); });
this.OnExit(() => { Get<IGameRepo>().Resume(); });
}
public Transition On(in Input.Initialize input)

View File

@@ -8,14 +8,18 @@ namespace GameJamDungeon
public partial record State
{
[Meta]
public partial record InventoryOpened : State, IGet<Input.InventoryMenuToggle>
public partial record InventoryOpened : Playing, IGet<Input.CloseInventory>
{
public InventoryOpened()
{
this.OnEnter(() => { Get<IGameRepo>().Pause(); Output(new Output.SetInventoryMode()); });
this.OnEnter(() => { Get<IGameRepo>().Pause(); Output(new Output.OpenInventory()); });
this.OnExit(() => { Get<IGameRepo>().Resume(); Output(new Output.HideInventory()); });
}
public Transition On(in Input.InventoryMenuToggle input) => To<Playing>();
public Transition On(in Input.CloseInventory input)
{
return To<Playing>();
}
}
}
}

View File

@@ -1,29 +0,0 @@
using Chickensoft.Introspection;
namespace GameJamDungeon
{
public partial class GameLogic
{
public partial record State
{
[Meta]
public partial record MenuBackdrop : State, IGet<Input.StartGame>, IGet<Input.Initialize>
{
public MenuBackdrop()
{
OnAttach(() => Get<IAppRepo>().GameEntered += OnGameEntered);
OnDetach(() => Get<IAppRepo>().GameEntered -= OnGameEntered);
}
public void OnGameEntered() => Input(new Input.StartGame());
public Transition On(in Input.StartGame input) => To<Playing>();
public Transition On(in Input.Initialize input)
{
return ToSelf();
}
}
}
}
}

View File

@@ -8,7 +8,7 @@ namespace GameJamDungeon
public partial record State
{
[Meta]
public partial record MinimapOpen : State, IGet<Input.MiniMapButtonReleased>
public partial record MinimapOpen : Playing, IGet<Input.MiniMapButtonReleased>
{
public MinimapOpen()
{

View File

@@ -8,7 +8,7 @@ namespace GameJamDungeon
public partial record State
{
[Meta]
public partial record Paused : State, IGet<Input.PauseButtonPressed>
public partial record Paused : Playing, IGet<Input.UnpauseGame>
{
public Paused()
{
@@ -20,7 +20,7 @@ namespace GameJamDungeon
this.OnExit(() => Output(new Output.ExitPauseMenu()));
}
public virtual Transition On(in Input.PauseButtonPressed input) => To<Resuming>();
public virtual Transition On(in Input.UnpauseGame input) => To<Resuming>();
}
}
}

View File

@@ -9,29 +9,29 @@ namespace GameJamDungeon
{
[Meta]
public partial record Playing : State,
IGet<Input.InventoryMenuToggle>,
IGet<Input.OpenInventory>,
IGet<Input.MiniMapButtonPressed>,
IGet<Input.GameOver>,
IGet<Input.FloorExitReached>,
IGet<Input.PauseButtonPressed>
IGet<Input.PauseGame>
{
public Playing()
{
OnAttach(() => Get<IGameRepo>().Ended += OnEnded);
OnDetach(() => Get<IGameRepo>().Ended -= OnEnded);
this.OnEnter(() => Get<IGameRepo>().Ended += OnEnded);
this.OnExit(() => Get<IGameRepo>().Ended -= OnEnded);
}
public void OnEnded() => Input(new Input.GameOver());
public Transition On(in Input.InventoryMenuToggle input) => To<InventoryOpened>();
public Transition On(in Input.OpenInventory input) => To<InventoryOpened>();
public Transition On(in Input.MiniMapButtonPressed input) => To<MinimapOpen>();
public Transition On(in Input.GameOver input) => To<Quit>();
public Transition On(in Input.FloorExitReached input) => To<FloorCleared>();
public Transition On(in Input.FloorExitReached input) => To<FloorClearedDecisionState>();
public Transition On(in Input.PauseButtonPressed input) => To<Paused>();
public Transition On(in Input.PauseGame input) => To<Paused>();
}
}
}

View File

@@ -8,7 +8,7 @@ public partial class GameLogic
public partial record State
{
[Meta]
public partial record Resuming : State, IGet<Input.PauseMenuTransitioned>
public partial record Resuming : Playing, IGet<Input.PauseMenuTransitioned>
{
public Resuming()
{