Start refactoring UI concerns away from game and into UI logic class
This commit is contained in:
@@ -42,8 +42,6 @@ public partial class GameLogic
|
|||||||
|
|
||||||
public readonly record struct SaveGame;
|
public readonly record struct SaveGame;
|
||||||
|
|
||||||
public readonly record struct AnnounceMessage(string Message);
|
|
||||||
|
|
||||||
public readonly record struct DoubleExpTimeStart(int lengthOfTimeInSeconds);
|
public readonly record struct DoubleExpTimeStart(int lengthOfTimeInSeconds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ public partial class GameLogic
|
|||||||
gameRepo.IsPaused.Sync += OnIsPaused;
|
gameRepo.IsPaused.Sync += OnIsPaused;
|
||||||
gameRepo.OpenInventory += OnOpenInventory;
|
gameRepo.OpenInventory += OnOpenInventory;
|
||||||
gameRepo.CloseInventory += OnCloseInventory;
|
gameRepo.CloseInventory += OnCloseInventory;
|
||||||
gameRepo.AnnounceMessage += OnAnnounceMessage;
|
|
||||||
gameRepo.DoubleExpTimeStart += OnDoubleExpTimeStart;
|
gameRepo.DoubleExpTimeStart += OnDoubleExpTimeStart;
|
||||||
});
|
});
|
||||||
OnDetach(() =>
|
OnDetach(() =>
|
||||||
@@ -25,7 +24,6 @@ public partial class GameLogic
|
|||||||
gameRepo.IsPaused.Sync -= OnIsPaused;
|
gameRepo.IsPaused.Sync -= OnIsPaused;
|
||||||
gameRepo.OpenInventory -= OnOpenInventory;
|
gameRepo.OpenInventory -= OnOpenInventory;
|
||||||
gameRepo.CloseInventory -= OnCloseInventory;
|
gameRepo.CloseInventory -= OnCloseInventory;
|
||||||
gameRepo.AnnounceMessage -= OnAnnounceMessage;
|
|
||||||
gameRepo.DoubleExpTimeStart -= OnDoubleExpTimeStart;
|
gameRepo.DoubleExpTimeStart -= OnDoubleExpTimeStart;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -34,8 +32,6 @@ public partial class GameLogic
|
|||||||
|
|
||||||
private void OnCloseInventory() => Output(new Output.CloseInventory());
|
private void OnCloseInventory() => Output(new Output.CloseInventory());
|
||||||
|
|
||||||
private void OnAnnounceMessage(string message) => Output(new Output.AnnounceMessage(message));
|
|
||||||
|
|
||||||
private void OnDoubleExpTimeStart(int lengthOfTimeInSeconds) => Output(new Output.DoubleExpTimeStart(lengthOfTimeInSeconds));
|
private void OnDoubleExpTimeStart(int lengthOfTimeInSeconds) => Output(new Output.DoubleExpTimeStart(lengthOfTimeInSeconds));
|
||||||
|
|
||||||
public void OnIsPaused(bool isPaused) => Output(new Output.SetPauseMode(isPaused));
|
public void OnIsPaused(bool isPaused) => Output(new Output.SetPauseMode(isPaused));
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ public interface IGameRepo : IDisposable
|
|||||||
|
|
||||||
public void EndDoubleExp();
|
public void EndDoubleExp();
|
||||||
|
|
||||||
|
public void AnnounceMessageOnMainScreen(string message);
|
||||||
|
|
||||||
public double ExpRate { get; }
|
public double ExpRate { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,17 +69,22 @@ public class GameRepo : IGameRepo
|
|||||||
public void StartDoubleEXP(TimeSpan lengthOfEffect)
|
public void StartDoubleEXP(TimeSpan lengthOfEffect)
|
||||||
{
|
{
|
||||||
CloseInventory?.Invoke();
|
CloseInventory?.Invoke();
|
||||||
AnnounceMessage?.Invoke("Experience points temporarily doubled.");
|
AnnounceMessageOnMainScreen("Experience points temporarily doubled.");
|
||||||
DoubleExpTimeStart?.Invoke(lengthOfEffect.Seconds);
|
DoubleExpTimeStart?.Invoke(lengthOfEffect.Seconds);
|
||||||
ExpRate = 2;
|
ExpRate = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndDoubleExp()
|
public void EndDoubleExp()
|
||||||
{
|
{
|
||||||
AnnounceMessage?.Invoke("Experience points effect wore off.");
|
AnnounceMessageOnMainScreen("Experience points effect wore off.");
|
||||||
ExpRate = 1;
|
ExpRate = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AnnounceMessageOnMainScreen(string message)
|
||||||
|
{
|
||||||
|
AnnounceMessage?.Invoke(message);
|
||||||
|
}
|
||||||
|
|
||||||
public void OnGameEnded()
|
public void OnGameEnded()
|
||||||
{
|
{
|
||||||
Pause();
|
Pause();
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using Chickensoft.Introspection;
|
||||||
|
using Chickensoft.LogicBlocks;
|
||||||
|
|
||||||
|
namespace Zennysoft.Game.Ma.Implementation;
|
||||||
|
|
||||||
|
public partial class InGameUILogic
|
||||||
|
{
|
||||||
|
[Meta]
|
||||||
|
public abstract partial record State : StateLogic<State>
|
||||||
|
{
|
||||||
|
protected State()
|
||||||
|
{
|
||||||
|
OnAttach(() =>
|
||||||
|
{
|
||||||
|
var gameRepo = Get<IGameRepo>();
|
||||||
|
gameRepo.AnnounceMessage += OnAnnounceMessage;
|
||||||
|
});
|
||||||
|
OnDetach(() =>
|
||||||
|
{
|
||||||
|
var gameRepo = Get<IGameRepo>();
|
||||||
|
gameRepo.AnnounceMessage -= OnAnnounceMessage;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnAnnounceMessage(string message)
|
||||||
|
{
|
||||||
|
Output(new Output.AnnounceMessage(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
using Chickensoft.Introspection;
|
||||||
|
using Chickensoft.LogicBlocks;
|
||||||
|
|
||||||
|
namespace Zennysoft.Game.Ma.Implementation;
|
||||||
|
|
||||||
|
public interface IInGameUILogic : ILogicBlock<InGameUILogic.State>;
|
||||||
|
|
||||||
|
[Meta]
|
||||||
|
[LogicBlock(typeof(State), Diagram = true)]
|
||||||
|
public partial class InGameUILogic : LogicBlock<InGameUILogic.State>, IInGameUILogic
|
||||||
|
{
|
||||||
|
public override Transition GetInitialState() => To<State.Active>();
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Zennysoft.Game.Ma.Implementation;
|
||||||
|
public partial class InGameUILogic
|
||||||
|
{
|
||||||
|
public static class Output
|
||||||
|
{
|
||||||
|
public readonly record struct AnnounceMessage(string Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
using Chickensoft.Introspection;
|
||||||
|
|
||||||
|
namespace Zennysoft.Game.Ma.Implementation;
|
||||||
|
|
||||||
|
public partial class InGameUILogic
|
||||||
|
{
|
||||||
|
public partial record State
|
||||||
|
{
|
||||||
|
[Meta]
|
||||||
|
public partial record Active : State
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -97,6 +97,7 @@ public partial class Game : Node3D, IGame
|
|||||||
GameLogic.Set(GameEventDepot);
|
GameLogic.Set(GameEventDepot);
|
||||||
GameLogic.Set(Player);
|
GameLogic.Set(Player);
|
||||||
GameLogic.Set(Map);
|
GameLogic.Set(Map);
|
||||||
|
GameLogic.Set(InGameUI);
|
||||||
Instantiator = new Instantiator(GetTree());
|
Instantiator = new Instantiator(GetTree());
|
||||||
RescuedItems = new RescuedItemDatabase();
|
RescuedItems = new RescuedItemDatabase();
|
||||||
|
|
||||||
@@ -185,10 +186,10 @@ public partial class Game : Node3D, IGame
|
|||||||
Input.MouseMode = Input.MouseModeEnum.Visible;
|
Input.MouseMode = Input.MouseModeEnum.Visible;
|
||||||
PauseMenu.SetProcessUnhandledInput(true);
|
PauseMenu.SetProcessUnhandledInput(true);
|
||||||
})
|
})
|
||||||
.Handle((in GameLogic.Output.LoadNextFloor _) => { Map.SpawnNextFloor(); })
|
|
||||||
.Handle((in GameLogic.Output.LoadMap _) => { Map.LoadMap(); })
|
|
||||||
.Handle((in GameLogic.Output.HidePauseMenu _) => { PauseMenu.Hide(); })
|
.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.ExitPauseMenu _) => { PauseMenu.FadeOut(); Input.MouseMode = Input.MouseModeEnum.Visible; PauseMenu.SetProcessUnhandledInput(false); })
|
||||||
|
.Handle((in GameLogic.Output.LoadNextFloor _) => { Map.SpawnNextFloor(); })
|
||||||
|
.Handle((in GameLogic.Output.LoadMap _) => { Map.LoadMap(); })
|
||||||
.Handle((in GameLogic.Output.ShowFloorClearMenu _) => { FloorClearMenu.Show(); FloorClearMenu.FadeIn(); })
|
.Handle((in GameLogic.Output.ShowFloorClearMenu _) => { FloorClearMenu.Show(); FloorClearMenu.FadeIn(); })
|
||||||
.Handle((in GameLogic.Output.ExitFloorClearMenu _) => { FloorClearMenu.FadeOut(); })
|
.Handle((in GameLogic.Output.ExitFloorClearMenu _) => { FloorClearMenu.FadeOut(); })
|
||||||
.Handle((in GameLogic.Output.OpenInventory _) => { InGameUI.ShowInventoryScreen(); InGameUI.InventoryMenu.SetProcessInput(true); })
|
.Handle((in GameLogic.Output.OpenInventory _) => { InGameUI.ShowInventoryScreen(); InGameUI.InventoryMenu.SetProcessInput(true); })
|
||||||
@@ -199,7 +200,6 @@ public partial class Game : Node3D, IGame
|
|||||||
.Handle((in GameLogic.Output.HideAskForTeleport _) => { GameRepo.Resume(); InGameUI.UseTeleportPrompt.FadeOut(); InGameUI.SetProcessInput(false); })
|
.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.ShowLostScreen _) => { DeathMenu.Show(); DeathMenu.FadeIn(); })
|
||||||
.Handle((in GameLogic.Output.ExitLostScreen _) => { DeathMenu.FadeOut(); })
|
.Handle((in GameLogic.Output.ExitLostScreen _) => { DeathMenu.FadeOut(); })
|
||||||
.Handle((in GameLogic.Output.AnnounceMessage output) => { AnnounceMessageOnMainScreen(output.Message); })
|
|
||||||
.Handle((in GameLogic.Output.DoubleExpTimeStart output) => { DoubleEXPTimer.WaitTime = output.lengthOfTimeInSeconds; DoubleEXPTimer.Start(); })
|
.Handle((in GameLogic.Output.DoubleExpTimeStart output) => { DoubleEXPTimer.WaitTime = output.lengthOfTimeInSeconds; DoubleEXPTimer.Start(); })
|
||||||
.Handle((in GameLogic.Output.SaveGame _) =>
|
.Handle((in GameLogic.Output.SaveGame _) =>
|
||||||
{
|
{
|
||||||
@@ -364,11 +364,6 @@ public partial class Game : Node3D, IGame
|
|||||||
InGameUI.InventoryMenu.ShowMessage(message);
|
InGameUI.InventoryMenu.ShowMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AnnounceMessageOnMainScreen(string message)
|
|
||||||
{
|
|
||||||
InGameUI.PlayerInfoUI.DisplayMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IDungeonFloor CurrentFloor => Map.CurrentFloor;
|
public IDungeonFloor CurrentFloor => Map.CurrentFloor;
|
||||||
|
|
||||||
public void EnemyDefeated(Vector3 defeatedLocation, EnemyStatResource resource)
|
public void EnemyDefeated(Vector3 defeatedLocation, EnemyStatResource resource)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ using Chickensoft.AutoInject;
|
|||||||
using Chickensoft.GodotNodeInterfaces;
|
using Chickensoft.GodotNodeInterfaces;
|
||||||
using Chickensoft.SaveFileBuilder;
|
using Chickensoft.SaveFileBuilder;
|
||||||
using Godot;
|
using Godot;
|
||||||
using System;
|
|
||||||
using Zennysoft.Game.Ma.Implementation;
|
using Zennysoft.Game.Ma.Implementation;
|
||||||
|
|
||||||
public interface IGame : IProvide<IGameRepo>, IProvide<IGameEventDepot>, IProvide<IGame>, IProvide<IPlayer>, IProvide<ISaveChunk<GameData>>, INode3D
|
public interface IGame : IProvide<IGameRepo>, IProvide<IGameEventDepot>, IProvide<IGame>, IProvide<IPlayer>, IProvide<ISaveChunk<GameData>>, INode3D
|
||||||
@@ -32,8 +31,6 @@ public interface IGame : IProvide<IGameRepo>, IProvide<IGameEventDepot>, IProvid
|
|||||||
|
|
||||||
public void AnnounceMessageOnInventoryScreen(string message);
|
public void AnnounceMessageOnInventoryScreen(string message);
|
||||||
|
|
||||||
public void AnnounceMessageOnMainScreen(string message);
|
|
||||||
|
|
||||||
public void FloorExitReached();
|
public void FloorExitReached();
|
||||||
|
|
||||||
public void NextFloorLoaded();
|
public void NextFloorLoaded();
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ public partial class Player : CharacterBody3D, IPlayer
|
|||||||
public override void _Notification(int what) => this.Notify(what);
|
public override void _Notification(int what) => this.Notify(what);
|
||||||
|
|
||||||
private PlayerLogic.IBinding PlayerBinding { get; set; } = default!;
|
private PlayerLogic.IBinding PlayerBinding { get; set; } = default!;
|
||||||
|
|
||||||
|
[Dependency] private IGameRepo _gameRepo => this.DependOn<IGameRepo>();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Save
|
#region Save
|
||||||
@@ -233,22 +235,22 @@ public partial class Player : CharacterBody3D, IPlayer
|
|||||||
var isAdded = Inventory.TryAdd(inventoryItem);
|
var isAdded = Inventory.TryAdd(inventoryItem);
|
||||||
if (isAdded)
|
if (isAdded)
|
||||||
{
|
{
|
||||||
Game.AnnounceMessageOnMainScreen($"{inventoryItem.ItemName} picked up.");
|
_gameRepo.AnnounceMessageOnMainScreen($"{inventoryItem.ItemName} picked up.");
|
||||||
inventoryItem.QueueFree();
|
inventoryItem.QueueFree();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Game.AnnounceMessageOnMainScreen($"Could not pick up {inventoryItem.ItemName}.");
|
_gameRepo.AnnounceMessageOnMainScreen($"Could not pick up {inventoryItem.ItemName}.");
|
||||||
}
|
}
|
||||||
if (area.GetParent() is DroppedItem droppedItem)
|
if (area.GetParent() is DroppedItem droppedItem)
|
||||||
{
|
{
|
||||||
var isAdded = Inventory.TryAdd(droppedItem.Item);
|
var isAdded = Inventory.TryAdd(droppedItem.Item);
|
||||||
if (isAdded)
|
if (isAdded)
|
||||||
{
|
{
|
||||||
Game.AnnounceMessageOnMainScreen($"{droppedItem.Item.ItemName} picked up.");
|
_gameRepo.AnnounceMessageOnMainScreen($"{droppedItem.Item.ItemName} picked up.");
|
||||||
droppedItem.QueueFree();
|
droppedItem.QueueFree();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Game.AnnounceMessageOnMainScreen($"Could not pick up {droppedItem.Item.ItemName}.");
|
_gameRepo.AnnounceMessageOnMainScreen($"Could not pick up {droppedItem.Item.ItemName}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ using Chickensoft.AutoInject;
|
|||||||
using Chickensoft.GodotNodeInterfaces;
|
using Chickensoft.GodotNodeInterfaces;
|
||||||
using Chickensoft.Introspection;
|
using Chickensoft.Introspection;
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using Renci.SshNet.Messages;
|
||||||
|
using Zennysoft.Game.Ma.Implementation;
|
||||||
|
|
||||||
namespace Zennysoft.Game.Ma;
|
namespace Zennysoft.Game.Ma;
|
||||||
|
|
||||||
@@ -31,9 +33,34 @@ public partial class InGameUI : Control, IInGameUI
|
|||||||
|
|
||||||
[Node] public IUseTeleportPrompt UseTeleportPrompt { get; set; } = default!;
|
[Node] public IUseTeleportPrompt UseTeleportPrompt { get; set; } = default!;
|
||||||
|
|
||||||
|
[Dependency] private IGameRepo _gameRepo => this.DependOn<IGameRepo>();
|
||||||
|
|
||||||
|
public IInGameUILogic InGameUILogic { get; set; } = default!;
|
||||||
|
|
||||||
|
public InGameUILogic.IBinding InGameUILogicBinding { get; set; } = default!;
|
||||||
|
|
||||||
[Signal]
|
[Signal]
|
||||||
public delegate void MinimapButtonReleasedEventHandler();
|
public delegate void MinimapButtonReleasedEventHandler();
|
||||||
|
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
InGameUILogic = new InGameUILogic();
|
||||||
|
InGameUILogic.Set(_gameRepo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnResolved()
|
||||||
|
{
|
||||||
|
InGameUILogicBinding = InGameUILogic.Bind();
|
||||||
|
|
||||||
|
InGameUILogicBinding
|
||||||
|
.Handle((in InGameUILogic.Output.AnnounceMessage output) =>
|
||||||
|
{
|
||||||
|
PlayerInfoUI.DisplayMessage(output.Message);
|
||||||
|
});
|
||||||
|
|
||||||
|
InGameUILogic.Start();
|
||||||
|
}
|
||||||
|
|
||||||
public override void _UnhandledInput(InputEvent @event)
|
public override void _UnhandledInput(InputEvent @event)
|
||||||
{
|
{
|
||||||
if (@event.IsActionReleased(GameInputs.MiniMap))
|
if (@event.IsActionReleased(GameInputs.MiniMap))
|
||||||
|
|||||||
Reference in New Issue
Block a user